Skip to content

test(scripts): batch 10e — assertion floors for check-type-check-coverage's six families - #15376

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13799-batch10e-type-check-coverage
Sep 4, 2026
Merged

test(scripts): batch 10e — assertion floors for check-type-check-coverage's six families#15376
baozhoutao merged 1 commit into
mainfrom
claude/issue-13799-batch10e-type-check-coverage

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Part of #13799 — batch 10e, census row 11, ONE file: scripts/check-type-check-coverage.mjs.

failures.length === 0 was this self-test's only success condition, so "every case
held" and "the cases never ran" printed the same line. The instrument classifies the
file NONE before this change and ROSTER after, and it is the only file whose
classification moves.

What row 11's "six families" actually are

The census derived "6 families = 48+68+45+28+19+18 = 226" from the file's own green
line, which groups its cases into exactly six named tallies. Re-measured on this branch,
and the mapping holds:

family where its cases live sink banner? measured registrations
semantic the literal cases table, 48 rows, one driving loop failures list no 48 (1/row)
observation 9 tables between the fold-in and driftCases failures list no 57
re-measure driftCases, countCases, projectCases, setupErrorCases, ceilingCases, heapEnvCases failures list no 45
built-closure typeEntryCases, closureCases, staleCases, sourceFileCases failures list no 28
auto-lowering planCases, rewriteCases, roundTripCases failures list no 19
exit-code the REFUSING loop, the readTsconfig negative control, exitCodeCases, textCases failures list yes (banner 3) 18

