graftfork is now in Claude's connector directory. Connect it in Claude

graftfork

Docs / Rebuilds

Rebuild from a spec

If a repository keeps its program in a duramen record, Graft can write the implementation again from the record alone, judge it with the record's own suite and hidden requests, and keep it only when every case passes. This page walks through it once, start to finish, on duramen's own heat-engine example. Why it works this way is on Regenerative software, and a real change made this way is replayed step by step.

Rebuilds are on Premium, and for members of a Team or Enterprise organization. Everything here happens in the Specs tab of your dashboard; the same steps work from an agent (Agents and Claude Code) or a script (HTTP API). On Free, the Specs tab offers the heat-engine example only: connect it, read its free grade, and check its weakened record; rebuilding it needs Premium, Team or Enterprise.

  1. 01What a duramen record is

    A duramen record is one .duramen file, or a folder of them, that holds a program's requirements, worked examples, decisions, the gaps left open on purpose, and an executable model of the program (the oracle). duramen check runs every example through the oracle before any implementation exists, so the record is tested on its own. duramen build turns the record into a brief for a builder and a suite of cases for a judge, from the same source, so they can't drift apart.

    The record is what you keep. The implementation is what Graft rebuilds from it. If a rebuild passes, the record said enough; where builds disagree, the record left a choice open, and that's a place to add an example.

  2. 02Connect a spec

    In /app, press Connect the heat-engine example: it reads a public copy of duramen at d843e00, so there is nothing to fork. It is craigm26/graft-lab on the branch lab/heat: the heat-engine record, its TypeScript implementation and 2 blind builds a rebuild. Graft grades it at once (step 03), and it doesn't use one of your spec slots. A kept rebuild of it is a bundle to take; pull requests, rebuilding on a push and editing the record in Graft come with your own repository on Graft's GitHub app. graft-lab also holds the two changes steps 07 and 10 use, each on a branch of its own.

    Your own fork

    A spec is a repository, a branch, the record's path and the folder its implementation lives in. In Specs, fill in Connect your own spec. The repository comes one of two ways:

    • A fork through Graft's GitHub app. Fork duramen, add the fork to Graft's GitHub app (Specs links to it under Repository; how), and choose it under Repository. Only this way can a push to the record grade it again on its own, and only this way can a rebuild open a pull request.
    • Its https git address. Any git host, for example your fork's https://github.com/<you>/duramen.git. Graft reads it; nothing is ever written there. Use your own fork: the deletion test and Try a change need a push, and upstream's address works for reading only.

    Connect heat-engine at d843e00, not at today's main. Every number on this page was measured on duramen at commit d843e00, so connect that commit to compare yours with them. duramen's main has moved on since: 8c9dc11 (November 1) adds draw lines to heat.duramen. Graft runs duramen 0.3.0, which reads them, so a spec on today's main checks clean and can be rebuilt too, but its numbers won't be the ones here. Connect the branch heat-d843e00: craigm26/duramen has it at d843e00. A fork made with "Copy the main branch only" won't have it, so fork with all branches, or run this in a clone of your fork:

    git push origin d843e00:refs/heads/heat-d843e00

    For heat-engine:

    Branch
    heat-d843e00 (at d843e00)
    Record
    examples/heat-engine/heat.duramen
    Implementation's folder
    examples/heat-engine/regen/impl/t06-ts (the folder a rebuild replaces)
    Language
    TypeScript. Python, Rust and Go are open too; Rust and Go use the standard library only.
    Blind builds per rebuild
    1 to 3. One costs least. Two or more also show where independent builds chose differently.

    From a terminal, the same spec with graftfork 0.3.1 or later (npm install -g graftfork, with GRAFT_TOKEN set to a personal API token from Settings made with Read and Act (sync) ticked; Act is off by default, and connect and run need it), for a fork through the GitHub app:

    graft regen connect <you>/duramen --branch heat-d843e00 --record examples/heat-engine/heat.duramen --impl examples/heat-engine/regen/impl/t06-ts --lang ts --builds 2

    For a fork by its address, give https://github.com/<you>/duramen.git in place of <you>/duramen. Leave out --builds and the spec gets 1 build: it costs about half, and step 05 has no second build to compare. It prints the spec's id. Graft grades the record on its own, and graft regen report <spec id> shows the free report about a minute later. graft regen run <spec id> rebuilds it, with --max-usd <n> for its budget.

    Use graftfork 0.3.1 or later (why).

    Leave "Rebuild when a push changes the record" off for now: with it on, a push starts a paid rebuild instead of a free report.

    You can connect up to 5 specs of your own, besides the example. Start with one or two; disconnect a spec to free its place.

  3. 03The free report and its grade

    As soon as a spec is connected, Graft grades its record before anything is spent. It runs duramen check, and, when the record names its oracle, plants mistakes in the oracle's code to see whether the cases catch them. No builder and no model are involved. It takes about a minute, and the first 20 reports a day are free.

    The grade is one of three, with its reasons first:

    • Thin. The record doesn't pass duramen check, a requirement has no example, evidence or property, or the cases catch under 80% of the planted mistakes that change an answer. A build could do almost anything there, so a rebuild proves little.
    • Usable. There's no oracle, no mutation score, a requirement rests on the oracle alone, or the cases catch under 95%.
    • Strong. None of the above.

    heat-engine at duramen's d843e00 grades strong: 22 requirements and 69 examples. Press Grade again after you change the record.

  4. 04Rebuild: cost and time

    Press Rebuild now. Under the button, Graft shows an estimate from real rebuilds, how many of them passed, and what a rebuild may spend: $2 by default, or the spec's own lower limit (max_usd, set through the API). A rebuild never spends more than that unless you allow it, or more than the agent work your plan has left. The cost is the blind builders' work, and it comes out of your plan's agent work, the same allowance syncs use.

    If the estimate is over that limit, nothing starts yet. Specs asks first, with the likely cost and two ways on: Rebuild with up to the estimate (when your agent work covers it), or Rebuild on the limit anyway, which may stop before it finishes; what it spent is spent. Not now leaves it. While the free grade of a spec that was never rebuilt is still running, Rebuild now waits for it; after that, Rebuild now asks before it stops a grade.

    Three phases follow, each in its own sandbox:

    1. The brief. Graft clones the branch and runs duramen check and duramen build.
    2. The blind builds. Each builder gets the brief and nothing else: no copy of your repository, no token and no network. Graft checks with Anthropic that the builders' environment has no network before they start.
    3. The judge. In another sandbox, each build runs against the record's suite, then against hidden requests the builder never saw, compared with the oracle's answers.

    Graft runs a limited number of rebuilds at once across everyone, so yours may wait in the queue first. Measured on heat-engine at d843e00 in production. The TypeScript rebuild had 2 blind builds, about $0.40 a build; the Rust and Go rebuilds had 1 each:

    LanguageResultAgent workRebuild
    TypeScriptPassed 215/215 cases and 1,500 hidden requests, in 4 minutes$0.86eGgYcAA0CyTwCpX0SpnuWg
    RustPassed, in 12 minutes$0.56UzSIJPaZB5BEfwgnITwJNA
    GoPassed, in 12 minutes$0.49NKncdSsVSVWSO8My9apkTQ

    A heat-engine rebuild takes about 4 to 12 minutes on Graft's runner, plus any wait in the queue: 4 to 7 minutes in TypeScript (five rebuilds at d843e00, from eGgYcAA0CyTwCpX0SpnuWg at 4.0 to po1qEN54ReZWLwQmIakuqQ at 7.2), and about 12 in Rust and Go. A large record takes longer.

    The tab checks on a running rebuild every 20 seconds, and Graft emails you when a rebuild ends, if result emails are on in Settings. A change order's check or rebuild, and a rebuild from a branch's record, send no email: their result appears where you started them.

  5. 05Reading the result

    Each rebuild ends as one of these. Press Details to see why.

    • Passed: kept. A build passed every case and every hidden request. Graft keeps it for you to take.
    • Not kept. No build passed. The reason names the first failures, for example "passed 210 of 215 cases".
    • Didn't finish. Something stopped the rebuild before a verdict, such as a time limit.
    • Unchanged: nothing to rebuild. The brief and the model are the same as a rebuild that already passed, so no builder started and nothing was spent on builders. Rebuild anyway builds regardless.

    In Details:

    • Each build's verdict and its cost. The Suite column reads like 215/215.
    • Hidden requests. After the suite, the judge asks each build requests drawn at random with a seed from the rebuild's id, and compares the answers with the oracle's. One different answer fails the build. A request the oracle itself can't answer is counted apart and never fails a build.
    • Choices. Every builder writes down each place the brief left it to decide. Graft compares those with the previous passing rebuild: "Chosen differently", "New" and "Gone" are the places your spec's words don't settle yet. The first passing rebuild has nothing to compare with.
    • Where the spec doesn't decide (the spec doctor): failing cases by requirement, places the builds chose differently from each other or from the last passing rebuild, and hidden requests a build answered differently from the oracle. Each one is a place an example in the record would pin down. One entry two builders headed differently counts once: entries naming the same requirement, open item or decision ID, or with near-identical headings, are matched. Two entries naming different IDs never are, and a pair only counts as the same choice when its headings are near-identical and both builders wrote the choice down. The count says how many of the places the record already declares open (an OPEN- item) and how many it doesn't.
    • Isolation. In words: the judge ran each build as a user of its own, which can't read the record or its oracle, with no network; the builders had no network; for Rust and Go, how long compiling took; and who started the rebuild.
  6. 06Taking a rebuild

    A passing rebuild is kept on a branch, graft/regen/<id>: the implementation's folder replaced, as one commit on the commit it was built from. Nothing is written to your repository. Under Take this rebuild, Details shows two commands for your clone; the download link works for an hour, and opening Details again makes a new one:

    curl -fsSL -o graft-regen-<id>.bundle '<link>'
    if git fetch graft-regen-<id>.bundle 'refs/heads/graft/regen/<id>:refs/heads/graft/regen/<id>'; then rm graft-regen-<id>.bundle; echo "Fetched graft/regen/<id>. Switch to it with: git switch graft/regen/<id> (or take it into <branch>: git checkout <branch> && git merge --ff-only graft/regen/<id>)"; else echo "Nothing was changed: git did not take graft/regen/<id> (its reason is above). If graft/regen/<id> already exists here with commits of its own, keep them under another name first (git branch -m graft/regen/<id> graft/regen/<id>-mine), or switch away from it if it is checked out, then run this line again."; fi

    The fetch is never forced and switches nothing: where your clone already has the branch with commits of its own, git refuses and nothing changes.

    Your clone needs the commit the rebuild was built from. The bundle carries only the new commit, not its history. A clone of your fork has it when the fork includes that commit (d843e00 for the runs above, which every later duramen main includes). If git fetch says a prerequisite commit is missing, update your clone from the branch the spec follows and run the commands again.

    From a terminal, graft regen status <rebuild id> prints the same commands (graftfork 0.3.1 or later: npm install -g graftfork). graft pull takes a sync's move, not a rebuild.

    A spec connected through Graft's GitHub app can also get a pull request for each passing rebuild: on the spec in Specs, set When a rebuild is kept to Keep it and open a pull request (or delivery in the HTTP API). A spec connected by its address is always a bundle to take.

  7. 07The deletion test

    The report should notice when a record loses what pins a requirement down. On the heat-engine example, press Weaken the record (free check) (free within the day's 20 free reports; the button shows the price after that): it grades invitee/heat-weak on graft-lab, where req FL-003 "Non-finite °F" has lost its only example. In about a minute and a half its grade is thin, beside the example's own grade, with reasons such as "REQ-FL-003 has no example, evidence or property: a build can do anything there". The weakened grade stays on the check, never on the spec.

    On your own fork:

    1. In examples/heat-engine/heat.duramen, under req FL-003 "Non-finite °F", delete its only example: the four lines from example flagF {"wetBulbF": "NaN"}. Push to the branch the spec follows.
    2. On a spec connected through the GitHub app, that push grades the record again on its own, free. On a spec connected by address, press Grade again.
    3. In about a minute and a half the grade is thin, with reasons such as "the record has 1 error in duramen check" and "REQ-FL-003 has no example, evidence or property: a build can do anything there".
    4. Then put the example back: git revert HEAD in your clone, and push. The grade is strong again (on a spec connected by address, press Grade again). Steps 10 and 11 start from this branch, so do this before them: from the record without the example, nothing can be built.
  8. 08Judge it again

    On a finished rebuild's Details, Judge these builds again runs the same builds, as Graft stored them, through today's judge: the same commit and brief, and a fresh draw of hidden requests. It answers "would these still pass?" without trusting the first judge. It delivers nothing and spends none of your agent work. The result lists each build: whether it passes now, and whether that matches its first verdict.

    Through the API you can ask for the same hidden requests again (same_seed) and name the rebuild's own duramen release (duramen_ref); another release is refused for now, because duramen writes its version into the brief, so another release's brief never matches the one the builders were given.

    The graft command line covers connect, report, run, status and verify-record. Judging again is in Details, the HTTP API (POST /api/v1/regen/runs/{id}/rejudge) and the MCP tool regen_rejudge, and so are drafts (below).

  9. 09Check the signed record

    Every finished rebuild, and every re-judge, gets a record signed by Graft with Ed25519: the commit, the duramen release, the brief's SHA-256s, the builders' isolation, each build's model, cost and verdict, the suite's numbers, what the judge's sandbox allowed, and who started it. Press Download the signed record in Details, which saves it as graft-record-regen-<id>.json, then, in the folder it saved to (graftfork 0.3.1 or later: npm install -g graftfork):

    graft verify-record graft-record-regen-<id>.json

    It checks the signature against the keys Graft publishes at /.well-known/graft-record-key, needs no account, and says what the record holds. graftfork 0.3.0 adds graft verify-record <rebuild id> (with GRAFT_TOKEN set), which fetches the record and checks it in one step, and reads a rebuild's record as a rebuild. To check one with nothing installed, verify the record's signature over its payload text with any Ed25519 library (Node.js 22's crypto.subtle will do), using the key whose id is the record's key.

    Two case counts. The record's spec.cases counts the cases in the brief, the lines of cases.jsonl that duramen build wrote. suite.total counts what the record's suite ran when it judged the build, and the verdict rests on that one. The two can differ by a few: on the heat-engine record, spec.cases reads 212 beside a suite of 215.

    For a few minutes after a rebuild ends, its record is still being signed (at most 10). graftfork 0.3.1 then says Graft is signing the record and when to run graft verify-record <rebuild id> again. Before 0.3.1, it said only "graftfork.com answered 409", read a free report's record as a rebuild with 0 builds, and called a passed draft or change order "kept", though neither ever becomes the spec's kept build. Its signature check was right all along.

  10. 10Change the software by changing the record

    To change what the program does, you change the record, not the code. Graft rebuilds from the edited record, then shows which answers changed. You, or your own agent, never touch the implementation.

    Say you want heat-engine's green flag to start at 78 °F instead of 80 °F. On the heat-engine example, once you have a kept rebuild of it, press Try the 78 °F change: it rebuilds lab/heat-78 on graft-lab, where the edit below is already made, priced like any rebuild, and compares its answers with your kept rebuild (step 4 below). The replay shows a recorded run of the same change.

    On your own fork:

    1. Make a new branch in your repository from the branch the spec follows (heat-d843e00 above), for example change/green-at-78. Edit three files in examples/heat-engine; the replay shows every changed line:
      • heat.duramen: under req FL-001, the band table (white w < 78, green 78 ≤ w < 85) and the two edge rows of table flagF, 79.99 white and 80 green, which become 77.99 white and 78 green. Under req FL-002, white_max goes from 80 to 78 in the constants text and in its example. 26.66666666666666 °C converts to just under 80 °F, so its row in table flagC (FL-004) and the summary example after it (FL-005) go from white to green.
      • evidence/flag-mapping.fixtures.csv: rows fm-003 (79.99, white) and fm-004 (80.00, green) become 77.99 and 78.00.
      • oracle.mjs: white_max in BOUNDS, and the w < 80 in band(), both become 78.
      Push the branch.
    2. In the Specs tab, open Try a change on the spec, enter the branch, and press Check it (free). Graft grades the record on that branch, and duramen check says whether every example still agrees with the oracle. Fix what it finds, push again, and check again.
    3. Press Rebuild it. It is priced and judged like any rebuild, from the record on your branch. It is kept only if every case passes.
    4. Open Compare. Graft's judge asks the same requests (the examples in both records, plus a seeded sweep) of four programs: the spec's previous kept build, your new build, the old record's oracle and your branch's oracle. A changed answer is explained when the two oracles changed there too, and not asked when they agree. Read the line Answers you did not ask to change: N of M first. It should be 0, and when it is, Graft says so. Anything else is a change you didn't ask for. Below it, for each part of the answer: how many answers changed, how many were explained and how many weren't, with examples, the unexplained ones first, each showing the request, the answer before and after, and the oracle's before and after. It also says how many requests came from examples and how many from the sweep, and when it couldn't compare, why (the verdict stands either way). (Every flag answer carries its audit's constants, so white_max changes everywhere: that one you asked for.)
    5. If you like it, merge the branch yourself. The next rebuild of the spec makes it the kept build.

    Graft never writes your branches. A draft rebuild that passes waits as a bundle on graft/regen/<id>, never as a pull request. It never becomes the spec's last kept build, and it never shows on the public page.

    A draft isn't held to the record's version: Graft rebuilds your branch as you wrote it, and raising the version before you merge is up to you. A change order is held to it, because there Graft writes the record change into the bundle itself, so it waits until the version is raised enough for what changed (step 11). Green at 78 is a breaking change, so in step 11 the version goes to 2.0.0-slice; on a branch, raise it the same way before you merge.

    One honest note. A change in behaviour also edits the oracle, and the oracle is code. Whoever approves the change reads that edit, the same way they would read any code review. What nobody touches is the implementation: it is rebuilt from the record.

    An agent does the same with the MCP tools regen_draft_check, regen_draft_rebuild and regen_draft_status, or the API's POST /api/v1/regen/{id}/drafts/check, POST /api/v1/regen/{id}/drafts and GET /api/v1/regen/{id}/drafts, each with {"branch": "change/green-at-78"}.

  11. 11Change it in Graft, without a branch

    You can also make the same change without a branch of your own. Graft holds the edit for you (a change order) and applies it only on its own copy of the repository. Nothing is written to your repository until you merge what you take.

    1. In the Specs tab, open Change the record here on the spec, say in one line what should change ("Green starts at 78 F"), and press Start a change. Graft starts it from your branch's head.
    2. Pick heat.duramen from the record's files, edit it in the text area, and press Save. Make the same edits as in step 10, then do the same for evidence/flag-mapping.fixtures.csv and oracle.mjs. Here, also raise the record's version, on the line spec heat-engine 1.5.0-slice: Check it says by how much. Each save shows the lines you changed. An edit you haven't saved stays in your browser.
    3. Press Check it (free). Graft runs duramen check on the record with your edits (an error links to its line in the editor), and duramen diff against the record before your edits: it says what kind of change each part is (breaking, tightening, additive, relaxing or prose) and whether the record's version was raised enough. A rebuild waits until the version is.
    4. The oracle is code the judge runs, so a change to it, or to any file the judge reads, waits for a person: read it under Code you approve, tick the box and press Approve. An agent can't approve it. Another edit needs approving again. A change to the record's words alone needs no approval.
    5. Press Rebuild it. It is priced and judged like any rebuild, and compared with the spec's last kept build as in step 10. A kept one waits as a bundle with two commits: the record change, then the implementation. Merge graft/regen/<id> to take both. If the implementation already does what the changed record says, the bundle holds the record change alone.
    6. Or take only the record change at any time: Record change only downloads it as a patch to apply in your clone with git apply --index.

    An agent can do all of this but the approval: the MCP tools regen_order_create, regen_order_write, regen_order_check, regen_order_rebuild, regen_order_status and regen_order_discard, or the API under /api/v1/regen/{id}/orders (Change orders). When the oracle or a file the judge reads changed, its rebuild is refused until you approve that change here, and the answer tells it what needs approving and why, so it can show you. Each step it takes is in the change's history as your agent's, with its token.

    Not open yet: the hosted drafter. Once Graft opens it, Change the record here also has Draft it: say the change in one line ("green starts at 78 F instead of 80, keep the other bands") and Graft's drafter writes the files for you. It sees only the record's folder, never the implementation, and has no network. It edits the record, and the oracle when the change needs it, runs duramen check until it passes or its budget ends, and hands back whole files that land in a new change order. You read them, check it, approve any oracle change and rebuild it yourself, as above: the drafter never approves or rebuilds. It spends at most $0.75 of your agent work by default, and the box says so before you press it. An agent can ask for one with regen_order_draft.

    For now a change order needs the spec on Graft's GitHub app, and it is rebuilt only while your branch is still where the change began: if the branch moves, check it again or take it as a patch, and start a new one from the head to rebuild. Graft keeps the edited files encrypted, and deletes them 90 days after the change is taken, discarded or last edited, or at once when you disconnect the spec.

  12. 12Use it as a required check

    Not open yet. This section describes the spec gate as it will work once Graft opens it. Until then the Specs tab doesn't show it.

    The spec gate makes Graft's judge a GitHub check. With it on for a spec, every commit GitHub asks about (a merge group in your merge queue, a pull request into the spec's branch, a push to that branch) gets a check named Graft spec gate (<record path> -> <implementation folder>). Two gated specs on one repository can't share that name. Graft judges the implementation folder at that commit against the record at the same commit: the record's own suite, then a hidden holdout. Nothing is built and no model runs, so it spends no agent work. Graft never merges, queues or batches anything. GitHub does that; Graft only answers the check.

    1. Install the spec gate app on the repository: open the spec's Use it as a required check panel in the Specs tab and press Install the spec gate app. It is a separate app from Graft's main one. It can write check runs and read code, pull requests and merge queues. It can't push, comment, merge or change your branch rules.
    2. Turn the gate on in the same panel. Only the spec's owner can, or an owner of its organization, and only signed in: no API token or agent can turn a gate on or off, because an agent that could turn it off could then merge past it. A spec connected by its git address can't have a gate.
    3. Make the check required in GitHub: in your repository's rules (or branch protection) for the spec's branch, add Graft spec gate (<record path> -> <implementation folder>) as a required status check, and pick the spec gate app as its source, so no other app's check of the same name counts. With a merge queue, the same rule applies to each merge group.

    What the check says.

    • Passed: N of N cases, M hidden requests agree. The implementation passed every case in the record's suite, then gave the same answers as the record's oracle on M requests drawn with a seed nobody knew before the commit was queued.
    • Passed (or Failed): same content as abc1234. Everything in the commit (the record, the implementation folder and the rest of the repository) is exactly the same as at a commit Graft already judged, so it gives that verdict again at once. The record's oracle and fixtures can live anywhere in the repository, so a change to any file outside the folder is judged again. A Re-run on GitHub always judges again.
    • Failed: N of M cases, or Failed the hidden holdout: D of M requests differ from the record's oracle. The implementation doesn't do what the record says.
    • Not judged: why. Graft didn't judge it, and the check fails so nothing merges unjudged: Graft's spec gate is paused, a cap was reached (with when to re-run), the record or the folder isn't in the commit (or the folder is a file or a symbolic link, or the record is a symbolic link), the judge couldn't isolate the build, the runner failed or took too long. Re-run it from GitHub when the reason has passed.

    The gate never passes a commit it didn't judge. It never answers "neutral" or "skipped", which GitHub would count as passing. The cost: while Graft is paused or over a cap, a merge queue that requires the check waits. To unblock, remove the check from your branch rules (your setting), or turn the gate off. While Graft is paused, the panel stays in the Specs tab for every spec whose gate is on, with Turn the gate off. Turning the gate off, or uninstalling the app, means Graft posts nothing more, so a rule that still requires the check waits forever: remove the required check first.

    Changes to the record, or anything else outside the folder. The judge reads more than the record: the record's oracle and its fixtures can be any file in the repository. By default a change that edits the record or anything else outside the implementation folder is judged against the changed files, and the check says so. You can choose instead to fail every such change, so a person reviews spec changes and bypasses the check on purpose. With that choice, a change that touches only the implementation folder is judged; anything else fails, even a change Graft judged before.

    Pull requests from forks are judged too unless you turn that off; then their check fails, saying forks aren't judged. Graft limits judged runs: per repository an hour (fewer for forks; merge groups aren't held to the hourly limit), per spec owner a month for your own commits and merge groups, and a separate monthly allowance for pull requests from forks, so people outside your repository can't use up yours. The panel shows how many are used.

    What a pass means. The implementation answers every case of the record's own suite, and a sample of requests nobody chose in advance, the same as the record's oracle. It does not mean every regression is caught. A regression the record's suite doesn't cover, and the sample doesn't happen to hit, passes. Graft will measure how often that happens by planting regressions in implementations it knows pass and counting how many the gate lets through, and will publish the rate before it opens the gate. Until then every check, record and page says: False-pass rate: not yet measured. One more honest note: in a rebuild the builder never saw the record; here the author of the implementation did. The hidden requests are still drawn with a seed nobody knew in advance.

    Records. Every judged commit gets a record signed by Graft (kind spec_gate): the commit, the record's and folder's tree ids, a fingerprint of everything else in the commit, the suite, the holdout and its seed, the judge's isolation, and the false-pass line. The check links to it; anyone with the link can check it with graft verify-record, no account needed.

    Agents can read a spec's gate and its runs with the MCP tools regen_gate_status and regen_gate_run, or the API's GET /api/v1/regen/{id}/gate and GET /api/v1/regen/gate-runs/{id}.

Troubleshooting

  • Use graftfork 0.3.1 or later (graft --version says which you have; 0.3.0 doesn't know it). 0.3.1 refuses an option it doesn't know, and says which one it meant. Before 0.3.1, an unknown option was dropped without a word: --max_usd 0.9 (the API's spelling) rebuilt on the $2 default, and a misspelled --builds connected with 1 build.
  • Run duramen on Node.js 22. To run duramen on your own machine as well, use Node.js 22, as Graft's judge does (22.22). duramen 0.3.0 reads JSON correctly on Node.js 24 too, and warns that 24.16's JSON.parse has a bug, but an oracle that uses JSON.parse can still misread there: on Node.js 24.16 the heat-engine record at d843e00 fails property CJ-P1, which passes on 22.
  • "The example's branch has moved from its pinned commit." The heat-engine example builds only at its pinned commits. If one of graft-lab's branches moved, Graft refuses the run, spends nothing and is told. Try again later, or write to support@graftfork.com.

Questions: support@graftfork.com.