Skip to content

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

Description

@yinlianghui

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:

"build": {
  "dependsOn": ["^build"],
  "outputs": ["dist/**", ".next/**", "build/**", "**/*.tsbuildinfo", "!**/node_modules/**"],
  "env": ["NODE_ENV", "VITE_BASE_PATH", "OBJECTSTACK_CLIENT_DIST"]
}

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.

Suggested shape

Symmetric with #4176 and #4178:

  1. 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.
  2. 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.

Related


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions