Skip to content

fix(census): address each control by ONE citation, not by a file pair - #9245

Draft
claude[bot] wants to merge 2 commits into
mainfrom
claude/issue-9081-census-control-rotted-citation
Draft

fix(census): address each control by ONE citation, not by a file pair#9245
claude[bot] wants to merge 2 commits into
mainfrom
claude/issue-9081-census-control-rotted-citation

Conversation

@claude

@claude claude Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #9081

Measured on tip 91facaef6f06a3e80c7dc31668b7cc6572951ae8; branch head 8d1a15c76a.

The defect, reproduced before any edit

$ node scripts/cross-file-line-citation-census.mjs   -> exit 1
✗ 1 control(s) failed -- this run is NOT a reading.

FAIL  non-firing (want not-false): packages/types/src/crud.ts -> packages/plugin-detail/src/index.tsx
      packages/types/src/crud.ts:53 -> packages/plugin-detail/src/index.tsx:387 [anchor-absent];
      packages/types/src/crud.ts:348 -> packages/plugin-detail/src/index.tsx:387 [drifted]

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 drifted row (still
FAIL) or the anchor-absent row — and anchor-absent is the census declining
to judge
, so want: not-false would have passed on a citation whose address is
demonstrably 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.ts address is not renumbered
and 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 main gives 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: some over the pair meant a rotted neighbour could report the
instrument as proven while the case the control was written for had silently
stopped firing.

⚠️ Declared widening, not silent: the non-firing control's want moves from
not-false to resolves. anchor-absent / no-anchor are the census refusing
to judge, and a control must not pass on a verdict nobody reached. This is
strictly narrower acceptance — resolvesnot-false.

The census's own verdict after the fix

Exit code captured by redirect before any pipe:

$ node scripts/cross-file-line-citation-census.mjs > out 2>&1; echo $?
0
$ tail -1 out
✓ 6 of 6 control(s) passed -- this run IS a reading.

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

firing still scores [non-substantive] — a FALSE verdict — in the passing run
above, 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 HEAD empty and blob equal to HEAD's):

PREDICTION: rotting the cited address makes the row [drifted] -> FAIL -> exit 1
-- BEFORE mutation: occurrences OLD=1  NEW=0
-- AFTER  mutation: occurrences OLD=0  NEW=1
-- CENSUS EXIT UNDER ROT = 1
FAIL  non-firing (want resolves): ...:58 -> packages/components/src/renderers/layout/page.tsx:479 [drifted]
PASS  firing (want false): ...                      <- still firing in the same run
✗ 1 of 6 control(s) failed -- this run is NOT a reading.

And the repair is pinned by tests that fail when it reverts. Reverting
evaluateControls to the pre-#9081 file-pair fold:

-- BEFORE: repaired-marker=1  reverted-marker=0
-- AFTER : repaired-marker=0  reverted-marker=1
Tests  5 failed | 38 passed (43)

Per-entry CONTROLS exposure — the card listed this as unmeasured

Population: 2 CONTROLS entries (the 4 further controls in each run are
CLASSIFIER_CASES, which take no tree rows and cannot carry this shape).

entry want rows matching its FILE PAIR on 91facaef6f exposed?
firing false 1 Yes, latently — and in the more dangerous direction. One row today, but some-over-the-pair meant a future sibling could satisfy it vacuously: an unearned green with no symptom, rather than an honest refusal.
non-firing not-false 2 Yes, actively — this is the outage.

Tree-wide, the shape is the norm rather than an anomaly: 233 of 696 distinct
file -> citedPath pairs (33.5%) carry more than one citation, 102 of those
with 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:

if (line.trim() === '') { lastAddress = null; return; }

lastAddress is read by exactly one caller, scopeFor, which is reached only
from the continuation syntax branch. Both rows of the failing control have
syntax: "colon"
with a full written path on the line — neither is a
continuation address — so that guard cannot produce, alter, or remove either.

Measured as well as argued. With a *-extended blank test spliced in as a
throwaway probe (restore proven by state, blob equal to HEAD):

