Skip to content

Commit 9140c76

Browse files
claude[bot]claude
andauthored
feat(devx): a closure-wide declaration sweep after the workspace build names a package whose .d.ts vanished (#15042) (#15796)
* feat(devx): sweep the built closure for vanished declarations after the workspace build `scripts/check-dts-emitted.mjs` runs per package, immediately after that package's own `tsup`, and is the last thing that ever looks. On #15042's observation it reported `3/3 declared declaration file(s) present` and the files were gone later in the same tree, with no second build and no `rm`. Adds `scripts/check-dts-closure.mjs`: a sibling that re-reads the whole built workspace once, AFTER the closure build. The derivation is imported from the per-package guard, not re-written, so the per-package contract is untouched and there is still one answer to "which declarations does this manifest promise". Exit 1 names the package and each missing file; exit 3 PREREQUISITE NOT MET when no package has a `dist/` at all, never a pass. Wired as `check:dts-closure` and run directly after the closure build in lint.yml's two full-closure lanes and ci.yml's `build-core`. Does not touch any `tsup.config.ts` `clean` semantics and makes no claim about what deleted the files. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk * fix(devx): the closure sweep's self-test names its failure instead of crashing Ablating the sweep predicate (`if (missing.length > 0)` -> `if (false)`) made the self-test exit 1 through a TypeError on `findings[0].missing`, so the named case that had already failed never reached the report. The optional read keeps the exit code and restores the diagnostic. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3508869 commit 9140c76

4 files changed

Lines changed: 626 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,19 @@ jobs:
14921492
- name: Build packages (excluding docs)
14931493
run: pnpm build
14941494

1495+
# [#15042] The closure-wide declaration re-check. `check-dts-emitted` runs
1496+
# per package, immediately after that package's `tsup`, and is the LAST
1497+
# thing that ever looks: on the filing observation it reported
1498+
# `3/3 declared declaration file(s) present` and the files were gone later
1499+
# in the same tree, with no second build and no `rm`. Sits directly after
1500+
# the build so the tree the steps BELOW read is the tree this swept — a
1501+
# package whose declarations are absent makes an importing symbol `any`,
1502+
# and the direction that does NOT throw is a suite passing against a type
1503+
# nothing is checking (#7668, #12078). No `dist/` anywhere is exit 3
1504+
# PREREQUISITE NOT MET, never a pass.
1505+
- name: Sweep the built closure for vanished declarations
1506+
run: pnpm check:dts-closure
1507+
14951508
# A package that builds with plain `tsc` and does not exclude tests emits
14961509
# `dist/**/*.test.js`. Two costs, and the second is the dangerous one:
14971510
#

.github/workflows/lint.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5014,6 +5014,19 @@ jobs:
50145014
- name: Build the ledgered packages' dependencies
50155015
run: pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*'
50165016

5017+
# [#15042] The closure-wide declaration re-check. `check-dts-emitted` runs
5018+
# per package, immediately after that package's `tsup`, and is the LAST
5019+
# thing that ever looks: on the filing observation it reported
5020+
# `3/3 declared declaration file(s) present` and the files were gone later
5021+
# in the same tree, with no second build and no `rm`. Sits directly after
5022+
# the build so the tree the steps BELOW read is the tree this swept — a
5023+
# package whose declarations are absent makes an importing symbol `any`,
5024+
# and the direction that does NOT throw is a suite passing against a type
5025+
# nothing is checking (#7668, #12078). No `dist/` anywhere is exit 3
5026+
# PREREQUISITE NOT MET, never a pass.
5027+
- name: Sweep the built closure for vanished declarations
5028+
run: pnpm check:dts-closure
5029+
50175030
# ⚠️ `NODE_OPTIONS` here is HALF of the heap ceiling this gate runs tsc
50185031
# under, and the two halves ship together or not at all (#14569, ruled
50195032
# 2026-09-03). The other half is `CI_TSC_HEAP_CEILING_MB` in
@@ -5189,6 +5202,19 @@ jobs:
51895202
- name: Build the nested packages the consumer gates resolve through
51905203
run: pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*'
51915204

5205+
# [#15042] The closure-wide declaration re-check. `check-dts-emitted` runs
5206+
# per package, immediately after that package's `tsup`, and is the LAST
5207+
# thing that ever looks: on the filing observation it reported
5208+
# `3/3 declared declaration file(s) present` and the files were gone later
5209+
# in the same tree, with no second build and no `rm`. Sits directly after
5210+
# the build so the tree the steps BELOW read is the tree this swept — a
5211+
# package whose declarations are absent makes an importing symbol `any`,
5212+
# and the direction that does NOT throw is a suite passing against a type
5213+
# nothing is checking (#7668, #12078). No `dist/` anywhere is exit 3
5214+
# PREREQUISITE NOT MET, never a pass.
5215+
- name: Sweep the built closure for vanished declarations
5216+
run: pnpm check:dts-closure
5217+
51925218
- name: Type check example apps
51935219
run: pnpm --filter './examples/*' run typecheck
51945220

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@
145145
"check:published-readme-exports": "node scripts/check-published-readme-exports.mjs --self-test && node scripts/check-published-readme-exports.mjs",
146146
"check:published-readme-links": "node scripts/check-published-readme-links.mjs --self-test && node scripts/check-published-readme-links.mjs",
147147
"check:dual-build-cjs-loads": "node scripts/check-dual-build-cjs-loads.mjs --self-test && node scripts/check-dual-build-cjs-loads.mjs",
148+
"check:dts-closure": "node scripts/check-dts-closure.mjs --self-test && node scripts/check-dts-closure.mjs",
148149
"check:type-check-coverage": "node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs",
149150
"check:type-check-debt": "node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs --re-measure",
150151
"check:driver-conformance": "node scripts/check-driver-conformance.mjs --self-test && node scripts/check-driver-conformance.mjs",

0 commit comments

Comments
 (0)