Skip to content

Commit 86918f2

Browse files
committed
test(scripts): six-banner battery roster for pm/bare-root-worklist's self-test
`failures.length === 0` was this self-test's only success condition, so "every case held" and "the cases never ran" printed the same verdict line. The Tier B multi-battery recipe closes that: one battery per named section banner, each roster key byte-equal to the banner it stands for, opened under it, with every case registered after that line attributed to it. A battery that stops registering names the banner a reader can go find instead of a number that says only that something moved. The floors are MEASURED on a run, never planned from static `t(` sites: eight of this body's sites sit inside loops over the file's own tables, so two batteries run several times their static count (65 and 43 against 9 and 7 static). The seven cases that run before the first banner have no section head of their own, so the first battery's opener is hoisted to the top of the body and they are attributed to it — no comment is promoted to a section head. The check sits at this body's own verdict site, immediately above the success line. The early-return hole an end-of-body floor would leave open is closed by the existing `SELF_TEST_VERDICT` handshake, which the dispatch refuses anything else than, so the two holes keep their own guards. No assertion condition, message or argument changes; the green line is byte-identical, and so is normal-mode output. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
1 parent 638ea04 commit 86918f2

1 file changed

Lines changed: 164 additions & 2 deletions

File tree

scripts/pm/bare-root-worklist.mjs

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,141 @@ function report({ wide = false } = {}) {
14201420
}
14211421
}
14221422

1423+
// ── The assertion floor, per battery (#13489) ───────────────────────────────
1424+
//
1425+
// One battery per NAMED SECTION of `selfTest()`, each key byte-equal to the
1426+
// box-drawing banner it stands for, so a battery that stops registering names
1427+
// the banner a reader can go find instead of a number that says only that
1428+
// something moved.
1429+
//
1430+
// The counts are FLOORS MEASURED ON A RUN, never static `t(` site counts: eight
1431+
// of this body's sites sit inside loops — four over the recorded spellings and
1432+
// four over the DECLARED-NARROWER rows of `TRIAGE` — so two of these batteries
1433+
// run several times their static site count, and a floor planned from the
1434+
// source would sit far below what actually runs and would floor nothing.
1435+
//
1436+
// ⛔ A pinned TOTAL is not the repair: one battery falling from 60 cases to 3
1437+
// keeps a total "right" the moment a sibling grows. That is what six batteries
1438+
// buy over one number.
1439+
//
1440+
// The counts are a FLOOR, not an equality — adding cases is ordinary work and
1441+
// must not red. A battery BELOW its floor means cases stopped running; the
1442+
// remedy is to find what stopped registering.
1443+
//
1444+
// ⚠️ The seven cases that run BEFORE the first banner have no section head of
1445+
// their own. They are attributed to the FIRST banner's battery, whose opener is
1446+
// hoisted to the top of the body so that banner carries no second opener —
1447+
// PR #13487's shape, as batches 1b and 2 landed it. Promoting their comment to
1448+
// a section head would be a source change this batch does not make, and leaving
1449+
// them unattributed reds by the set difference below, which is the point.
1450+
const SELF_TEST_BATTERIES = Object.freeze({
1451+
'The FOLD: one row per literal, however many invocations reach it': 14,
1452+
'The triage coupling, both directions': 6,
1453+
'The MECHANISM a repaired reason turns on, held mechanically': 4,
1454+
'The RECORDED SPELLINGS, pinned: LIVENESS and PRECISION': 65,
1455+
"The DECLARATION a row describes, read from the gate's own SOURCE": 43,
1456+
'CENSUS_REFUSE_WIDE, pinned on its OWN terms (#14695)': 5,
1457+
});
1458+
1459+
// DELETING an entry silences that battery's floor exactly as effectively as
1460+
// zeroing it, so the roster's own size is pinned too.
1461+
const SELF_TEST_BATTERY_FLOOR = 6;
1462+
1463+
// The key a case is filed under when no battery is open. It is not a declared
1464+
// battery, so it reds by the same set difference rather than silently inflating
1465+
// whichever battery happened to run last.
1466+
const UNATTRIBUTED_BATTERY = '(no battery open)';
1467+
1468+
// ── Why the CHECK sits inside `selfTest()`, at its verdict site ─────────────
1469+
//
1470+
// This body both REGISTERS and DECIDES: it prints its own verdict and exits 1
1471+
// itself, so the success line and the floor are in the same frame and the floor
1472+
// goes immediately above that line — the only place a run that registered
1473+
// nothing can still be stopped from reporting that every case held.
1474+
//
1475+
// The landed recipe refuses a floor placed before a plain `return`, because an
1476+
// early return above it skips the check. That hole is not open here, and the
1477+
// reason is mechanical rather than argued: this body's only exit that a caller
1478+
// accepts is the `SELF_TEST_VERDICT` sentinel returned BELOW the success line
1479+
// (#13798), and the dispatch refuses anything else. An early return therefore
1480+
// reds at the HANDSHAKE, not silently — while a section that keeps running to
1481+
// the bottom with its cases gone reds at the FLOOR. The two holes stay
1482+
// orthogonal, each with its own guard, which is how that card ruled them.
1483+
1484+
// The battery ledger, read by `batteryFloorFailures()` at `selfTest()`'s verdict
1485+
// site. `battery()` opens a battery; every case registered after that line is
1486+
// attributed to the one most recently opened, so a section that stops running
1487+
// stops registering and names ITSELF at the floor rather than going quiet.
1488+
//
1489+
// ⚠️ Named for the roster's role, deliberately NOT with a self-test spelling:
1490+
// `check:pm-dispatch-gates` anchors on a top-level declaration whose NAME spells
1491+
// self-test and every such name owes a row in its COMPOUND_ANCHOR_LEDGER. This
1492+
// machinery holds no fixtures to mask and reads no path literal, so the accurate
1493+
// name is the one that says `battery`.
1494+
const batterySeen = new Map();
1495+
let openBattery = null;
1496+
1497+
/** Open a battery. Every case registered after this line is attributed to it. */
1498+
function battery(name) {
1499+
openBattery = name;
1500+
}
1501+
1502+
/** Called by `selfTest()`'s own case sink, once per case. */
1503+
function registerCase() {
1504+
const name = openBattery ?? UNATTRIBUTED_BATTERY;
1505+
batterySeen.set(name, (batterySeen.get(name) ?? 0) + 1);
1506+
}
1507+
1508+
/**
1509+
* The floor: every declared battery RAN, and ran its cases (#13489).
1510+
*
1511+
* Guards the registrations made by `selfTest()` — the body whose case sink
1512+
* `t()` routes through `registerCase()`. It is called at that body's verdict
1513+
* site, after every battery has had its chance and before the success line, so
1514+
* that line can only be printed by a run in which the set of batteries that
1515+
* registered cases EQUALS the set declared, each at or above its own count. A
1516+
* set difference says WHICH battery stopped; a count says only that something
1517+
* did.
1518+
*
1519+
* @returns {string[]} floor breaches; empty means the floor held
1520+
*/
1521+
function batteryFloorFailures() {
1522+
const declared = Object.keys(SELF_TEST_BATTERIES);
1523+
const problems = [];
1524+
if (declared.length < SELF_TEST_BATTERY_FLOOR) {
1525+
problems.push(
1526+
`SELF_TEST_BATTERIES declares ${declared.length} batteries, below the pinned `
1527+
+ `${SELF_TEST_BATTERY_FLOOR} — a battery deleted from the roster takes its own floor with it.`,
1528+
);
1529+
}
1530+
for (const [name, count] of batterySeen) {
1531+
if (declared.includes(name)) continue;
1532+
problems.push(
1533+
`self-test battery "${name}" registered ${count} case(s) but is not declared in `
1534+
+ 'SELF_TEST_BATTERIES — a case attributed to no declared battery is one nothing floors.',
1535+
);
1536+
}
1537+
for (const name of declared) {
1538+
const count = batterySeen.get(name) ?? 0;
1539+
if (count >= SELF_TEST_BATTERIES[name]) continue;
1540+
problems.push(
1541+
count === 0
1542+
? `self-test battery "${name}" DID NOT RUN — 0 cases registered, ${SELF_TEST_BATTERIES[name]} pinned. `
1543+
+ 'The verdict below would have claimed those cases hold.'
1544+
: `self-test battery "${name}" registered ${count} case(s), below its pinned floor of `
1545+
+ `${SELF_TEST_BATTERIES[name]} — cases that used to run no longer do.`,
1546+
);
1547+
}
1548+
if (problems.length) {
1549+
problems.push(
1550+
'A battery at or below its floor means cases STOPPED RUNNING — the battery is the bug, not the '
1551+
+ 'number. Find what stopped registering (an early return, a deleted block, a guard that now '
1552+
+ 'skips, a loop that no longer reaches it) and restore it.',
1553+
);
1554+
}
1555+
return problems;
1556+
}
1557+
14231558
// Returned by `selfTest()` only after its verdict is printed. The dispatch
14241559
// refuses anything else: a `return` that leaves the function above that line
14251560
// prints nothing and still exits 0 — a self-test that never finished, reported
@@ -1428,7 +1563,17 @@ const SELF_TEST_VERDICT = 'bare-root-worklist self-test reached its verdict';
14281563

14291564
function selfTest() {
14301565
const failures = [];
1431-
const t = (label, ok) => { if (!ok) failures.push(label); };
1566+
// The one case sink, unchanged in what it judges: the only addition is that a
1567+
// case is COUNTED whether it holds or not, which is what lets the floor at the
1568+
// verdict site tell "held" from "never ran".
1569+
const t = (label, ok) => {
1570+
registerCase();
1571+
if (!ok) failures.push(label);
1572+
};
1573+
// Cases run before the first banner, so the first battery is opened at the
1574+
// top of the body and that banner carries no second opener — PR #13487's own
1575+
// shape, as batches 1b and 2 landed it.
1576+
battery('The FOLD: one row per literal, however many invocations reach it');
14321577

14331578
const files = trackedFiles();
14341579
const dirs = topLevelDirs(files);
@@ -1479,6 +1624,11 @@ function selfTest() {
14791624
//
14801625
// Every (invocation, file, constant, word) the derivation reaches, walked
14811626
// through the same predicates the sweep uses and with no dedupe of its own.
1627+
//
1628+
// ⚠️ This section's battery is opened at the TOP of the body, not here: the
1629+
// seven cases above run before any banner and have no section head of their
1630+
// own, so they are attributed to THIS battery rather than left unattributed.
1631+
// This banner therefore carries no second opener.
14821632
const perInvocation = new Set();
14831633
for (const [check, entry] of families) {
14841634
for (const file of entry.files ?? []) {
@@ -1563,6 +1713,7 @@ function selfTest() {
15631713
// takes a declaration, or a family is renamed, the verdict must come out with
15641714
// it. A verdict describing a row the sweep no longer finds is the shape that
15651715
// rots into an allowlist nobody re-reads, which #10840 refused by name.
1716+
battery('The triage coupling, both directions');
15661717
const stale = [...TRIAGE.keys()].filter((k) => !keys.has(k)).sort();
15671718
t(`no recorded verdict outlives its row${stale.length ? ` — STALE: ${stale.join(' · ')}. `
15681719
+ 'Delete the entry; do not re-point it at another row.' : ''}`, stale.length === 0);
@@ -1664,6 +1815,7 @@ function selfTest() {
16641815
// are joined rather than spelled, for the same reason the probes above take
16651816
// their root from the tree: a glob literal here would hand this file a
16661817
// population of its own.
1818+
battery('The MECHANISM a repaired reason turns on, held mechanically');
16671819
const PKG = 'packages';
16681820
const seg = (f) => f.split('/');
16691821
const underPkg = files.filter((f) => seg(f)[0] === PKG);
@@ -1712,6 +1864,7 @@ function selfTest() {
17121864
// zero-segment forms of `**`). A divergence means the record stopped
17131865
// describing the tree. ⛔ The remedy is to re-measure the ROW, never to relax
17141866
// `holds` until it agrees again.
1867+
battery('The RECORDED SPELLINGS, pinned: LIVENESS and PRECISION');
17151868
const spellingRows = [...TRIAGE.entries()].filter(([, v]) => v.spelling);
17161869
// The two verdicts whose whole content is a claim only a spelling records, so
17171870
// a record without one records nothing for the pins to hold. SPELLABLE-
@@ -1805,6 +1958,7 @@ function selfTest() {
18051958
// been removed. ⛔ When this reds the remedy is to re-measure
18061959
// the ROW -- never to extend `omits` until it agrees again, which is the same
18071960
// move as relaxing `holds`, refused above in as many words.
1961+
battery("The DECLARATION a row describes, read from the gate's own SOURCE");
18081962
const declaredHintsAt = (file, root) => {
18091963
const abs = join(ROOT, file);
18101964
if (!existsSync(abs)) return null;
@@ -1871,6 +2025,7 @@ function selfTest() {
18712025
// battery skips out of laziness. What CAN be held mechanically instead:
18722026
// every row's own internal shape, and that this table never collides with
18732027
// `TRIAGE`'s key space or contributes a population hint of its own.
2028+
battery('CENSUS_REFUSE_WIDE, pinned on its OWN terms (#14695)');
18742029
{
18752030
const overlap = [...CENSUS_REFUSE_WIDE.keys()].filter((k) => TRIAGE.has(k)).sort();
18762031
t(`no CENSUS_REFUSE_WIDE key collides with a TRIAGE key${overlap.length
@@ -1904,9 +2059,16 @@ function selfTest() {
19042059
+ 'each row was actually measured at instead of one shared field.' : ''}`, bases.size === 1);
19052060
}
19062061

2062+
// ── The assertion floor, at the verdict site (#13489) ─────────────────────
2063+
// The batteries above REGISTER but do not decide, so the floor over their
2064+
// registrations is evaluated here, into the same sink the cases use — the
2065+
// only place a run that registered nothing can still be stopped from
2066+
// reporting that every case held.
2067+
for (const breach of batteryFloorFailures()) failures.push(breach);
2068+
19072069
if (failures.length) {
19082070
for (const f of failures) console.error(` x self-test: ${f}`);
1909-
console.error(`\nbare-root-worklist --self-test: ${failures.length} failure(s).\n`);
2071+
console.error(`\nbare-root-worklist --self-test: ${failures.length} failure(s) (cases and floor).\n`);
19102072
process.exit(1);
19112073
}
19122074
console.log(

0 commit comments

Comments
 (0)