Skip to content

Commit e6ac0c6

Browse files
os-trumpclaude
andauthored
fix(runtime): wire the test layer into check:test-typecheck, so its 214 test files are type-checked at all (#14504) (#14785)
* fix(runtime): wire the test layer into check:test-typecheck, so its 214 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 * fix(runtime): re-baseline the type-source-resolution registry for the 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 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 36a8adb commit e6ac0c6

7 files changed

Lines changed: 370 additions & 24 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
"@objectstack/runtime": patch
3+
---
4+
5+
fix(runtime): wire `packages/runtime`'s test layer into `check:test-typecheck`, so its 214 test files are type-checked at all (#14504)
6+
7+
`packages/runtime/tsconfig.json` excluded `**/*.test.ts` and `**/*.spec.ts`, and
8+
the package's `typecheck` script was a bare `tsc --noEmit` against that very
9+
config — so no gate anywhere read a runtime test file with a type checker.
10+
Measured at `224f8ea4a0` with the workspace closure built first, rather than
11+
read off the config: `tsc --noEmit --listFiles -p tsconfig.json` puts 899 files
12+
in the program and **0** of the package's 214 `src/**/*.test.ts` among them,
13+
while 79 of its non-test `src/**` files ARE there — so the zero is the
14+
`exclude` line, not a probe that sees nothing. The directional control is
15+
`packages/drivers/driver-memory`, whose tsconfig carries no test exclusion: the
16+
same probe puts 40 of its 40 test files in the program. Under the new
17+
`tsconfig.test.json` the count is **214 of 214**.
18+
19+
Onboarded by *wiring* to the shared mechanism (`scripts/check-test-typecheck.mts`)
20+
the way `objectql`, `rest`, `lint` and the fourteen `packages/plugins/**` are
21+
wired, never by copying it: a sibling `tsconfig.test.json` matching vitest's
22+
real module semantics (`module: esnext`, `moduleResolution: bundler`,
23+
`lib: ["ES2022"]`), named by `typecheck` via `check:test-typecheck --project`.
24+
Strictness and `rootDir` are untouched and inherited; not one `any` and not one
25+
`@ts-expect-error` was added to any test file to open the gate.
26+
27+
**Seeded, not repaired, per this card's triage ruling.** The layer reports 191
28+
errors across 27 files and they are recorded EXACT and shrink-only in the new
29+
`test-typecheck-debt.json`. Every one is pre-existing: no test file is edited
30+
here. The other 187 files carry no entry, so any error they gain is red on
31+
arrival.
32+
33+
This is a CONVERSION rather than a new debt-opening decision. The same program
34+
under the build config's inherited NodeNext reports 206 — exactly the number
35+
`scripts/check-type-check-coverage.mjs` already held for this package in its
36+
per-PACKAGE `TEST_DEBT` ledger — and that entry graduates here, as the pairing
37+
forces. The 206 → 191 step is attributed in both directions with no remainder:
38+
−19 config-tier diagnostics that dissolve under vitest's module semantics
39+
(TS2835 ×13, the TS7006 ×4 cascading above them, TS2550 ×2) and +4 that
40+
collapsing the cascade exposed (TS2322 ×4 in `src/seed-loader.test.ts`,
41+
previously masked by an `any` from the unresolved import).

packages/runtime/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
"scripts": {
2222
"build": "tsup --config tsup.config.ts && node ../../scripts/check-dts-emitted.mjs",
2323
"dev": "tsc -w",
24-
"typecheck": "tsc --noEmit",
24+
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
25+
"check:test-typecheck": "tsx ../../scripts/check-test-typecheck.mts --self-test && tsx ../../scripts/check-test-typecheck.mts --package packages/runtime --project tsconfig.test.json",
26+
"gen:test-typecheck-debt": "tsx ../../scripts/check-test-typecheck.mts --update --package packages/runtime --project tsconfig.test.json",
2527
"test": "vitest run"
2628
},
2729
"dependencies": {
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
{
2+
"_comment": "Per-file tsc error debt of the @objectstack/runtime TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/runtime gen:test-typecheck-debt",
3+
"_note": "SEEDED, NOT REPAIRED, and that was the card's own triage ruling rather than this author's convenience: 191 errors across 27 of this package's 214 test files, measured at 224f8ea4a0 with the workspace closure built first, on the PR that first put those files in front of tsc. Repairing them in the same change would have buried the gate under a 191-error cleanup, which is how an onboarding stops landing; the ratchet only has to shrink from here. WHERE THE 191 CAME FROM, both directions attributed: the same program under the build config's inherited NodeNext semantics reports 206, and 206 is exactly what `scripts/check-type-check-coverage.mjs` had recorded for this package in its per-PACKAGE `TEST_DEBT` ledger — so this file does not add debt, it holds the SAME population one level finer, per file and per signature, and that `TEST_DEBT` entry graduated in the same change. 19 of the 206 dissolve under this program's vitest-matching module semantics (TS2835 x13 extension-less relative imports, the TS7006 x4 above them, TS2550 x2 `Array.prototype.at`) and were about the CHECK rather than the code; collapsing that cascade EXPOSED 4 more (TS2322 x4 in src/seed-loader.test.ts, previously hidden behind an `any` from the unresolved import). 206 - 19 + 4 = 191, with no unexplained remainder. WHAT IS ALREADY GATED, and it is most of the package: 187 of the 214 test files carry no entry here at all, so any error any one of them gains is red on arrival. ⚠️ This layer holds ZERO `@ts-expect-error` directives — measured, not assumed — so unlike packages/spec and packages/client no pin was silently dead here and none reports TS2578 under this 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; the second half is what this file makes possible. THE PILE IS CONCENTRATED, which is the useful thing for whoever pays it down: src/http-dispatcher.actions-type-dispatch.test.ts x30, src/http-dispatcher.test.ts x18, src/notifications.hono.integration.test.ts x16, src/http-dispatcher.actions-identity-addressing.test.ts x14 and src/action-body-identity.test.ts x14 are 92 of the 191, and TS18048 x91 (reads of a possibly-undefined optional) is very nearly half of the whole ledger on its own — the shape src/http-dispatcher.keys.test.ts already solved with a `responseOf()` narrowing helper. RECORDED EXACTLY, no bootstrap margin: this layer has never been gated, so the first new error in it should go red rather than be absorbed.",
4+
"entries": {
5+
"src/action-body-identity.test.ts": {
6+
"TS18048: 'actionCtx' is possibly 'undefined'.": 8,
7+
"TS2339: Property 'executionContext' does not exist on type 'never'.": 1,
8+
"TS2493: Tuple type '…' of length '0' has no element at index '2'.": 5
9+
},
10+
"src/action-execution-calldata-query.test.ts": {
11+
"TS2322: Type '…' is not assignable to type '…'.": 1
12+
},
13+
"src/auth-unknown-subpath.hono.integration.test.ts": {
14+
"TS2353: Object literal may only specify known properties, and 'requireAuth' does not exist in type 'DispatcherPluginConfig'.": 1,
15+
"TS2571: Object is of type 'unknown'.": 1
16+
},
17+
"src/dispatcher-plugin.anonymous-gate.integration.test.ts": {
18+
"TS2339: Property 'data' does not exist on type '…'.": 1,
19+
"TS2493: Tuple type '…' of length '0' has no element at index '1'.": 1
20+
},
21+
"src/dispatcher-plugin.ready.integration.test.ts": {
22+
"TS18046: 'body' is of type 'unknown'.": 8
23+
},
24+
"src/domains/automation-descriptor-query-validation.test.ts": {
25+
"TS2339: Property 'field' does not exist on type '…'.": 1
26+
},
27+
"src/domains/automation-write-capability-gate.test.ts": {
28+
"TS2348: Value of type '…' is not callable. Did you mean to include 'new'?": 1
29+
},
30+
"src/domains/meta-item-envelope.test.ts": {
31+
"TS18048: 'res.response' is possibly 'undefined'.": 9
32+
},
33+
"src/domains/meta-migrate-stored.test.ts": {
34+
"TS18048: 'res.response' is possibly 'undefined'.": 6
35+
},
36+
"src/domains/meta-object-fls.test.ts": {
37+
"TS18048: 'res.response' is possibly 'undefined'.": 4
38+
},
39+
"src/error-envelope.conformance.test.ts": {
40+
"TS2345: Argument of type '…' is not assignable to parameter of type '…'.": 6
41+
},
42+
"src/http-dispatcher.actions-identity-addressing.test.ts": {
43+
"TS18048: 'res.response' is possibly 'undefined'.": 14
44+
},
45+
"src/http-dispatcher.actions-type-dispatch.test.ts": {
46+
"TS18048: 'res.response' is possibly 'undefined'.": 24,
47+
"TS2493: Tuple type '…' of length '0' has no element at index '1'.": 6
48+
},
49+
"src/http-dispatcher.kernel-resolver.test.ts": {
50+
"TS2352: Conversion of type 'undefined' to type 'HttpProtocolContext' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.": 1,
51+
"TS2493: Tuple type '…' of length '0' has no element at index '0'.": 1,
52+
"TS2493: Tuple type '…' of length '1' has no element at index '1'.": 1
53+
},
54+
"src/http-dispatcher.keys.test.ts": {
55+
"TS18048: 'res.response' is possibly 'undefined'.": 9
56+
},
57+
"src/http-dispatcher.mcp.test.ts": {
58+
"TS18048: 'res.response' is possibly 'undefined'.": 11
59+
},
60+
"src/http-dispatcher.test.ts": {
61+
"TS18048: 'mint.response' is possibly 'undefined'.": 1,
62+
"TS18048: 'res.response' is possibly 'undefined'.": 5,
63+
"TS2339: Property 'chat' does not exist on type '…'.": 1,
64+
"TS2339: Property 'execute' does not exist on type '…'.": 1,
65+
"TS2339: Property 'getLocales' does not exist on type '…'.": 2,
66+
"TS2339: Property 'listFlows' does not exist on type '…'.": 1,
67+
"TS2339: Property 'listInbox' does not exist on type '…'.": 1,
68+
"TS2339: Property 'provider' does not exist on type '…'.": 1,
69+
"TS2339: Property 'registerFlow' does not exist on type '…'.": 1,
70+
"TS2339: Property 'route' does not exist on type '…'.": 1,
71+
"TS2339: Property 'trigger' does not exist on type '…'.": 1,
72+
"TS2339: Property 'user' does not exist on type 'never'.": 1,
73+
"TS2493: Tuple type '…' of length '0' has no element at index '2'.": 1
74+
},
75+
"src/notification-schema-conformance.integration.test.ts": {
76+
"TS18046: 'body' is of type 'unknown'.": 1,
77+
"TS2353: Object literal may only specify known properties, and 'requireAuth' does not exist in type 'DispatcherPluginConfig'.": 1
78+
},
79+
"src/notification-schema-conformance.test.ts": {
80+
"TS18046: 'f' is of type 'unknown'.": 1
81+
},
82+
"src/notifications.hono.integration.test.ts": {
83+
"TS18046: 'after' is of type 'unknown'.": 2,
84+
"TS18046: 'afterOne' is of type 'unknown'.": 1,
85+
"TS18046: 'before' is of type 'unknown'.": 2,
86+
"TS18046: 'body' is of type 'unknown'.": 1,
87+
"TS18046: 'cleared' is of type 'unknown'.": 2,
88+
"TS18046: 'list' is of type 'unknown'.": 4,
89+
"TS18046: 'readAll' is of type 'unknown'.": 1,
90+
"TS2353: Object literal may only specify known properties, and 'requireAuth' does not exist in type 'DispatcherPluginConfig'.": 1,
91+
"TS2571: Object is of type 'unknown'.": 2
92+
},
93+
"src/observability/error-reporter.test.ts": {
94+
"TS2554: Expected 0 arguments, but got 2.": 1
95+
},
96+
"src/observability/metrics.test.ts": {
97+
"TS2554: Expected 0 arguments, but got 1.": 1,
98+
"TS2554: Expected 0 arguments, but got 2.": 2
99+
},
100+
"src/route-parity.integration.test.ts": {
101+
"TS18046: 'disc' is of type 'unknown'.": 4,
102+
"TS2339: Property 'data' does not exist on type '…'.": 1,
103+
"TS2353: Object literal may only specify known properties, and 'requireAuth' does not exist in type 'DispatcherPluginConfig'.": 1
104+
},
105+
"src/runtime.test.ts": {
106+
"TS6133: 'PluginContext' is declared but its value is never read.": 1,
107+
"TS6133: 'beforeEach' is declared but its value is never read.": 1
108+
},
109+
"src/sandbox/quickjs-runner.test.ts": {
110+
"TS2345: Argument of type '…' is not assignable to parameter of type '…'.": 4,
111+
"TS6133: 'n' is declared but its value is never read.": 1
112+
},
113+
"src/security/resolve-execution-context.test.ts": {
114+
"TS2322: Type '…' is not assignable to type 'never'.": 1,
115+
"TS2339: Property '$in' does not exist on type 'object'.": 2,
116+
"TS7006: Parameter 'object' implicitly has an 'any' type.": 1,
117+
"TS7006: Parameter 'opts' implicitly has an 'any' type.": 1,
118+
"TS7006: Parameter 'ql' implicitly has an 'any' type.": 1,
119+
"TS7006: Parameter 'row' implicitly has an 'any' type.": 1,
120+
"TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ sys_api_key: { id: string; key: string; revoked: boolean; user_id: string; active_organization_id: string; expires_at: string; }[]; sys_member: { user_id: string; organization_id: string; role: string; }[]; ... 4 more ...; sys_user_position: never[]; }'.": 1
121+
},
122+
"src/seed-loader.test.ts": {
123+
"TS2322: Type '…' is not assignable to type '…'.": 4,
124+
"TS6133: 'result' is declared but its value is never read.": 2,
125+
"TS6133: 'type' is declared but its value is never read.": 1,
126+
"TS6196: 'SeedLoaderRequest' is declared but never used.": 1
127+
}
128+
}
129+
}

0 commit comments

Comments
 (0)