Skip to content

check-duration-unit-keys has no self-test battery floor: emptying its vocabulary DE-REGISTERS two cases, shrinking the battery 103 to 101 while the printed count stays non-zero #18512

Description

@os-warren

Filed by the domain:spec execution seat, session session_01KB5PFtxuy1x3dcR5gxudx6, 2026-09-16T17:26Z, out of the at-tier contract review of PR #18486 (card #18123), record 5701703741, flag F3 — 「ESCALATED, PM to file」. ⛔ Unlabelled beyond finding and unassigned; grading and routing are triage's.

The defect: a mutation can shrink the battery while the printed count stays non-zero

packages/spec/scripts/check-duration-unit-keys.ts predates the SELF_TEST_BATTERIES / floor / handshake discipline. It has no battery roster, no pinned per-battery minimum, and no module-level verdict flag — so a return above its verdict would print nothing and exit 0.

Measured, twice, on two different heads:

empty the DURATION_ROOTS map:
  at the PR head   103 registered  →  101 registered      (95 green + 6 red)
  at the prior head 101 registered →   99 registered      (94 green + 5 red)

⇒ the two per-root module-coupling cases are generated by iterating the map (for (const root of DURATION_ROOTS.keys())), so emptying the map de-registers them. The battery shrinks by 2 and the printed count is still a plausible non-zero number. ⭐ A reader watching the count would see 101 and conclude the suite ran; what actually happened is that two of its cases stopped existing.

⚠️ This is the 「a printed case count is EVIDENCE, NOT PROOF」 shape, and it is measured here rather than hypothesised. A floor would catch it; there is no floor.

Two residual vacuous cases, carried here rather than filed separately

The same review measured two cases that stay green under the vocabulary ablation while naming the vocabulary:

  • compliant by TYPE: name, describe and type all agree — expects '', which 0 sites also satisfies.
  • the declared duration units are units this reader actually knows — an every over an empty map, which is vacuously true.

⇒ population 2, same root cause (no floor, no handshake), so they belong in the same retrofit rather than in their own card.

⭐ For contrast, the case that was tightened in PR #18486 now discriminates: the old rulesOf(...).join() === '' read true on a site outside the population and true under ablation; the new assertion reads false on both and true only on the admitted DurationMs site. ⇒ the retrofit shape is known to work; it just has not been applied to the rest of the file.

What the round owes

  1. Give this gate the three parts scripts/check-agent-model-declared.mjs carries — SELF_TEST_BATTERIES, SELF_TEST_BATTERY_FLOOR, selfTestReachedVerdict — per AGENTS.md's 「Copy a landed one — ⛔ never import one」. ⚠️ Copy it, ⛔ do not import it: each self-test must keep running standalone as node scripts/<x>.mjs --self-test.
  2. Make the two vacuous cases above discriminate, using the tightening already landed in this file as the pattern.
  3. ⚠️ Prove the floor bites: with the roster in place, de-register a battery and show the run goes red on the floor rather than merely printing a smaller number. ⛔ A floor you never saw fire is the same defect one level up.

⛔ Scope fences

Dedupe words

check-duration-unit-keys SELF_TEST_BATTERIES · self-test floor retrofit duration-unit-keys · de-register case count · selfTestReachedVerdict · printed count is evidence not proof

Refs

#18123 / PR #18486 (where it was measured) · scripts/check-agent-model-declared.mjs (the landed pattern) · #18124 (step 3 on this same gate's vocabulary) · #18500 (dimensionless renderer half, the other owed half of this gate's mechanism — already filed, ⛔ not this card)


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions