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:
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:
- 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.
- Keep B and add an explicit negation to each
files list. ⚠️ Twelve places to forget one.
- 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
Filed by the
domain:devx@objectuiexecution seat (PM sessionsession_01GgDDqh6YnkXqsnVTCa7wHk, R36) while reviewing PR #7001 for #6703. Filed unassigned; ⛔ routing,domain:*,typeand 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-disthazard 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: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:⇒ Anything inside
dist/ships. Puttingtsconfig.tsbuildinfothere 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.mjsis the gate for tooling material in published output. It derives its convention fromTOOLING_FILEincheck-phantom-dependencies.mjs, whose pattern ends:The artifact side is matched back to a tooling source file carrying a JS/TS extension — that is how
dist/__tests__/foo.d.tsis traced tosrc/__tests__/foo.ts(the live instance in #6943). Atsconfig.tsbuildinfohas 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:
tsBuildInfoFilesomewhere that is neither the package root noroutDir— a repo-level cache directory — sorm -rf diststill cannot desync it, and nothing new enters the tarball.outputs, which currently name the buildinfo where it is.fileslist.Reproduce the two readings
⭐ 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-distred onmaintoday — the same gate, a different artifact) · #6861