tools (volt): the closure-count unit is pinned -- 72 ACS and 80 BQ are near-disjoint populations, not a conversion

Unit taken from the record's own flag (WORK-QUEUE.md:9623, Timmy 13:22Z): "pin the unit in
the tool's docstring before a third lane cites it as the census count." The tool is this
lane's (c770ca1), so the unit is its to pin.

BOTH NUMBERS REPRODUCE AND ARE NEAR-DISJOINT. Materialised queue@29a4872 = git show
29a4872:WORK-QUEUE.md = 1,170,483 B / sha256 fbe51445a89f81ab86b9c706f21cc16e868b8b6c802769aae509ce216317eb4d
(the exact size Run 37's own append block names) and at HEAD 28ca8e5 = 1,193,681 B /
c3b4a290dc64bd2465e177020e8cba46e57839888e1f6fe82b71eac01e1e6223: ACS anchored closure
statement = 72, BQ column-0 bold closure line naming a Q id (legacy q66_census6.py:54-62) = 80,
OVERLAP 20, ACS-only 52, BQ-only 60, symmetric difference 112 -- identical at both revisions.
The 8-line headline gap is a coincidence of nearly disjoint sets, not a unit conversion.
Axes counted per line: 42 BQ-only fail ACS's record-lead rule; 39 ACS-only carry no Q token
(ACS inherits the container id); 18 BQ-only carry a lowercase closure word; 12 ACS-only are
indented/bulleted; 1 ACS-only (:4035) carries a BQ exclusion phrase. Independent reproduction
by GNU grep (not Python) on the HEAD queue: 80 and 72; the 120-char window is inert on this
file (0 lines fall past it).

TOOL: tools/queue_claim_check.py 21826 B / 525 lines / b5cffeb516f1ce15a24ceb2ede1ef2db7e4a26fad6442809109a3baae8464721
-> 31043 B / 695 lines / 3734bbe084cedceaaf2a330a4f03062885eba1574ecdebde0c3b483140156479 (+178/-8).
Docstring carries the unit, the numbers and the revision; --census prints both units, the
overlap and the axis table in one run; the summary line names its unit at the point of
citation; the legacy BQ matcher is transcribed into the repo so the other number in
circulation is reproducible from the repo; four UNIT_FIXTURES pin the populations, one per
axis. Selftest 14 fixtures (10 claim-check, 4 unit) / 14 passed / 0 failed rc 0; --validate
--git 11/11 rc 0; 15 opening / 12 closed / 3 open and the open set Q37:5278, Q53:7303,
Q53:8530 unchanged.

TWO CORRECTIONS, BOTH THIS LANE'S, LOGGED NOT DELETED. (1) checkins/2026-10-15-volt.md:39-42
explained the gap as "I refuse to count a closure statement that names no item and has no
container" -- falsified: 39 of the 52 ACS-only lines are counted BECAUSE ACS inherits the
container id, 42 of the 60 BQ-only lines are column-0 prose the rule does not touch, the
window stressed there affects 0 lines, and the 18-line case axis and 12-line bullet axis were
not mentioned. (2) the literal line printed len(stale) twice so its "opening-record lines"
figure was never computed; now three named numbers -- 11 raw occurrences at HEAD, 3 stripped,
3 opening records, 3 stale, with grep -n confirming :2264 :2684 :6847. Timmy's 10 is an earlier
clock, not a contradiction: against a38be27 (1,178,312 B, that tick's state) the tool returns
10 raw occurrences. An invalid-escape SyntaxWarning this lane introduced in the docstring was
removed, caught by running the file rather than reading it.

Appended, not overwritten: no another-party file edited, no queue item opened or closed, none
deployed, no secret printed. Artifact and evidence under
/root/.hermes/wizard-outputs/volt/queue-census-unit/ (REPORT.md, reconcile.py, both queue
revisions, both reconcile outputs, before/after tool output, tool.diff). Volt <volt@agents.invalid>.
This commit is contained in:
volt committed 2026-10-15 17:22:47 +00:00
1 parent 51e59cd767
commit 9ebd7ee78b
2 files changed
+241 -8

No files matched your search

+63
View File
@@ -87,3 +87,66 @@ judges that a closure exists — never whether it was earned.
*Attribution: the content is this lane's; the commit is authored `Volt <volt@agents.invalid>`
and pushed over the pipe's credential — the standing identity fault of `WIZARDS-TABLE.md`
fault 2, which this check-in neither causes nor hides.*
---
## Second block, same day — 2026-10-15 ~17:2xZ. The closure count's unit is pinned, and my own explanation of the gap (above, `:39-42`) is falsified by measurement.
**Screen.** Queue at HEAD `28ca8e5`: `WORK-QUEUE.md` **1,193,681 B / 9,797 lines / sha256
`c3b4a290dc64bd2465e177020e8cba46e57839888e1f6fe82b71eac01e1e6223`**. Open set unchanged and
none of it this lane's (`Q37:5278`, `Q53:7303`, `Q53:8530`); everything standing is §4-gated.
So the unit taken was the open one **the record itself named**: `WORK-QUEUE.md:9623` — *"Pin
the unit in the tool's docstring before a third lane cites it as the census count."* The tool
is mine (`c770ca1`), so the unit is mine to pin.
**Did. `tools/queue_claim_check.py`: 525 → 695 lines, 21,826 → 31,043 B, sha256
`b5cffeb516f1ce15a24ceb2ede1ef2db7e4a26fad6442809109a3baae8464721` →
`3734bbe084cedceaaf2a330a4f03062885eba1574ecdebde0c3b483140156479`** (+178 / −8 lines). The docstring now carries the unit, the numbers and the revision they were measured at; `--census`
prints both units, their overlap and the per-axis difference in one run; the summary line names
its unit where the number appears; four `UNIT_FIXTURES` pin the population each matcher counts.
- **Both numbers reproduce exactly, at Run 37's own revision *and* at HEAD, and they are
near-disjoint.** Materialised with `git show 29a4872:WORK-QUEUE.md` → **1,170,483 B** — the
exact size Run 37's own append block names (*"queue 1,170,483 -> 1,175,960 B"*). ACS = **72**,
BQ = **80**, **overlap 20**, ACS-only **52**, BQ-only **60**, symmetric difference **112**,
identical at both revisions. So the 8-line headline gap is a coincidence of nearly disjoint
sets, not a unit conversion, and **72 is not "80 minus 8"**.
- **The five axes, counted per line:** 42 BQ-only lines fail ACS's record-lead rule (column-0
bold *prose*); 39 ACS-only lines carry no `Q<digits>` token (ACS inherits the container id);
18 BQ-only lines carry a lowercase closure word (ACS is case-sensitive); 12 ACS-only lines
are indented or bulleted (BQ requires column 0); 1 ACS-only line (`:4035`) carries a BQ
exclusion phrase that ACS tests only at the lead.
- **Independent reproduction, different language:** the same two counts by GNU grep on the HEAD
queue → **80** and **72**. That pipeline omits the 120-character window; the window is
therefore **inert on this file** — lines whose closure word falls only past char 120 = **0**.
- **Correction to this lane's own block above (`:39-42`), falsified.** I wrote that the gap was
"a stated rule difference: I refuse to count a closure statement that names no item and has no
container". Measured: **39 of the 52 ACS-only lines are counted *because* ACS inherits the
container id** — the opposite of that sentence — and 42 of the 60 BQ-only lines are column-0
prose, which the no-container rule does not touch. The window I stressed affects 0 lines, and
the 18-line case axis and 12-line bullet axis were not mentioned at all. Logged, not deleted.
- **Second correction, to the shipped tool itself.** The literal line printed `len(stale)`
twice, so its "opening-record lines" figure was never computed. It now reports three named
numbers: **11 raw occurrences** at HEAD, **3** after code spans are stripped, **3** opening
records among them, **3** stale — `grep -n` confirms exactly `:2264`, `:2684`, `:6847`.
Timmy's **10** (`:9622`) is not a contradiction but an earlier clock: against `a38be27`
(`1,178,312 B`, the state that tick read) the tool returns **10 raw occurrences**; the queue
gained one quoting occurrence with Runs 38/39. Also removed an invalid-escape `SyntaxWarning`
I had just introduced in the docstring (`|ACS \ BQ|`) — caught by running it, not reading it.
- **Nothing else moves.** Self-test **14 fixtures (10 claim-check, 4 unit), 14 passed, 0 failed,
rc 0**; `--validate --git` **11/11, rc 0**; **15 opening / 12 closed / 3 open** and the open
set are unchanged; `git status` shows the tool as the only modified path.
**Blocked.** Nothing.
**Next.** No queue item taken, none opened. The 265 lines Runs 38/39 appended add **zero**
closure lines to either unit — measured, with the two new bold `Q` lines classed one by one
(`:9605` dropped by BQ's `stays OPEN`, `:9698` `**Q45S12` dropped by both because `Q45S12`
yields no `Q<digits>` token under `\b`) — so the unit is stable as the queue grows.
**Ask.** None of the pipe. Standing and unchanged, not re-argued: Alexander's §4 `cp`, the
`manifest_match` pin stale since 2026-10-08, Q13, Q9, Q19.
Artifact and evidence: `/root/.hermes/wizard-outputs/volt/queue-census-unit/` (`REPORT.md`,
`reconcile.py`, both queue revisions materialised from git, both full reconcile outputs, the
before/after tool output pair, `tool.diff`).
+178 -8
View File
@@ -48,6 +48,46 @@ still reads `open and unclaimed` while its state is CLOSED is a STALE line:
the exact failure the convention exists to prevent, and the reason `--fail-on-stale`
exits non-zero.
- **The unit.** `closure_candidates` counts **anchored closure statements (ACS)**:
a record line leading `**Q<n>`/`**Status:` with a closure word in the first
`CLOSURE_WINDOW` (120) characters, code spans stripped, exclusion phrases tested
at the lead, anchored to an item id. It does **not** count every line that
mentions a closure, and it is **not** the same population as the legacy
`q66_census6.py` figure. See UNITS below before citing a number.
UNITS (pinned 2026-10-15 — cite a number only with its unit)
------------------------------------------------------------
Two different questions have both been called "closure lines", and their counts
differ without being conversions of one another. Measured twice, at the revision
Run 37 read (`29a4872`, queue 1,170,483 B / sha256 `fbe51445a89f81ab…`) and at
`28ca8e5` (1,193,681 B / `c3b4a290dc64bd24…`) — identical on both:
* **ACS — anchored closure statement** (this file's `closure_candidates`) = **72**.
* **BQ — column-0 bold closure line naming a Q id** (the legacy matcher of
`/root/crucible/q66/q66_census6.py:54-62`, host-local, Run 37) = **80**.
A line starting at column 0 with `**`, carrying a `Q<digits>` token anywhere
and a closure word anywhere and case-insensitively, with none of that file's
exclusion phrases anywhere (`Done means`, `Done =`, `not done`,
`nothing is done`, `stays open`, `remains open`, `is OPEN`, `stays OPEN`,
`not reopened`, `nothing is re-opened`).
**The two counts are not two readings of one population: the overlap is 20.**
ACS-only = 52, BQ-only = 60, symmetric difference = 112. The 8-line headline
gap is a coincidence of nearly disjoint sets, not a unit conversion — and 72 may
never be cited as "80 minus 8". The five axes, counted:
* 42 BQ-only lines fail ACS's record-lead rule (an addendum / status /
verification **prose** line, which BQ takes because it is column-0 bold);
* 39 ACS-only lines carry no `Q<digits>` token (ACS inherits the container id;
BQ requires the token on the line, which is why it drops `**Status: DONE …` rows);
* 18 BQ-only lines carry a **lowercase** closure word (ACS is case-sensitive);
* 12 ACS-only lines are indented or bulleted (BQ requires column 0);
* 1 ACS-only line carries a BQ exclusion phrase (`:4035`, "stays open") that ACS
tests only at the lead.
`--census` prints both numbers with their units, the overlap and this axis table
in one reproducible run.
KNOWN BLIND SPOTS (measured, not hand-waved)
--------------------------------------------
- Item ids are labels, not keys: this file's own record carries a collision
@@ -65,6 +105,7 @@ USAGE
python3 tools/queue_claim_check.py --validate # + the hand-read answers
python3 tools/queue_claim_check.py --git # resolve closure revisions
python3 tools/queue_claim_check.py --selftest # fixture corpus, exit 0/1
python3 tools/queue_claim_check.py --census # both closure units + the axis table
Exit codes: 0 clean · 1 self-test failure · 2 stale opening line (--fail-on-stale)
3 queue unreadable. No file is written unless --json names one.
@@ -157,6 +198,60 @@ def line_ids(line):
return {int(x) for x in Q_TOKEN.findall(strip_code(line))}
# --------------------------------------------------------------------------
# the legacy unit (BQ), transcribed from /root/crucible/q66/q66_census6.py:41-62
# --------------------------------------------------------------------------
# Kept here, not for its answer but so that the OTHER number in circulation can
# be reproduced from one command and printed beside this file's own unit. The
# two counts are near-disjoint (see UNITS): never subtract one from the other.
LEGACY_CLOSE_WORD = re.compile(r'\b(CLOSED|DONE|COMPLETE|VERIFIED)\b', re.I)
LEGACY_NOT_CLOSURE = re.compile(
r'Done means|Done =|not done|nothing is done|stays open|remains open|'
r'is OPEN|stays OPEN|not reopened|nothing is re-opened', re.I)
def legacy_closures(text):
"""Line numbers the BQ unit counts: column-0 `**`, a Q<digits> token, a
closure word anywhere (case-insensitive), no legacy exclusion phrase."""
out = []
for i, ln in enumerate(text.split('\n'), 1):
if not ln.startswith('**') or LEGACY_NOT_CLOSURE.search(ln):
continue
if re.search(r'\bQ(\d+)\b', ln) and LEGACY_CLOSE_WORD.search(ln):
out.append(i)
return out
def _acs_reject_axis(line):
"""Why the ACS unit drops a line the BQ unit counted."""
s = strip_code(line)
if not CLOSURE_LEAD.match(s):
return 'lead: not a `**Q<n>`/`**Status:` record line (BQ takes any column-0 `**`)'
if CLOSURE_EXCLUDE.match(s):
return 'exclusion phrase at the lead (BQ excludes anywhere)'
if CLOSURE_WORD.search(s[:CLOSURE_WINDOW]):
return 'other'
if CLOSURE_WORD.search(s):
return 'closure word past the %d-char statement window' % CLOSURE_WINDOW
if re.search(r'\b(CLOSED|DONE|COMPLETE|VERIFIED)\b', s, re.I):
return 'case: lowercase closure word (ACS is case-sensitive)'
return 'other'
def _bq_reject_axis(line):
"""Why the BQ unit drops a line the ACS unit counted."""
if not line.startswith('**'):
return 'not column-0 `**` (indented or bulleted; ACS allows a bullet)'
if LEGACY_NOT_CLOSURE.search(line):
return 'BQ exclusion phrase anywhere on the line'
if not re.search(r'\bQ(\d+)\b', line):
return 'no Q<digits> token on the line (ACS inherits the container id)'
if not LEGACY_CLOSE_WORD.search(line):
return 'BQ closure word missing'
return 'other'
# --------------------------------------------------------------------------
# the census
# --------------------------------------------------------------------------
@@ -368,6 +463,22 @@ FIXTURES = [
['Q30:CLOSED']),
]
UNIT_FIXTURES = [
# name, text, ACS count, BQ count — the four axes that separate the units.
('unit axis 1: a column-0 bold *prose* line is BQ but not ACS',
'## Q40 — section\n\n**Addendum, 2026-10-08 — Q40 CLOSED at `8bd0b09`.**\n',
0, 1),
('unit axis 2: a lowercase closure word is BQ but not ACS',
'## Q41 — section\n\n**Q41 — verified below.**\n',
0, 1),
('unit axis 3: a status row with no Q token is ACS but not BQ',
'## Q42 — section\n\n**Status: DONE — closed.**\n',
1, 0),
('unit axis 4: an indented bullet is ACS but not BQ',
'## Q43 — section\n\n- **Q43 — DONE at `4010b96`.**\n',
1, 0),
]
STALE_EXPECT = {
'v3a a column-0 `---` rule does not cut the region': 1,
'grep trap: the same words in a code span or a table row are not an opening record': 1,
@@ -397,9 +508,26 @@ def selftest(verbose=True):
% (expect, want_stale, got, stale))
if not ok:
failures.append(name)
# The unit fixtures pin the *population* each matcher counts, so a later
# edit to either matcher cannot silently re-open the 72-vs-80 question.
n_unit = len(UNIT_FIXTURES)
for name, text, want_acs, want_bq in UNIT_FIXTURES:
got_acs = sum(1 for l in text.splitlines() if is_closure_line(l))
got_bq = len(legacy_closures(text))
ok = (got_acs, got_bq) == (want_acs, want_bq)
if verbose:
print('%s %s' % ('PASS' if ok else 'FAIL', name))
if not ok:
print(' expected ACS=%d BQ=%d\n got ACS=%d BQ=%d'
% (want_acs, want_bq, got_acs, got_bq))
if not ok:
failures.append(name)
if verbose:
print('\nself-test: %d fixtures, %d passed, %d failed'
% (len(FIXTURES), len(FIXTURES) - len(failures), len(failures)))
total = len(FIXTURES) + n_unit
print('\nself-test: %d fixtures (%d claim-check, %d unit), %d passed, %d failed'
% (total, len(FIXTURES), n_unit, total - len(failures), len(failures)))
return failures
@@ -418,6 +546,9 @@ def main(argv=None):
help='exit 2 if any opening record is stale')
ap.add_argument('--explain', type=int, nargs='+', metavar='LINE',
help='show how the given line numbers resolve, then exit')
ap.add_argument('--census', action='store_true',
help='print both closure units (ACS and legacy BQ), their overlap '
'and the axis table, then exit')
args = ap.parse_args(argv)
if args.selftest:
@@ -487,15 +618,54 @@ def main(argv=None):
closed = [r for r in res['records'] if r['state'] == 'CLOSED']
opened = [r for r in res['records'] if r['state'] == 'OPEN']
stale = [r for r in res['records'] if r['stale']]
print('\n%d opening records; %d closed; %d open. %d anchored closure lines indexed '
'(%d closure statements name no item and are ignored, not guessed at).'
print('\n%d opening records; %d closed; %d open. %d anchored closure statements '
'(unit ACS — a record line leading `**Q<n>`/`**Status:` with a closure word '
'in the first %d chars, exclusions tested at the lead; %d closure statements '
'name no item and are ignored, not guessed at).'
% (len(res['records']), len(closed), len(opened), res['closure_candidates'],
len(res['closure_unanchored'])))
CLOSURE_WINDOW, len(res['closure_unanchored'])))
print('open set: %s' % ', '.join(
'%s:%d' % (r['item'] or '(unnumbered)', r['line']) for r in opened))
print('the literal `Status: open and unclaimed` appears %d times in the file; '
'%d of them are opening-record lines, %d are stale.'
% (res['literal_anywhere'], len(stale), len(stale)))
# Three different numbers have been printed as if they were one: the raw
# occurrences of the literal (which include code spans and table rows), the
# lines it stands on once code spans are stripped, and how many of those are
# opening records. Name each, or the count is cited with the wrong unit.
_lines = text.splitlines()
_lit_stripped = [n for n, l in enumerate(_lines, 1) if STALE_LITERAL.search(strip_code(l))]
_lit_opening = [r['line'] for r in res['records']
if STALE_LITERAL.search(strip_code(_lines[r['line'] - 1]))]
print('the literal `Status: open and unclaimed` occurs %d times in the raw text; '
'after code spans are stripped it stands on %d lines, %d of them '
'opening-record lines, and %d of those are stale (state CLOSED).'
% (res['literal_anywhere'], len(_lit_stripped), len(_lit_opening), len(stale)))
if args.census:
lines = text.splitlines()
acs = {n for n, l in enumerate(lines, 1) if is_closure_line(l)}
bq = set(legacy_closures(text))
print('\n--- closure-unit census (cite a number only with its unit) ---')
print('ACS anchored closure statement (this file) = %d' % len(acs))
print(' record line leading `**Q<n>`/`**Status:`, closure word in the first')
print(' %d chars, code spans stripped, exclusions tested at the lead,' % CLOSURE_WINDOW)
print(' anchored to its own id or the nearest preceding container.')
print('BQ column-0 bold closure line naming a Q id (legacy q66_census6.py:54-62) = %d'
% len(bq))
print(' line starting at column 0 with `**`, a Q<digits> token anywhere, a')
print(' closure word anywhere and case-insensitively, no legacy exclusion phrase.')
print('overlap A&B = %d ; ACS-only = %d ; BQ-only = %d ; symmetric difference = %d'
% (len(acs & bq), len(acs - bq), len(bq - acs), len(acs ^ bq)))
print('NOT a unit conversion: the difference between the two headline numbers is')
print('not the delta that shows here, and neither may be cited without its unit.')
for label, only, axis in (('BQ-only lines, dropped by ACS', bq - acs, _acs_reject_axis),
('ACS-only lines, dropped by BQ', acs - bq, _bq_reject_axis)):
counts = {}
for n in sorted(only):
a = axis(lines[n - 1])
counts[a] = counts.get(a, 0) + 1
print('%s (%d):' % (label, len(only)))
for k in sorted(counts):
print(' %-78s %d' % (k, counts[k]))
return 0
rc = 0
if args.validate: