Skip to content

Commit 0d46da5

Browse files
committed
tooling(scripts): assertion floor for check-declaration-mirrors' self-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
1 parent 1bc3c09 commit 0d46da5

1 file changed

Lines changed: 102 additions & 1 deletion

File tree

scripts/check-declaration-mirrors.mjs

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,63 @@ async function main() {
406406
// as one that passed (#13798).
407407
const SELF_TEST_VERDICT = 'check-declaration-mirrors self-test reached its verdict';
408408

409+
// ── The self-test's own battery roster and floor (#13489) ──────────────────
410+
//
411+
// `cases.filter((c) => !c.cond)` used to be this self-test's ONLY success
412+
// condition, so "every case
413+
// held" and "the cases never ran" printed the same line. Closed the way
414+
// PR #13487 validated on check-doc-authoring: what is pinned is the registered
415+
// NAMES, not a number. The floor requires the OPENED set to equal the DECLARED
416+
// set with each battery at or above its own count.
417+
//
418+
// This file declares ONE battery, opened at the top of the self-test body. Its
419+
// blocks are headed by unmarked prose comments, so it carries fewer than the two
420+
// named section banners the sectioning criterion needs, and ⛔ a comment is NOT
421+
// promoted to a section head — that is a judgement per comment this transplant
422+
// does not make. The hoisted single battery is the shape PR #14896, PR #15003
423+
// and PR #15217 landed for exactly this case.
424+
//
425+
// ⛔ A pinned TOTAL is not the repair: a battery dropping from 9 cases to 3
426+
// keeps a total "right" the moment a sibling grows.
427+
//
428+
// The count is a FLOOR, not an equality — adding cases is ordinary work and must
429+
// not red. A battery BELOW its floor means cases stopped running; the remedy is
430+
// to find what stopped registering.
431+
const SELF_TEST_BATTERIES = Object.freeze({
432+
'check-declaration-mirrors self-test': 23,
433+
});
434+
435+
// DELETING an entry silences that battery's floor exactly as effectively as
436+
// zeroing it, so the roster's own size is pinned too.
437+
const SELF_TEST_BATTERY_FLOOR = 1;
438+
439+
// The key an assertion is filed under when no battery is open. It is not a
440+
// declared battery, so it reds by the same set difference rather than silently
441+
// inflating whichever battery happened to run last.
442+
const UNATTRIBUTED_BATTERY = '(no battery open)';
443+
409444
async function selfTest() {
445+
// The battery ledger this self-test's floor is evaluated against (#13489).
446+
// `battery()` opens a battery; every assertion below is attributed to the one
447+
// most recently opened, so a section that stops running stops registering and
448+
// names ITSELF at the floor rather than going quiet.
449+
const batterySeen = new Map();
450+
let openBattery = null;
451+
const battery = (name) => {
452+
openBattery = name;
453+
};
454+
const registerCase = () => {
455+
const b = openBattery ?? UNATTRIBUTED_BATTERY;
456+
batterySeen.set(b, (batterySeen.get(b) ?? 0) + 1);
457+
};
458+
battery('check-declaration-mirrors self-test');
410459
const cases = [];
411-
const ok = (label, cond) => cases.push({ label, cond });
460+
// The concise arrow gains a BLOCK body so the case can be registered before
461+
// it is recorded; `cases.push` is unchanged, so no assertion is rewritten.
462+
const ok = (label, cond) => {
463+
registerCase();
464+
cases.push({ label, cond });
465+
};
412466
const dir = mkdtempSync(join(tmpdir(), 'os-decl-mirror-'));
413467
let seq = 0;
414468

@@ -549,6 +603,53 @@ async function selfTest() {
549603
mirrorFiles().every((f) => f.endsWith('.d.mts')),
550604
);
551605

606+
// ── The floor: every declared battery RAN, and ran its cases (#13489) ────
607+
//
608+
// Evaluated after every battery has had its chance and BEFORE the verdict, so
609+
// the success line below can only be printed by a run in which the set of
610+
// batteries that registered assertions EQUALS the set declared. A set
611+
// difference names WHICH battery stopped; a count says only that something did.
612+
// This file's sink IS the `cases` ledger, so the floor speaks its idiom: a
613+
// breach is recorded as a failing case and reds through the existing verdict
614+
// below. It bypasses `ok()` deliberately — a floor message is not a case.
615+
const floorFailure = (message) => { cases.push({ label: message, cond: false }); };
616+
const declaredBatteries = Object.keys(SELF_TEST_BATTERIES);
617+
let floorBreached = false;
618+
if (declaredBatteries.length < SELF_TEST_BATTERY_FLOOR) {
619+
floorBreached = true;
620+
floorFailure(
621+
`SELF_TEST_BATTERIES declares ${declaredBatteries.length} batteries, below the pinned `
622+
+ `${SELF_TEST_BATTERY_FLOOR} — a battery deleted from the roster takes its own floor with it.`,
623+
);
624+
}
625+
for (const [name, count] of batterySeen) {
626+
if (declaredBatteries.includes(name)) continue;
627+
floorBreached = true;
628+
floorFailure(
629+
`self-test battery "${name}" registered ${count} case(s) but is not declared in `
630+
+ 'SELF_TEST_BATTERIES — an assertion attributed to no declared battery is one nothing floors.',
631+
);
632+
}
633+
for (const name of declaredBatteries) {
634+
const count = batterySeen.get(name) ?? 0;
635+
if (count >= SELF_TEST_BATTERIES[name]) continue;
636+
floorBreached = true;
637+
floorFailure(
638+
count === 0
639+
? `self-test battery "${name}" DID NOT RUN — 0 cases registered, ${SELF_TEST_BATTERIES[name]} pinned. `
640+
+ 'The verdict below would have claimed those cases hold.'
641+
: `self-test battery "${name}" registered ${count} case(s), below its pinned floor of `
642+
+ `${SELF_TEST_BATTERIES[name]} — cases that used to run no longer do.`,
643+
);
644+
}
645+
if (floorBreached) {
646+
floorFailure(
647+
'A battery at or below its floor means cases STOPPED RUNNING — the battery is the bug, not the '
648+
+ 'number. Find what stopped registering (an early return, a deleted block, a guard that now '
649+
+ 'skips) and restore it.',
650+
);
651+
}
652+
552653
const failed = cases.filter((c) => !c.cond);
553654
for (const c of cases) console.log(`${c.cond ? 'ok ' : 'FAIL'} ${c.label}`);
554655
if (failed.length) {

0 commit comments

Comments
 (0)