fix(census): address each control by ONE citation, not by a file pair - #9245
fix(census): address each control by ONE citation, not by a file pair#9245claude[bot] wants to merge 2 commits into
Conversation
`census:cross-file-line-citations` exited 1 on every run of `main` -- `1 control(s) failed -- this run is NOT a reading` -- and had for some 580 commits, so no tree-wide row count on this script could be re-derived by anyone. The controls were addressed by FILE PAIR, and `evaluateControls` folded every row matching that pair into one answer: `every` row not-false for a non-firing control, `some` row false for a firing one. Two epitaphs in `packages/types/src/crud.ts` address `packages/plugin-detail/src/index.tsx` with one number between them. That number rotted, so one sentence took the whole census down with it. Both directions of the fold were wrong. A non-firing control was sunk by any second citation between the same two files; a firing control could be satisfied by a row that is NOT its subject, reporting the instrument as proven while the case it was written for had silently stopped firing. A control now carries a SUBJECT phrase out of its citing prose and must name exactly ONE citation -- zero matches or more than one is a failure rather than something to fold away. Still addressed by content: no control names a line number of its own. The non-firing control also now requires `resolves` rather than merely not-false, because `anchor-absent` is the census declining to judge and a control must not pass on a verdict nobody reached. The rotted `crud.ts` address is NOT renumbered and NOT repaired here. objectui#8875 clause 4 repairs an address "by converting it to a content anchor, never by moving the number to a different number", and a converted citation leaves no row for a control to score -- so the control moved to another citation and the rot stays in the population, where this census now reports it instead of refusing to run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
… guard The certification line added in the previous commit printed directly under the control check and ABOVE the empty-population guard, so a blind run announced `✓ ... this run IS a reading.`, then printed `✗ Empty population ...` and exited 1. A reader -- or a grep keying on that string -- took a certificate off a run that had refused. That is the unearned green this census exists to prevent, arriving through the door marked "say the good news out loud", in the one script whose whole subject is that an instrument must not report a reading it did not take. The empty- population guard exists precisely because a blind scanner is indistinguishable from a clean tree; the misplaced line made that failure mode print a certificate. The ordering is now one exported pure function, `finalVerdict`, so the ORDER is a fact a test can hold rather than a line position a later edit can move back. Every refusal is consulted first, and a refusing verdict carries NO certification string at all rather than a suppressed one -- there is nothing left for a later edit to print by accident. Pinned two-sided: an empty population must refuse and carry no `IS a reading` anywhere in the verdict, and a healthy population in the same suite must carry it, so the absence is a barrier rather than a dead assertion. A third leg covers the failed-control branch. ⛔ The empty-population guard itself is untouched, and `--json` is unaffected: the certification stays behind the same `!asJson` guard and refusals still go to stderr in both modes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
✅ ACCEPT after the send-back — the defect is closed, and closed better than I asked. Probe below, posted BEFORE the merge.
§0 — the send-back, and why the answer is better than the requestI asked for the certification line to be moved below the empty-population guard. What shipped instead: if (failed.length > 0) return { exit: 1, certification: null, refusal: [ '✗ … NOT a reading.' ] };
if (populationSize === 0) return { exit: 1, certification: null, refusal: [ '✗ Empty population. …' ] };
return { exit: 0, refusal: null, certification: '✓ … IS a reading.' };⭐ A move fixes the ordering; this removes the string. There is nothing left for a later edit to print by accident, which is the stronger property and the one that survives the next person. The extraction was DECLARED, with an offer to collapse it — and I am accepting it, on the round's own argument. 「controls pass AND population empty」 is unreachable from the real tree (population 1274) and unreachable from a synthetic repo, because the controls fail first — so a subprocess-level test would have passed even with the defect present, for the wrong reason. ⇒ the seam is what lets the negative leg bite. That is the a control must be able to fire discipline applied to the pin itself, ⛔ not scope creep. The pin is genuinely two-sided, and leg 2 is the load-bearing half:
Ablation restored the defect and exactly 1 of 3 legs failed with the control leg still green — the shape a real pin has.
§1 — what I verified myself about the ORIGINAL repair (unchanged by the send-back)⭐ The control got STRICTLY STRONGER in both directions — the fence held. Counted on the base, code lines only:
⭐ Route 2's premise was falsified by measurement, and that is the round's best work. The two rows are not unrelated — distinct cited line numbers across that pair = exactly one ( ⛔ Clause 4 respected: ⛔ Not weakened anywhere: The probe — ⛔ posted BEFORE the merge, run scoped to
|
Fixes #9081
Measured on tip
91facaef6f06a3e80c7dc31668b7cc6572951ae8; branch head8d1a15c76a.The defect, reproduced before any edit
6 controls ran, 5 PASS / 1 FAIL, the firing control among the passing set. The
refusal was a correct instrument and nothing here loosens it.
Route taken: 2 (narrow the control to ONE citation), and why not 1
The card offered two routes. Measuring them first changed which one is available:
Route 2's stated premise does not hold for this instance. It assumes "a
second, unrelated citation into the same file". The two rows are not
unrelated — they carry the same address,
plugin-detail/src/index.tsx:387,from two epitaphs. Distinct cited line numbers in that pair: exactly one,
387.So narrowing alone repairs nothing: it selects either the
driftedrow (stillFAIL) or the
anchor-absentrow — andanchor-absentis the census decliningto judge, so
want: not-falsewould have passed on a citation whose address isdemonstrably rotted. That is the unearned green this family exists to prevent.
Route 1 does not avoid a re-pin either. objectui#8875 clause 4 repairs an
address "by converting it to a content anchor, never by moving the number to a
different number". A content anchor leaves no row for a control to score, so
the control has to move to another citation regardless. Route 1 therefore costs
everything route 2 costs plus an edit to a published package's prose, and it
takes a repair decision the census itself prints as reserved to objectui#8875.
⇒ the instrument is repaired; the rotted
crud.tsaddress is not renumberedand not repaired here. It stays in the population, where the census now
reports it as one of the false rows instead of refusing to run at all —
strictly more information than
maingives today.What changed
A control is no longer addressed by FILE PAIR. It carries a subject phrase
out of its citing prose and must name exactly one citation; zero matches, or
more than one, is a failure rather than something to fold away. Still addressed
by content — no control names a line number of its own, and the existing test
that pins that now covers the subject too.
Both directions of the old fold were wrong, and the quieter one was the firing
control's:
someover the pair meant a rotted neighbour could report theinstrument as proven while the case the control was written for had silently
stopped firing.
wantmoves fromnot-falsetoresolves.anchor-absent/no-anchorare the census refusingto judge, and a control must not pass on a verdict nobody reached. This is
strictly narrower acceptance —
resolves⊂not-false.The census's own verdict after the fix
Exit code captured by redirect before any pipe:
The population is byte-identical to the refused run — 1274 citations, 558 false,
263 resolving, 453 unjudged — so this changed the controls, not the reading.
A success line is now printed. Certification by silence cannot be told apart
from a script that died before printing.
Proof the firing control still fires, and that the new control can fire
firingstill scores[non-substantive]— a FALSE verdict — in the passing runabove, so it is firing, not merely present.
The re-pinned non-firing control, ablated on the tree (mutation proven on disk
by occurrence counts in both directions and a changed blob hash, restore proven
by state —
git diff HEADempty and blob equal toHEAD's):And the repair is pinned by tests that fail when it reverts. Reverting
evaluateControlsto the pre-#9081 file-pair fold:Per-entry
CONTROLSexposure — the card listed this as unmeasuredPopulation: 2
CONTROLSentries (the 4 further controls in each run areCLASSIFIER_CASES, which take no tree rows and cannot carry this shape).91facaef6ffiringfalsesome-over-the-pair meant a future sibling could satisfy it vacuously: an unearned green with no symptom, rather than an honest refusal.non-firingnot-falseTree-wide, the shape is the norm rather than an anomaly: 233 of 696 distinct
file -> citedPathpairs (33.5%) carry more than one citation, 102 of thosewith mixed verdicts. A file pair was never a citation identity.
The fix covers both entries — the subject requirement is per entry, not a
patch on the failing one.
objectui#9216 — same root? No. Measured, not argued
The guard it reports, quoted inline from
carryScope:lastAddressis read by exactly one caller,scopeFor, which is reached onlyfrom the
continuationsyntax branch. Both rows of the failing control havesyntax: "colon"with a full written path on the line — neither is acontinuation address — so that guard cannot produce, alter, or remove either.
Measured as well as argued. With a
*-extended blank test spliced in as athrowaway probe (restore proven by state, blob equal to
HEAD):⇒ not one defect. They are not merged here and only objectui#9081 is fixed.
not acted on here: on this tip a
*-extended guard removes zero rowstree-wide. objectui#9216 explicitly holds that whether the guard should extend
is an unmade judgement, so this is left for it.
Tests
pnpm exec vitest run scripts/— 148 passed | 2 skipped (150 files), 4418 passednode scripts/check-new-cross-file-line-citations.mjs --base origin/main→0 new citation(s) ... exit 0node scripts/check-changeset-presence.mjs→ exit 0, "no changeset is owed"; anempty-frontmatter changeset is added anyway as an explicit no-release declaration
node scripts/check-lint-coverage.mjs→ exit 0node scripts/check-governed-queue-guard.mjs --test <the 3 changed paths>→NOT GOVERNEDdecided it, count from
--format json); the 2 files this diff changes lint0 errors / 0 warnings.
eslint.config.jsis untouched and type-awarelinting is not enabled, so no verdict on the other 4862 files can move.
⛔ No gate weakened: no threshold lowered, no ratchet raised, no test skipped, no
exception list added, and
evaluateControlsis not tolerant of a false row —it is strictly less tolerant than before.
Review follow-up — the certification line was itself an unearned green (fixed in
2944842db6)Caught in review of the first commit, and the direction matters: the new
✓ ... IS a reading.line printed under the control check and above theempty-population guard, so a blind run announced a reading and then printed
✗ Empty population ...and exited 1. A reader — or a grep keying on thatstring — took a certificate off a run that had refused. That is the unearned
green this census exists to prevent, arriving through the door marked "say the
good news out loud", in the one script whose whole subject is that an instrument
must not report a reading it did not take.
Certification is now last: every refusal is consulted first, and the
ordering is one exported pure function,
finalVerdict, so the ORDER is a fact atest holds rather than a line position a later edit can move back. A refusing
verdict carries no certification string at all rather than a suppressed one,
so there is nothing left for a later edit to print by accident.
⛔ The empty-population guard itself is untouched. ⛔ The control subjects, the
wanttightening and the re-pin are untouched.--jsonis unaffected — confirmed, not inferred. The certification staysbehind the same
!asJsonguard and refusals still go to stderr in both modes:Healthy tree, certification printed last and stderr empty:
Pinned two-sided, so the absence is a barrier rather than a dead assertion:
exitis 1,certificationisnull, andJSON.stringify(verdict)contains noIS a readinganywhere;refusalcontainsEmpty populationexitis 0,refusalisnull,certificationcontainsIS a readingexitis 1,certificationisnull, noIS a reading;refusalcontainsNOT a readingAblation — the defect restored on disk (
if (populationSize === 0)neutralised;marker counts 1→0 and 0→1, blob
5953e579→a963862a, restore proven by statewith
git diff HEADempty and the blob back to5953e579...):Re-run on
2944842db6:pnpm exec vitest run scripts/→ 148 passed | 2skipped (150 files), 4421 passed | 2 skipped;
check-new-cross-file-line-citations --base origin/main→0 new citation(s) ... exit 0;check-changeset-presence,check-lint-coverage→ exit 0;check-governed-queue-guard --test→NOT GOVERNED;the 2 changed files lint 0 errors / 0 warnings.
🤖 Generated with Claude Code
https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
Generated by Claude Code