Skip to content

Commit 64011dd

Browse files
os-steveclaude
andauthored
feat(devx): check:published-files gates an exports map retrofitted onto an already-published package (#15715) (#16082)
* feat(devx): check:published-files gates an exports map retrofitted onto an already-published package GATED asserts an `exports` map exists; it is silent on the TRANSITION, and the transition is where the damage is. 17.3.0 added a map to `@objectstack/cli`, which had published without one, and every deep path a consumer reached through `dist/` stopped resolving at once -- found after publish, by the consumer, twice (#13662, #15325). ANNOUNCED is the second half of #15589, ruled B1 on #15715: a base-vs-HEAD comparison, the same shape `check-adr-0087-registration --base` already uses, and deliberately not `git log -S` archaeology. A `package.json` absent at the merge base -- or present but private/unnamed there -- is born-sealed and passes, because it has no published predecessor whose consumers could be deep-importing it. Measured when #15715 was filed: 69 publishable packages declare a map from 51 introducing commits, but 56 were born with it and only 13 retrofitted, from 7 commits. Gating all 51 would demand a consumer note 44 times from packages that had no consumers, every one of them on a new-package PR -- and a gate answered by boilerplate 44 times out of 51 has stopped being read by the 7th time it matters. What the announcement must say is checked against the head map rather than for a form of words: a `minor`-or-greater changeset on the package whose body names a deep specifier the new map does NOT resolve. Naming a path that still resolves tells a consumer nothing and does not satisfy it. Absence is never a pass (#4690). Every way the base read can fail -- no `origin/main`, no merge base, an unreadable `.changeset/` -- makes every package look born-sealed and the clause vacuously green, so each is a refusal that names itself, and the read carries its own census control (BASE_READ_FLOOR) exactly as GATED carries EXPORTS_CENSUS_FLOOR. In CI the base comes from `Lint & Repo Gates` checking out at `fetch-depth: 0`. Claude-Session: https://claude.ai/code/session_01PU9zBGbH2s2ZtxSyu963M3 Co-authored-by: Claude <noreply@anthropic.com> * fix(devx): only the changesets a change introduces can announce what it narrows Measured while ablating the clause: a real `./console` subpath removal went GREEN because an unrelated changeset already on main contained the string `./console` in a sentence about a different release. The pending stock is ~1300 files of prose about these same packages, so "some changeset mentions this path" is satisfied by accident constantly -- the boilerplate-answered gate this clause exists to avoid, reached from the other direction. The subject is now the diff: a changeset absent at the merge base, or one whose text differs from its base copy. The removal half also reads the changeset BODY rather than the whole file, since the frontmatter names the package on every changeset and would otherwise let the bump line answer the note. Nothing in the file is exported any more either. `check:entry-guard`'s second rule is that a `scripts/**` file exporting a binding can be imported for it, whereupon this gate's top-level dispatch -- and its `process.exit` -- runs inside the importer; the self-test is in the same module and needs no exports. Claude-Session: https://claude.ai/code/session_01PU9zBGbH2s2ZtxSyu963M3 Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2648774 commit 64011dd

1 file changed

Lines changed: 786 additions & 3 deletions

File tree

0 commit comments

Comments
 (0)