Rebuilds from a spec
Change the spec. Graft rebuilds the code blind.
We moved a flag from 80 to 78 °F by editing the spec and two lines of its reference model. Rebuilt without seeing the old code, it passed 215 of 215 cases and 1,500 of 1,500 hidden requests. Of the 1,892 answers we compared, 0 changed that nobody asked for.
Works today on programs that answer one request at a time. Stateful code and UIs are not supported yet.
Check the signed record yourself: npx graftfork verify-record po1qEN54ReZWLwQmIakuqQ.json
Two ways in
Have a spec, or have a fork
Have a spec?
Change it, and Graft rebuilds the code. It keeps the build only if every case passes, and you see every answer that changed. On Premium, Team and Enterprise. On Free you can connect the heat-engine example, read its grade and check its weakened record.
Have a fork?
Your commits and their reasons already record what you meant. Graft carries them onto each upstream release, runs your tests, and has the moved branch ready for you only if every change lands and nothing new fails. No spec needed to start.
No fork to hand? One click on a real one: pattonw/tqdm, clarketm/pflag or one that stays. Or sign up free to connect yours.
Trying a fork is closed until Graft opens, for everyone. Your dashboard works: connect your copy in Copies, or rebuild a program from its spec in Specs (how rebuilds work).
A real try of pattonw/tqdmpattonw/tqdm, replayed. Or watch the 30-second walkthrough.
Three edits, three results
The code is replaceable. The behaviour stays where the spec puts it.
A repository keeps a program's spec as a duramen record: its requirements, worked examples, decisions, and a small reference model of the program you can run (the oracle). Builders that never see your code write it again in TypeScript, Python, Rust or Go. A change made on a branch is rebuilt and compared, answer by answer, with the last kept build.
- Retitled a requirement: 0 of 1,760 answers changed.
- Added a rule: 194 of 1,960 changed, and every one is now
bad_request. - Rebuilt the unchanged record twice: the two builds agreed on all 1,628 requests.
How a rebuild is kept honest
- The builder never sees your code. It gets the brief and nothing else: no repository, no token, no network.
- The builder is never the judge. Each build runs as a separate user with no network. Hidden requests are answered by your reference model, not by another AI model. Anything less than every case changes nothing in your repository.
- A free check grades the spec first. No model and no builder run. A half-done edit graded thin with 6 errors, at $0.
- Every rebuild is signed, kept or not. Anyone holding the record can check it with one command.
Limits
What it can't do yet
- Rebuilds fit only programs that answer one request at a time. Stateful services, UIs and timing are on the roadmap.
- We have measured the judge on one program. 1 in 130 planted faults got past it.
- A person has to keep the reference model (the oracle) right, and approve every edit an agent makes to it.
- Under half of fork syncs with a conflict move: 15 of 34 moved with Graft's agent. The rest stay, with the reason.
Keep a fork current
Three screens, from a try to a moved copy



