A case's head is read from the held-out home, pinned by the case, and held to its tree (#611, record NNNN)
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/1requireshead_sha256andtree_sha256. - How it is read.
adapters/heldout.besidereads each file with the home's token, using the raw media typeapplication/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
+jsonanswer, 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_differsotherwise).
- The answer must be of that type: a
- How it is held.
head_ofunpacks the tarball as before. Then it holds it to the tree file by file, throughhead.tree_ofandheld, 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.
- A head that isn't the pinned one is
- Nothing anonymous is left in the eval job.
fetchhas 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.mdandadapters/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
| Check | Result |
|---|---|
SIM_SEEDS=40 make verify | OK, 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 changes | 160 of 160 killed |
| gitleaks | No leaks |
| Argon (ca15b26), 12 parts | 1 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 |
| Muse | Pending: read after the lane's owed reads, live PRs first |
| Astra | Only where Muse gives no read |
🤖 Generated with Claude Code