tooling(scripts): assertion floors for the batch 6a self-tests — sink repair plus one hoisted battery (#13799 batch 6a) - #15250
Merged
Conversation
…-test `cases.filter((c) => !c.cond)` was this self-test's only success condition, so "every case held" and "the cases never ran" printed the same line (#13489). Class-1 sink repair, the PR #15156 shape: the concise-arrow `ok` sink gains a block body that calls `registerCase()` before the unchanged `cases.push`. No assertion condition is inverted or rewritten. Class-2 roster, the PR #15217 shape: ONE battery hoisted to the top of the self-test body, floor at the measured 23, `SELF_TEST_BATTERIES` size pinned at 1. No comment was promoted to a section head. Case count before == after, measured by pinning the roster to an unreachable value and reading the breach line: 23. `--self-test` stdout and stderr are byte-identical to the base tree's, exit 0 on both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
`cases.filter((c) => !c.ok)` was this self-test's only success condition, so "every case held" and "the cases never ran" printed the same line (#13489). Class-1 sink repair, the PR #15156 shape: the concise-arrow `t` sink gains a block body that calls `registerCase()` before the unchanged `cases.push`. No assertion condition is inverted or rewritten. Class-2 roster, the PR #15217 shape: ONE battery hoisted to the top of the self-test body, floor at the measured 20, `SELF_TEST_BATTERIES` size pinned at 1. The file's single named section banner is NOT split on, and no comment was promoted to a section head. Case count before == after, measured by pinning the roster to an unreachable value and reading the breach line: 20 — which agrees with the count the existing verdict line prints. `--self-test` stdout and stderr are byte-identical to the base tree's, exit 0 on both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
`problems.length` / `failed` were these self-tests' only success condition, so "every case held" and "the cases never ran" printed the same line (#13489). Class-1 sink repair via the THUNK route PR #15198 measured, because each sink write is failure-only: routing failure-only writes through a helper would floor zero cases on a green run, which is no floor at all. `check(() => { ... })` registers the case and then runs the existing site VERBATIM, so registration happens whether or not the site fires and no assertion condition is inverted or rewritten. Per-iteration registration through a block-bodied helper is the landed shape (check-doc-frontmatter, check-test-source-alias both call their helper from inside a `for`). Class-2 roster, the PR #15217 shape: ONE battery hoisted to the top of each self-test body, floor at the measured count, roster size pinned at 1. No comment was promoted to a section head; a single banner was not split on. Floors, each measured by pinning the roster to an unreachable value and reading the breach line -- never transcribed: check-meta-type-normalized 4 (4 thunked sites) check-org-identifier 31 (agrees with its printed `cases.length + 1`) check-error-code-casing 51 (agrees with its printed 46 + 5) `--self-test` stdout and stderr byte-identical to the base tree's on all three, exit 0 both sides; normal mode also byte-identical where the gate has one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…ests Same repair as the previous commit: the THUNK route PR #15198 measured, because every sink write in these three is failure-only, plus PR #15217's single hoisted battery with the roster size pinned at 1. Floors, each measured by pinning the roster to an unreachable value and reading the breach line -- never transcribed: check-console-intercept-disarm 11 (its printed 10 cases + the real-tree floor) check-examples-live-imports 36 (agrees with its printed `cases.length`) check-optional-error-sink-contract 66 (its printed 19 + 9x4 spellings + the reject side + 9 derivation + the `run` reference pin) check-examples-live-imports' one sink site is an if/ELSE, so it is wrapped by hand rather than by a brace matcher that would stop at the `if` block's own closing brace; the branches are reindented, not rewritten. ⛔ check-optional-error-sink-contract's two assertions over `baseline.entries` are deliberately left UNREGISTERED and say so in place: they run one-per-row of a shrink-only ledger, and a floor moving with that list would red every legitimate removal (#13797's ruling, carried forward by PR #15217's check-whole-set-label-write). `LOG_CHANNELS` is not that -- it is the contract's own vocabulary, not a list meant to shrink -- so its loops do register. `--self-test` stdout and stderr byte-identical to the base tree's on all three, exit 0 both sides; normal mode byte-identical where the gate has one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
baozhoutao
marked this pull request as ready for review
September 4, 2026 07:37
baozhoutao
enabled auto-merge
September 4, 2026 07:38
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.
Part of #13799 (batch 6a — the class-1 + class-2 deferrals from PR #15003's table whose sink is N inline writes or a concise-arrow helper, and whose named section banners number fewer than two).
Dispatched by PM claim
5536968867; dev claim5536986594. Concurrent with batch 5 (PR #15217, since landed) and batch 6b — file sets disjoint, verified by set intersection.failures.length === 0/failed === 0was these self-tests' only success condition, so "every case held" and "the cases never ran" printed the same line. Eight of the nine candidate files now carry PR #13487's roster-and-floor shape; the ninth is deferred with a measured reason.What each file got
Two recipes, both landed and both applied verbatim:
registerCase()before the unchanged push;check(() => { ... })registers the case and then runs the existing site verbatim. This is the route the card names for sites that would otherwise need rewriting, and it is the only honest one here: routing failure-only writes through a helper would floor zero cases on a green run, which is no floor at all. Registration happens whether or not the site fires.⛔ No assertion condition is inverted or rewritten anywhere in this diff. ⛔ No comment was promoted to a section head; the two files carrying a single named banner were not split on it.
scripts/check-console-intercept-disarm.mjsfailurescounter, 2 inline sitescheck-console-intercept-disarm self-testscripts/check-declaration-mirrors.mjsokregisterCase()check-declaration-mirrors self-testscripts/check-docs-single-h1.mjstregisterCase()check-docs-single-h1 self-testscripts/check-error-code-casing.mjsfailedcounter, 3 inline sitescheck-error-code-casing self-testscripts/check-examples-live-imports.mjsfailedcounter, 1 inline sitecheck-examples-live-imports self-testscripts/check-meta-type-normalized.mjsproblemsarray, 4 inline sitescheck-meta-type-normalized self-testscripts/check-optional-error-sink-contract.mjsfailurescounter, 7 inline sitescheck-optional-error-sink-contract self-testscripts/check-org-identifier.mjsfailedcounter, 2 inline sitescheck-org-identifier self-testEvery floor was measured, never transcribed: the roster was pinned to an unreachable value, the self-test run, and its own breach line (
registered N case(s), below its pinned floor of ...) read for N. Four of the eight print a case count of their own, and all four agree with the measurement —check-org-identifier31 = itscases.length + 1,check-error-code-casing51 = its printed 46 + 5,check-examples-live-imports36 = itscases.length,check-console-intercept-disarm11 = its printed 10 + the real-tree floor, andcheck-optional-error-sink-contract66 = its printed 19 + 9×4 spellings + the reject side + 9 derivation rows + therunreference pin.One deliberate non-registration
check-optional-error-sink-contract's two assertions overbaseline.entriesare left unregistered on purpose, and say so in place. They run one-per-row of a ⛔ shrink-only ledger, and a floor moving with that list would red every legitimate removal — training the next author to edit the floor, which is the one habit these floors exist to prevent (#13797's ruling, carried forward by PR #15217'scheck-whole-set-label-write).LOG_CHANNELSis not that: it is the contract's own vocabulary rather than a list meant to shrink, so its two loops do register.Deferred, with a measurement
scripts/check-agent-model-declared.mjsfailedsink has 7 inline sites, and 3 of them cannot be wrapped verbatim: all three sit inside thefor (const c of cases)loop and terminate incontinue, which cannot cross a thunk's function boundary, and one of the three is acatchclause rather than anifstatement at all. There is no per-case helper to give a block body to. The 4 discovery-block sites outside the loop are thunk-able, but flooring only those would pin 4 of 22 cases (18 table rows + 4 discovery) while flipping the file's census class fromNONEtoROSTER— the census would then report a hole as closed that is mostly still open, which is worse than an honestNONE(PR #15217's ruling, restated). Deferred rather than improvised, per the card's own instruction.The residue for this file is a real class decision, not a one-file judgement: what to do with a table-driven self-test whose per-case decision is made by
continuein a loop body. It belongs withcheck-startup-registry-verdictandjs-comment-mask, which PR #15217 deferred for the neighbouring reason.Evidence
Case count before == after, measured. Roster pinned to an unreachable value on each file, breach line read for the registered count; restored and re-verified.
--self-teststdout and stderr byte-identical to the base tree's on all eight, exit 0 on both sides; normal mode also byte-identical on the three that have one.Line-level identity of the sink rewrite. Over the whole diff, 68 removed lines against 937 added: after whitespace normalisation exactly 2 removed lines do not reappear, and both are the concise arrows that gained block bodies (
const ok = (label, cond) => cases.push(...)andconst t = (name, ok, detail) => cases.push(...)). Their expressions reappear verbatim as their own lines — the residue is the arrow head becoming a block head, nothing else.Ablations, each from the committed implementation, each proving the mutation on disk by an anchored count and a
git hash-objectthat moved off the HEAD blob (an empty hash read as FAILURE, not "nothing to compare"), each proving the restore by hash equality against the HEAD blob and an emptygit diff HEAD— never by an exit code, never by a baregit checkout -- path(that reads the index the mutation also wrote). Anchors had to match exactly once or the leg aborted; a deletion leg additionally proves the byte length moved by exactly the anchor's length. Nodistis on the resolution path of any of the eight, so no rebuild leg applies.self-test battery "check-optional-error-sink-contract self-test" DID NOT RUN — 0 cases registered, 66 pinned.check-org-identifier): exit 0 → 1 naming both halves —SELF_TEST_BATTERIES declares 0 batteries, below the pinned 1andregistered 31 case(s) but is not declared in SELF_TEST_BATTERIES— so the size pin is load-bearing even at size 1.registerCase()removed from the sink helper (both shapes:check-declaration-mirrors,check-docs-single-h1,check-error-code-casing): exit 0 → 1 with every original case still passing — zero original-case failures in the output — and the floor reportingDID NOT RUN.Census (
node scripts/measure-self-test-floor.mjs --json), as set assertions rather than read by eye:ROSTER113 → 121,COUNT2 → 2,NONE54 → 46. UnflooredNONEdrops by exactly 8; the set of files whose class changed equals the worklist exactly (symmetric difference empty); every transition isNONE→ROSTER;git diff --name-onlyagainst the pin equals the worklist exactly.Watch hints:
extractWatchHintsrun over each of the eight on both trees, both with a realwatchHintTreebundle built from that tree'sgit ls-filesand without one — 8/8 byte-identical. (A first harness passedtreeas a path string and crashed identically on both sides; that "identical" was two identical crashes, not a measurement, and was discarded rather than reported.) Battery names contain a space, so they cannot pass the hint admission test at all.Gates. Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths passed — it reads the change set from the merge base) = 31 commands; plus each edited script's own--self-test, plus the always-runs tail (check-self-test-wiredboth modes,check-self-test-workflow-commands.mjsboth modes,check:declared-population-live,check:ratchet-remedy-authority,check:watch-hint-literal,check:nul-bytes). 44 run, 44 exit 0, every exit code captured by redirect before any pipe — includingcheck:pm-dispatch-gatesin the foreground (✓ dispatch-gates self-test: 1353 cases pass.). Nothing read NOT MEASURED. One invocation of mine was wrong rather than red:pnpm check:self-test-wiredreturned 254 withERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL Command "check:self-test-wired" not found— there is no such package script; the real gate is thenode scripts/check-self-test-wired.mjsform the derivation itself printed, and it ran green in both modes. Recorded rather than counted as a failure.pnpm lintwhole repo (eslint . --no-inline-config) exit 0 in 99 s — no narrowing claimed.Control-byte scan (
grep -naPover the control range) across all eight changed files and every body posted to GitHub: no hits.All of the above ran on
3263b6955, this branch's head and its final commit, withgit status --porcelainempty.Notes
skip-changeset: nothing is published from any package.origin/mainadvanced 4 commits (PR tooling(scripts): assertion floors for the class-2 self-tests, one hoisted battery each (#13799 batch 5) #15217 landing among them) and 11 files it derives from changed. The branch is deliberately not merged forward: none of those commits touches any of these eight (set intersection empty, merge-base still the dispatch pin1bc3c092a), so a merge would only invalidate every byte-identical measurement above. Recorded rather than silently absorbed.🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code