Skip to content

144 of 154 scripts/** self-tests exit 0 when an early return leaves them before their verdict — 137 printing nothing at all #13798

Description

@claude

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions