Skip to content

test(scripts): batch 10a — class-3 floors at the verdict site for four self-tests - #15327

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13799-batch10a-class3-remainder
Sep 4, 2026
Merged

test(scripts): batch 10a — class-3 floors at the verdict site for four self-tests#15327
baozhoutao merged 1 commit into
mainfrom
claude/issue-13799-batch10a-class3-remainder

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

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

file recipe roster floors (measured) check sits in
scripts/check-osv-exemptions.mjs recipe A (literal table + driving loop) 17 rows, size pin 17 1 each — every row registered exactly 1 main()'s --self-test branch
scripts/typecheck-configs.mjs recipe A over both tables, ONE roster 11 rows, size pin 11 1 each the --self-test dispatch block
scripts/check-comment-mask-corpus.mjs b3 (concise arrow sink → block-bodied helper) + b5 (one hoisted battery) 1 battery, size pin 1 12 selfTest()
scripts/check-workspace-manifest-cycles.mjs Tier B multi-battery, one per named section banner 7 batteries, size pin 7 13 / 10 / 2 / 1 / 2 / 4 / 2 = 34 runSelfTest()

registerCase() is the FIRST statement of each driving loop body (recipe A) or of the
file's own case sink (b3/b5/Tier B). Each handshake is kept exactly as it landed — two
selfTestReachedVerdict flags, two SELF_TEST_VERDICT sentinels. Handshake and floor stay
orthogonal.