Real results
Four real forks, including one that stayed
From our benchmark of real forks on GitHub, each read by hand afterwards. A copy that stays is the safety rule working: nothing moves until every change lands and the tests pass.
tqdm/tqdm: from v4.66.1 onto v4.70.1
- keptadd a train
- keptfix some small spacing bugs
- keptmove import to top of file
- keptmake train optional
- keptuse custom random state to not interfere with other generators
Tests pass on the new release with the changes. Checked by hand: correct. Measured 2026-10-28.
fastapi/typer: from commit f83c66d, between releases onto 0.9.1
- kept#88: Add asyncio support
- kept#88: Fix unrelated failing test of powershell autocomplete
- kept#88: Fix the mypy linter
- kept#88: Remove the loop factory to simplify the PR and make mypy happy
- kept[pre-commit.ci] Auto format from pre-commit.com hooks
Tests pass on the new release with the changes. Checked by hand: correct. Measured 2026-10-28.
marshmallow-code/marshmallow: from commit ba8b512, between releases onto 4.3.1
- droppedFix Constant field rejecting None values during load
- droppedUpdate changelog and AUTHORS
Tests pass on the new release with the changes. Checked by hand: correct. Measured 2026-10-28.
tqdm/tqdm: from commit ebda712, between releases onto v4.70.1
- keptAdded Additional Base Functionality
- keptAdded current time
- keptPrinting also conforms to bar format
- stuckHardening the last commit
- not triedFixes #1,2
Stopped before the tests decided anything. Nothing moved. Measured 2026-10-28.
The problem
Changing open source is easy now. Keeping the change is not.
You, or your agent, fixed the thing that bothered you in a tool you use. It works. Then upstream ships a release, and you have three choices.
Redo your changes
Rebase by hand, read the conflicts, remember why you made each change. Again on the next release.
Fall behind
Stay on the old release and miss its fixes, including the security ones, until the gap is too big to close.
Let Graft carry them
Graft moves your changes onto each release, checks them with your tests, and asks you only when it needs your call.
Patched dependencies too: if your project patches its npm dependencies (patch-package, or pnpm or bun patchedDependencies), Graft carries each patch onto the package's newest version, retires the ones the new version already has, and checks the result with your tests. In a sample of 141 real patch-package patches, two-thirds no longer applied on their package's latest release. How
Sign up free
The free plan is open to everyone
Give your email and we send you a sign-up link at once. The first time, you set up a 6-digit code from an authenticator app; after that you sign in with the code. Tell us the copy you'd want kept current, if you like. Premium is an upgrade inside your dashboard once you're in.
- CostFree, with up to 10 syncs a month and 5 copies. Premium is $12 a month.
- NeedsA repository on GitHub, or on any git host by its address, with your changes as commits on top of an upstream release.
- TestsFound by themselves for Python and Node projects; anything else takes a short
.graft.yml.
You're in. Check your email for a link from noreply@graftfork.com. It works once. It lasts 72 hours for a new account, or 30 minutes if you already have one; if it runs out, ask for a new one at sign in. The first time, you also set up a 6-digit code from an authenticator app. Not there in a minute? Look in Spam or Junk: Graft is new, so some mail apps file us there at first. Add noreply@graftfork.com to your contacts, or mark it "Not junk". When a lot of people sign up at once, the link can take up to an hour. Still nothing after that? Email support@graftfork.com.
You're in, and your account is ready. We're sending a lot of links right now, so yours is in the queue: it comes from noreply@graftfork.com, usually within the hour. Nothing there after an hour? Look in Spam or Junk, or email support@graftfork.com.
Thanks, we've got your sign-up. Some sign-ups get a quick look from a person before the account opens, and yours is one of them, so there's no link in your email yet. When it's open, we email you from noreply@graftfork.com, usually within a day. Not heard from us by then? Email support@graftfork.com.
Thanks. We've got your address. We haven't sent you a link yet; when we do, it comes from noreply@graftfork.com. Not heard from us in a day? Email support@graftfork.com.
How it works
Three steps, then it runs on every release
- upstreamv2.0.0 ships
- change 1config path: applies, kept
- change 2logging: conflicts in src/log.ts
- agentrewrites change 2 onto the new code
- change 3retry flag: applies, kept
- your testsno new failures next to v2.0.0 as shippedtest_retry_timeout fails, and only with your changes on
- resultmoved:
graft/v2.0.0waits for you to take itstayed: your copy is still on v1.4.0, and the report names the test
Connect your copy
Install Graft's GitHub app on your repository, or give its git address on any other host, and say which upstream it follows and which release your changes sit on. Your changes are the commits after that release.
A release ships
Graft carries each change onto it in a short-lived sandbox: kept, dropped because upstream has it now, or rewritten. Then it runs your tests on the result and on the release as shipped.
You get a moved branch, or a reason
If everything lands and your tests pass, Graft keeps the moved branch for you, with a note on every change. Take it when you want. If not, your copy stays where it was and you're told why.
Time and money
What carrying a fork costs by hand, and what Graft costs
Put in your own numbers. The defaults are a survey's average for a company's private fork and a median wage, both linked, so treat the result as a rough estimate.
- By hand, a year
- 720 hours, $46,800
- 3 forks × 4 releases × 60 hours = 720 hours; × $65 = $46,800
- Graft's plan, a year
- $144
- Premium: $12 a month × 12 = $144, for up to 5 copies and 40 syncs a month
- Agent work, if every sync conflicted
- $6.60
- 12 syncs × $0.55 = $6.60, inside the $72 a year Premium includes
An estimate, not a quote. A sync where every change applies needs no agent work at all. A sync that did need Graft's agent cost about $0.55 at the median in production (October 2026), and one sync never spends more than $1.25. Plan prices are from pricing and Team: Premium is $12 a month with $6 of agent work included; Team is $15 per fork a month with $6 of agent work each, up to 20 forks. No overage is ever billed. Your own time with Graft, reading each move and taking it, isn't measured, so it isn't in the sum.
The safety promise
It never moves you onto a copy that fails your checks.
That's narrower than "it's always right," on purpose. Agents miss some calls and tests don't catch everything. So the rule is built to stay put when in doubt:
- Move only when everything lands. Every change is kept, dropped because the new release already has it, or rewritten. If any change is stuck, nothing moves.
- Move only when the checks pass. Your tests run on the carried copy and on the new release as shipped. The carry passes when it adds no failure that upstream, or your copy before the move, didn't already have.
- No unchecked rewrites. A rewrite, by Graft's agent or by an agent on your own key, is accepted only when tests exist to check it and none of them was already failing.
- No drop on an agent's word when the file is gone. If the release deleted a file your change touched, an agent saying the change is no longer needed isn't accepted as proof: the code may have moved.
- No keep that deletes. Keeping a change is refused if it would delete or empty a file.
- Otherwise, stay. Your branch is never touched; by default Graft writes nothing to your repository. If an agent needs your call, you get the question with its options instead of a dead end.
For agents
Add Graft to Claude Code
When your agent changes a dependency, a fork or a vendored package, keeping that change alive is one call. Graft's plugin teaches Claude Code to write why it made each change into the commit, in the form Graft reads, and to track the repository with Graft. Your agent can then check on syncs and see why one stayed, and an agent that tracks a copy can resolve that copy's conflicts itself. Graft still runs your tests before anything moves.
- One install in Claude Code, then sign in from your browser.
- Any MCP client works too:
https://graftfork.com/mcp, Streamable HTTP, OAuth sign-in or a bearer token. - A plain HTTP API for scripts and other agents, with an OpenAPI description.
In Claude Code:
/plugin marketplace add craigm26/graft-claude-code/plugin install graftfork@graftforkHad the plugin under its old name, graft (1.5 or earlier)? Claude Code keeps the name the marketplace had when you added it, graft-claude-code, so install graftfork@graft-claude-code instead, then /plugin uninstall graft@graft-claude-code, and sign in again from /mcp. Upgrading
Restart Claude Code, run /mcp, choose plugin:graftfork:graftfork and sign in. For CI, see the token option.
Then ask Claude:
Track this fork with Graft and tell me how my copies are doing.Measured
What we've measured so far, wins and stays
We ran the sync on real forks and on Debian's release history before inviting anyone. These are the results as of 2026-10-28, and we update them when we rerun.
What stopped the 14 that stayed
- 5 the agent wasn't sure enough of its fix
- 4 the fork's own changes already fail upstream's tests
- 3 the agent asked the person for a decision
- 2 a partial drop: part of a change was already upstream
7 of 12 syncs onto the next release moved, and 3 of 12 onto the newest. These runs used one Claude Code agent at the default settings. A stay changes nothing in your repository: you get the reason, and a question when an agent needs your call. Syncing each release as it ships moves more often than catching up later.
Every sync, moved or stayed, with its reason, is on the results page, next to the live outcomes of hosted syncs since launch. The data and method are in the evidence repository.
A second measurement, the credit sweep of 2026-10-31 to 11-02, replayed real forks against the merges their own people made. Of the forks it ran, 13 of 18 clean syncs moved, each byte-identical to that merge, and 15 of 34 runs with a conflict moved with Graft's agent, 8 of them matching the merge in every file the fork changed. Of the forks picked in advance, 12 of 30 clean ones and 6 of 24 with conflicts were never run. The details are on the results page.
Why Graft
What sets it apart from the other ways to keep a fork current
- Automatic and hosted. It watches upstream's releases and runs each sync for you. Nothing to schedule or keep running.
- Works on the fork you already have. Your commits as they are, merges included. Fork sync reads the commits you already have, so no spec is needed. When you want a program kept by its spec instead, that's a rebuild.
- A safety rule Graft enforces, not the agent. A copy moves only when every change lands and no new test fails. A final check confirms every change is there.
- Every result is public. Moves and stays, on the results page. Our launch-day bug is on the changelog.
For teams
Every fork your company keeps, carried and reviewed
Find every fork in your GitHub organization, how far behind it is and which security fixes it hasn't taken. Then Graft carries them onto each release, with a reviewer's approval, an audit log and a signed record of every move.
- Fork inventory. A dry sync of every fork, never pushed, with the security fixes it's missing.
- Review step. Someone other than the fork's owner approves each move, or asks, or sends it back.
- Signed records. What moved, why, which tests ran and who approved, checkable by anyone.
- Your own Anthropic account. On Enterprise, the sandboxes run in your workspace, and report only keeps your code out of Graft.
Plans
Free when nothing conflicts. Premium resolves conflicts too.
Free
- A sync on every upstream release, in a sandbox
- Your tests run before anything moves
- A moved branch with a note on every change, ready when you are
- Moves automatically when nothing conflicts
- Your first conflict is resolved free, automatically, while the month's trial budget lasts
- Or resolve conflicts automatically with your own Anthropic key
- An early warning, checked weekly, when a coming release would conflict
- Up to 10 syncs a month and 5 copies per person
Premium
Everything in Free, and conflicts are resolved automatically too, by Graft's agent, checked by your tests.
- $6 of agent work included each month, with no overage charges
- Up to 40 syncs a month
- Early warnings checked nightly
- Cancel any time; Premium runs to the end of the month you paid for
Upgrade from your dashboard once you're in. What's included.
For a company's forks: Team is $15 per fork a month, and Enterprise is by contract. Team and Enterprise plans.
Keep your changes and keep getting updates
The free plan stays free. You can disconnect a copy at any time, and Graft never pushes to your branch.