fix(runtime): wire the test layer into check:test-typecheck, so its 214 test files are type-checked at all (#14504) - #14785
Merged
Conversation
…14 test files are type-checked at all (#14504) packages/runtime/tsconfig.json excluded **/*.test.ts and **/*.spec.ts while the package's typecheck script was a bare `tsc --noEmit` against that very config, so no tsc program anywhere read a runtime test file. Measured at 224f8ea with the closure built: the build config puts 899 files in the program and 0 of the package's 214 test files among them, while 79 non-test src/** files ARE there; the directional control (packages/drivers/driver-memory, no test exclusion) puts 40 of its 40 in. Under the new tsconfig.test.json the count is 214 of 214. Wired to the shared scripts/check-test-typecheck.mts, never copied, the way objectql / rest / lint / packages/plugins/** are wired. Strictness and rootDir inherited untouched; no test file is edited and no `any` or @ts-expect-error was added to open the gate. Seeded, not repaired, per this card's triage ruling: 191 errors over 27 files recorded EXACT and shrink-only in the new test-typecheck-debt.json; the other 187 test files carry no entry, so an error arriving in one of them is red. This is a CONVERSION of the coverage gate's existing @objectstack/runtime TEST_DEBT entry (errors: 206), which graduates here as the pairing forces: 206 - 19 config-tier + 4 newly exposed = 191, attributed with no remainder. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
… onboarded test program Onboarding `tsconfig.test.json` moves this package's PROGRAM SET, which since #11490 a package may do, so check:type-source-resolution's registry entry is re-measured rather than widened. Nine deps become visible, every one annotated `(via tsconfig.test.json)` by the gate itself and absent from a `--list` taken with the wiring reverted as the only difference between the two trees. Numbers stated in place per the registry's own condition 2, both from `--list` on the same checkout: 114 -> 115 programs, 270 -> 279 package-dep pairs, +0 entries, +0 non-clean packages. `paths` is deliberately not the tool here on the onboarding limb's measured grounds (PR #12570). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-trump
marked this pull request as ready for review
September 3, 2026 01:23
os-trump
enabled auto-merge
September 3, 2026 01:23
This was referenced Sep 3, 2026
This was referenced Sep 3, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14504
packages/runtime/tsconfig.jsonexcluded**/*.test.tsand**/*.spec.ts, and the package'stypecheckscript was a baretsc --noEmitagainst that very config — so no tsc program anywhere read a runtime test file, whilepnpm --filter @objectstack/runtime typecheckexited 0 and read as a pass.The premise, re-measured on current
mainrather than taken from the cardThe card and its triage both counted 208 test files at
ed44512; fourpackages/runtimePRs landed since, and the population is now 214. Everything else in the filing holds exactly. Measured at224f8ea4a0with the workspace closure built first — an error count taken against an unbuilt closure is not a reading:*.test.tsin programtsc --noEmit --listFiles -p packages/runtime/tsconfig.json(build config)-p tsconfig.test.json(this PR)The zero is the
excludeline and not a probe that sees nothing: 79 non-testsrc/**files ARE in the build program. Directional control —packages/drivers/driver-memory, whose tsconfig carries no test exclusion — puts 40 of its 40 test files in.Scope taken: wire and ledger, no repair — and the count that justifies it
191 errors across 27 files. The ruling is the card's own triage, not a narrowing invented here: "⛔ Do not fix the type errors the first measurement finds. Seed the ledger and let the ratchet shrink." Repairing 191 errors in the PR that opens the gate would bury the gate, which is how an onboarding stops landing. No test file is edited in this PR, so no file held by another open PR is touched.
Precedent followed: the wiring shape of
objectql,rest,lintand the fourteenpackages/plugins/**— the sharedscripts/check-test-typecheck.mtsis called, never copied.What changed
packages/runtime/tsconfig.test.json(new) — module semantics only, pluslib:module: esnext,moduleResolution: bundler,lib: ["ES2022"], matching how vitest actually executes these files. ⛔ Strictness is untouched and inherited;rootDirstays./src(measured: this layer produces no TS6059, unlikeclientandrest). Not oneanyand not one@ts-expect-errorwas added to any test file to open the gate.packages/runtime/test-typecheck-debt.json(new, generated) — 27 files / 191 errors / 69 signatures, EXACT and shrink-only. The other 187 test files carry no entry, so an error arriving in any of them is red on the PR that introduces it. Carries an authored_notewith the composition and the attribution.packages/runtime/package.json—typecheckbecomestsc --noEmit && pnpm check:test-typecheck, pluscheck:test-typecheckandgen:test-typecheck-debtbeside it. No new devDependency:tsxresolves from the workspace-root bin, the same waypackages/lintinvokes it (verified by reading the script PATH, not assumed).scripts/check-type-check-coverage.mjs— the@objectstack/runtimeTEST_DEBTentry (errors: 206) graduates, with the graduation documented in the block comment beside the four that graduated under [finding] No plugin package has a tsc program that compiles its tests — plugin-approvals alone hides 345 type errors, and 0 of 14 are in the test-typecheck ledger #14062 / [finding] packages/lint has no tsc program that compiles its tests — the 2,700-line rule pin file, receiver scan included, is type-checked by nobody #14173. ⛔ Nothing was paid down; the same population moved to a sharper instrument.scripts/check-type-source-resolution.mjs— a re-baseline on that registry's own onboarding limb (see below).scripts/regen-artifacts.mjs— the sixthtest-typecheck-debt.jsonrow, so a merge never recomputes this ledger on a half-merged tree..changeset/runtime-test-typecheck-wiring.md.206 to 191, attributed in both directions with no remainder
The same program under the build config's inherited NodeNext reports 206 — exactly the number the coverage gate already held for this package. So this is a conversion, not a new debt-opening decision.
Array.prototype.at).src/seed-loader.test.ts, previously masked by ananyfrom the unresolved import.206 - 19 + 4 = 191.
The registry re-baseline, on its own three conditions
Onboarding a
tsconfig.test.jsonmoves the package's PROGRAM SET, which since #11490 a package may do, andcheck:type-source-resolutionnames that case explicitly as a reviewed re-baseline rather than a widening.(via tsconfig.test.json)by the gate itself, and a--listtaken with the wiring reverted as the ONLY difference between the two trees reports the entry without any of the nine.--liston the same checkout: 114 to 115 programs, 270 to 279 package-dep pairs, +0 entries, +0 non-clean packages. Shrink-only from 279.pathsis deliberately not the tool, on the onboarding limb's measured grounds (PR build(rest): give the package a test-layer tsc program and ledger its 37 errors #12570): it would bill other packages' source diagnostics into a ledger those packages cannot see.One thing the card overstated, measured
Its sharpest line — "a
@ts-expect-errorwritten in anypackages/runtimetest today is a phantom check" — is about what WOULD happen, not an existing pin. This layer holds zero@ts-expect-errordirectives across all 214 files, and none reports TS2578 under the new program. The cost of the gap was the 191 unreported errors and the fact that a type-level pin could not be written in this package at all.Verification
Everything below on the final tree,
0a492f6bb6.Red-first, both ratchet directions, with the mutations proved on disk and the restores proved by blob identity under a
trap ... EXIT INT TERMon absolute paths:src/domains/actions-validation-envelope.test.ts, pure append (injected-marker-count=1,removed-text-count=0, bytes6706 -> 6852, blob81345b00d727 -> be093dd04637). Gate EXIT=1: "1 type error(s) in a file the ledger does not cover ... ⛔ MAINTAINER-ONLY, NOT a co-equal option: add the file to test-typecheck-debt.json."src/observability/metrics.test.ts, same discipline (blob9384d284b0a8 -> 2b15c61ad383). Gate EXIT=1: "1 type error(s) carrying a signature the ledger does not record — ARRIVED: TS2322 ..."81345b00d727,9384d284b0a8), marker count 0,git diff HEADempty.Gates.
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commandsderives 49 commands at0a492f6bb6(7 paths vs merge base224f8ea4a). All 49 run with each exit captured before any pipe; 47 exit 0. The two non-zero are prerequisite verdicts in the gates' own words and are NOT MEASURED, neither a pass nor a red:check-test-completeness.mjs— EXIT=3, "Nothing was measured: this gate exited before parsing a single summary line ... ⛔ It is NOT a finding" (it needs a savedturbo run testlog).scripts/pm/check-half-states.mjs— EXIT=3, "Treat this exit as an unread instrument, never as a quiet board" (repo-scoped GitHub REST is 403 for this session).check:type-check-debtandcheck:dual-build-cjs-loadsfirst returned their own prerequisite verdict ("Runpnpm buildfirst. ⛔ This is NOT a pass"); the full closure was then built (turbo run build --filter='./packages/*'and--filter='./packages/*/*', 57 + 70 tasks, exit 0) and both re-run green —--re-measure: OK — 21 ledger entr(ies) re-measured in 157.8s, 549 raw tsc error(s) total, none above its recorded number.Package.
pnpm --filter @objectstack/runtime typecheckexit 0 — the full new chain, self-test included.vitest run --maxWorkers=2: 214 test files / 3121 tests, all passing.Whole repo.
pnpm lint(eslint . --no-inline-config) exit 0, unnarrowed.check:nul-bytesOK over 8055 tracked text files.All heavy runs went through
scripts/pm/os-verify-lock.sh; verdicts read from itsVERDICTline, never a bare$?.🤖 Generated with Claude Code
https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
Generated by Claude Code