test(scripts): batch 10a — class-3 floors at the verdict site for four self-tests - #15327
Merged
Merged
Conversation
…self-tests The class-3 shape: the body that REGISTERS cases is not the body that prints the verdict, so the floor is evaluated at the verdict site — the place that prints the green line — with roster, sink and ledger at module scope. Copies the placement PR #15309 settled. - check-osv-exemptions: recipe A over the 17 literal table rows; floor at the verdict site in main()'s --self-test branch. Boolean `passed` converted to a `failures` counter so the floor shares the counted sink (sink/verdict lines only). - typecheck-configs: recipe A over BOTH literal tables under one roster (11 keys, size pin 11); check in the --self-test dispatch block, so the two importers that fold this self-test in never reach it. - check-comment-mask-corpus: concise arrow sink converted to a block-bodied helper calling registerCase(); one hoisted battery, floor 12; check at the verdict site in selfTest(), so the production sweep in main() — which calls runSelfTestCases() too — never reaches it. SELF_TEST_CASE_COUNT and its production read are untouched. - check-workspace-manifest-cycles: Tier B multi-battery, one battery per named section banner (7), floors measured per battery on a run; check at the verdict site in runSelfTest(). Every floor is read off a run with the roster pinned at 9999, never counted from source. No assertion condition, message or argument is changed. Also adds the one ENTRY_BY_HAND row the instrument needs to probe check-workspace-manifest-cycles at all: it defines two self-test-shaped functions and reads NOT MEASURED without it. 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 11:55
baozhoutao
enabled auto-merge
September 4, 2026 11:56
This was referenced Sep 4, 2026
Merged
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
Part of #14842
Batch 10a: the four remaining class-3 self-tests — the shape where the body that
REGISTERS cases is not the body that prints the verdict. Copies the placement PR #15309
settled: roster, sink and ledger at module scope, and the FLOOR CHECK evaluated at the
verdict site, on a path reached only from
--self-test.Floors are measured on a run (roster pinned at 9999, read off the breach line), never
counted from source. No assertion condition, message or argument is changed.
The four files
scripts/check-osv-exemptions.mjsmain()'s--self-testbranchscripts/typecheck-configs.mjs--self-testdispatch blockscripts/check-comment-mask-corpus.mjsselfTest()scripts/check-workspace-manifest-cycles.mjsrunSelfTest()registerCase()is the FIRST statement of each driving loop body (recipe A) or of thefile's own case sink (b3/b5/Tier B). Each handshake is kept exactly as it landed — two
selfTestReachedVerdictflags, twoSELF_TEST_VERDICTsentinels. Handshake and floor stayorthogonal.
Roster cross-checked against the source both ways, by this branch:
check-osv-exemptions17 roster keys vs 17name:rows, 0 duplicates either side, emptydifference both directions;
typecheck-configs11 vs 11, same;check-workspace-manifest-cycles7 roster keys vs 7
battery()openers, and each opener's string is byte-equal to the bannerabove it (⛔ no comment was promoted to a section head — the seven names are the seven
banners the file already had).
Two library scopings, proven rather than asserted
typecheck-configsis a library. ItsselfTest()is folded intocheck-type-check-coverage.mjsand its predicates are imported bycheck-type-source-resolution.mjs. Those importers callselfTest(), which registers intothe module ledger — but the FLOOR lives in this file's own
--self-testdispatch, which animporter never reaches. Neither importer is edited.
check-comment-mask-corpus's production path callsrunSelfTestCases()on every sweep.The floor is in
selfTest(), which the sweep never calls.SELF_TEST_CASE_COUNTand itsproduction read are untouched; the roster does not replace it.
Deletions — sink/verdict lines only, declared
8 deleted lines in total, in two files; the other three add only.
check-comment-mask-corpus— 1: the concise arrow sinkok = (label, cond) => cases.push(...),replaced by the block-bodied helper that calls
registerCase()and then pushes the same object(the b3 conversion, PR test(scripts): give six more self-tests a battery roster and floor (#13799 batch 3) #15156's shape).
check-osv-exemptions— 7, the boolean→counter conversion 8b landed oncheck-override-consistency:let passed = true,if (!ok) passed = false,return { passed, lines },the
@returnsJSDoc,const { passed, lines } = …,if (!passed) {, and the old red verdict line.The red run now prints the uniform
N failure(s) (cases and floor); the GREEN line is untouched."after the existing failures branch and immediately before the success line". In
check-osv-exemptionsthe same dispatch also ordered the boolean→counter conversion so the floorshares the counted sink — and those two cannot both hold, because a shared sink means ONE branch,
not one after another. The counter conversion won (it is the per-file instruction, with a named
precedent); the floor is still immediately before the success line. The other three files have a
separate floor branch after the existing failures branch, exactly as the pilot does.
The instrument row (
Part of #14842)node scripts/measure-self-test-floor.mjs --probestill readsscripts/check-workspace-manifest-cycles.mjsas NOT MEASURED (ambiguous entry (selfTest,runSelfTest) and no ENTRY_BY_HAND row) on this pin — checked before editing, so the row #14842
prescribes is still needed. Added as one line (plus a three-line reason). With it, the probe reads:
{"verdict":"HELD","entry":"runSelfTest","baselineExit":0,"mutatedExit":1,"mutatedBytes":220, "mutatedHead":"✗ check-workspace-manifest-cycles self-test: runSelfTest() returned without reaching its verdict,"}Ablations — 18 legs across the split, mutation AND restore proven on disk
Every leg: the mutation is proven by counting the text it was anchored on (removed count → 0,
injected count ≥ 1) and the blob hash moving; the restore is
git checkout HEAD --anABSOLUTE path in a
finally(with SIGTERM/SIGINT handlers, so a cap kill cannot leave a mutatedtree), proven by
git hash-objectequalling the HEAD blob and an emptygit diff HEAD— anempty hash is read as FAILURE, not as "nothing to compare". All 18 restores passed; the tree is
clean. These are plain
.mjsscripts executed from source with nodist, so no rebuild legapplies — stated rather than skipped.
registerCase()removedOK -- 11 cases holdAll 12 … passedall cases passedreturnin the registering body⭐ (d) came out in two directions, and both are reported as observed rather than as the template
predicted. Where the handshake flag is set on the last line of the registering body
(
check-osv-exemptions,typecheck-configs), an early return trips the handshake before thefloor is ever consulted — the two holes catching the same defect at different depths, which is what
orthogonal looks like in practice. For those two an extra leg (d2) injects a skip guard into
the driving loop instead — the "a guard that now skips" defect the floor's own remedy text names —
and it lands as exactly one battery DID NOT RUN with every other case green, count below floor.
Where the handshake sits on the deciding body (
check-comment-mask-corpus,check-workspace-manifest-cycles), (d) reaches the floor as designed; inmanifest-cyclesthe setdifference names the four banners that stopped and leaves the three that ran at their floors.
Byte comparison vs the installed base
A second worktree detached at the same pin
103677652,pnpm installexit 0 (an uninstalled basewould be exit 3 = NOT MEASURED, not a reading). Both modes, stdout and stderr compared separately
with
cmp:check-osv-exemptions--self-test/ normaltypecheck-configs--self-test/ normalcheck-comment-mask-corpus--self-testcheck-comment-mask-corpuscheck-workspace-manifest-cycles--self-test/ normalcheck-type-source-resolution(importer)--self-test/ normalcheck-type-check-coverage(importer, foldstypecheck-configs)--self-test/ normalThe one varying line, proven to vary base-against-base. The corpus sweep prints its own
elapsed time. Branch 58.9s vs base 56.4s — and a second run of the BASE tree against the first
gives 63.7s vs 56.4s, so the field varies with nothing changed at all. Every other byte of that
line is equal across all three runs (
5889 files, 0 disagree, 0 unparseable,comparator self-test: 12 cases pass), and masking the seconds makes base and branchbyte-identical.
Both importers of
typecheck-configsare byte-identical in both modes, in both directions —that is the proof that the floor is scoped to this file's own dispatch and cannot fire inside a
fold-in. Neither importer is edited.
check-type-check-coverage --self-teststill reports its sixfamilies (
48 + 68 + 45 + 28 + 19 + 18) unchanged.to
os-verify-lock.shas parts joined with;, so the lock's own line saysVERDICT batch-last-exit 0 · ⚠ NOT A VERDICT ON THE WHOLE COMMAND. It is right to say so: that 0covers only the last part. The evidence here is not that number — each of the nine runs printed and
captured its own exit code (
TCCST_W=0 TCCST_B=0 TCCN_W=0 TCCN_B=0 CMN_W=0 CMN_B=0 CMN_B2=0 TSRN_W=0 TSRN_B=0), and those are what is reported. Thepnpm check:pm-dispatch-gatesrun was asingle command and its line reads a real
VERDICT command-exit 0.Instrument before/after
node scripts/measure-self-test-floor.mjs --json, run in each tree, exit 0, 170 rows both times:103677652NONE drops by exactly 4 —
check-comment-mask-corpus,check-osv-exemptions,check-workspace-manifest-cycles,typecheck-configs— and nothing entered NONE. Thesymmetric difference between the set that left and this batch's worklist is empty.
extractWatchHints(imported fromscripts/pm/dispatch-gates.mjs), computed in both trees:identical on all four target files. The fifth edited file,
measure-self-test-floor.mjs,gains exactly one hint —
scripts/check-workspace-manifest-cycles.mjs, the path its new rownames, which is the point of the row.
pnpm check:watch-hint-literalexit 0.Gates
Exit codes captured by redirect BEFORE any pipe throughout (
cmd > out 2>&1; ec=$?), and eachresult is quoted from the gate's own verdict line, never from a bare
$?.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no hand-built path list — the script takes its own change set from the merge base; it reports
5 paths, committed 5 / working tree 0 / untracked 0): 26 commands, 26 exit 0.
pnpm check:pm-dispatch-gatesin the foreground underscripts/pm/os-verify-lock.sh—✓ dispatch-gates self-test: 1381 cases pass., lock VERDICTcommand-exit 0 · held 367s · waited 160s;check-self-test-workflow-commands.mjsand its--self-test;check:declared-population-live;check-self-test-wired.mjsand its--self-test;check:ratchet-remedy-authority;check:nul-bytes;check:watch-hint-literal.--self-test, all exit 0:node scripts/check-osv-exemptions.mjs×2 (validate-deps.yml runs exactly these two — there isno
check:osv-exemptionspackage script),pnpm check:workspace-manifest-cycles,pnpm check:type-source-resolution,pnpm check:type-check-coverage,node scripts/check-comment-mask-corpus.mjs,node scripts/typecheck-configs.mjs --self-test.pnpm lint(eslint . --no-inline-config) exit 0 — the full farm, no narrowingclaimed and none needed.
scripts/measure-self-test-floor.mjsships no--self-test(its controls run inline on everyinvocation) and no test file in the tree names it, so running the instrument IS its own suite:
exit 0 in both trees.
Control-byte scan (
grep -naPover the five edited files and over every body posted for thisbatch): no hits.
Classification (measurement only, no edit)
scripts/audits/14744-before-update-per-row-value-census.mjs— its census row is in the reportcomment on #13799. Headline: recipe A, 10 literal table rows, no handshake in any of the
three landed spellings, verdict INSIDE the body (so not class-3), a derived
SELF_TEST_CASES.lengthnothing compares, 0 banners, and zero CI wiring — no package.jsonscript, no workflow mention. Measuring it also turned up an instrument defect, filed as #15324:
the probe awards
HELDon a non-zero exit code alone, and this file exits 1 printing zero byteson an early return, so a file with no handshake at all scores
HELD.🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code