Files
troupe-standup/checkins/2026-10-18-volt.md
T
volt c6180b6d7d tools (volt): verify.py -- the gate's home: three legs, one rc, every red path exercised
index-current (queue_index --check), append-audit (queue_append_audit --guard
--to HEAD), selftest-sweep (skippable with --fast, printed SKIP and counted as
skipped). rc 0 graded clean / 1 graded a fault / 2 could not grade, with 2
outranking 1 so an ungradable leg cannot be read as a certified run; the fault
count is still printed beside it. Tools resolve from --repo, not from this
file's directory, so a worktree is graded with its own instruments.

selftest 24/24 (stub legs through the real CLI: rc mapping incl. retired rc 3,
missing tool, timeout, --fast, --json, missing repo, fixed order). Added to
both sweep probe axes (read-refusal 19/19, malformed 17/17, 14 tools 14 OK) and
the sweep's stale "15 such probes / nine tools" prose corrected to 17 / ten.

Green at 019b75c: 3/3 pass, rc 0. Red paths on a full 785-commit clone:
0 -> 1 (working-tree append, no re-render) -> 0 (--write) -> 1 (committed
stale: both legs faulted) -> 2 (tool absent; index fault still printed).
Queue tick appended and index re-rendered in this same commit.
2026-10-18 19:34:48 +00:00

28 KiB
Raw Blame History

Check-in — Volt, 2026-10-18 (00:16–00:5xZ)

Did

Built and landed the instrument for a contract that had two statements and no reader: tools/checkin_check.py (588784d, --since at edaef63, the files/days separation at c213a5d). 27 selftest cells, rc 0:

$ python3 tools/checkin_check.py --selftest
selftest: 27 cells, 27 passed, 0 failed          # rc 0

The two sentences, verbatim. checkins/README.md: "One file per person per day: YYYY-MM-DD-<handle>.md." WIZARDS-TABLE.md §"The churn contract", item 1: "One check-in in checkins/YYYY-MM-DD-<name>.md (Did / Blocked / Next / Ask)." Nothing in tools/ read either one. Measured at 07441fa from this host:

$ python3 tools/checkin_check.py --repo . --gaps
== 69 check-in files in /root/troupe-standup/checkins ==
roster: 9 handles; today 2026-10-18
  SKIP README.md  (the directory's own README: not a check-in)
...
checkin_check: 69 files, 35 with a fault (BAD_NAME 25; DUPLICATE groups 10), 57 advisory
  • 25 of 69 filenames are not <date>-<handle>.md: -01..-07 suffixes, zephyrus-wizards{,-02,-03}, cassian-02, cassian-q5-census, cassian-q5-recount.
  • The suffixes are not cosmetic — 10 (date, handle) days carry 2 to 8 files. Worst: 2026-10-06 for zephyrus, 8 files.
  • 57 of 69 do not carry all four of Did / Blocked / Next / Ask; 12 do.
  • 0 UNKNOWN_HANDLE, BAD_DATE, FUTURE, EMPTY.

Cross-checked by shell, not by the tool that reports it — a scanner's own count is not evidence for the scanner:

$ ls checkins/*.md | grep -v README | grep -vcE '^checkins/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z][a-z0-9]*\.md$'
25
$ # intersect the four heading greps over checkins/*.md
12                      # carry all four -> 69 - 12 = 57 lack at least one

Which rule is a fault and which is an advisory — measured, not assumed. The filename rule was in the tree before the first check-in existed: README added 5f7f773 2026-09-24T10:30:32Z, first check-in file added a3c487e 2026-09-24T10:52:32Z (22 minutes later). The four-heading sentence entered at aeac3ea 2026-10-08T17:20:45Z, two weeks into the archive. So F1–F5 grade rc 1 and the heading axis is counted and printed but never fails the run — grading history by a rule that postdates it would report the archive faulty for having been written first, and that noise would bury the 25 real name faults.

The split that matters for the ruling below:

$ python3 tools/checkin_check.py --repo . --since 2026-10-08
since 2026-10-08: 30 graded, 39 older file(s) not graded
no file violates the filename, date, emptiness or duplicate rule
advisory (never rc 1): 21 of 30 files lack a Did/Blocked/Next/Ask heading
checkin_check: 30 files, 0 with a fault, 21 advisory

All 25 name faults predate 2026-10-08 — the -NN practice stopped on 2026-10-07 at cassian-q5-recount. The archive's live practice is filename-clean and heading-dirty: 21 of the 30 check-ins written since the churn contract existed ignore it, this lane's own 2026-10-15/16/17 files among them (Did/ Blocked/Next/Ask appear nowhere in them). This file is the first of mine that carries all four.

Wired into the gates. tools/selftest_sweep.py gained checkin_check.py on the read-refusal axis, and a {bindir} fixture: this tool's input is a directory of UTF-8 files, so a {bin} file probe would only have proven it refuses a non-directory. Sweep at c213a5d:

$ python3 tools/selftest_sweep.py --repo .
discovery: git ls-files at c213a5d (12 tracked in tools/)
checkin_check.py           OK                   27 cells     27 cells  27 cells
sweep: 12 tools, 12 OK, 0 fatal
checkin_check.py           missing   rc=2    OK   cannot read checkins dir .../there-is-no-such-...
checkin_check.py           not-utf8  rc=2    OK   cannot read .../not-utf8-dir/2026-01-01-volt.m...
read-refusal: 17 probes, 17 ok, 0 fault            # was 15 probes / 4 file readers

A number I got wrong and fixed before it landed. The gap table reported a files column that was really distinct days — zephyrus read 23 files when he has 44 files across 23 days (c213a5d; fixture cell c27 now pins the two columns apart). Called out because the number was in a table I was about to quote in this file, and a mislabelled count is the exact defect this archive keeps grading other lanes for.

A sibling gate's silent zero, found by using it. doc_census_check.py --tools <name> takes repo-relative paths; passing the bare basename checkin_check.py scanned zero tools and exited 0 with tools scanned at 8932d06: 0 — indistinguishable from a clean pass over an empty claim set. Fixed at 76043b7: a requested name that is not tracked at the rev is now rc 2 with the names and the shape of a valid one, and resolve_tools() splits the request from the tree so both halves are unit-tested (2 cells; 33 → 35).

$ python3 tools/doc_census_check.py --repo . --tools checkin_check.py
cannot grade: --tools names nothing tracked at HEAD: checkin_check.py
  names are repo-relative, e.g. --tools tools/checkin_check.py; a filter
  that matches nothing is not a clean scan
rc=2
$ python3 tools/doc_census_check.py --repo . --rev 8932d06 --tools tools/checkin_check.py --no-run
tools scanned at 8932d06: 1 (internal-split only, label vocabulary)
tools/checkin_check.py: 0 INTERNAL SPLIT, 0 STALE claim(s), 0 leg failure(s), 0 claims checked
rc=0

Deliberately not done. The tool renames nothing. The 25 historical names are the record; a gate that edited the record to turn its own report green would be worth less than the 25 lines it rewrote. That is why --since exists: the gate can be adopted forward (--since 2026-10-18 --fail → rc 0 today, 69 files left ungraded and counted, not hidden) without a single rename.

Blocked

Nothing. One open question needs a ruling, not a blocker — see Ask.

Next

  • Await the ruling on the four-heading sentence; if it binds, run python3 tools/checkin_check.py --repo . --since 2026-10-18 --fail in the daily gate and make 21 lanes (this one first) comply.
  • doc_census_check.py full run at c213a5d in progress as this file is written — a twelfth tracked tool changes its population, and my last two check-ins were spent on claims that read STALE at a new rev. Verdict to be appended to this file, not asserted here.
  • Carry the four headings in every check-in from today.
  • The census verdict for the new tool, measured rather than assumed: tools/checkin_check.py: 0 INTERNAL SPLIT, 0 STALE claim(s), 0 leg failure(s), 0 claims checked at 8932d06 — it carries no docstring census block, so doc_census_check has nothing to adjudicate in it. The population question (does a twelfth tool make a sibling's claim STALE?) is the full run's to answer, not this line's.

Ask

One ruling from Alexander: does the churn contract's (Did / Blocked / Next / Ask) bind, or should the sentence be amended to what is practised? Two weeks of evidence says it is not binding: 21 of 30 files written while it existed skip it, including Timmy's own daily replies being a separate channel and Merlin's 70–100 KB single-section check-ins. If it binds, it needs a gate that fails and 21 files to fix. If it does not, the sentence in WIZARDS-TABLE.md is the thing to change — a contract nobody follows is worse than an honest convention, because it teaches readers that stated rules are decoration.

The filename half needs no ruling: it is already clean since 2026-10-08 and the 25 historical names can stay as the record. I recommend (a) leave the history, gate forward with --since.


Check-in — Volt, 2026-10-18 (02:3xZ, appended; the block above is 00:16–00:5xZ)

Did

Closed yesterday's filed carry — "a tool that mis-codes a decodable but malformed input is not measured" — by measuring it on every tool. Landed tools/selftest_sweep.py only; no tool was edited, because no tool was wrong.

The class. Input that decodes as UTF-8 and cannot be parsed: a .json that is not JSON, a {} where an audit file should be, a directory that is not a git repo, a queue with no records. It is the class where a tool is most tempted to answer 0 and exit 0 — exactly the doc_census_check --tools bug (76043b7).

15 probes, each graded against the answer its own tool states, not against a blanket "must be rc 2" — because that universal is false here: check_lint grades a junk log MISSING (rc 0 report, rc 1 under --fail-on-fault), checkin_check grades a heading-less check-in advisory (rc 0, its docstring says "never rc 1"), queue_claim_check reports 0 opening records (rc 0; its --fail-on-stale is the gate). Nine tools must refuse at rc 2.

$ python3 tools/selftest_sweep.py
read-refusal: 17 probes, 17 ok, 0 fault
malformed-input: 15 probes, 15 ok, 0 fault          # rc 0, 12 tools OK

15/15 at HEAD is the honest finding, and stated as such: nothing was broken, nothing measured it. Re-run against the revision's own copies (git show HEAD:tools/*.py) so the working tree is not grading itself: 15/15.

The gate reproduces the class on real history. Same axis, tools as they were at 461eede (before the rc-2 unification 6ee8fce):

malformed-input: 15 probes, 8 ok, 7 fault (NO_TOOL, RC_WRONG, TRACEBACK)
read-refusal:   17 probes, 4 ok, 13 fault (NO_TOOL, RC_NOT_2, TRACEBACK)

Six of the seven are defects in tools that existed then — three raw tracebacks (append_only_audit not-a-repo; append_only_owners malformed-json and wrong-shape) and three rc 1 where the contract says 2 (census_row_delta both shapes; selftest_sweep not-a-repo). The seventh is NO_TOOL (checkin_check.py did not exist at that rev) — named, not skipped.

It discriminates, which is the only thing that makes a gate worth its lines. One bug reintroduced into a copy of append_only_owners.py (swallow ValueError, print 0 owners adjudicated, return 0):

malformed-input: 15 probes, 14 ok, 1 fault (RC_WRONG)
RC_WRONG  rc 0, contract says 2: 0 owners adjudicated: Expecting value ...
# and that same tool's own --selftest: 15 cells, 15 passed, 0 failed

The tool's own fixtures never covered the class, so it could regress in silence. That sentence is the whole unit.

The axis found its own bug on the first run — six probes were substituting {badjson} as a bare key, leaving a literal path that refused at rc 2 for the wrong reason. The required-substring check caught it; without it those six rows would have printed OK. Fixed and re-run before any of these numbers were written.

Selftest 22 → 28 cells, including c24 (the silent-zero shape: rc 0 where the contract says 2 → RC_WRONG), c26 (right code, wrong reason → UNEXPLAINED) and c28 (coverage: every tool with a missing-probe also has a malformed probe, so a new tool is visible rather than skipped):

$ python3 tools/selftest_sweep.py --selftest
selftest: 28 cells, 28 passed, 0 failed

Queue untouched. queue_index.py --check docs/queue-index.md → rc 0 (49 sections, 45 ids, 4 continuation sections, 9 nested ids) before this block and after it. No queue item opened or closed; open set unchanged (Q37 :5278 pipe; career-lane Q53 held for Alexander).

Blocked

Nothing.

Next

  • If a tool's malformed contract changes, its probe changes with it: the table is in tools/selftest_sweep.py:MALFORMED_PROBES, cited by line in the review, not inferred.
  • The axis grades the code, a message, and one required word — not whether the message is good. That is the next honest increment if it is ever needed; it is not claimed now.

Ask

The four-heading ruling from the block above still stands (unchanged, still the only thing I need from Alexander). Nothing new.

Artifact: /root/.hermes/wizard-outputs/volt/2026-10-18-malformed-axis/ (decision.md, selftest.txt, sweep-head.txt, head-copies.txt, ab-461eede.txt, discrimination.txt).

Verdict, appended 04:55Z — the carried doc_census_check full run, and the two false defects it was reporting

Reply 20 carried one item on my side: the full census my check-in promised to append had not landed. It is run, at 4ce1aed, and it found a defect in the instrument that was running it.

The run. 12 tracked tools, 145 verdict rows, 4m47s, rc=0:

--- verdict totals (unit: claims) ---
  AMBIGUOUS    11
  MATCHES      26
  NOT_PRINTED  87
  REV_UNCHECKED 8
  SELF_NOT_RUN 11
  STALE        2

Both STALE rows are false, and both are in one sentence. The single-tool view is the indictment:

$ python3 tools/doc_census_check.py --repo . --tools tools/checkin_check.py
tools/checkin_check.py: 0 INTERNAL SPLIT, 2 STALE claim(s), 0 leg failure(s), 13 claims checked
  STALE      tools/checkin_check.py:59 Never claimed 8 at HEAD -- printed 2 [selftest]
  STALE      tools/checkin_check.py:59 never claimed 1 at HEAD -- printed 2 [selftest]

Line 59 is read as UTF-8. Never 1, never a traceback. — an exit-code sentence. The 8 is the tail of UTF-8, paired across the sentence's period with the word Never; the 1 is the code, paired with never across a comma. Neither is a count of a unit. The oracle then found some two-count elsewhere in the selftest output and graded both STALE: two defect claims against a docstring that is correct, which is the failure mode this archive grades other lanes for.

The cause is the separator class, measured on the whole corpus, not reasoned from the two rows. The same 12 committed docstrings at HEAD were read by the old parser and the new one (vocab-before.txt, vocab-after.txt, same code, git show corpus):

before: 140 claims   after: 104 claims
  sep=' '                 95          sep=' '                 87
  sep=''                  11          sep='(unit:value form)'  9
  sep='(unit:value form)'  9          sep='` '                 6
  sep='` '                 6          sep='  '                 1
  sep='-'                  5          sep=') '                 1
  sep='. '                 5
  sep='  '                 4
  sep='; '                 2   sep=' " ' 1   sep='+ ' 1   sep=') ' 1

Only 95 of 140 were a count and its unit. The rest: a hex run welded to its letters (83acffe0 -> 83 acffe0, 11), an ordinal or a sentence end (1. INTERNAL, 0. Usage, 8. Never, 5), a compound adjective (120-char, 1-based, 5), an aligned list marker (0 ran, 4), punctuation spills (5).

Fix — three rules, six cells. CLAIM.sep is now one space, or a closing delimiter followed by one space. num is [0-9]+(?:,[0-9]{3})*, so a trailing comma is punctuation and not a thousands separator — the old class read 1, which as claim 1 of unit which and 680, refs as claim 680, which is 8 of the 40 removed verdict rows on its own. ordinal_at() refuses a line-leading number followed by 2+ spaces, the exit-code block's 0 ran / 1 ran / 2 could. Six cells pin them (welded, ordinal, list marker, sentence end, compound adjective, and a positive control that 471 UNRESOLVED / 1,612 citations still read): 35 -> 41.

After, at the same revision and over the same docstrings:

$ python3 tools/doc_census_check.py --repo . --rev 4ce1aed
--- verdict totals (unit: claims) ---
  AMBIGUOUS    11
  MATCHES      26
  NOT_PRINTED  52
  REV_UNCHECKED 8
  SELF_NOT_RUN 8

145 -> 105 rows;  STALE 2 -> 0;  NOT_PRINTED 87 -> 52;  SELF_NOT_RUN 11 -> 8

The invariant that makes this a repair and not a blindfold: the 26 MATCHES are the same 26 rows, by tool, unit, value and verdict —

$ python3 scratch/diff_census.py census-head.json census-head-tightened.json
MATCHES identical: True | lost: [] | gained: []

so the tightening dropped no adjudicated verification; it dropped only rows that were never a count and a unit. MATCHES unchanged is the whole evidence claim.

Gates, re-run after the change: --selftest 41 cells, 41 passed, 0 failed, rc 0; tools/selftest_sweep.py 12 tools, 12 OK, 0 fatal (doc_census_check.py 41 cells claimed and printed), read-refusal 17/17, malformed-input 15/15, rc 0. The sweep's advertised-count gate caught nothing because the usage line was updated in the same commit, which is the point of it.

What the tightening does not reach, stated rather than implied. Six claims behind a backticked token (`-07` suffixes), one aligned mid-line (WORK-QUEUE.md:8003 cites) and one 120) characters are still read; none is in a unit any tool prints, so all are NOT_PRINTED and none can become a STALE. NOT_PRINTED at 52 remains the bulk of the verdict rows, which is this tool's stated gap (§"WHAT THIS DOES NOT CHECK"), unchanged in kind.

A contract gap this run exposed, named not fixed. doc_census_check.py exits 0 while reporting STALE > 0 (measured above: rc 0 with two STALE rows); it has no --fail, where checkin_check.py does. A gate cannot fail on the class this tool exists to catch without parsing its text. That is the next increment, not something to fold into this one silently.

Artifact: /root/.hermes/wizard-outputs/volt/2026-10-18-doc-census/ (census-head.txt/.json pre-fix, census-head-tightened.txt/.json post-fix, diff.txt row-by-row, vocab-before.txt/vocab-after.txt, sweep-after.txt).

Check-in — Volt, 2026-10-18 (07:0x–07:4xZ, appended; the blocks above stand)

Did

Closed the gap this file named at 04:55Z — "it has no --fail … a gate cannot fail on the class this tool exists to catch without parsing its text." tools/doc_census_check.py now carries the gate: 26056d2, +147/−3, blob sha256 731d9073a99f5cf56c70fef4d6ac204248964f7f1e77ed1e40b752993987e332.

rc 0  ran, graded no fault        rc 1  ran, graded a STALE or a SPLIT
rc 2  could not grade             (usage, --tools matches nothing, unreadable)

A leg failure is reported in its own column and never spent as a claim defect: a leg that produced no census adjudicated no claim. --selftest 41 → 52 cells; four of the new cells pin the process exit code on stub repos, because a helper returning 1 proves nothing about a gate.

The gate's first armed run went red — on a false claim, not a defect. queue_claim_check.py's axis list says 39 ACS-only lines, 12 ACS-only lines, 1 ACS-only line — three sub-counts of one population of 52 — and the token read as a unit was the adjective ACS in ACS-only, splitting 39/12/1:

SPLIT  ACS [no rev named] (LABEL_ONLY): 39@83, 12@86, 1@87     # rc 1
(no-run.txt)

Fixed in the same commit: a unit immediately followed by - is a compound adjective, not a unit — the refusal the reader already made for 120-char. Same rev after: 0 INTERNAL SPLIT, OK (no-run-after.txt).

The cost is measured, not asserted. Row-level --json diff before/after (diff_claims.py): 6 claims no longer read — queue_claim_check 23 → 19, checkin_check 8 → 7, queue_index 10 → 9; 5 NOT_PRINTED + 1 REV_UNCHECKED; every lost token is the first half of a compound (ACS-only, check-in, self-test, follow-on). The invariant that licenses it: MATCHES 26 before and 26 after, identical rows. One real count is caught in the net — 69 check-in files at checkin_check.py:12 — whose unit word (files) was already being misread, and which was REV_UNCHECKED anyway. A genuinely hyphenated unit (citations-per-block) is now unread; stated in the docstring.

A second defect the two runs exposed, named not repaired: on the pre-hyphen build the gate's verdict depended on the mode. HEAD, one tool: run mode --fail printed (not flagged: 1 split(s) in units NOT_A_CENSUS_UNIT) and rc 0; --fail --no-run printed the split and rc 1 (mode-*.txt in the artifact). The gate passed in the mode that spends the verdict and failed in the mode that only labels it. Both modes agree at 0 after the fix, because the false claim is no longer read — the asymmetry itself is unrepaired and said so.

Gates re-run after the change: --selftest 52/52 rc 0; --fail at HEAD — 12 tools, 0 INTERNAL SPLIT, 0 STALE, rc 0 (gate-HEAD-full.txt, ~6 min); negative tooth fca3f2e --tools tools/citation_resolve_check.py --fail — 1 split + 1 STALE, rc 1, and the STALE is a real pre-existing docstring defect (UNRESOLVED claimed 441 at babdadc — printed 471), not a fixture; sweep 12 tools OK (52 claimed / 52 printed), read-refusal 17/17, malformed-input 15/15, rc 0. The pre-tightening build at 4ce1aed still reproduces rc 0 with 2 STALE (historical-stale-pretightening.txt) — cited with its build, never as current behaviour.

Artifact: /root/.hermes/wizard-outputs/volt/2026-10-18-census-fail-gate/ (REPORT.md, before/after census --json, the two mode runs, the tooth runs, the sweep log, SHA256SUMS).

Blocked

Nothing blocks. Two limits stated rather than discovered later: the full gate run is ~6 minutes over 12 tools, and nothing in the repository invokes --fail yet — the gate is armed, not wired.

Next

  • Wire --fail --no-run (fast, ~0.2 s) into whatever runs selftest_sweep.py, so the sweep's 12/12 and the census's 0/0 are one command. That is a one-line change to a runner nobody owns yet; propose it rather than take it.
  • The NOT_A_CENSUS_UNIT vocabulary is the next precision question (see Ask).

Ask

  • Should --fail in run mode spend a split in a unit outside the census vocabulary? Today run mode calls it advisory (not flagged) and --no-run calls it fatal, which is the asymmetry measured above. Repaired the false positive that surfaced it; the policy is a human decision, not mine to make in a tool default.

Check-in — Volt, 2026-10-18 (15:0x–15:2xZ, appended; the blocks above stand)

Did

Closed a gate that was red on main and that nothing had re-run since it went red: tools/queue_index.py --check docs/queue-index.md returned rc 1, STALE at line 59 at HEAD 69f3b56, because 067afdf (the 12:33Z control-plane tick) appended nine lines to WORK-QUEUE.md in a detached worktree and committed WORK-QUEUE.md only — no docs/queue-index.md. The index pins the queue's sha256, so that commit is red by construction; it had been red for 2h36m at the read.

Repair is a re-pin, not a re-parse: --write against the tree as found replaces 7 lines (the Q45 extent, the pinned bytes/lines/sha); the diff this commit lands is 9 insertions / 9 deletions across 5 hunks (git diff -U1), because this block is itself inside the queue being rendered — one added Q53 reference and 13 lines on Q45's extent. No structural count moves — 49 sections, 45 ids, 4 continuation sections, 9 nested ids before and after. --check rc 0 at the commit this lands in; --selftest 54/54; sweep 12/12, read-refusal 17/17, malformed-input 15/15.

Controls, so the claim is measured rather than argued — same tool, three worktrees: 067afdf rc 1, ece5228 rc 1 (a different staleness: 13 nested ids rendered against 16 pinned), 39312c2 rc 0 (the one commit that changed queue and index together). Scope: 6 commits since the index existed at 1423c4d touch the queue; 3 re-rendered, 3 left the pin stale at their own commit.

A "Next" of mine, corrected against measurement before anyone wires it. The 07:4xZ block proposed doc_census_check.py --fail --no-run as the ~0.2 s gate to wire into the runner. Measured at 69f3b56 it prints "no oracle in this mode: nothing was verified, so nothing is graded", checks 0 claims across all 12 tools and exits 0 — wiring it as-is would add a leg that can never go red. Its teeth live in a cached vocabulary (--save-vocab), not in --no-run.

Blocked

Nothing.

Next

  • The fast census gate only has teeth with a vocabulary cache present. Either the cache is written where the runner can find it, or --no-run should refuse (rc 2) when it has no oracle instead of printing a green 0 — a tool default that reads like a policy call, so it is named here, not taken.
  • Whoever appends to WORK-QUEUE.md re-renders docs/queue-index.md in the same commit. That is the whole defect class; the tool already refuses the result, but nothing runs it at commit time.

Ask

  • Nothing for Alexander. (Still standing from the 07:4xZ block: whether --fail in run mode should spend a split in a unit outside the census vocabulary.)

Artifact: /root/.hermes/wizard-outputs/volt/2026-10-18-index-stale/ (REPORT.md, before-check.txt, after-check.txt, index.diff, index-history.txt, worktree-checks.txt, check.sh).

— Volt

CORRECTION (15:2xZ, same run, append-only). The ledger block above states "In scope since the index was introduced at 1423c4d (10-17): 6 commits touch the queue, 3 also re-rendered it, 3 left the pin stale at their own commit" — a mutable count with no revision named, which by this repo's own rule reads stale forever. It is measured at 69f3b56. At the landing commit de3dcdc the same count is 7 touch / 4 re-rendered / the same 3 still stale, the seventh being the repair commit itself (a queue+index commit, so it is in the re-rendered class, not the stale one). The sentence stays as written; this line is the frame it should have carried.

19:33Z — the gate has a home: tools/verify.py

What landed. tools/verify.py (18,723 B / sha256 7bea2260… / 424 lines), tracked in this commit with the sweep-probe additions in tools/selftest_sweep.py. One command, three legs in fixed order, one exit code: index-current (queue_index --check docs/queue-index.md), append-audit (queue_append_audit --guard --to HEAD), selftest-sweep (skippable with --fast, printed as SKIP and counted as skipped). rc 0 all graded legs pass, rc 1 a leg ran and graded a fault, rc 2 a leg could not grade — 2 outranks 1 because a run with an ungradable leg has not certified anything, and the summary still prints the fault count beside it.

Why it exists. Three ticks of my own advice told Alexander to wire queue_index --check into "the tick's check.sh". git ls-files shows no check.sh and no scripts/; the advice named a target that does not exist. Whether every lane must run the gate is still Alexander's call; building the home was a task, and this is it.

Measured. Green at 019b75c, full run: 3 legs, 3 pass, rc 0, 25.3 s (389 / 822 / 23,833 ms). Red paths on a full clone (785 commits) of 019b75c, verify.py driving that clone's own tools: baseline rc 0 → one working-tree queue append without re-render rc 1 (STALE … line 59) → clone's own --write rc 0 → the same append committed without re-render (c5d685b) rc 1 with both legs faulted → queue_append_audit.py removed rc 2 with the still-live index fault printed beside it. A --depth 1 clone grades append-audit UNGRADABLE rc 2 ("no commit in HEAD touches WORK-QUEUE.md") — cannot-grade, not a false green. --selftest 24/24. Sweep with --tools-dir tools: 14 tools, 14 OK, read-refusal 19/19, malformed 17/17, rc 0 (prose said 15 malformed probes while the tool printed 16; corrected to 17 with "nine tools" → "ten").

Blocked. Nothing.

Next. The home exists; adoption is the open question. A lane runs python3 tools/verify.py in its tick (this one did), or Alexander wires it into whatever runner the troupe settles on — the script does not decide that.

Ask. Nothing for Alexander that is new: the standing adoption call (does every tick run verify.py?) is the same policy question the 17:44Z block named as needing a home, and the home now exists to be adopted.

Artifact: /root/.hermes/wizard-outputs/volt/2026-10-18-verify-home/ (REPORT.md, red-matrix.sh, red-matrix-full.txt, verify-green.txt, verify-green.json, selftest.txt, sweep.txt).

— Volt