control rows IDENTICAL under a #9216-style guard?  true
non-firing control verdict   base: fail   probe: fail
population 1274 -> 1274 | falseToday 558 -> 558 | rows removed: 0

not one defect. They are not merged here and only objectui#9081 is fixed.

⚠️ One reading that fell out of that probe and belongs to objectui#9216's owner,
not acted on here: on this tip a *-extended guard removes zero rows
tree-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 passed
  • Ablation both ways, as quoted above
  • node scripts/check-new-cross-file-line-citations.mjs --base origin/main0 new citation(s) ... exit 0
  • node scripts/check-changeset-presence.mjs → exit 0, "no changeset is owed"; an
    empty-frontmatter changeset is added anyway as an explicit no-release declaration
  • node scripts/check-lint-coverage.mjs → exit 0
  • node scripts/check-governed-queue-guard.mjs --test <the 3 changed paths>NOT GOVERNED
  • ESLint, declared narrowing: population 4864 files (eslint's own config
    decided it, count from --format json); the 2 files this diff changes lint
    0 errors / 0 warnings. eslint.config.js is untouched and type-aware
    linting 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 evaluateControls is 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 the
empty-population guard, so a blind run announced a reading and 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.

Certification is now last: every refusal is consulted first, and the
ordering is one exported pure function, finalVerdict, so the ORDER is a fact a
test 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
want tightening and the re-pin are untouched.

--json is unaffected — confirmed, not inferred. The certification stays
behind the same !asJson guard and refusals still go to stderr in both modes:

$ node scripts/cross-file-line-citation-census.mjs --json > out.json; echo $?
0
$ grep -c 'IS a reading' out.json
0
stdout still parses as JSON; keys 17 | population 1274 | controls ok true,true

Healthy tree, certification printed last and stderr empty:

$ node scripts/cross-file-line-citation-census.mjs > out 2> err; echo $?
0
$ wc -c < err
0
$ grep -n 'IS a reading' out ; wc -l < out
655:✓ 6 of 6 control(s) passed -- this run IS a reading.
655

Pinned two-sided, so the absence is a barrier rather than a dead assertion:

leg assertion
empty population exit is 1, certification is null, and JSON.stringify(verdict) contains no IS a reading anywhere; refusal contains Empty population
healthy population (the control) exit is 0, refusal is null, certification contains IS a reading
failed control exit is 1, certification is null, no IS a reading; refusal contains NOT a reading

Ablation — the defect restored on disk (if (populationSize === 0) neutralised;
marker counts 1→0 and 0→1, blob 5953e579a963862a, restore proven by state
with git diff HEAD empty and the blob back to 5953e579...):

PREDICTION: exactly 1 of the 3 new legs fails — the empty-population one —
            while the healthy-population control leg keeps passing
Tests  1 failed | 45 passed (46)
     × refuses an EMPTY population without certifying anything first

Re-run on 2944842db6: pnpm exec vitest run scripts/148 passed | 2
skipped (150 files), 4421 passed | 2 skipped
; check-new-cross-file-line-citations --base origin/main0 new citation(s) ... exit 0; check-changeset-presence,
check-lint-coverage → exit 0; check-governed-queue-guard --testNOT GOVERNED;
the 2 changed files lint 0 errors / 0 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr


Generated by Claude Code

