Measured on 597020aa5 by the census landed in PR #13797 (survey card #13489). Filed unassigned.
The reading
node scripts/measure-self-test-floor.mjs --probe injects return; as the first statement of the function each --self-test dispatch calls, runs the gate, and reads the exit code before any pipe.
144 of 154 measured gates exit 0. 137 of those print nothing at all. A self-test that never finished reports as a self-test that passed.
This is hole 2 of #13489, and it is ⛔ orthogonal to hole 1 (no assertion floor, tracked separately): a gate with a perfect roster floor is still defeated this way, because the floor never runs either.
The remedy, already validated twice
The boundary-only half of the PR #13487 shape. Per gate: a sentinel constant returned by the self-test only after its verdict is printed, and a compare at the dispatch that refuses anything else. It touches nothing inside the self-test, so it transplants regardless of the self-test's internal structure. Landed verbatim on scripts/check-self-test-wired.mjs and scripts/check-self-test-workflow-commands.mjs in PR #13797, ablation recorded on each.
What the grep does not catch, and must not be trusted for
return selfTest() is one spelling of three measured in this tree:
process.exit(selfTest()) — an early bare return yields undefined, and process.exit(undefined) is exit 0. This shape reads like a handshake and is not one.
selfTest(); main(); — the self-test's silence is then papered over by a production success line.
if (--self-test) selfTest(); else main(); — nothing printed, exit 0.
Take candidates with the grep; decide with the probe.
Boundary
⛔ Not the empty-scan class (#13014). scripts/check-adr-links.mjs and scripts/check-doc-anchors.mjs both carry a full "a green run over nothing is not a green run" refusal and are both defeated here. Neither class covers for the other.
Notes for whoever takes this
Generated by Claude Code
Measured on
597020aa5by the census landed in PR #13797 (survey card #13489). Filed unassigned.The reading
node scripts/measure-self-test-floor.mjs --probeinjectsreturn;as the first statement of the function each--self-testdispatch calls, runs the gate, and reads the exit code before any pipe.144 of 154 measured gates exit 0. 137 of those print nothing at all. A self-test that never finished reports as a self-test that passed.
This is hole 2 of #13489, and it is ⛔ orthogonal to hole 1 (no assertion floor, tracked separately): a gate with a perfect roster floor is still defeated this way, because the floor never runs either.
The remedy, already validated twice
The boundary-only half of the PR #13487 shape. Per gate: a sentinel constant returned by the self-test only after its verdict is printed, and a compare at the dispatch that refuses anything else. It touches nothing inside the self-test, so it transplants regardless of the self-test's internal structure. Landed verbatim on
scripts/check-self-test-wired.mjsandscripts/check-self-test-workflow-commands.mjsin PR #13797, ablation recorded on each.What the grep does not catch, and must not be trusted for
return selfTest()is one spelling of three measured in this tree:process.exit(selfTest())— an early barereturnyieldsundefined, andprocess.exit(undefined)is exit 0. This shape reads like a handshake and is not one.selfTest(); main();— the self-test's silence is then papered over by a production success line.if (--self-test) selfTest(); else main();— nothing printed, exit 0.Take candidates with the grep; decide with the probe.
Boundary
⛔ Not the empty-scan class (#13014).
scripts/check-adr-links.mjsandscripts/check-doc-anchors.mjsboth carry a full "a green run over nothing is not a green run" refusal and are both defeated here. Neither class covers for the other.Notes for whoever takes this
scripts/pm/dispatch-gates.mjsis NOT MEASURED, not clean: the injection anchor lands inside a template literal and produces a SyntaxError.node scripts/measure-self-test-floor.mjs --proberather than re-deriving the number.Generated by Claude Code