Skip to content

check-changeset-presence.mjs guards only <pkg>/src/**, so a published-contract change in package.json is owed no changeset — live instance in #6683 #6736

Description

@os-sales

Found while implementing #6683 (PR #6735). Filed, not fixed there — out of that card's scope.

The gap

scripts/check-changeset-presence.mjs derives its guarded surface as <pkg>/src/** for every package in the fixed group of .changeset/config.json. Its own header states that derivation and says why it is derived rather than listed, and the reasoning is sound for source.

It does not cover <pkg>/package.json. So a change to a package's published contract carries no obligation to declare anything, and the platform-side release criterion (objectstack#4731 / #4843 reads this repo's declared changesets) never learns about it.

Fields in that class, all of them read by consumers and none of them under src/:

  • sideEffects — every consumer's bundler reads it and tree-shakes accordingly
  • exports / main / module / types — what a consumer can import at all
  • files — what is in the tarball
  • peerDependencies / engines — what a consumer must satisfy

The live instance

PR #6735 adds a sideEffects ARRAY to @object-ui/app-shell. That changes how every consumer's bundler treats the package: modules the array does not name become droppable, which is the whole point of the change and is also a behaviour change a consumer can be bitten by. The gate's own verdict line on that diff:

Compared the working tree with 9486ac672 (merge-base with origin/main): 7 file(s) changed,
0 of them published source of a package the release covers, 0 under a package changesets
ignores, 1 changeset(s) added.
✅ No source of a released package changed in this range, so no changeset is owed.

The changeset in that PR is there because the author decided it was owed, not because anything asked for it. That is exactly the condition objectui#3387 was filed about — "a change to published source carries a changeset" enforced by nothing — one field over.

Why it is worth a card rather than a note

The same three fixes that rode out anonymously in objectui#3387's measurement (19716b5bf, 5e7ef1141, 0e50440) are the argument: the omission is silent, the release notes are assembled from the declarations, and a contract change that no CHANGELOG records is one a consumer debugs from the outside. A sideEffects or exports edit is arguably more consequential per byte than a source edit, because it changes what a consumer's build does with code that did not change.

Shape of a fix (not a decision — for triage)

Widen the guarded surface from <pkg>/src/** to <pkg>/src/** plus a named set of package.json FIELDS, judged by diffing the manifest rather than by the file's mtime — a version bump written by changeset version itself, or a devDependencies bump from Dependabot, must not demand a changeset, or the gate becomes noise and gets routed around. The field list is the decision worth taking deliberately.

Not attempted in #6735: that PR is the ruled sideEffects work, and widening a repo-wide changeset gate inside it would put an unrelated CI-shaped risk on a published-contract change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:queuepriority:p1tooling

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions