You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
turbo build inputs have the same out-of-package hole as #3514 / #4178 — root tsconfig.json / tsconfig.base.json and scripts/vite-*.ts are not hashed; measured frozen at 3f85d1417964dce6 #4185
Found by the task sweep #4178 asked for ("any OTHER turbo task with out-of-package program files — MEASURE"). Filed unassigned; not fixed in the PR for #4178, which is scoped to the test task.
The gap
Same mechanism as #3514 (PR #4176) and #4178: turbo hashes a task from its inputs, $TURBO_DEFAULT$ covers only files inside the package directory, and globalDependencies is unset, so any file the task reads from elsewhere in the repo is invisible to the cache key and turbo replays the previous verdict.
build declares no inputs at all and so runs on turbo's default:
Two out-of-package reads are already known to this repo from the type-check work, and both apply to build as well:
Nearly every package's tsconfig.json extends the repo-root tsconfig.json (and examples/byo-backend-console extends the root tsconfig.base.json). ci(turbo): derive the type-check inputs guard from each package's tsc program (#3514) #4176 added both to type-check's inputs for exactly this reason — compiler options are as load-bearing as source. build never got them.
apps/console/vite.config.ts imports ../../scripts/vite-crypto-stub.ts and ../../scripts/vite-maplibre-worker.ts. type-check covers these with $TURBO_ROOT$/scripts/vite-*.ts; build, which is the task that actually runs that Vite config, does not.
Measured
On claude/issue-4178-turbo-test-inputs (which changes only the test task, so this measurement is of main's build):
$ npx turbo run build --filter @object-ui/core --dry=json
baseline 3f85d1417964dce6
after touching tsconfig.json 3f85d1417964dce6 <- frozen
after touching tsconfig.base.json 3f85d1417964dce6 <- frozen
$ npx turbo run build --filter @object-ui/console --dry=json
baseline e6c5943a3e062002
after touching scripts/vite-crypto-stub.ts
e6c5943a3e062002 <- frozen
Not local-only: .github/workflows/ci.yml and .github/workflows/performance-budget.yml both run turbo run build and persist .turbo/cache through actions/cache, so a stale artifact verdict travels between runs.
Arguably the highest-stakes of the three instances, because build produces the dist/ that every other task consumes — test and type-check both declare dependsOn: ["^build"]. A build replayed from a cache key that ignored a strict flip in the root tsconfig hands stale dist/ to everything downstream.
Give build an explicit inputs list carrying at minimum $TURBO_ROOT$/tsconfig.json, $TURBO_ROOT$/tsconfig.base.json and $TURBO_ROOT$/scripts/vite-*.ts. Note that adding an inputs list at all is a behavior change worth thinking about: the default is currently $TURBO_DEFAULT$, and an explicit list must not accidentally narrow what is already covered.
Derive rather than pin. The shared plumbing exists at scripts/__tests__/helpers/turbo-inputs.ts after turbo test inputs have the same out-of-package hole #3514 closed for type-check — the root vitest.config.mts every package re-exports is not hashed #4178, and the build program is a union of the two derivations already written: the tsc side (turbo-type-check-inputs.test.ts) and the Vite-config side (helpers/vitest-config-program.ts, which already walks a vite.config.ts import chain — @object-ui/plugin-ai and friends resolve their Vitest config to exactly that file). The open question is which of a package's build scripts drive tsc vs Vite, since build scripts are more varied than type-check scripts.
Whether the fix is the inputs list alone or the list plus a derivation guard is a maintainer/PM call, as it was for #3514 and #4178.
Found by the task sweep #4178 asked for ("any OTHER turbo task with out-of-package program files — MEASURE"). Filed unassigned; not fixed in the PR for #4178, which is scoped to the
testtask.The gap
Same mechanism as #3514 (PR #4176) and #4178: turbo hashes a task from its
inputs,$TURBO_DEFAULT$covers only files inside the package directory, andglobalDependenciesis unset, so any file the task reads from elsewhere in the repo is invisible to the cache key and turbo replays the previous verdict.builddeclares noinputsat all and so runs on turbo's default:Two out-of-package reads are already known to this repo from the
type-checkwork, and both apply tobuildas well:tsconfig.jsonextends the repo-roottsconfig.json(andexamples/byo-backend-consoleextends the roottsconfig.base.json). ci(turbo): derive the type-check inputs guard from each package's tsc program (#3514) #4176 added both totype-check's inputs for exactly this reason — compiler options are as load-bearing as source.buildnever got them.apps/console/vite.config.tsimports../../scripts/vite-crypto-stub.tsand../../scripts/vite-maplibre-worker.ts.type-checkcovers these with$TURBO_ROOT$/scripts/vite-*.ts;build, which is the task that actually runs that Vite config, does not.Measured
On
claude/issue-4178-turbo-test-inputs(which changes only thetesttask, so this measurement is ofmain'sbuild):Not local-only:
.github/workflows/ci.ymland.github/workflows/performance-budget.ymlboth runturbo run buildand persist.turbo/cachethroughactions/cache, so a stale artifact verdict travels between runs.Arguably the highest-stakes of the three instances, because
buildproduces thedist/that every other task consumes —testandtype-checkboth declaredependsOn: ["^build"]. A build replayed from a cache key that ignored astrictflip in the root tsconfig hands staledist/to everything downstream.Suggested shape
Symmetric with #4176 and #4178:
buildan explicitinputslist carrying at minimum$TURBO_ROOT$/tsconfig.json,$TURBO_ROOT$/tsconfig.base.jsonand$TURBO_ROOT$/scripts/vite-*.ts. Note that adding aninputslist at all is a behavior change worth thinking about: the default is currently$TURBO_DEFAULT$, and an explicit list must not accidentally narrow what is already covered.scripts/__tests__/helpers/turbo-inputs.tsafter turbotestinputs have the same out-of-package hole #3514 closed fortype-check— the rootvitest.config.mtsevery package re-exports is not hashed #4178, and thebuildprogram is a union of the two derivations already written: the tsc side (turbo-type-check-inputs.test.ts) and the Vite-config side (helpers/vitest-config-program.ts, which already walks avite.config.tsimport chain —@object-ui/plugin-aiand friends resolve their Vitest config to exactly that file). The open question is which of a package's build scripts drive tsc vs Vite, sincebuildscripts are more varied thantype-checkscripts.Whether the fix is the inputs list alone or the list plus a derivation guard is a maintainer/PM call, as it was for #3514 and #4178.
Related
type-check的手维护 inputs 名单已两次因"包程序越出包目录"失真 —— 评估从 tsconfig include 派生或加钉扎测试 #3514 / PR ci(turbo): derive the type-check inputs guard from each package's tsc program (#3514) #4176 —type-check, with the full measurement and the guard architecture.testinputs have the same out-of-package hole #3514 closed fortype-check— the rootvitest.config.mtsevery package re-exports is not hashed #4178 —test, same mechanism; its sweep is what found this.lintinputs have the same out-of-package hole as #3514 / #4178 — the rooteslint.config.jsthat IS the lint program is not hashed; measured frozen at 79872f192ee4828c #4184 — the sibling finding on thelinttask.Generated by Claude Code