bumpsmith

An agent that turns a failing pydantic v1–to–v2 migration into a reviewed pull request — and stops when it cannot.

What these are

Every page below is a real run against a real repository, rendered from the same JSON the tool writes with --json. Three of the four end without a migration. That is the point: a migration tool that always edits something is not reporting what it found, it is guessing.

The runs

Three real breaks, then a stop

reverted

The flagship run. It peels three genuine pydantic v1-to-v2 breaks off a real SDK — a __root__ field across 19 sites, regex= across 5, a validator's field/config pair — and then meets a failure it cannot classify. It does not guess. It reverts all three, and git diff on the checkout afterwards is empty.

https://github.com/emnify/emnify-sdk-python.git · pydantic 1.10.26 · at 1c595e480602

One site found, and deliberately not rewritten

untouched

The rule matches one site. The rewriter declines it: field_not_none reads field inside its own body, and v2 passes nothing to rebind it from, so removing the parameter would leave a name that is not defined. The run ends untouched and marks itself not complete rather than claiming a migration it did not perform.

https://github.com/data-mie/dbt-cloud-cli.git · pydantic 1.10.10 · at cb2680d35372

A break with no rewriter, said out loud

untouched

The break arrives through a dependency rather than the project's own source. bumpsmith classifies it, names the rule, and then reports that no rewriter is written for it — because the name is still read further down the file, and deleting the site alone would swap this error for a NameError. The classification is still useful output; the edit is not made.

https://github.com/cloudblue/connect-eaas-core.git · pydantic 1.10.26 · at 25ab907b9a4b

A migration that is kept

migrated

The other half of the claim. Two breaks, both fixed, suite green, edits kept. The interesting part is the edit it did *not* make: a class body that rebinds conlist to something of its own before using it is left alone, because at that point the name is no longer pydantic's.

a small fixture written for this project · pydantic 1.10.x

Where TrueForge fits

The loop refuses to edit a checkout in one place and test it in another, because the suite would then answer a question about code the edits never reached. So the whole migration goes into a TrueForge sandbox together — clone, edit, run, revert — one sandbox per repository, many at once. Opening a pull request is gated on a human answering through the harness, and the destination is never inferred from the clone's own origin.

Source, review log and pull request history on GitHub