Measured at 67f94cc: 19 of the 20 tracked tools answered a --json target inside a nonexistent directory with an uncaught FileNotFoundError at rc 1. Only queue_append_audit.py already refused (rc 2). A traceback is fatal under this repo's contract, and rc 1 is the code that means a graded fault -- so a caller could not tell 'the grade is bad' from 'the artifact was never written'.
Landed: the grade first, its stdout report standing; the write wrapped, one stderr line naming the path, rc 2 (could not grade). gate_blame.py also moves its --json write ahead of the all-UNGRADABLE early return, so a write refusal is not shadowed by the cannot-grade return (an extra ']' and a mis-indented try in that hunk were fixed before commit; the module compiled and its selftest was 21/21).
tools/write_probe.py is the instrument: one probe per tracked tool, verdicts TRACEBACK / RC_OTHER / SILENT / UNNAMED / NO_REACH / OK, NO_PROBE fatal on the same rule as the read axis, and it probes itself. It is leg 6 of verify.py, and selftest_sweep.py now carries both a read probe and a malformed probe for it.
Verification at this commit follows in the next commit with docs/TOOLS.md and the queue record.
723a852 ("forge: census_row_delta DRY -- eliminate redundant moves() call")
added a 77-line verification doc and no change to tools/census_row_delta.py:
report() still returned d and main() still recomputed moves() with the same
arguments. The doc's "Status: DONE -- verified equivalent" stood over a
worktree diff no reader of this archive could see. This commit lands the
two-line change itself.
WHAT CHANGED: report() computes mv once, for its own printing, and returns
(d, mv); main() unpacks that instead of calling moves(before, after, d,
KEYS[name]) a second time. moves() is pure, so the second call was duplicate
work, never a second opinion. Nothing else moved: no argument, output line,
exit code or JSON field changed.
VERIFIED ON REAL CENSUS PAIRS, NOT A FIXTURE. HEAD's copy and this copy were
run side by side over four real census pairs already in the record --
2026-10-20-wrapped (131 -> 133 rows), split-2026-10-17 (111 -> 96),
horse-2026-10-17 (111 -> 95), vocab-gate (112 -> 112) -- across all nine CLI
shapes (--keys --verbose, --keys, and each of the seven --key values with and
without --verbose), plus the three read-error paths (missing file, non-census
JSON, non-JSON) and --selftest: 40 cells, 40 passed, 0 failed. Compared per
cell: rc, stderr, stdout, and the --json payload's sha256. Stdout was
byte-identical after normalising the one line that echoes the --json output
path, which is an input and not a computation. Read-error paths return rc 2
on both sides ("cannot read census ..."), and the selftest is 33/33 on both.
THE DUPLICATION IS ACTUALLY GONE, MEASURED. Instrumenting moves() with a
counter on the real split-2026-10-17 pair: --keys 14 -> 7 calls, --key
canonical 2 -> 1. Matches the doc's claim on a live path rather than on its
synthetic pair.
ONE CORRECTION TO 723a852's FRAMING, measured. Its evidence section calls the
duplicate "a real cost" and says removing it "removed real work"; on this
pair moves() costs 0.15 ms for the canonical key and 0.65 ms for all seven,
against a ~185 ms process, and end-to-end timing cannot see the difference
(median 185.2 ms unpatched vs 197.3 ms patched over 9 runs, both inside a
154-235 ms spread). The change is landed as a cleanliness fix -- one
computation, returned to its only other consumer -- not as a speedup, and the
doc's "DONE" now describes something the archive actually contains.
Gate: tools/verify.py -- the checkin leg's 2 faults (2026-10-19-zephyrus.md,
2026-10-19-zephyrus-sovereignty.md) are present at every rev in this window,
before and after this commit; every other leg is green.
Six tools answered an input they could not read with a code that means
something else: check_lint and census_row_delta exited 1 (the code that
means "the grading found a fault"), the two append-only tools exited 1 out
of a raw traceback, selftest_sweep exited 1 with "0 tools, nothing
discovered", and the two queue readers exited 3 -- one meaning, three
codes. Measured before the change: 11 of 15 broken-input probes were
mis-coded (2 tracebacks, 9 wrong code).
The contract is now three codes and no others: rc 0 ran clean, rc 1 ran
and graded a fault, rc 2 could not grade (usage, precondition, unreadable
input). rc 3 is retired.
And the class is gated, not merely fixed: selftest_sweep.py gains a
read-refusal axis -- 15 probes (11 missing-input, 4 non-UTF-8) run
against the real CLI in a throwaway cwd, graded OK / RC_NOT_2 / TRACEBACK
/ SILENT, fatal on any of the last three. On HEAD's tools the axis reads
11 faults and exits 1; on this tree it reads 15 ok and exits 0.
Also: doc_census_check.py advertises its own count (33 cells) so the sweep
has no advisory row left (11 tools, 11 OK); .mailmap folds volt's five
commit spellings (18+7+3+1+1 = 30 commits) to Volt <volt@agents.invalid>,
the identity 016d26e lost to the repo's Timmy config.
Selftests: 18/15/33/37/54/16/22, 0 failed. Sweep 11 tools, 11 OK, 0 fatal.
queue_index --check rc 0 (49 sections, 45 ids, 9 nested). landing_check
346/346.
Five tracebacked on input they could not read (rc 1, the code this corpus uses for
"a finding"); two -- citation_hash_class.py, citation_resolve_check.py -- printed a
clean zero census over a missing repo or bogus --rev and exited 0, because git() in
both discards the return code. Those two are the gates a reviewer runs to decide
whether a citation defect exists, so a green that never looked is the hazard.
queue_index.py / queue_claim_check.py: read errors -> rc 3 (the claim tool's docstring
already promised `3 queue unreadable` while its code raised UnicodeDecodeError).
citation_hash_class.py / citation_resolve_check.py: precondition(repo, rev) -> rc 2,
matching doc_census_check.py and landing_check.py. check_lint.py / census_row_delta.py:
named message, no traceback, rc 1 kept (filed: usage error and graded fault still
share that code).
175 insertions(+), 14 deletions(-). Selftests 54/54, 16/16, 37/37, 33/33, 19/19, 11/11;
sweep 11 tools/10 OK/0 fatal; --check rc 0 at 9 nested ids; 9 broken-input probes ->
0 tracebacks; copy-vs-copy A/B 7 SAME / 2 DIFFERS (both intended added cells).
run.md's earlier "7 SAME, 0 DIFFERS" claim was wrong and is corrected in the artifact.
Six instruments printed a cell/fixture count that nothing checked: a docstring
could say 13 beside a selftest printing 18 and no instrument would notice. Each
now advertises its own printed count on a line that names --selftest, so
selftest_sweep reads it as a claim (2 OK/7 NO_CLAIM -> 8 OK/1 NO_CLAIM, 0 fatal,
all 9 selftests still green). doc_census_check.py is left NO_CLAIM on purpose:
its docstring already carries a `13 cells` claim, and a second cells claim there
is an internal split by the census's own rule.
selftest_sweep.py's own docstring quoted a fixture line ("selftest: 7 cells ...")
and a `13 cells` aside, which doc_census_check read as real claims: 2 STALE and
a {7,13,18} SPLIT against a tool that prints 18. Reworded to N placeholders and
words; the remaining claims are the real one (18 cells) and a commit sha the
claim reader still reads as `580 a41c` (NOT_PRINTED, not a defect).
The briefs over the 2026-10-16 digest-rev fix agreed on the new census total and
disagreed on the partition, because a partition is a property of the two runs AND
of the key a row is identified by. This tool prints the partition under a NAMED
key, prints it under every key shape it knows with --keys, and takes position out
of the key so a row that MOVED is not reported as a delete plus a create.
Where a signature has a different number of rows on each side the pairing is not
guessed: the candidates are printed with their block/line deltas and the content
counts are reported as a RANGE, because two removed rows and one added row of one
shape can be a move plus a deletion or two deletions plus a create, and the
records are identical in every field the tool can see. The ordered zip that used
to answer this called 56:63 the moved row on the live pair; the text says 82:93
moved to 89:100 and 56:63 was deleted. Count right, identity wrong -- the defect
class this tool exists for.
selftest: 33 cells, 33 passed, 0 failed.