23 KiB
Check-in — Volt, 2026-10-19 (00:00–00:2xZ)
Did
Fixed a silent under-report in the queue's table of contents: a Status:
marker whose bold run closes before its value was published as --, i.e.
the table said "no status" about an item that states one.
The rule was written for one emphasis form and silently broke the other.
tools/queue_index.py's STATUS pattern consumes the optional leading **,
so the value arrives as value** tail (bold closes after the value) or as
** value (bold closes before it). The old one-liner cut at the first **:
raw = m.group(1).strip()
if "**" in raw: # a bold status marker closes mid-line
raw = raw.split("**", 1)[0]
which is right for the first form and returns "" for the second. Empty is
falsy, so the parse stored None and the index rendered --. The live case
was Q13 at WORK-QUEUE.md:1129:
**Status:** 1 of 8 has a decision and staged correction (`magazine-091`; reply 09 §3), ...
Measured over the real queue, the class is small and the failure is total for
the form it affects (/root/.hermes/wizard-outputs/volt/probe-status-forms.py,
run against WORK-QUEUE.md at 2e8ae5a):
49 heading sections
bold-value 24 **Status: value**
plain 20 Status: value
bold-label 1 **Status:** value <- 1 of 1 emptied by the old rule (Q13:1129)
So: one row wrong today, and every future **Status:** line would have gone
wrong the same way without a sound.
The fix — status_value() strips a leading bold close until none is left,
then cuts a trailing one, so both emphasis forms yield the value:
def status_value(raw):
raw = raw.strip()
while raw.startswith("**"):
raw = raw[2:].strip()
if "**" in raw:
raw = raw.split("**", 1)[0].strip()
return raw
The call site keeps its break-on-first-marker semantics, so no section that was previously read is read differently:
status = status_value(m.group(1)) or None
Selftest 54 -> 58 cells, four new ones on an inline fixture (so no existing
fixture line numbers move): the bold-label form extracts its value, it reports
its own status_line, a bold value still extracts, and a marker with no value
at all stays None.
$ python3 tools/queue_index.py --selftest
selftest: 58 cells, 58 passed, 0 failed # rc 0
The derived document was regenerated, and the diff is exactly the two cells that carry that parse — no other row moved, which is the proof the blast radius is one section:
$ git diff --numstat docs/queue-index.md
2 2 docs/queue-index.md
-| 13 | Q13 | 1111-1145 | 2788 | opening | ... | -- |
+| 13 | Q13 | 1111-1145 | 2788 | opening | ... | 1 of 8 has a decision and staged correction (`magazine-091`; reply 09 §3), but its decided note carries |
- "status": null,
+ "status": "1 of 8 has a decision and staged correction (`magazine-091`; reply 09 \u00a73), but its decided note carries",
An independent witness, because every existing check of this parse runs
through the tool itself. --check re-renders with the same parse() and
compares bytes; --selftest runs fixtures. Both are statements about one
implementation. independent_index_witness.py (in
/root/.hermes/wizard-outputs/volt/tools/, shares no code with the tool)
re-derives all 49 published rows, the header counts, the byte accounting and
the nested-record table from the queue's bytes with its own logic, and grades
docs/queue-index.md cell by cell. It agrees with the corrected document:
$ python3 independent_index_witness.py --repo /root/troupe-standup
note named but never opened as a record (correctly absent): Q54,Q55,Q56,Q58,Q62,Q77,Q99
witness: 49 sections / 45 ids / 4 continuation / 9 nested / 1261058 bytes graded against docs/queue-index.md
witness: agree -- every published cell re-derived from 1261342 bytes of WORK-QUEUE.md by independent logic
rc 0
and it goes RED on the pre-fix document, naming the row — so it is a witness, not a rubber stamp:
$ python3 independent_index_witness.py --repo . --index <pre-fix copy>
FAULT row 13 (Q13) status: published '--', derived '1 of 8 has a decision and staged correction (`magazine-091`; reply 09 '
witness: 1 fault(s) -- the independent parse does NOT corroborate the published table
rc 1
Gate at the commit that follows, run whole:
$ python3 tools/verify.py
index-current PASS index: 49 sections, 45 ids, 4 continuation sections, 9 nested ids, 10046 lines / 1261342 bytes
append-audit PASS every graded commit left the index current in its own tree
selftest-sweep PASS sweep: 14 tools, 14 OK, 0 fatal
gate: OK -- 3 of 3 graded leg(s) passed # rc 0
Nothing else changed: WORK-QUEUE.md is untouched (queue_sha256 in the pin is
unchanged), no other tool imports this one, and the census's tool set and LOC
totals are the repo's own business, not pinned to a number in any document
(grep for a pinned queue_index.py line count returns nothing).
Blocked
tools/doc_census_check.py did not finish inside a 180 s foreground call on
this host (killed at the harness timeout, rc 124, no output captured). Not on
the gate's path — verify.py's three legs all ran — but the census was not
re-measured this tick and I am not claiming it was.
Next
- Re-run
doc_census_check.pyin the background and report its totals against the same revision, so the tool set's LOC is measured at the newqueue_index.py(+34/−6) rather than assumed. - The same emphasis-form question applies to any other marker this repo parses
by hand;
checkin_check.pyandcitation_resolve_check.pyare the next candidates for a**Label:**fixture each.
Ask
None. No item opened or closed, no decision needed.
Did (second tick, 00:1x–00:3xZ)
Closed the second item on the previous tick's own Next list — "the same emphasis-form question applies to any other marker this repo parses by hand" — and it was not an emphasis bug this time, it was a fence bug, in the reader that grades the four-heading contract.
tools/checkin_check.py's headings_missing() scanned every line for
^#{1,6}\s+... with no fence state. A check-in that quotes the contract —
a fenced block containing ## Did, ## Blocked, ## Next, ## Ask — was
therefore graded as carrying all four headings while carrying none of them as
structure. tools/queue_index.py has skipped fences since it was written
(FENCE, and in_fence around its heading scan); the check-in reader never
did, so the same question had two different answers in one tools/ directory.
Measured, both directions, on one inline fixture (no fixture line numbers move):
$ python3 /root/.hermes/profiles/volt/cache/scratch/compare-headings.py
quoted-heading fixture
pre-fix headings_missing = [] (no fault: false green)
post-fix headings_missing = ['next', 'ask']
plain fixture untouched: True
The blast radius on the record is zero, and that is the point of the fix rather
than a caveat: over all 74 files in checkins/ at 331927f, the advisory
count is 60 before and 60 after, with 0 files changing grade
(probe-advisory.py). The defect was latent — no check-in in the archive quotes
headings today — so this is a sound for the form, not a re-reading of anybody's
history.
$ python3 tools/checkin_check.py --repo .
checkin_check: 73 files, 35 with a fault (BAD_NAME 25; DUPLICATE groups 10), 59 advisory
rc 0
Selftest 27 → 29 cells, both counted: c28 a heading inside a fenced block is not a heading (the quoted fixture yields ['next','ask']) and c29 an unclosed fence quotes to end of file, and says so (an unterminated fence swallows the
rest, matching queue_index.py's toggle). Advertised counts updated in both
places the sweep reads them (module docstring and --help text), so the sweep's
own COUNT_MISMATCH has nothing to fire on.
$ python3 tools/checkin_check.py --selftest
selftest: 29 cells, 29 passed, 0 failed # rc 0
Gate, run whole at the commit that follows:
$ python3 tools/verify.py
index-current PASS index: 49 sections, 45 ids, 4 continuation sections, 9 nested ids, 10046 lines / 1261342 bytes
append-audit PASS every graded commit left the index current in its own tree
selftest-sweep PASS sweep: 14 tools, 14 OK, 0 fatal
gate: OK -- 3 of 3 graded leg(s) passed # rc 0
Artifact with the pre/post harness: /root/.hermes/wizard-outputs/volt/2026-10-19-checkin-fence/
(verify_fix.py rebuilds both versions' behaviour from HEAD~1 and HEAD and
exits 0 only if pre-fix is a false green and post-fix names the two headings).
Blocked
tools/doc_census_check.py is running in the background on this host
(--repo . --json ...) against 331927f; it had not finished when this block
was written, so its totals are not reported here and not claimed. The
previous tick's 180 s foreground kill is not yet explained by measurement.
Next
- Collect the background census run and publish its totals against
331927f, or report the timeout as the finding. citation_resolve_check.py'sPAThas no fence state either; whether apath:lineinside a fenced block should be graded as a citation is a real question (a quoted tool output is not a claim). Not measured yet — do not assume the answer from this fix.
Ask
None. No queue item opened or closed.
Append (00:30Z) — the census finished, and it is green
The background run named under Blocked above completed at 00:30:23Z against
fd84b68 (clean tree, no concurrent edit; the first attempt was discarded
because it overlapped this tick's own edit of checkin_check.py and would have
graded a moving tree). Transcript and JSON:
/root/.hermes/profiles/volt/cache/scratch/census-fd84b68/.
$ python3 tools/doc_census_check.py --repo . --json census.json
tools scanned at HEAD: 14 (docstring vs printed census)
tools/append_only_audit.py: 0 INTERNAL SPLIT, 0 STALE claim(s), 0 leg failure(s), 1 claims checked
... (all 14 tools carry the same 0 / 0 / 0 line)
tools/verify.py: 0 INTERNAL SPLIT, 0 STALE claim(s), 0 leg failure(s), 6 claims checked
--- verdict totals (unit: claims) ---
AMBIGUOUS 11
MATCHES 26
NOT_PRINTED 54
REV_UNCHECKED 8
SELF_NOT_RUN 24
rc 0
14 tools, 0 split, 0 stale, 0 leg failures, ~6 minutes wall (started ~00:24:2xZ,
finished 00:30:23Z — the time line did not land in the transcript, so the wall
figure is from the process, not the tool). The 123 claims behind those totals break
down as 26 matched, 54 whose unit the run does not print (NOT_PRINTED, not a
defect), 11 AMBIGUOUS, 8 REV_UNCHECKED (claims pinned to an older revision),
and 24 SELF_NOT_RUN (doc_census_check.py's own docstring, which no leg can
grade because the tool does not run itself). This also answers the previous
tick's open question: the 180 s foreground kill was a timeout, not a hang — the
same work finishes in ~6 min when it is not killed.
Did (third tick, 04:5x–05:1xZ) — the fence rule reaches the citation scanner
Closed the question the previous tick left under Next: whether a path:line
inside a fenced block should be graded as a citation. It should not, and the
measurement is why the fix is small.
tools/citation_resolve_check.py had no fence state. tools/checkin_check.py
and tools/queue_index.py both skip fenced blocks on the rule that a quoted
heading is not structure; that rule had never been applied to a quoted citation,
so a fenced code listing carrying :line rows was graded as the containing
document's own.
Measured over the whole corpus at a2d9bc0 (345 markdown files) with an outside
probe that imports nothing from the tool
(/root/.hermes/wizard-outputs/volt/2026-10-19-fence-cites/probe_fence_cites.py):
citations 2273 of which fenced 6 (0.26%)
fenced by verdict: UNRESOLVED 5, AS_SELF 1, every other class 0
fenced mentions: 398 of 7890
The class is real and bounded. The five fenced UNRESOLVED rows are four in
recoveries/render-site-channels.md (a code listing whose inline comments cite
the listed file's lines) and one in docs/how-to-check-this-archive.md; none
is a claim the containing document makes about itself.
The fix is the mask queue_index.py and checkin_check.py already use,
computed per FILE rather than per paragraph because a fence can contain blank
lines and so straddle two of this scanner's blocks — absolute line numbers make
the join sound. A citation or mention on a masked line is counted and skipped,
and the count is printed on every run, so the exclusion can never be silent:
fenced skipped: 6 citations, 398 mentions (unit: rows) -- a fenced block is
quoted material, not this document's prose
The witness (verify_fix.py in the artifact directory) runs the PRE-fix
build (git show a2d9bc0:tools/citation_resolve_check.py) and the post-fix build
against the SAME corpus at the SAME revision, so the tool build is the only
variable:
PASS pre-fix build carries no fence state
PASS the fix removed nothing outside the fence -- 0 row(s) exist only after the fix
PASS every removed row is on a fenced line -- 6 removed, 6 fenced
PASS no surviving row changed verdict or multiplicity -- 0 row(s) moved
PASS the census delta is the fenced rows and nothing else -- bare classes
fell by 6 against 6 fenced; rises=[]; explicit classes unchanged=True
PASS post-fix selftest is 14/14
PASS the exclusion is printed, not silent
witness: agree -- the fix removes exactly the fenced rows, changes no
verdict, and says so on its own output # rc 0
Verdict counts, pre to post, same revision:
RESOLVES 151->151 STALE_LINE 0->0 EXTERNAL_PATH 318->318
AS_NAMED 143->143 AS_SELF 776->775 AMBIGUOUS 57->57
EXTERNAL_NAMED 258->258 UNRESOLVED 570->565
citations 2273->2267 mentions 7890->7492
Selftest 11 -> 14 fixtures: a fenced citation is not graded; the fence CLOSES (the same citation in prose is graded again — the positive control that this is a state and not a blanket refusal); an unterminated fence quotes to end of file, which is the rule's documented cost.
$ python3 tools/citation_resolve_check.py --selftest
self-test: 14 fixtures, 14 passed, 0 failed # rc 0
The tool's own docstring census still grades clean on the build that carries the change, and the archive gate too:
$ python3 tools/doc_census_check.py --tools tools/citation_resolve_check.py --fail
tools/citation_resolve_check.py: 0 INTERNAL SPLIT, 0 STALE claim(s), 0 leg
failure(s), 22 claims checked
OK: 0 INTERNAL SPLIT, 0 STALE claim(s) at HEAD # rc 0
$ python3 tools/verify.py
index-current PASS index: 49 sections, 45 ids, 4 continuation sections,
9 nested ids, 10067 lines / 1267509 bytes
append-audit PASS every graded commit left the index current in its own tree
selftest-sweep PASS sweep: 14 tools, 14 OK, 0 fatal
gate: OK -- 3 of 3 graded leg(s) passed # rc 0
Not changed, stated rather than implied: an INLINE-quoted citation is still counted. The scanner does not parse quotation marks and that limitation stands; a fence is a block state the archive already uses elsewhere, quotes are not.
Blocked
The full-corpus doc_census_check.py run started this tick was discarded: it
overlapped this edit, and a census over a moving tree is not a census — the same
reason the first attempt this morning was discarded. Every figure above is cited
at a2d9bc0, the revision it was measured at.
Next
- Re-run the full doc census against the commit that lands this change, so the tool set is measured at 14 fixtures and at the new printed line.
Ask
None. No queue item opened or closed.
Did (fourth tick, 09:37–09:50Z) — the gate gets a fourth leg: the check-in contract
tools/verify.py graded the index, the newest queue-touching commit and every
tool's selftest. It did not grade a check-in — the one artifact every lane writes
every tick — even though tools/checkin_check.py has existed since 2026-10-18 with
--fail, --since and 29 cells.
The hole, measured before the change. A clone of 3890c12 with one added file,
checkins/2026-10-19-volt-02.md:
$ python3 tools/checkin_check.py --repo . --since 2026-10-19 --fail
FAIL: 2 file(s) violate the check-in contract # rc 1
$ python3 tools/verify.py --repo . --fast
gate: OK -- 2 of 2 graded leg(s) passed # rc 0
A tree that breaks the contract, certified by the repo's own gate.
The leg. checkin_check.py --repo <repo> --fail --since <day>, where <day>
is max() over the <YYYY-MM-DD> prefixes in checkins/. The day is read from
the record, so there is no constant to rot and no clock to disagree with the
archive. First in the leg order because it is the cheapest by measurement —
124–153 ms, against 241–300 ms for index-current and 516–630 ms for
append-audit. --checkin-day DATE sets the --since floor in the open and can
only widen it.
One day, not the archive, and that is measured too. checkin_check --fail at
3890c12 → 73 files, 35 with a fault, rc 1 (BAD_NAME 25, DUPLICATE groups 10),
the fault rows dated 2026-09-24 through 2026-10-07. A gate wired to that number
can never go green, so it stops being read; the newest day is the only one on which
a new fault can appear.
A second defect, found by the first real run. The FAULT row read
SKIP README.md (the directory's own README: not a check-in) — pick_detail()'s
weak hint not a matched that note before the tool's FAIL: line. Hints are now
tiered STRONG > WEAK > per-file SKIP note; cells 18/18b pin both directions.
Measured after, same clone and same defect:
$ python3 tools/verify.py --repo . --fast
checkin FAULT rc=1 124ms FAIL: 2 file(s) violate the check-in contract
verify: 4 legs, 2 pass, 1 fault, 0 ungradable, 1 skipped
gate: FAULT -- 1 leg(s) ran and graded a fault: checkin # rc 1
Measured on this tree, full run: 4 legs, 4 pass, 0 fault, 0 ungradable, rc 0
("gate: OK -- 4 of 4 graded leg(s) passed"); checkin row
checkin_check: 1 files, 0 with a fault, 0 advisory. verify.py --selftest
26 → 35 cells, 35 passed, 0 failed. ruff check --select F,E9 tools/ All
checks passed. doc_census_check --tools tools/verify.py 6 claims, 0 STALE, 0
INTERNAL SPLIT, rc 0.
Git identity. Reply 33's ask is done: user.name Volt /
user.email volt@agents.invalid are set in the shell that ran these commits, so
the author line stops landing as the pipe.
Blocked
Nothing. The only thing I chose not to do is a ruff leg on the gate: ruff 0.16.4
is installed on this host and is not a repo dependency, so the leg would turn a
ruff-less host into rc 2 for the whole gate. That is a dependency decision, not a
wiring step, and the 07:34Z block already records it as an open question.
Next
- Read the full 14-tool census at this commit (running now, artifact
census-full-at-5ed9da9.txt): the new leg adds printed output toverify.py, so the claim totals andSELF_NOT_RUNset should be read at this revision, not at the previous one. - If Alexander wants the 35 historical rows graded rather than skipped, the switch
is
--checkin-day 2026-09-24on the gate — one flag, and the gate goes rc 1 until history is relabelled. That is his call, not this lane's.
Ask
None. No queue item opened or closed.
Did (fifth tick, 18:50–19:0xZ) — the gate runs inside a worktree: ask git, not isdir(.git)
Reply 36 ended with a real limitation found by hitting it: from
git worktree add --detach <path>, tools/verify.py returned rc 2 "cannot
read repo: … is not a git repository", because line 404 asked
os.path.isdir(<repo>/.git) and a linked worktree's .git is a 47-byte
file holding gitdir: /root/troupe-standup/.git/worktrees/ts. The rc-2
contract behaved correctly — could-not-grade, never a silent pass — but the
consequence was that a lane which sandboxed correctly could not run the operator
gate at all, and had to choose between grading unsandboxed in the shared clone
and reporting rc 2.
Measured before the change, on cf5101f, same tree, two blobs
(before/red-green.txt): the committed blob (git show HEAD:tools/verify.py)
— rc 2, one line of stderr. The fixed blob — rc 0, four legs PASS, one
SKIP, index current … 10171 lines / 1308413 bytes. Full (non---fast) gate in
that same worktree: 5 of 5 legs pass, selftest-sweep … 15 tools, 15 OK, 0 fatal, 36.0 s.
The fix is one function and no special case. resolve_repo() asks
git -C <repo> rev-parse --show-toplevel. It succeeds in every work tree — main,
linked, submodule — and fails in a bare repository or a directory that merely
holds a .git entry, which is the second half of the same defect: an empty
.git/ directory passed the old test on a path git itself refuses. --repo
is still the ROOT: a subdirectory is rc 2 naming the root it would have
graded, because widening it silently would grade a tree nobody named. The leg
table, the rcs and the five legs are untouched; --queue/--index stay
repo-relative for git show <rev>:<path>.
The selftest grew by eight cells, and the fixture got honest. _fixture()
used to create an empty .git/ — a repository only to the test being replaced —
and now runs git init, with commit=True when a cell needs a HEAD to branch a
worktree from. New cells: 23/23b/23c a linked worktree is graded and the row
names the worktree (RED on the old blob, GREEN here), 24/24b a subdirectory
is refused with the root named, 25/25b an empty .git directory is refused,
26 a bare repository is refused. --selftest 42 → 50 cells, 50/50, rc 0.
Refusals measured, each rc 2 (before/refusals.txt): subdirectory
(--repo takes the root), empty .git (fatal: not a git repository), bare
(fatal: this operation must be run in a work tree), missing path
(is not a directory).
Blocked
Nothing.
Next
- Re-run the gate at the commit this lands in, so the fix is graded by the revision that carries it rather than by the working tree (doing that now).
- No queue item opened, closed, or claimed; no another-party file edited.
Ask
None.
Postscript to the fifth tick — the count above said 50, and it is 51.
Committing f59a592 left the very defect this lane keeps finding in documents:
the docstring and the run said 50 cells while --selftest's argparse help
string still said 42, and nothing failed — caught by reading the blob back
off the forge (served-verify.py, sha256 4855de27…, which matched the
committed blob and still carried the stale line). 81d2c0a closes it two ways:
the help string no longer carries a number, and cell 27 parses the
docstring's fixture corpus, N cells claim and grades it against the count that
actually ran. Measured RED (before/cell27-red.txt): a copy differing only in
that claim prints selftest: 51 cells, 50 passed, 1 failed /
FAIL 27 … got: 50 want: 51, rc 1. Selftest 51/51 rc 0; gate at
81d2c0a 5 of 5 legs PASS, rc 0 in the main tree, and 5 of 5 rc 0 in a
fresh clone's linked worktree (all legs, selftest-sweep 15 tools / 15 OK /
0 fatal). Both commits are pushed to origin/main.