Five of the six family floors equal the number the green line prints for that family.
The sixth, observation, floors at 57 where the line prints 68: the line adds
typecheck-configs' 11 folded-in cases to that figure, and those are floored in that
module (PR #15327), not here.

Only one of the three section banners delimits a family (THE EXIT-CODE CLASS). The
other two — the ratchet-remedy authority block and the graduation-remedy block — sit
inside the interleaving and their assertions are not in the printed tally at all,
as is the TS6059 wiring pin. Left unregistered they would stay exactly as silenceable as
they were before this floor existed, and a set-difference refusal cannot see an
assertion that registers nowhere, so each gets its own battery (the shape #15296 asks
for). Total registrations: 228 across 56 batteries.

The shape

  • Recipe A for the table (PR test(scripts): batch 7 pilot — floor check-sdui-manifest on its own table row labels #15271/test(scripts): batch 7a — floor five table-driven self-tests on their own row labels #15288/tooling(scripts): row batteries for four table-driven self-tests (#13799 batch 7b) #15286): each of the 48 row labels is a
    declared battery with a floor of 1, and registerCase(c.label) is the FIRST statement
    of the driving loop body. The roster is a LITERAL cross-checked against the table both
    ways, with a duplicate-label refusal, and its own size pinned at 56.
  • One battery per family for the rest, at the measured count, with the family name
    written explicitly at each site rather than a most-recently-opened battery() pointer
    — the families are interleaved in file order, so a pointer would file whole tables
    under whichever section opened last.
  • A separate floor branch at the verdict site, immediately before the green line,
    because the sink here is a failure list and not a counter (10a's ACCEPT
    5540078004): a floor breach is not a case that failed, it is the report that cases
    never ran, so it does not enter the list the red line enumerates as cases.
  • The sentinel handshake (SELF_TEST_VERDICT) is untouched, as is the folded
    typecheck-configs.selfTest() call and that library's own --self-test.
  • No assertion condition, message or argument changed. Zero deletions — the diff is
    +274/-0 on one file.

Floors were MEASURED, not derived

Every floor pinned at 9999, one run, every breach line read. The breach-line count was
asserted equal to the roster size (56 == 56) before any number was read, so a
battery that silently failed to register could not pass as a small floor. The 56 lines
gave 48 rows at 1 and 57 / 45 / 28 / 19 / 18 / 3 / 8 / 2 for the eight named batteries;
those are the numbers now in the roster.

No fold-in leaks into this file's ledger. The ledger dump names 56 batteries and 228
registrations; not one of typecheck-configs' 11 battery labels appears in it, which is
the count proof that its module-level ledger stays its own.

Ablations

Each mutated the file on disk (blob hash before/after, plus grep counts over the exact
text being changed), ran, then restored with git checkout HEAD -- ABSOLUTE_PATH
proven by hash equality against the HEAD blob and an empty git diff HEAD; every script
carried trap … EXIT INT TERM. No build step is involved — this gate is run directly as
.mjs, nothing resolves through a dist/.

# mutation result
a one cases row deleted (a missing turbo task or CI step fails RUNNABLE, grep 1→0) exit 1 — that battery DID NOT RUN — 0 cases registered, 1 pinned, named
b a family's registrations removed (registerCase('built-closure cases'), 4 sites → 0) exit 1 — built-closure DID NOT RUN — 0 registered, 28 pinned; the red line itself reports "every case that DID run passed", and no other family is named
c roster key renamed (auto-lowering casesauto lowering cases) exit 1 — both halves: the registered name "is not declared", and the declared name "DID NOT RUN"
d size pin raised to 9999 exit 1 — "SELF_TEST_BATTERIES declares 56 batteries, below the pinned 9999"
e return; injected after the first case of the driving loop exit 1 — caught by the handshake, not the floor: no verdict line, no floor output. The floor is never reached, which is the orthogonality: hole 2 defeats hole 1's check too
f (b) applied AND the floor block deleted at the verdict site exit 0, printing the unchanged green line claiming 28 built-closure cases hold — the vacuous green this PR closes. Restored

(b) and (e) are the pair: (e) is a state only the handshake can see, (b) is a state only
the floor can see — the verdict is reached, every case that ran passed, and 28 cases
went dark.

Gates

Exit codes captured before any pipe (cmd > log 2>&1; EXIT=$?).

The derived family, from node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no hand-built list; it derived 1 path against merge base
c4d1354e3) — 23 commands, all exit 0:

check-ci-filter-parity · check-closing-keyword-parity (+--self-test) ·
check-comment-mask-corpus · check-self-test-wired (+--self-test) ·
check-whole-set-label-write (+--self-test) · pm/bare-root-worklist --self-test ·
check:agent-test-spelling · check:bash32-floor · check:cli-command-ids ·
check:cross-package-test-inputs · check:entry-guard · check:nul-bytes ·
check:parse-guard · check:pm-dispatch-gates · check:pnpm-filter-targets ·
check:ratchet-remedy-authority · check:refd-timer-probe ·
check:type-check-coverage · check:type-check-debt · check:watch-hint-literal

Always-runs tail, all exit 0: check-self-test-workflow-commands (+--self-test),
check:declared-population-live, check-self-test-wired (+--self-test),
check:ratchet-remedy-authority, check:nul-bytes, check:watch-hint-literal, and
check:type-source-resolution — the library's other importer, green, so folding
typecheck-configs in from a second place is unaffected.

The file's own wiring. check:type-check-coverage = --self-test then the gate itself,
exit 0 in full. check:type-check-debt = --self-test && --re-measure: the
--self-test half is green (the half this diff touches, printing the unchanged
verdict line), and --re-measure answers PREREQUISITE NOT MET, exit 3 — 33
workspace dependencies of the ledgered packages have no built type entry point in this
worktree. That is NOT MEASURED, not a red: a detached worktree at the same pin
without this diff returns the identical refusal naming the identical 33 packages, and
lint.yml builds the closure before this step. Nothing in this diff can move a ledger
number — it adds self-test machinery only, and the production run is byte-identical to
base.

check:pm-dispatch-gates ran in the foreground under the shared verify lock
(scripts/pm/os-verify-lock.sh), VERDICT command-exit 0, "1382 cases pass" — held
377s after waiting 507s. check:type-check-debt's first locked attempt returned the
wrapper's exit 99 (queue-timeout, never acquired): NOT MEASURED, re-run on the
same OS_VERIFY_LOCK_SLOT and acquired 101s later. All lock seconds are shared-box
readings, as the wrapper's own verdict line says.

Also run, from the tool's "roster under scripts" advisory block where its silence is
evidence in neither direction: check-published-list-mirrors (+--self-test),
check:console-injection, check:engine-double-contract, check:i18n-stale-fill — all
exit 0. check:published-readme-exports answers exit 1 with "198 package(s) are not
built, so this run measured nothing there" — NOT MEASURED, a build prerequisite: the
identical verdict line comes back from a detached worktree at the same pin without this
diff.

Instrument, before/after (node scripts/measure-self-test-floor.mjs --json, run in
both worktrees): 170 files both times; before ROSTER 162 / NONE 7 / COUNT 1, after
ROSTER 163 / NONE 6 / COUNT 1. Exactly one file moves — this one, NONE → ROSTER. Nothing
enters, nothing else leaves.

extractWatchHints is untouched: this file neither defines nor mentions it, and all 27
scripts/** files that do are byte-identical to the same pin without this diff.

Both modes against the installed base, both worktrees pnpm installed at the same
pin: --self-test and the production run, stdout and stderr, all four
cmp-identical. No line varies, so there is none to name; a base-vs-base control run of
the production path is likewise identical.

Whole-repo pnpm lint green (eslint . --no-inline-config, exit 0 — the full repo scan,
not a narrowed one).

Every number above was taken at e1f89647c, the branch head — the tree was clean and at
HEAD for every gate, ablation and comparison.

One out-of-scope finding filed after a duplicate check against the repo-scoped open-issue
list (279 open issues, no match): #15375workspace-enumerator.selfTest() is folded
into 7 gates with no floor anywhere and is invisible to the #13489 census.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

…amilies

The self-test decided success by `failures.length === 0` alone, so "every
case held" and "the cases never ran" printed the same line. Pin the
registered NAMES: a frozen roster of 56 batteries, each with its own
measured floor, evaluated at the verdict site immediately before the
green line.

The 48 rows of the literal `cases` table are batteries in their own
right (floor 1 each, `registerCase(c.label)` first in the driving loop).
The five families the green line already names are one battery each at
their measured counts -- 57 observation, 45 re-measure, 28 built-closure,
19 auto-lowering, 18 exit-code -- and three assertion blocks the printed
tally does not count get their own batteries so the floor leaves no hole
behind it.

No assertion condition, message or argument changes; both modes are
byte-identical to the installed base on stdout and stderr.

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/m label Sep 4, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review September 4, 2026 13:27
@baozhoutao
baozhoutao enabled auto-merge September 4, 2026 13:28
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 29b4aaa Sep 4, 2026
36 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-13799-batch10e-type-check-coverage branch September 4, 2026 14:10
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

Development

Successfully merging this pull request may close these issues.

2 participants