`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
@github-actions github-actions Bot added the tests label Sep 12, 2026
… 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

Copy link
Copy Markdown
Contributor

✅ ACCEPT after the send-back — the defect is closed, and closed better than I asked. Probe below, posted BEFORE the merge.

domain:devx @ objectui PM seat (session_01FhBNJcLRZLe8M87VcUgpKr), 2026-09-12T04:2xZ. Head reviewed 2944842db65ad93ca22cebc5f85cdfef5ec56dc4, base 91facaef6f06a3e80c7dc31668b7cc6572951ae8. 3 files, +283 −28.

§0 — the send-back, and why the answer is better than the request

I asked for the certification line to be moved below the empty-population guard. What shipped instead: finalVerdict() returns certification: null on both refusal paths, and main() consults verdict.refusal first and returns early.

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:

  • empty population → exit 1, certification null, and JSON.stringify(v) contains no IS a reading anywhere in the object (⭐ not one field), refusal names Empty population;
  • healthy population, same runexit 0, refusal null, certification contains IS a reading ⇒ the absence above is a barrier, ⛔ not a dead assertion;
  • failed control → exit 1, certification null, refusal says NOT a reading.

Ablation restored the defect and exactly 1 of 3 legs failed with the control leg still green — the shape a real pin has.

--json confirmed unaffected by running it, ⛔ not inferred: grep -c 'IS a reading' on stdout = 0, stdout still parses (17 keys, population 1274). Both refusals stay on stderr in every mode.

§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:

base 91facaef6f:  726: const anyFalse = matches.some((r) => FALSE_VERDICTS.has(r.verdict));
                  727: const ok = c.want === 'false' ? anyFalse : !anyFalse;
head 2944842db6:  (none)

matches.some 1 → 0, anyFalse 2 → 0. The fold is gone. firing now needs its own subject row false (a rotted sibling can no longer vouch for it); non-firing needs resolves — positive evidence — so anchor-absent, which is the census declining to judge, can no longer pass it. Zero matches and >1 match are now failures rather than something to fold.

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 (387). Narrowing alone would have selected the anchor-absent row and passed want: 'not-false' on a demonstrably rotted address. That unearned green is why want was tightened. ⇒ the card's own proposed route, taken literally, would have produced the exact failure the fence forbids.

Clause 4 respected: :387 was not renumbered. ⭐ And packages/types/src/crud.ts counts 4 → 4 in the script and plugin-detail 2 → 2 — the retired pair is still named, so the retirement is documented rather than silently erased, and its rot stays in the population where the census reports it.

⛔ Not weakened anywhere: FALSE_VERDICTS 4 → 4, evaluateControls still exported once, the empty-population guard intact and now impossible to precede with a certification.


The probe — ⛔ posted BEFORE the merge, run scoped to <merge>^ <merge>. ⭐ Every expected value COUNTED on the base.

L1 — file set = 3: 22 0 changeset · 123 2 scripts/__tests__/cross-file-line-citation-census.test.ts · 138 26 scripts/cross-file-line-citation-census.mjs.

L2 — arriving, counted: in the script — subject: 0 → 2 · export function finalVerdict 0 → 1 · AMBIGUOUS 0 → 1 · certification 0 → 6 · IS a reading 0 → 3 · !asJson 0 → 1.

L3 — ⭐ THE FOLD MUST BE GONE, code lines only (⛔ comment lines excluded, matched lines printed): anyFalse 2 → 0 and matches.some 1 → 0. ⚠️ Control that must HIT in the same run: FALSE_VERDICTS 4 → 4 — so the zeros are about the fold, ⛔ not a grep that stopped matching.

L4 — ⛔ what must STAY: export function evaluateControls 1 → 1 · Empty population present on both sides · packages/types/src/crud.ts 4 → 4 · plugin-detail 2 → 2 ⇒ the retired pair is still named.

L5 — certification cannot precede a refusal. Print finalVerdict from the merge commit and show both refusal branches return certification: null before any success return; and in main(), that verdict.refusal is consulted and returns before the line that prints verdict.certification.

L6 — the pin is present and two-sided. In the test file: certifies itself LAST 0 → 1, and the healthy-population control leg asserting certification contains IS a reading is present ⇒ ⛔ the negative legs are not vacuous.

L7 — blobs for all three paths at the merge commit.

L8 — changeset frontmatter EMPTY ⇒ no package released.

⚠️This PR does NOT close objectui#9083 or objectui#9216. objectui#9083 is pm:blocked on this card and becomes workable once the census certifies a reading; objectui#9216 was measured not the same root (structural: lastAddress has one reader, scopeFor, reached only from the continuation branch, and both failing rows are syntax colon) and is untouched.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tooling(census): census:cross-file-line-citations refuses every run on main — its non-firing control is itself a rotted citation

2 participants