Skip to content

fix(devx): freeze each gate's census ref inside the record and print the comparison on every pass - #13290

Merged
os-elon merged 2 commits into
mainfrom
claude/issue-13237-stale-gate-census
Aug 30, 2026
Merged

fix(devx): freeze each gate's census ref inside the record and print the comparison on every pass#13290
os-elon merged 2 commits into
mainfrom
claude/issue-13237-stale-gate-census

Conversation

@os-elon

@os-elon os-elon commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Fixes #13237

Two gates recorded the census their vacuity floors were derived from, enforced those floors as inequalities over a live census, and had nothing reconciling the record against the tree. Both records had silently stopped describing it, and by construction no run could ever say so.

Re-derived class membership (the card's figure was re-measured, not taken on trust)

15 scripts under scripts/ declare a MIN_ / FLOOR_ / MAX_ / CEIL constant. The class needs all three of (a) inequality floors over a live census, (b) the census recorded in source, (c) nothing reconciling the record against the tree. Three qualify — confirming the card's count — and the third, scripts/check-dual-build-cjs-loads.mjs, is repaired in PR #13234 and deliberately untouched here.

The 12 exclusions are exclusions for a reason, not by omission. Six declare a constant that is not a census floor at all (prose lengths, a recursion depth, a pagination cap, a version floor, a shard ratio). Three record no number and say so where the constant is declared. scripts/check-published-files.mjs is the near miss worth naming: it does record a census, but its self-test derives the live population every run, bounds the floor against it in both directions and prints floor 50 vs 69 of 69 live — so it already ships this repair, in its own shape.

Why neither floor could ever see it

gate recorded today drift
check-keyed-text-bounds 113/118/255/594/151 112/117/251/589/148 −1/−1/−4/−5/−3
check-undeclared-dep-imports 78/2057/1805 78/2085/1819 =/+28/+14

A floor is an inequality with slack, so it can only see a collapse. Both self-tests compared the record against the floors — two constants in the same file — and never against the tree. The second gate is the sharp case twice over: its floors are >=, so an upward drift moves away from the only thing looking at it and no floor can ever see it; and its census was a bare comment rather than a constant, so nothing in the language could hold it, no self-test could reference it and no run could print it.

Note the second gate has drifted further since the card was filed (+15/+14 there, +28/+14 today).

The records were exact when written

Both censuses were re-derived by running today's instrument against each recorded ref, and both came back exactly the recorded values (113/118/255/594/151 and 78/2057/1805). So the drift is legitimate tree movement, not a mis-transcribed count — measured here rather than assumed from #13128.

The reproduction recipe from PR #13234 does not transfer, and that is a finding

Neither ref is a tree its own gate can run in. Each names the PR's base — 2h35m and 3h17m before the gate landed — so git worktree add --detach $REF && node scripts/check-....mjs fails with MODULE_NOT_FOUND, measured. Each header now carries the recipe that actually works: run today's instrument against that tree via the exported sweep(root). Both headers also record that a shallow clone cannot do it at all, since both refs predate the default checkout window.

The change

Per gate, following PR #13234's shape: the ref moves inside the frozen MEASURED record so a count and its tree cannot be edited apart; every quoting site interpolates from the record instead of restating it; and a new provenanceLine prints, on every pass, the census this run read beside the floors, the recorded census and its ref, with the delta in both directions. The delta is marked information, never a verdict.

A green run now ends:

provenance — packages/scannedFiles/specifiers: this run 78/2085/1819 · floors 60/1500/1200 · derived from 78/2057/1805 measured on aef1b7e6 (=/+28/+14 vs the record).

⛔ No band, and no equality against the tree. Both refusals are re-derived in the headers rather than restated: the band already exists and is called the floor, and no width measures anything when the three instances drifted +28, −5 and −1 in both directions within days.

An ablation caught a phantom check in this PR's own first draft

Four ablations, each proving the mutation landed on disk and each restore proved against the HEAD blob hash. Three went red as predicted. One did not: restating ${MEASURED.ref} in a refusal as the same sha typed by hand leaves the output byte-identical, so an assertion over the output stayed green while the ref and its counts had become editable apart — the exact defect being repaired.

The separating property is that the ref literal occurs exactly once in the code. Comments are masked first, using this tree's own js-comment-mask.mjs, because prose naming the ref is legitimate — and that mask is load-bearing rather than tidy: check-undeclared-dep-imports dates a separate comment-mask claim to the same commit, and that second occurrence is what caught this. Both gates now carry the strengthened case, and the re-run ablation reds it.

Declaration

This change does not alter contract accept/reject behaviour and does not touch the published surface. Every floor value, every verdict, every exit code and every finding is untouched; the only behavioural difference is two extra printed lines on the pass path of two internal gates. No package version changes, which is why this carries skip-changeset rather than a changeset.

Local verification, at 8cb5317dbe (the final commit)

Both gates and their self-tests: green, printing the new provenance line. The full derived gate family from node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack — 14 matched families plus both convention-triggered ones (bare-root-worklist --self-test, check:pm-dispatch-gates) and check:nul-bytes: all green, each exit code captured before any pipe.

check-test-completeness is NOT MEASURED, on its own instruction: with no turbo run test log to hand it, it exits 3 before parsing a line and its own output says this "is not a red, and there is nothing here to fix".

pnpm lint was narrowed to the two changed files, and the narrowing is declared: eslint's own --print-config resolves for both, --format json reports 2 files linted with 0 errors and 0 warnings, and this repo runs one eslint.config.mjs that never enables type-aware linting for any file (no parserOptions.project, no typed rules — stated and measured at eslint.config.mjs:325), so this diff cannot move the verdict of any file it does not touch. CI runs the repo-wide sweep regardless.

⚠️ Merge-order note for review: PR #13234 edits its own header to say these two gates "had already drifted from their own record". Once this lands, that sentence describes a state that no longer holds. That file is fenced for this card, so it is not touched here.

Generated by Claude Code


Generated by Claude Code

os-elon and others added 2 commits August 29, 2026 17:33
…the comparison on every pass

Two gates recorded the census their vacuity floors were derived from, enforced
those floors as inequalities over a LIVE census, and had nothing reconciling the
record against the tree. Both records had silently stopped describing it:

  check-keyed-text-bounds      113/118/255/594/151 recorded, 112/117/251/589/148 today  (-1/-1/-4/-5/-3)
  check-undeclared-dep-imports 78/2057/1805 recorded, 78/2085/1819 today                (=/+28/+14)

The second is the sharp case: the floors are `>=`, so an UPWARD drift moves away
from the only thing looking at it and no floor can ever see it. Its census was
also a bare comment rather than a constant, so nothing in the language held it.

Both records were re-derived at their own refs and were EXACT when written, so
the drift is legitimate tree movement, not a mis-transcribed count.

Neither ref is a tree its gate can run in -- each names the PR's base, 2-3h
before the gate landed -- so the recipe "check the ref out and run the gate"
fails with MODULE_NOT_FOUND. Both headers now give the recipe that works.

No accept/reject behaviour changes: the floors, their values and every verdict
are untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
An ablation showed the previous assertion was a phantom check: restating
`${MEASURED.ref}` in a refusal as the same sha typed by hand leaves the output
byte-identical, so an assertion over the output stayed green while the ref and
its counts became editable apart -- the exact defect these files were repaired
for.

The separating property is that the literal occurs exactly once in the CODE.
Comments are masked first, using this tree's own `js-comment-mask.mjs`, because
prose naming the ref is legitimate: each header explains how to reproduce the
census, and `check-undeclared-dep-imports` dates a separate comment-mask claim
to the same commit. That second occurrence is what caught this.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
@os-elon os-elon added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 29, 2026 — with Claude
@os-elon
os-elon marked this pull request as ready for review August 30, 2026 06:16
@os-elon
os-elon enabled auto-merge August 30, 2026 06:16
@os-elon
os-elon added this pull request to the merge queue Aug 30, 2026
Merged via the queue into main with commit 39df668 Aug 30, 2026
34 checks passed
@os-elon
os-elon deleted the claude/issue-13237-stale-gate-census branch August 30, 2026 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

1 participant