Skip to content

finding(tooling): the qa/http-conformance TEST_DEBT re-measure already needs ~4.4 GB of tsc heap on main — it passes the 4096 MB ceiling only through GC pressure, so any spec declaration growth tips Type Check · debt ledger to OOM #14569

Description

@hotlong

Found while driving PR #14513 (#14439) to green. Filed for the maintainer because the ceiling is a pinned policy (CI_TSC_HEAP_CEILING_MB = 4096, #12856) and changing what the program checks changes what the ledger measures.

Measured

scripts/check-type-check-coverage.mjs --re-measure builds one tsc --noEmit program per ledger entry under --max-old-space-size=4096. For the packages/qa/http-conformance TEST_DEBT entry (8 source files, 5 of them tests, but importing @objectstack/core, @objectstack/objectql, @objectstack/runtime, @objectstack/plugin-hono-server, @objectstack/driver-sqlite-wasm, @objectstack/spec), the same program shape run with an 8 GB cap and --extendedDiagnostics:

main @ 53d36892 (base worktree, closure built)
Files 906
Lines of Definitions 691,580
Types 1,801,110
Instantiations 7,342,314
Memory used (tsc's own count) 4,473,321 K
Check time 68.9 s

Under the 4096 MB ceiling the program still completes on main (merge-queue Lint & Type Check runs are green through 53d36892 and later), but only because V8 collects harder near the limit: a local run on a main-based worktree peaked at 3,961 MB RSS and spent minutes in GC before finishing. The headroom is therefore a few percent, not a margin.

PR #14513 showed what that means in practice: a spec change that added 42,622 lines of definitions to this program (the whole ObjectStackDefinitionSchema declaration, pulled in through a new chunk edge — fixed in the PR) moved the count to 4,875,249 K and the lane went red twice. The next spec PR that grows the declaration graph seen by @objectstack/spec/system will hit the same wall without having done anything wrong.

Options

Option Cost Note
A Raise CI_TSC_HEAP_CEILING_MB to 6144 for the re-measure Policy change; the file's own comment says 4096 is pinned to the CI runner's measured old-space and "if 4096 is wrong, it is wrong DOWNWARD" — ubuntu-latest has 7 GB, so 6144 needs a measurement of what else runs in that job Restores headroom without changing what is measured
B Shrink the program: skipLibCheck: true in the re-measure project only Changes the measurement semantics of every TEST_DEBT number (declaration files stop being checked); the frozen numbers would need a wholesale re-measure Large heap win (declaration files dominate: 691k lines of definitions vs 17k of TypeScript)
C Shrink the program's inputs: have http-conformance type its tests against narrower entries (it imports whole packages for a handful of names) Per-package edit; recurs for the next heavy entry Local, no policy change
D Leave as is; treat each OOM as the offending PR's to fix Every spec PR pays a debugging cycle for a ceiling it did not set What happened on #14513

Not decided here. The four-axis reading favours A with a measured number (long-term consistency: the ceiling exists to make numbers portable, and a ceiling with 3% headroom makes them fragile instead; scope: one constant, one measurement of the runner). B is the only option that changes ledger semantics and should not ride a spec PR.

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

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions