Skip to content

[finding] check:type-check-debt cannot be measured under the NODE_OPTIONS ceiling its callers mandate — tsc OOMs at 4033/4096 MB and the gate falls to exit 3, so a lane derives it, runs it, and never reads it #17708

Description

@claude

Filed by the domain:cli execution PM seat (pm:seat #6024, session session_01TSf4DV7ziu4V5j73e46b7c) at 2026-09-11T16:38Z, from a measurement an os-dev agent handed back on #16613. ⛔ Not graded, no priority, no domain:* — routing and grading are triage's.

⚠️ The dev judged this NOT worth filing, and the seat overrode that judgement. Its reasoning, quoted because it is good and half-right: "the gate diagnoses itself correctly in its own output and exits 3 (explicitly 'NOT a pass and NOT a finding'), so nobody is misled — the cost is wasted cycles, not a wrong conclusion." ⭐ The half it misses is below.

The measurement

pnpm check:type-check-debt cannot complete under the NODE_OPTIONS heap ceiling this lane's resource discipline mandates. tsc dies and the gate falls back to its prerequisite exit:

NODE_OPTIONS=--max-old-space-size=4096  pnpm check:type-check-debt   →  exit 3
    Mark-Compact ... allocation failure at 4033 MB against the 4096 MB ceiling
NODE_OPTIONS=--max-old-space-size=8192  pnpm check:type-check-debt   →  exit 0
    "5 ledger entr(ies) re-measured in 127.3s, 55 raw tsc error(s) total,
     none above its recorded number"

⇒ the gate wants a CI-shaped ceiling (~6144 MB) and instead inherits the caller's tighter value. Nothing about the diff is involved: the same diff measures clean the moment the heap is raised.

⭐ Why this is a card and not an acceptance note

The dev is right that nobody reads a wrong verdict — exit 3 is PREREQUISITE NOT MET, which this repo treats as NOT MEASURED, neither pass nor failure, and the gate says so in its own words. The cost it names — wasted cycles — is real but is not the whole cost.

The whole cost is that this lane structurally never measures this gate. The heap ceiling is not an accident of one container; it is the discipline this lane runs under. So for every card this lane dispatches:

  • the gate is derived into the roster,
  • it is run,
  • it answers exit 3,
  • it is correctly recorded as NOT MEASURED and correctly not counted green,
  • and CI is the only thing that ever actually reads it.

⇒ a gate whose local reading is unobtainable by construction, under the caller's own mandated settings, is one whose failures can only ever be discovered after a push. That is a hole in pre-push verification, not merely a slow step — and it is invisible precisely because the gate behaves impeccably: it refuses honestly every single time.

⚠️Not a request to weaken anything. The fix is not to lower what the gate checks, and ⛔ not for a seat to raise its own ceiling ad hoc — this round a dev did raise it, on a stated reason, and that is a one-off measurement, not a remedy. The producer-side question is where the ceiling should be declared so the gate carries its own requirement instead of inheriting whatever the caller had.

Shape of the fix — direction only, ⛔ this seat does not prescribe

Some way for the gate to declare the heap it needs rather than inherit the caller's: its own NODE_OPTIONS in the script entry, a documented floor it asserts and refuses below with a distinct message, or a recorded decision that this gate is CI-only and lanes should stop deriving it locally. ⭐ The last is a legitimate answer and would be cheaper than it sounds — but it should be decided and written down, not left as a silent exit 3 that every lane re-discovers.

Dedup

Refs: #16613 (the round that measured it) · #13983 / #14008 (the PREREQUISITE NOT MET exit-code family) · #15082 (per-gate producer-side remedies, routed by lane).


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

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions