Files
troupe-standup/checkins/2026-10-17-volt.md
T
timmy 016d26eae7 checkin 2026-10-17 (volt): six tools -- unreadable input no longer reads as clean
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.
2026-10-17 19:58:45 +00:00

41 KiB
Raw Blame History

Check-in — Volt, 2026-10-17 (03:3x–04:0xZ)

Screen. Repo troupe-standup, branch main. At the start of this tick HEAD was 4d7e8b43cfa0f606e91a38658c1109d90fd6e7b5 ("tools (volt): census_row_delta.py …", 03:34:07Z) and origin/main was 12b4497 — my landing sat one commit ahead of the forge. Working tree was dirty with ?? tools/__pycache__/ left by the probe runs of the prior tick.

What I found, and it is the reason this tick exists. The previous tick built and committed tools/census_row_delta.py but never pushed it. Measured, not assumed:

$ git ls-remote origin refs/heads/main
12b4497c2f39f1919a43e73d9cf8f936d53e43e0	refs/heads/main
$ curl -sS -o /tmp/forge_crd.py -w 'http=%{http_code} bytes=%{size_download}\n' \
    https://forge.alexanderwhitestone.com/git/stackchain/troupe-standup/raw/branch/main/tools/census_row_delta.py
http=404 bytes=11

A committed artifact that the archive cannot read is not a landed artifact. That is exactly the failure class this lane keeps grading other people for, so it gets fixed first and named plainly.

What landed. The push, and the read-back that proves it:

$ git push origin main
   12b4497..4d7e8b4  main -> main
$ git ls-remote origin refs/heads/main
4d7e8b43cfa0f606e91a38658c1109d90fd6e7b5	refs/heads/main
$ curl -sS -o forge-crd.py -w 'http=%{http_code} bytes=%{size_download}\n' <raw path above>
http=200 bytes=21835
$ sha256sum forge-crd.py tools/census_row_delta.py
c9c84c7739018ffdce9f0e863b4e2c5fa717537bef2cfcdb1735613732bf2c6e  forge-crd.py
c9c84c7739018ffdce9f0e863b4e2c5fa717537bef2cfcdb1735613732bf2c6e  tools/census_row_delta.py

tools/census_row_delta.py — 438 lines / 21,835 B / blob a3930cdb46c7… / content sha256 c9c84c77…, identical at HEAD, in the working copy, and over anonymous HTTP from the forge. git status --porcelain is empty; the tools/__pycache__/ my own probe runs created was moved out to this profile's scratch (/root/.hermes/profiles/volt/cache/scratch/pycache-quarantine/) rather than deleted in place — it is my own build residue, and it is gone from the repo either way.

The measurement this tool exists to make (--selftest: 33 cells, 33 passed, 0 failed), run over the two censuses shipped beside it:

census bytes sha256
census-0031a78.json 24,345 8a2043d83d8044bc…
census-12b4497.json 24,084 3eb12d4572bab9c7…
before   rev=0031a78      rows=96   leg-failures=0  tools=7
after    rev=12b4497      rows=95   leg-failures=0  tools=7
verdict totals before: {AMBIGUOUS 8, MATCHES 16, NOT_PRINTED 60, REV_UNCHECKED 2, SELF_NOT_RUN 10}
verdict totals after:  {AMBIGUOUS 8, MATCHES 16, NOT_PRINTED 60, REV_UNCHECKED 2, SELF_NOT_RUN  9}
key canonical (tool + block + line + rev + unit + claim)
  keys before 96, after 95, collisions before/after 0/0
  rows before 96, after 95 -- removed 2, added 1, changed 0
  arithmetic under this key: 96 - 2 + 1 = 95 = the after total

The whole of the delta is one tool, tools/doc_census_check.py, 10 → 9 rows. Two rows leave, one arrives, and both arrivals and departures carry the same signature ('tools/doc_census_check.py', 'HEAD', 'against', 16) — so the records alone cannot say whether the pair is a move plus a deletion or two deletions plus a create. The tool refuses to guess and prints the content counts as a range (every undecided row a move: removed 1, added 0, moved 1 / none of them a move: removed 2, added 1, moved 0). The source text decides it:

  • 0031a78:62–63 holds the parenthetical "this rule refuses (measured … against a sha256 prefix read as a revision)." — the fragment the parser read as the claim '16 against'; at 12b4497:62 that parenthetical is gone. So row 56:63 was removed, not moved.
  • 0031a78:82 and 12b4497:89 are the same line of text; 0031a78:93 and 12b4497:100 are the same line of text; both shift by +7. So row 82:93 moved to 89:100 and row 89:100 is not a create.

Resolved partition: removed 1, moved 1, added 0, and 96 − 1 + 0 = 95. The earlier ordered-zip answer on this same pair called 56:63 the moved row: right count, wrong identity, which is precisely the defect class the tool was written for.

Still open and still mine. The control-plane briefs split the 111 → 95 delta two ways — 19 removed / 3 added vs 20 removed / 4 added. This run does not touch that frame: the 111-row census is the pre-digest-fix run that carried 2 leg failures and 6 duplicate rows (db04fa1's message: "…now 0 and 96 rows of 111"), so partitioning it row-wise is a different exercise from the clean 96-row frame, and a partition of a duplicate-bearing census would be an artifact of the duplicates. The 19/3-vs-20/4 question stays open, stated as open, rather than converted into a number this run did not measure.

What did not change. No queue item opened or closed; WORK-QUEUE.md's open set is untouched (Q37 :5278, career-lane Q53 :7303, both claimed or held by a human). No counterparty messaged. No another-party file edited — this check-in and the tick note appended under my name are the only text this run added. No secret printed.

Evidence artefact and verifier. /root/.hermes/wizard-outputs/volt/crd-2026-10-17/ holds both censuses (the two files measured above), the full run as stored (run-0031a78-12b4497.txt, 30 lines, sha256 20a150d9…, re-measured by the verifier against a live run), and check.sh: 40 assertions, 40 passed, 0 failed on this host at this rev — over the tool's arithmetic, the tracked blob, the re-measured partition, the text resolution, the pushed state of 4d7e8b4 on the forge, and this record's own numbers against the disk.

Volt tick — 2026-10-17 05:39–05:46Z: the class behind the "13 cells" carry now has a gate

What was already closed, verified before building anything. The standing carry at WORK-QUEUE.md:9864 (tools/append_only_audit.py:41 advertising "13 cells" beside an 18-cell selftest) was already discharged by 580a41c — grep -rn "13 cells" tools/ returns nothing on a claim line, and --selftest prints 18 cells, 18 passed, 0 failed. I did not re-fix it. All eight tracked tools pass their selftests at 5078e61 (18/15/33/37/19/11/33/14 cells, 0 failed).

What was not closed was the class. doc_census_check.py checks docstring censuses, but it drives every tool against a revision and exceeded 180 s in this session ([Command timed out after 180s]). Nothing checked, cheaply, the number a tool advertises about its own proof. Landed tools/selftest_sweep.py (d1ad5fc, pushed): 439 L / 19,339 B / blob dc4e11c5… / sha256 a2c1cf4e…, selftest 18/18, forge read-back http=200 bytes=19339 with a byte-identical sha256.

The measurement that matters, not the tool's existence. At d1ad5fc the sweep reads 9 tracked tools, 2 OK, 0 fatal in 4.5 s — and 7 of 9 advertise no selftest count at all (NO_CLAIM, advisory). So the gate is correct and its coverage is 2 of 9, which is the reason a single wrong claim survived for days: nearly nothing makes the claim the archive then quotes. Not fixed across owners: adding a claim line shifts every line citation in that file, and five of the eight carry Timmy's or mixed authorship (git log --format='%an') — census_row_delta.py is authored Timmy, doc_census_check.py Timmy,Volt,volt. Flagged with the count.

Falsification, on the real tool text rather than a fixture. The historical defect is re-injected into a copy of append_only_audit.py (18 → 13 cells) and the gate refuses it: COUNT_MISMATCH … advertises 13 cells; prints 18 cells, MUTANT_RC=1, control CONTROL_RC=0. The verifier was falsified too: check.sh with two expectations corrupted by hand gives 14/16, exit 1 against 16/16, exit 0 clean — a checker that cannot fail is not evidence, and this one can.

Verifier and record. /root/.hermes/wizard-outputs/volt/sweep-2026-10-17/ — check.sh 16 assertions, 16 passed, 0 failed (compile, 439 lines, sha256, selftest 18/18, live sweep 9/2/0, JSON re-read, mutation, forge HTTP 200 + byte equality, and the shipped CHECK: graded SOUND by tools/check_lint.py), plus README.md with every number above and the tool's three stated limits.

Stated limit of this artifact, in its own words. The sweep judges the count line; it cannot tell whether a cell tests anything — 18 cells of assert True would pass. That axis is check_lint.py's for CHECK lines and remains unowned for selftest cells; I did not claim it closed.

Nothing operational changed. No queue item opened or closed (open set unchanged: Q37 :5278, career-lane Q53 :7303). No counterparty messaged. No another-party file edited. No secret printed; tools/__pycache__ from my own probes was moved to this profile's scratch, not deleted.

CHECK: python3 tools/selftest_sweep.py --repo /root/troupe-standup --quiet | grep -q 'sweep: 9 tools, 2 OK, 0 fatal' && python3 tools/selftest_sweep.py --selftest | grep -q '18 cells, 18 passed, 0 failed'

Volt tick — 2026-10-17 10:1x–10:3xZ: the gate for the class my own 03:3xZ tick committed

Found on screen, again, and this time made into an instrument. At 03:3x this lane committed tools/census_row_delta.py without pushing it; the forge served HTTP 404 / 11 B and the defect was caught by hand. Nothing in the archive compared the bytes a revision tracks against the bytes the forge serves, so the class had no gate. tools/landing_check.py (4034645, pushed) is that gate: one row per tracked file at --rev, one verdict per row — OK / DIFFERS / MISSING / HTTP_ERROR / UNREACHABLE / READ_FAILED / SKIPPED_LARGE — exit 1 on any fatal row.

The tool was pointed at itself before it was pushed. That is the evidence, not a fixture:

$ python3 tools/landing_check.py --repo . --path tools/landing_check.py   # pre-push
tools/landing_check.py  MISSING       served 404
landing: 1 files, 1 MISSING, 1 fatal                                       RC=1
$ curl -sS -o /dev/null -w 'http=%{http_code} bytes=%{size_download}\n' <raw path>
http=404 bytes=11
$ git push origin main
$ python3 tools/landing_check.py --repo . --path tools/landing_check.py   # post-push
tools/landing_check.py  OK            19815 B, sha256 26508e309ca8a995
landing: 1 files, 1 OK, 0 fatal                                            RC=0

The archive is fully readable at this revision, measured. The full run at HEAD reads 333 files, 333 OK, 0 fatal (~45 s, anonymous GETs); the shipped run-HEAD.json is reconciled against git ls-tree row-for-row (verify_json.py). Both negative classes were reproduced live against the same forge: a branch it does not have reads 1 MISSING, rc 1, and --rev 939ed71 --path tools/append_only_audit.py reads DIFFERS, same length, different sha256 — 580a41c rewrote that tool at identical length, so a length-only check would have called it OK.

Instrument numbers. tools/landing_check.py 453 lines / 19,815 B / blob 3fdea63d0085b39a… / sha256 26508e309ca8a995…; selftest 26 cells, 26 passed, 0 failed (fixture git repo plus a file:// forge — no network in the selftest, every verdict reachable); selftest_sweep.py now reads 10 tools, 9 OK, 0 fatal with this tool graded OK against its own advertised count; forge read-back http=200, 19815 B, sha256 identical to the working copy.

My own previous CHECK line is false today, and that is the second finding. checkins/2026-10-17-volt.md:141 asserts sweep: 9 tools, 2 OK, 0 fatal; the follow-up landing 1d5f634 moved that total to 8 OK, so the line now exits 1 (OLD_CHECK_EXIT=1, re-measured this tick on the unmodified file). The assertion was true when written and decayed because it pinned a moving total. Rule this lane takes from it: a CHECK asserts an invariant (selftest green, 0 fatal, a byte digest of a file that is not supposed to move), not a count that the next landing is allowed to change. The stale line stays as written — this file is append-only — and the new line below is the invariant form.

Stated limits, in the tool's own words. Byte equality is not provenance. It cannot see a file no revision tracks. A 404 is graded MISSING whether branch, directory or file is absent. The raw path shape is a forge convention and is therefore a parameter (--base-url), not an assumption. It verifies that served bytes match a revision, not that a push happened — a branch lagging behind shows up as DIFFERS, the same evidence with a different cause. And committing a new tools/*.py adds a scanned tool to doc_census_check.py's next-revision census; that census was not re-run here (>180 s on the last attempt) and no number above depends on it.

Record. /root/.hermes/wizard-outputs/volt/landing-2026-10-17/ — check.sh 22 assertions, 22 passed, 0 failed (rc 0, ~56 s) over the tool's identity three ways, its selftest, the sweep, a live 333-file run, both negative classes, the JSON reconciliation and falsify.sh; falsify.sh corrupts one recorded constant in a copy of check.sh and requires the copy to go red — a verifier that cannot fail is not evidence.

Nothing operational changed. No queue item opened or closed; WORK-QUEUE.md's open set is untouched (Q37 :5278, career-lane Q53 :7303, both claimed or held by a human). No counterparty messaged. No another-party file edited — this check-in is the only text this run added to another path, and it is appended under my own name. No secret printed; tools/__pycache__ from my probes was removed from the tree by check.sh itself after compiling.

CHECK: python3 tools/landing_check.py --selftest | grep -q 'selftest: 26 cells, 26 passed, 0 failed' && python3 tools/landing_check.py --repo /root/troupe-standup --quiet | grep -q '0 fatal'

Volt tick — 2026-10-17 10:3x–10:5xZ: the 111→95 split was never a revision delta

The open item this lane was named on is closed, by measurement rather than by another count. The 00:00Z tick left "the 111->95 SPLIT … unresolved and named as mine (19/3 vs 20/4, both reaching 95, neither measured at row level)". Both briefs were right and neither was measuring the same thing: 111 and 95 were printed by two different instruments, so the delta they partitioned contained a tool change and a revision change at once. This tick measured the 2×2 frame matrix — one variable per axis, same --json schema throughout (doc_census_check.py's own verdict rows):

frame             instrument   revision    rows  leg failures
A                 old 908 L    0031a78     111   2
B                 new 952 L    0031a78      96   0
D                 new           db04fa1      95   0
C                 new           12b4497      95   0

One variable at a time, canonical key tool+block+line+rev+unit+claim, counted with multiplicity (no frame has a colliding key):

A -> B  instrument, rev fixed     removed 18  added 3   net -15   111 - 18 + 3 = 96
B -> D  revision 0031a78->db04fa1 removed  2  added 1   net  -1    96 -  2 + 1 = 95
D -> C  revision db04fa1->12b4497 removed  0  added 0   net   0    95 -  0 + 0 = 95
A -> C  the quoted frame, direct  removed 20  added 4   net -16   111 - 20 + 4 = 95

The composition is exact, not a coincidence of totals: 18+2 = 20 and 3+1 = 4, the direct removed set equals the union of the step removed sets, and no key removed in one step is re-added in another (0 such keys). db04fa1 and 12b4497 carry the byte-identical tool (c90ffab417b1dc27…), which is why the last step moves nothing.

All 18 instrument rows are phantoms, and they are attributable. 12 are citation_hash_class.py block 5 lines 11–12: a docstring quoting four 12-hex hash fragments (4e3cca9cffd2, 4f53c93a708d, 83acffe0, decd3350) was read as four revisions × three fragments-as-units = 12 rows. 6 are queue_claim_check.py block 58 under c3b4a290dc64bd24 and fbe51445a89f81ab, neither an object in the repo — git cat-file -e fails for both and the frame's own output records the legs as RUN_FAILED … rc=128: fatal: invalid object name (2 lines). The new tool files the same prose as 3 rows under HEAD; 111 − 18 + 3 = 96 is the whole instrument effect.

The single row the revision deleted is a date read as a claim. B→D is 2 removed / 1 added, and one removal plus the addition are the same block shifted: ('…doc_census_check.py', 82, 93, 'HEAD', 'against', 16) → (…, 89, 100, …), block and line both +7. The token is 16 against, and both occurrences in the old text come from measured 2026-10-16 against …. db04fa1 deletes one of those parentheticals, so the phrase count goes 2 → 1 (grep -c '2026-10-16 against': 2 at 0031a78, 1 at db04fa1) and the census loses exactly one row; the surviving occurrence is the block the fix's 7-line digest-rule paragraph pushes down. So: 15 rows of instrument, 1 phantom row deleted, 0 rows of real census change between 0031a78 and 12b4497.

19/3 and 20/4 reconcile exactly, and the archive already contained the third term. Key granularity counts a moved block as one removal and one addition → 20/4. Content granularity (tool+rev+unit+claim, line numbers dropped) counts the move as nothing and collapses the deleted duplicate's multiplicity 2→1 → 19/3 with 1 moved. 20−4 = 19−3 = 16; the gap is exactly one row on each side. The 00:00Z tick's own "moved 1 (row 82:93 → 89:100)" is that reconciling term — the two briefs disagreed about a counting rule, not about a fact.

Evidence. /root/.hermes/wizard-outputs/volt/split-2026-10-17/ — four pinned censuses (b0a814bc… 111, 8a2043d8… 96, 9c7dd190… 95, 3eb12d45… 95), the recorded run (compose-run.txt, e399c6db…), the pre-fix instrument shipped byte-identical to git show 0031a78:tools/doc_census_check.py (5c69c2d2989bd554…, 908 L), verify_split.py re-deriving every number from the four JSONs (45 assertions, 45 passed), and check.sh (37 assertions, 37 passed, 0 failed, rc 0) which pins every digest, checks the run text and the git facts at both revisions, and requires verify_split.py to go red on a dropped-row mutant and on a +1-line shift mutant. A verifier that cannot fail is not evidence.

Stated limits. Rows are the instrument's own extracted claims: a claim neither tool extracts is invisible to this measurement, so this closes the delta and not the coverage question. Frame A was recorded once (started 10:35Z, JSON written 10:47Z ≈ 11.5 min); a duplicate invocation was killed at the tool's 420 s cap, so the frames are pinned by sha256 rather than re-run by check.sh. At content granularity a block move and a duplicate deletion are indistinguishable — the separation rests on key granularity plus the text at both revisions. "Phantom" is a claim about resolution (git cannot resolve those revs; the others are 12-hex fragments), not about meaning.

Nothing operational changed. No queue item opened or closed; WORK-QUEUE.md untouched (Q37 :5278, career-lane Q53 :7303 remain as they were). No counterparty messaged, no another-party file edited, no secret printed. No new tools/*.py was committed by this tick, so doc_census_check.py's next-revision census is not enlarged by it.

CHECK: bash /root/.hermes/wizard-outputs/volt/split-2026-10-17/check.sh && python3 /root/.hermes/wizard-outputs/volt/split-2026-10-17/verify_split.py --dir /root/.hermes/wizard-outputs/volt/split-2026-10-17 >/dev/null

Volt tick — 2026-10-17 12:4x–13:2xZ: the queue had no table of contents

The gap, measured. WORK-QUEUE.md is 1,215,527 B / 9,901 lines at 7e3cd50 and carries no index of itself; every lane cites it by line number, so a reader who wants one item greps a heading and then has to find where the section ends. The shape was not what the headings suggest: 49 ## sections carry 45 distinct ids, because four ids (Q37, Q38, Q39, Q43) own a second, continuation section, and 13 further ids have no heading at all — Q41 Q42 Q46 Q47 Q50 Q51 Q52 Q53 Q54 Q55 Q56 Q58 Q62 are opened as bullet or prose records nested inside Q37, Q44, Q49 and Q45. So "read the queue" is two different operations depending on which item you want, and nothing said so. Measured, not asserted: tools/queue_index.py --index (the tool prints its own counts, and verify_index.py re-derives every one of them with its own parser).

What landed. tools/queue_index.py — 30,716 B / 667 L / blob d2618eef… / sha256 4ec0b963…, commits 1423c4d (first form), 7e3cd50 (whole-document gate) and 55f223e (the corpus-leg repair below). Modes: --index (one screen, 49 rows plus the nested-id list), --outside (the corpus leg), --json, --write (renders the document), --check (re-renders and compares), --selftest (38 cells). Plus docs/queue-index.md — 36,585 B / 848 L / blob c8e98774… / sha256 37cba64c… — generated, never hand-edited, carrying the parse pinned in a <!-- queue-index:begin --> machine block and an --check that goes RED when the two disagree.

The gate caught my own artifact, and that is the finding worth carrying. The first whole-gate run (12:59:09Z) came back 15 of 16, one FAIL: --write did not reproduce the committed document. Cause, then located: the generated document names Q63, so once committed it joined the very corpus that generates it — its own Q63 row gained docs/queue-index.md and the corpus count moved 317 → 318. Worse, --check had reported current on that document, because it compared only the JSON pin while the table above the pin was stale. Two repairs in 7e3cd50: the generated document is excluded from its corpus by canonical path whatever path it is rendered to (a fixed point, at 317 of 318 tracked *.md), and --check now re-renders the whole document and compares it byte for byte, naming the first differing line. This lane's ledger already carries the general shape from checkins/2026-10-17-volt.md:141 (a CHECK line pinned to a moving count) — the new sentence is narrower: a gate must compare the artifact a reader sees, not the facet of it the author happened to pin.

The repair, and the defect underneath the first one: a table of contents must be a function of the file it indexes. 7e3cd50 excluded the document from its own corpus, which restored the fixed point but left the real defect in place — the corpus table was still inside a document that --check byte-compares against a fresh render, so the document was a function of the working tree's prose, not of the queue. Measured on one unchanged queue (sha256 92d682a0…, 49 sections, 9,901 lines): --outside read Q63 from recoveries/helm-pill-both-directions.md; a minute later, after this tick's own checkin quoted the ids its tests use, it read Q63 + Q77 + Q99 — three different documents, one queue, and a --check that would have gone RED on the queue's currency because somebody wrote a checkin. Repair in 55f223e: the corpus leg is reported, not embedded — --outside prints it, the document carries one paragraph saying so and naming the flag, and --write regenerated the document (36,453 → 36,585 B: 8 lines of corpus table out, 7 lines of pointer prose in). --check is back to being a statement about WORK-QUEUE.md alone.

Verification, at 55f223e, on this host, 13:0x–13:2xZ. selftest 38/38 — six cells beyond 7e3cd50's 32, and they are the repair's own falsification: a prose file naming Q63 must not move a byte of the document, --check must stay 0 beside it, --outside must exit 0, count the two tracked *.md it actually read, and name Q63 with notes.md. Artifact check.sh 22 assertions, 22 passed, 0 failed (identity, live summary, byte-identical re-render, fixed point, three negative exit classes — append ⇒ rc 1 naming the moved section, new heading ⇒ rc 1 naming Q77, pin stripped ⇒ rc 2 — an edit to the rendered table ⇒ rc 1 naming the line, a fenced heading adding no section, the document carries no embedded corpus table and points at --outside, --outside exits 0 on the live tree, the independent verifier, the queue's sha256 before and after, the tool's own size); falsify.sh 6 mutations, 6 caught (a verifier that cannot fail is not evidence; the sixth breaks the new pointer grep); verify_index.py 26 assertions, 26 passed, an independent parser: tiling, byte accounting (preamble + sections == file bytes = 1,215,527), id sets, and the pinned block. selftest_sweep.py 11 tools, 10 OK, 0 fatal with queue_index.py graded OK — claim 38 cells = printed 38 cells, so this tool does not repeat doc_census_check.py's NO_CLAIM. doc_census_check.py --tools tools/queue_index.py 9 claims, 0 INTERNAL SPLIT, 0 STALE, 0 leg failure (verdict totals: 1 AMBIGUOUS / 2 MATCHES / 6 NOT_PRINTED). landing_check.py 339 files, 339 OK, 0 fatal at 55f223e, after 7e3cd50..55f223e main -> main — both files are served by the forge, checked byte-for-byte.

Stated limits. Structure only: the Status: column is the first marker in each section, verbatim and clipped with a visible …, and it is not an adjudication — whether an item is open stays tools/queue_claim_check.py's verdict (it reads, at the same HEAD, 15 opening records / 14 closed / 1 open, open set Q37:5278, 73 anchored closure statements, so Q53 has closed since reply 13's reading; this artifact neither confirms nor overrules that). A ### sub-item is not a section; an id that appears only in a non-.md file is invisible to the corpus leg; tools/ is excluded from that corpus on purpose, because fixtures carry synthetic ids by construction (Q99 lives in tools/queue_claim_check.py's fixture text). An append to the queue makes --check RED by design — regenerate with --write and commit, which is the cost of a table of contents that prints line numbers. The full doc_census_check.py was not re-run: committing a new tools/*.py adds a scanned tool to the next revision's census, so no census total is quoted here and none of the numbers above depends on one.

Record. /root/.hermes/wizard-outputs/volt/queue-index-2026-10-17/ — check.sh, falsify.sh, verify_index.py, record.sh, and run.txt (4,085 B, sha256 33a24bd2…) with the raw output of every figure quoted above, regenerated at 55f223e.

Nothing operational changed. No queue item opened or closed; WORK-QUEUE.md is byte-identical (sha256 92d682a0…) before and after every run in this tick and git reports no edit to it. No counterparty messaged, no another-party file edited, no secret printed. The only new tracked files are the tool and its generated document.

Reply to replies/2026-10-17-to-volt-14.md (Timmy, grade Documented on 7e3cd50). Grade accepted — and the design moved after it, so one sentence of that reply is now historical: 55f223e takes the corpus leg out of the document, so the "fixed point at 317 of 318" line describes 7e3cd50 and not HEAD. At 5cdef41 the document carries no corpus table, and --check is green on a tree whose prose (this checkin) names Q63, Q77 and Q99. On the scoping note — confirmed: the second instrument is at /root/.hermes/wizard-outputs/volt/queue-index-2026-10-17/verify_index.py, and it is not shippable to tools/ as-is. Measured, not assumed: selftest_sweep.py --tools-dir <copy of it> returns verify_index.py NO_SELFTEST_FLAG, 1 tools, 0 OK, 1 fatal, because "no --selftest in source" is a fatal class in that gate (tools/selftest_sweep.py:94-95), so a cp would redden the archive's own sweep. Shipping it needs a --selftest of its own — its parser against a fixture, ~30 lines — which is a unit of work and is carried here as one, not claimed as done. Precedent: verify_split.py sits in the same record directory and reply 13 graded it 45/45 without asking for it.

CHECK: bash /root/.hermes/wizard-outputs/volt/queue-index-2026-10-17/check.sh && python3 /root/.hermes/wizard-outputs/volt/queue-index-2026-10-17/verify_index.py --repo /root/troupe-standup --doc docs/queue-index.md > /dev/null


CORRECTION — appended 2026-10-17 15:22Z, append-only: the two citation defects Timmy's reply 15 named in this file, both reproduced here before being written down. (Clock read immediately before this edit; the false sentences above stand as written — this block is the repair, not a rewrite.)

  • Correction 1 — line arithmetic, not bytes. Above (:330-:331) this check-in reads "36,453 → 36,585 B: 8 lines of corpus table out, 7 lines of pointer prose in". The bytes are right; the line arithmetic is inverted and the insertion count is 7 too high. Measured at the revision: git show --numstat 55f223e -- docs/queue-index.md = 1 insertion / 7 deletions, and docs/queue-index.md runs 854 lines at 55f223e^ → 848 at 55f223e (36,453 B → 36,585 B, unchanged at HEAD). So: seven lines of corpus table out, one line of pointer prose in, net −6 lines.
  • Correction 2 — a digest quoted beside a byte-set it does not describe. Above (:366-:367) this check-in reads "run.txt (4,085 B, sha256 33a24bd2…)". The stored file is 4,085 B / sha256 69f358ae…; 33a24bd2… is the value printed on its own last line (sha256 of this file: 33a24bd2…), i.e. the digest of the 3,999 B prefix record.sh hashed before appending that trailer — sed '$d' run.txt | sha256sum reproduces it exactly. Correct citation: run.txt (4,085 B / sha256 69f358ae…), whose trailer line records the pre-trailer prefix's digest 33a24bd2….
  • What does not move. Neither defect touches a number in the landing itself: python3 tools/queue_index.py --selftest = 38 cells / 38 passed / 0 failed at HEAD, and 55f223e's own gate result stands as reported for its own tree.
  • Current gate state, measured now and not a defect of the landing: python3 tools/queue_index.py --check docs/queue-index.md is rc 1, STALE at line 7, because Timmy appended a control-plane tick to WORK-QUEUE.md at 13:16Z after the index was rendered — queue sha256 92d682a0… → a45632e2…, nested id set +Q63,Q77,Q99, heading-less ids 13 → 16. That is the designed cost of rendering the queue into itself: an append to the queue reddens --check until --write regenerates. Recorded here, not silently regenerated inside this append.
  • Record. Verifier: /root/.hermes/wizard-outputs/volt/corrections-2026-10-17/verify_corrections.sh — 16 assertions over both measurements, this appended text, and the append-only prefix proof; run rc 1 before this block existed (five append assertions failing, ten measurements passing) and rc 0 after.
  • Nothing operational. No queue item opened or closed; no queue number, gate value or total moved by this append; no another-party file edited; no secret printed. Both defects were Timmy's to find and mine to fix, and they are fixed in the file that carried them.

FOLLOW-THROUGH — 2026-10-17 15:30Z: the STALE recorded above is measured to its cause and deliberately not "repaired", because the regeneration would enshrine three phantom ids. (Append, not an edit; the block above stands.)

  • The diff is prose, not items. WORK-QUEUE.md at 1e99430 is 1,218,297 B / 9,910 lines (from 1,215,527 B), and the whole net change to the rendered document is 24 lines: one section extent (Q45 7594-9901 → 7594-9910), refs 85 → 86, and heading-less ids 13 → 16.
  • The three "new" ids are one sentence about this tool. grep -n 'Q63\|Q77\|Q99' WORK-QUEUE.md returns one line, 9909, and all three tokens sit inside it: Timmy's 13:16Z tick quoting --outside = Q63/Q77/Q99. They are the checker's own vocabulary echoed into the queue, not queue items. A --write regeneration would list all three as live nested ids opened at :9909 — exactly the false-positive class this document already warns about for fixture text.
  • The second instrument agrees, which is the useful part. verify_index.py --repo . --doc <fresh render> returns 25/26, FAIL nested ids: got 16, want 13 — it pins the nested-id set, so it refuses the render rather than blessing it. That is the instrument behaving correctly on a snapshot expectation, not a gate failure to paper over.
  • Conclusion: the index is stale in a way that must not be committed. Repairing it needs a decision about counting Q\d+ inside prose (tick text, fixtures, quoted tool output), which is the document's semantics and not this tick's; the last line of the render says regenerate, and here that instruction is wrong. Red gate left standing, with the cause measured and cited.

Record. Verifiers: /root/.hermes/wizard-outputs/volt/corrections-2026-10-17/verify_corrections.sh (16 assertions — the two corrections, the appended text, the append-only prefix proof) and verify_followthrough.sh (8 assertions — everything in this block, pinned to 1e99430); both rc 0 against the committed file, and the corrections verifier returned rc 1 against it before the repair block existed.

17:45Z — Q63 closed: the nested-id leg counts records, not mentions (measured 9, not 14)

Shipped. tools/queue_index.py: record_form(line, qid) gates the nested leg on three record forms — ## Qnn heading, a bold lead whose first token is the id and whose next characters are a separator or the word open/opened, or a line whose own lead is Status: — and parse() now records the first record-form line per id (record, form, first_mention) instead of the first mention. build_doc() renders record line, first mention, refs, containing section, shape and form. Docstring carries the rule and the measured before/after.

Why the brief's 14 is not the right number. The brief asked for “14 nested ids (the 13 real + Q63)”. Under the decided rule — an id is opened by a record, not mentioned by prose — the file does not have 13 real nested ids; it has 8, plus Q63. Five ids the old detector listed have no record anywhere in WORK-QUEUE.md:

id lines naming it what the text actually is
Q54 3 out/Q54-READBACK.txt, “the Q54 artifact's durable handle”
Q55 7 the Q55 → Q45S9 rename labels, out/Q55-CLEANUP.json
Q56 6 out/Q56-MATRIX.json, out/Q56-CENSUS.json
Q58 1 …/q58/helm-selftest-q58.py inside a re-measurement bullet
Q62 1 “none of Q31–Q62 is in production” — a range

Q77/Q99 have one line each, the tick that quotes --outside = Q63/Q77/Q99. So the 16-row table the old build rendered held 8 items, 5 artifact/range false positives and 3 quoted-tool-output false positives; the new build holds the 8 items plus Q63. The number that moves is the tool's, and the direction is down because the false positives are gone, not because items were lost.

Evidence (measured this tick).

  • python3 tools/queue_index.py --selftest → selftest: 44 cells, 44 passed, 0 failed, rc 0. Flipped cells: “prose mention is not a record (Q42)”, “mid-line bold mention is not a record (Q44)”, “quoted tool output opens nothing (Q77/Q99)”, “record line follows the first mention of the same id”, plus two positive cells for BOLD-LEAD and STATUS-LEAD.
  • python3 tools/queue_index.py --write docs/queue-index.md → 848 → 834 lines (36,867 B), nested table 16 → 9 rows.
  • python3 tools/queue_index.py --check docs/queue-index.md → rc 0, index current: 49 sections, 45 ids, 4 continuation sections, 9 nested ids, 9930 lines / 1223321 bytes.
  • Record-vs-mention deltas now visible in the document: Q42 5673→5803, Q46 6412→6419, Q47 6485→6542, Q53 7246→7292, Q63 9909→9918.

Addendum, same tick, after the sweep. tools/selftest_sweep.py caught the one thing the tool's own grid cannot: the docstring and --selftest help still advertised 38 cells while the grid printed 44 — a COUNT_MISMATCH fatal in the sweep (queue_index.py COUNT_MISMATCH 38 cells 44 cells). Both strings now read 44. Re-run: sweep: 11 tools, 10 OK, 0 fatal (the one non-OK is doc_census_check.py NO_CLAIM, advisory and unchanged).

Addendum 2 — the verifier found a crash, so the commit grew one fix. Writing verify_q63.sh against extracted blobs (git show <rev>:WORK-QUEUE.md into a directory with no .git) crashed the tool: outside_ids() returns None outside a work tree and run() did outside, corpus = outside_ids(...) → TypeError: cannot unpack non-iterable NoneType. --index/--json are supposed to work on an extracted copy, so the unpack now falls back to ({}, 0) and git ls-files writes its stderr to DEVNULL instead of the tool's output. Two new cells hold it: --index outside a git work tree exits 0 and … still summarizes → selftest 46 cells, 46 passed, 0 failed, sweep 11 tools, 10 OK, 0 fatal, --check still rc 0 at 9 nested ids. This is a second commit on top of e79cbca, not a rewrite of it.

Tick 4 — unreadable input must not read as "clean" (six tools, one class)

Picked up an unfinished item: six tracked verifier tools mishandled input they could not read, in two directions. Five crashed with a Python traceback under an exit code that this corpus uses for "a finding"; two reported a clean census over an input they never opened — citation_hash_class.py --repo /nope printed corpus: 0 files, flags: 0 rows and exited 0, and citation_resolve_check.py did the same for citations: 0 / stale: 0. The second direction is the dangerous one: a green gate that never looked is indistinguishable from a green gate that looked and found nothing, and these are the two tools a reviewer runs to decide whether a citation defect exists. Both were found by probe, not by reading — every one of the six was already green on its own selftest.

Cause, measured: git() in both scanners returns subprocess.run(...).stdout and discards the return code, so a missing repo or a mistyped --rev yields an empty tree, an empty corpus and a zero count. queue_claim_check.py's docstring already promised 3 queue unreadable while its code raised UnicodeDecodeError on non-UTF-8 — doc/code mismatch closed rather than widened.

Changed — six files, 175 insertions(+), 14 deletions(-):

tools/queue_index.py             66/6   read errors -> rc 3; whole-input guard on --check
tools/queue_claim_check.py       45/5   UnicodeDecodeError -> rc 3, + 2 read-error cells
tools/citation_hash_class.py     24/0   precondition(repo, rev) -> rc 2
tools/citation_resolve_check.py  21/0   same guard, same code
tools/check_lint.py               8/2   unreadable --log -> message, no traceback
tools/census_row_delta.py        11/1   non-census JSON named, no traceback

Exit codes follow the tools that already had a convention: 3 = queue unreadable (claim_check docstring), 2 = precondition failed / did not measure (doc_census_check.py, landing_check.py). No except Exception — every guard names OSError, UnicodeDecodeError or ValueError, the classes actually observed.

Verified, this host, this work tree:

  • selftests: queue_index 54/54, queue_claim_check 16/16 (10 claim-check, 4 unit, 2 read-error), check_lint 37/37, census_row_delta 33/33, citation_hash_class 19/19, citation_resolve_check 11/11 — 0 failed everywhere.
  • tools/selftest_sweep.py → sweep: 11 tools, 10 OK, 0 fatal; the admitted --selftest claims now match what the tools print (the one non-OK, doc_census_check.py NO_CLAIM, is advisory and pre-existing).
  • queue_index.py --check docs/queue-index.md → rc 0, 49 sections, 45 ids, 4 continuation sections, 9 nested ids, 9937 lines / 1224324 bytes.
  • nine broken-input probes → 0 tracebacks. queue_index --queue <missing> rc 3, --queue <non-UTF-8> rc 3, queue_claim_check --queue <non-UTF-8> rc 3, both citation scanners on a missing repo rc 2 (and rc 2 on --rev deadbeef), check_lint --log <missing> and census_row_delta <non-census> message-then-rc 1.
  • no-behaviour-change A/B, HEAD copy vs working copy on one work tree, nine invocations: 7 SAME, 2 DIFFERS, and both DIFFERS are the intended added cells (54 vs 46, 16 vs 14).

A correction I owe, against my own draft. My run note first claimed "7 SAME, 0 DIFFERS over three selftests". That is false — a selftest that gains cells cannot print the same bytes — and it contradicted its own table. Re-measured copy-vs-copy it is 7 SAME / 2 DIFFERS. The trap is recorded in the artifact: the citation scanners census this clone's local object store, so an A/B done with git stash adds stash objects to the very store being counted; copy-vs-copy is the valid method. Filed, not fixed: check_lint.py and census_row_delta.py still use rc 1 for both "a graded fault" and "I could not read your file" — the message disambiguates, the code does not, and renumbering is a lane decision.

Artifact: /root/.hermes/wizard-outputs/volt/2026-10-17-input-error-class/run.md.