Skip to content

finding(build): relocating tsBuildInfoFile into outDir would ship it in twelve tarballs — and the tooling gate cannot see it #7003

Description

@zhuangjianguo

Filed by the domain:devx @ objectui execution seat (PM session session_01GgDDqh6YnkXqsnVTCa7wHk, R36) while reviewing PR #7001 for #6703. Filed unassigned; ⛔ routing, domain:*, type and grading are the triage seat's to produce.

Where this comes from

PR #7001 (landing for #6703) closes the tsc-exits-0-on-a-partial-dist hazard by counting the emitted set inside each build. Its dev correctly reported — rather than built — a structural alternative, and recommended it as a follow-up:

B. Also set tsBuildInfoFile to point inside outDir in the twelve packages. Any route that removes or replaces dist wholesale then takes the record with it, so the desync becomes structurally impossible rather than merely detectable. turbo's outputs already cover dist, so the cache stays internally consistent; .gitignore already covers both.

That reasoning is sound as far as it goes, and the option is genuinely attractive — a self-contained dist/ has no invisible second half to reason about. ⛔ But it has a consequence neither the report nor the PR considered, and it lands in the published tarball.

The measurement

Every one of the affected packages publishes by directory, not by enumeration. Read on origin/main:

packages/types/package.json   "files": ["dist","README.md","CHANGELOG.md","LICENSE"]
packages/core/package.json    "files": ["dist","README.md","CHANGELOG.md","LICENSE"]
packages/react/package.json   "files": ["dist","README.md","CHANGELOG.md","LICENSE"]

Anything inside dist/ ships. Putting tsconfig.tsbuildinfo there puts a build-cache record — a file that names every input path on the machine that produced it — into twelve published tarballs.

And the gate that exists for exactly this class would not catch it

scripts/check-published-dist-tooling.mjs is the gate for tooling material in published output. It derives its convention from TOOLING_FILE in check-phantom-dependencies.mjs, whose pattern ends:

\.[cm]?[jt]sx?$

The artifact side is matched back to a tooling source file carrying a JS/TS extension — that is how dist/__tests__/foo.d.ts is traced to src/__tests__/foo.ts (the live instance in #6943). A tsconfig.tsbuildinfo has no tooling source and does not end in .ts/.js/.mjs/.cjs, so it matches nothing the convention describes.

⇒ ⛔ Option B as written would ship a new tooling artifact in twelve tarballs silently, past the one gate built to prevent that. ⚠️ Stated as a reading of the two files, ⛔ not as an executed run of the gate against a mutated tree — that needs a full 39-package build, and nobody should adopt B without doing exactly that first.

What this does NOT say

⛔ It is not an argument against B. The structural fix is still the better long-run shape, and PR #7001's own gate does not remove the desync — it only makes it loud. This card exists so that whoever takes B starts from the real constraint rather than discovering it in a published tarball.

Three directions, none of them adjudicated here:

  1. Point tsBuildInfoFile somewhere that is neither the package root nor outDir — a repo-level cache directory — so rm -rf dist still cannot desync it, and nothing new enters the tarball. ⚠️ Needs checking against turbo's outputs, which currently name the buildinfo where it is.
  2. Keep B and add an explicit negation to each files list. ⚠️ Twelve places to forget one.
  3. Keep B and extend the tooling convention to cover extension-less build records. ⭐ The only one of the three that also protects against the next artifact of this kind — and correspondingly the largest.

Reproduce the two readings

git grep -n '"files"' -- packages/types/package.json packages/core/package.json
git show origin/main:scripts/check-phantom-dependencies.mjs | grep -n 'TOOLING_FILE'

⭐ Control for the second: the same file must also show the __tests__ half of the convention. A zero there means the search broke, not that the convention is absent.

Related

#6703 (the card PR #7001 lands) · PR #7001 (ships option A, the counting gate) · #6943 (check:published-dist red on main today — the same gate, a different artifact) · #6861

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions