A case's head is read from the held-out home, pinned by the case, and held to its tree (#611, record NNNN)

DO
1d ago
+1750-104

Issue #611, "A case's head is read from the private home, pinned by its hash, and the run is sharded", PR 1 of 2: the heads. It follows the Factory Builder's rulings (a) to (d) of 2026-11-08 and the ruling on P-62's verdict. It follows #657, the trial P-62, now on main as d465eaac. The second PR shards the run.

Not mergeable until the Maintainer's run. By ruling (c), there is no transition: every case now needs head_sha256 and tree_sha256. The Maintainer runs the tool below against his checkout of the home, and this PR's evals/pr-review/cases.json then takes the hashes it prints. Merged before that, every case would be not_this_set.

What changes

  • Where a head is kept. The home keeps <role>/<id>.tar.gz (the commit's tarball) and <role>/<id>.tree.json (its tree as the API answered it, written compact) beside each case. eval-case/1 requires head_sha256 and tree_sha256.
  • How it is read. adapters/heldout.beside reads each file with the home's token, using the raw media type application/vnd.github.raw (P-62; pinned by the ruling on its verdict, with a mutant, "the eval blob is asked for as raw+json").
    • The answer must be of that type: a +json answer, which the transport would parse, is no file.
    • It must be within its bound (TARRED, or 8 MiB for a tree) and must hash to its pin (hash_differs otherwise).
  • How it is held. head_of unpacks the tarball as before. Then it holds it to the tree file by file, through head.tree_of and held, as a live head is held (decision 0142). That closes 0142's gap for eval heads.
    • A head that isn't the pinned one is hash_differs.
    • One that can't be read, unpacked or held whole is head_unreadable, and its folder is removed.
    • A pin that is no sha256 reads nothing, and the case is not_this_set.
  • Nothing anonymous is left in the eval job. fetch has one transport, the home's, read-only. The canary still reads its own example's head from this public repo.
  • tools/heads_into_home.py, for the Maintainer's terminal:
    • It reads each case's head from GitHub, through the one transport, read-only.
    • It holds the tarball to the tree, writes both beside the case, and writes the case anew with the pins.
    • Each file is written whole and moved over its name, so a link there is replaced, never written through.
    • A case or folder that is a link is not read. A case it can't pin, or whose head is over the job's bounds, is left as it was.
    • It prints counts and hashes alone.
  • Record NNNN, numbered at enqueue (0172 at the earliest). It amends 0138's rows "A transport with no token" and "The eval case", 0138's Boundaries row on the eval head, and 0142's row "An eval case's head".
  • Rules: rows in harness/eval/AGENTS.md and adapters/AGENTS.md, and 0138's Boundaries row now checks the new test.

The Maintainer's command

Run in his checkout of the home, from his checkout of this repo on this branch:

GH_TOKEN="$(gh auth token)" python3 -m tools.heads_into_home <the home's checkout> pr-review

It prints pinned N of M cases and, by code, any it did not pin, then one {"id", "sha256"} line per pinned case. Those lines go into evals/pr-review/cases.json. He then commits the new files and cases in the home.

Checks

CheckResult
SIM_SEEDS=40 make verifyOK, 1715 tests (at d0a2adae, on a local commit that numbers the record)
Filtered mutants: every mutant on adapters/heldout.py, harness/head.py, harness/eval/canary.py, harness/eval/fetch.py, schemas/eval-case.schema.json and tools/heads_into_home.py, every head, tree and fetch mutant on harness/eval/__init__.py, and every one whose test this changes160 of 160 killed
gitleaksNo leaks
Argon (ca15b26), 12 parts1 major. Not changed: 0138's Boundaries row keeps its words, since a row may only have its Check changed. The new record's Status amends it instead, as the Builder agreed
Claude review (ca15b26)Blocking: a mutant that survived, now killed by a tree answered 404; and the manifest, which waits by design on the Maintainer's run. Low, fixed: the tree is written compact and held to the job's bounds; a pin of the wrong shape is not_this_set; the tool writes atomically and counts a failure; two stale comments; a cleanup mutant; a faster bound test
Claude security (ca15b26)Nothing blocking. Low, fixed: the tool wrote through a link; it now replaces it. A tree over the bound; a failure part-way. Info, fixed: the token is read-only and the tree path is checked
MusePending: read after the lane's owed reads, live PRs first
AstraOnly where Muse gives no read

🤖 Generated with Claude Code