Roster cross-checked against the source both ways, by this branch:
check-osv-exemptions 17 roster keys vs 17 name: rows, 0 duplicates either side, empty
difference both directions; typecheck-configs 11 vs 11, same; check-workspace-manifest-cycles
7 roster keys vs 7 battery() openers, and each opener's string is byte-equal to the banner
above 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-configs is a library. Its selfTest() is folded into
    check-type-check-coverage.mjs and its predicates are imported by
    check-type-source-resolution.mjs. Those importers call selfTest(), which registers into
    the module ledger — but the FLOOR lives in this file's own --self-test dispatch, which an
    importer never reaches. Neither importer is edited.
  • check-comment-mask-corpus's production path calls runSelfTestCases() on every sweep.
    The floor is in selfTest(), which the sweep never calls. SELF_TEST_CASE_COUNT and its
    production 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-corpus1: the concise arrow sink ok = (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-exemptions7, the boolean→counter conversion 8b landed on
    check-override-consistency: let passed = true, if (!ok) passed = false, return { passed, lines },
    the @returns JSDoc, 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.

⚠️ One declared deviation from the dispatch's wording. The class-3 spec says the floor goes
"after the existing failures branch and immediately before the success line". In
check-osv-exemptions the same dispatch also ordered the boolean→counter conversion so the floor
shares 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 --probe still reads
scripts/check-workspace-manifest-cycles.mjs as 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 -- an
ABSOLUTE path in a finally (with SIGTERM/SIGINT handlers, so a cap kill cannot leave a mutated
tree), proven by git hash-object equalling the HEAD blob and an empty git diff HEAD — an
empty hash is read as FAILURE, not as "nothing to compare". All 18 restores passed; the tree is
clean. These are plain .mjs scripts executed from source with no dist, so no rebuild leg
applies — stated rather than skipped.

leg osv typecheck-configs comment-mask manifest-cycles
(a) battery/row renamed in the roster exit 1, both halves named exit 1, both halves exit 1, both halves exit 1, both halves
(b) registerCase() removed exit 1, 17 × DID NOT RUN, every case still ✓ exit 1, 11 × DID NOT RUN exit 1, DID NOT RUN (0/12) exit 1, 7 × DID NOT RUN
(c) floor check deleted at the verdict site exit 0, vacuous green exit 0, OK -- 11 cases hold exit 0, All 12 … passed exit 0, all cases passed
(d) early return in the registering body handshake fires first handshake fires first exit 1, DID NOT RUN (0/12) exit 1, batteries 4–7 DID NOT RUN

(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 the
floor 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; in manifest-cycles the set
difference 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 install exit 0 (an uninstalled base
would be exit 3 = NOT MEASURED, not a reading). Both modes, stdout and stderr compared separately
with cmp:

run mode stdout stderr
check-osv-exemptions --self-test / normal identical (843 B / 76 B) identical (0 B / 0 B)
typecheck-configs --self-test / normal identical (51 B / 54 B) identical
check-comment-mask-corpus --self-test identical (837 B) identical
check-comment-mask-corpus normal (corpus sweep) ⚠ one field varies — see below identical
check-workspace-manifest-cycles --self-test / normal identical (70 B / 175 B) identical
check-type-source-resolution (importer) --self-test / normal identical (44 B / 230 B) identical
check-type-check-coverage (importer, folds typecheck-configs) --self-test / normal identical (198 B / 972 B) identical

The 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 branch
byte-identical.

Both importers of typecheck-configs are 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-test still reports its six
families (48 + 68 + 45 + 28 + 19 + 18) unchanged.

⚠️ A verdict-line caveat, recorded rather than glossed. The two comparison batches were passed
to os-verify-lock.sh as parts joined with ;, so the lock's own line says
VERDICT batch-last-exit 0 · ⚠ NOT A VERDICT ON THE WHOLE COMMAND. It is right to say so: that 0
covers 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. The pnpm check:pm-dispatch-gates run was a
single 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:

tree ROSTER NONE COUNT
base worktree at 103677652 156 13 1
this branch 160 9 1

NONE drops by exactly 4check-comment-mask-corpus, check-osv-exemptions,
check-workspace-manifest-cycles, typecheck-configs — and nothing entered NONE. The
symmetric difference between the set that left and this batch's worklist is empty.

extractWatchHints (imported from scripts/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 row
names, which is the point of the row. pnpm check:watch-hint-literal exit 0.

Gates

Exit codes captured by redirect BEFORE any pipe throughout (cmd > out 2>&1; ec=$?), and each
result is quoted from the gate's own verdict line, never from a bare $?.

  • Derived family, 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.
  • Always-runs tail, all exit 0: pnpm check:pm-dispatch-gates in the foreground under
    scripts/pm/os-verify-lock.sh✓ dispatch-gates self-test: 1381 cases pass., lock VERDICT
    command-exit 0 · held 367s · waited 160s; check-self-test-workflow-commands.mjs and its
    --self-test; check:declared-population-live; check-self-test-wired.mjs and its
    --self-test; check:ratchet-remedy-authority; check:nul-bytes; check:watch-hint-literal.
  • Each edited script's own wiring, normal mode AND --self-test, all exit 0:
    node scripts/check-osv-exemptions.mjs ×2 (validate-deps.yml runs exactly these two — there is
    no check:osv-exemptions package 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.
  • Whole-repo pnpm lint (eslint . --no-inline-config) exit 0 — the full farm, no narrowing
    claimed and none needed.
  • scripts/measure-self-test-floor.mjs ships no --self-test (its controls run inline on every
    invocation) 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 -naP over the five edited files and over every body posted for this
batch): no hits.

Classification (measurement only, no edit)

scripts/audits/14744-before-update-per-row-value-census.mjs — its census row is in the report
comment 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.length nothing compares, 0 banners, and zero CI wiring — no package.json
script, no workflow mention. Measuring it also turned up an instrument defect, filed as #15324:
the probe awards HELD on a non-zero exit code alone, and this file exits 1 printing zero bytes
on 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

…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
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 4, 2026
@github-actions github-actions Bot added the size/l label Sep 4, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review September 4, 2026 11:55
@baozhoutao
baozhoutao enabled auto-merge September 4, 2026 11:56
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 607534f Sep 4, 2026
37 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-13799-batch10a-class3-remainder branch September 4, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants