fix(devx): freeze each gate's census ref inside the record and print the comparison on every pass - #13290
Merged
Merged
Conversation
…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
marked this pull request as ready for review
August 30, 2026 06:16
os-elon
enabled auto-merge
August 30, 2026 06:16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 aMIN_/FLOOR_/MAX_/CEILconstant. 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.mjsis 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 printsfloor 50 vs 69 of 69 live— so it already ships this repair, in its own shape.Why neither floor could ever see it
check-keyed-text-boundscheck-undeclared-dep-importsA 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-....mjsfails withMODULE_NOT_FOUND, measured. Each header now carries the recipe that actually works: run today's instrument against that tree via the exportedsweep(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
MEASUREDrecord so a count and its tree cannot be edited apart; every quoting site interpolates from the record instead of restating it; and a newprovenanceLineprints, 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:
⛔ 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
HEADblob 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-importsdates 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-changesetrather 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) andcheck:nul-bytes: all green, each exit code captured before any pipe.check-test-completenessis NOT MEASURED, on its own instruction: with noturbo run testlog 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 lintwas narrowed to the two changed files, and the narrowing is declared: eslint's own--print-configresolves for both,--format jsonreports 2 files linted with 0 errors and 0 warnings, and this repo runs oneeslint.config.mjsthat never enables type-aware linting for any file (noparserOptions.project, no typed rules — stated and measured ateslint.config.mjs:325), so this diff cannot move the verdict of any file it does not touch. CI runs the repo-wide sweep regardless.Generated by Claude Code
Generated by Claude Code