chore(build): make turbo's typecheck inputs self-verifying, and lock two runtime assumptions into tsc - #9853
Conversation
…two runtime assumptions into tsc turbo.json's //#typecheck `inputs` list is a hand-maintained approximation of tsc's real transitive surface. Its own comment says so -- "a snapshot ... not a structural guarantee" -- and asks a human to "re-run the same grep ... before trusting this list again". Nobody re-runs a grep on request, and it HAD drifted. Four paths that src/+test/ statically import were unhashed: packages/loopover-mcp/lib/** (mcp-cli-error, mcp-gateway tests) packages/loopover-mcp/bin/** (mcp-cli-completion-spec imports CLI_COMMAND_SPEC) packages/loopover-miner/scripts/** (miner-benchmark, miner-env-reference tests) packages/discovery-index/scripts/** (validate-posthog-release test) Editing any of them could leave a stale cache HIT on a typecheck a real `tsc --noEmit` would fail -- the #5082 class this list exists to prevent. The bin/** case also falsified the comment's own stated reason for excluding it ("never a static import"), which is now corrected rather than left misleading. Add scripts/check-turbo-typecheck-inputs.ts: compute the reach every CI run instead of remembering it. A path is covered by a glob OR by a dependsOn build (turbo hashes a dependency's own inputs), so engine/contract sources are not false-positived. Paths that do not exist on disk are ignored -- the checker-test fixtures embed import statements inside STRINGS naming a package renamed away, which a naive scan reports as real reach. Also enable isolatedModules + verbatimModuleSyntax: both cost ZERO errors today (measured) and turn assumptions the runtime already makes into compile-time guarantees -- per-file transpilability for `--experimental-strip-types` and esbuild, and type-only imports that can never be silently elided from (or dragged into) the self-host bundle. Deliberately NOT enabling noImplicitReturns: 3 errors, and two are documented, intentional implicit-undefined switch arms. Churn for marginal value.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
loopover-ui | b69fa14 | Commit Preview URL Branch Preview URL |
Jul 29 2026, 03:16 PM |
|
Important 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏳ LoopOver is waiting…LoopOver has seen this pull request and is waiting on CI checks to finish before reviewing it. This comment will update once the review runs. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟨 Waiting |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9853 +/- ##
==========================================
- Coverage 91.74% 91.65% -0.09%
==========================================
Files 917 917
Lines 112894 112840 -54
Branches 27153 27131 -22
==========================================
- Hits 103576 103429 -147
- Misses 8034 8125 +91
- Partials 1284 1286 +2
Flags with carried forward coverage won't be shown. Click here to find out more. |
# Conflicts: # package.json
Bundle ReportBundle size has no change ✅ |
The find
turbo.json's//#typecheckinputsis a hand-maintained approximation of tsc's real transitive surface, and its own comment admits the hazard:Nobody re-runs a grep on request. It had already drifted — four statically-imported paths were unhashed:
packages/loopover-mcp/lib/**mcp-cli-error,mcp-gatewaytestspackages/loopover-mcp/bin/**mcp-cli-completion-spec(importsCLI_COMMAND_SPEC)packages/loopover-miner/scripts/**miner-benchmark,miner-env-referencetestspackages/discovery-index/scripts/**validate-posthog-releasetestEditing any of them could leave a stale cache HIT on a typecheck a real
tsc --noEmitwould fail — precisely the #5082 class this list exists to prevent.The
bin/**case is worse than an omission: it falsifies the comment's own stated reason for excluding it ("every test reference to it is a runtime path string … never a static import"). That was true when written; a later test made it false, and nothing noticed. Comment corrected rather than left misleading.The fix
scripts/check-turbo-typecheck-inputs.ts— run that grep every CI instead of remembering it. This is the maintainability point directly: a computed list rather than a remembered one.Two precision details that matter:
dependsOncounts as coverage.@loopover/engine#buildmeans turbo already hashes the engine's inputs, so engine/contract sources aren't false-positived. A checker that cried wolf here would be ignored within a week.packages/engine/..., a workspace renamed away. A naive scan reported those as real reach — a false positive whose "fix" would have been hashing a directory that doesn't exist.Also: two free tsc flags
isolatedModulesandverbatimModuleSyntax, both measured at zero errors today. They turn assumptions the runtime already makes into compile-time guarantees: per-file transpilability (what--experimental-strip-typesand esbuild already require) and type-only imports that can never be silently elided from — or dragged into — the self-host bundle that must have zerocloudflare:*imports.Deliberately not enabling
noImplicitReturnsdespite it costing only 3 errors: two are documented, intentional implicit-undefined switch arms ("Every other case implicitly returns undefined"). Churn against deliberate code for marginal value.Verification
Guard mutation-tested via 8 unit cases (drift reported,
dependsOncoverage, glob-narrower-than-reach, fixture-string exclusion, plus an invariant asserting this repo's own turbo.json stays covered so aturbo.jsonedit fails the suite too).turbo run typecheck --drystill resolves the graph. Full suite 25,332 passed;tsc,dead-source-files,import-specifiersgreen.