Skip to content

Changeset gate accepts 0000- and wrong-PR changelog fragment names #8978

Description

@proggeramlug

The gap

The changeset gate in lint accepts any fragment matching:

^changelog\.d/[0-9]+-[^/]+\.md$

That requires some digits, not this PR's number. So both of these pass:

  • changelog.d/0000-<slug>.md — the placeholder, when an author has not filled in the number yet
  • changelog.d/<other-PR>-<slug>.md — a number belonging to a different PR

changelog.d/README.md says filenames are PR-keyed precisely so in-flight PRs cannot collide, and the failure is silent: fragments are only folded into release notes at tag time by scripts/cut_release_notes.sh, so a wrong number is invisible until a release is cut and then attributes the change to the wrong PR.

Evidence it happens

Four in one day (2026-08-28), all caught by eye during review rather than by any gate:

PR shipped as should have been
#8944 0000-inline-array-pop-tier.md 8944-
#8947 0000-inline-method-shape-probe.md 8947-
#8291 0000-node-version-26.5.1.md 8291-
#8977 8976-write-stub-two-way.md 8977-

The first three sat on main until #8973 renamed them; the fourth misattributed a write-stub change to #8976, an unrelated Array-subclass loop-guard fix that had merged an hour earlier.

Why the obvious fix is wrong

"The fragment must start with this PR's number" would be a false positive on legitimate cases:

So the check needs to be "the number is this PR's, or an existing PR number", or to warn rather than fail. The 0000 case specifically is unambiguous though: no PR is ever number 0, so rejecting ^changelog\.d/0+- is a safe tightening on its own and would have caught three of the four above.

Suggested minimum

Reject 0000- (and any all-zero prefix) outright; treat a number that is neither this PR's nor an existing PR as a warning. That closes the common case without breaking cleanups.

Found while auditing the PR queue; not fixed here because a naive tightening would have blocked #8973.

Activity

  1. proggeramlug commented on Aug 28, 2026

    @proggeramlug
    ContributorAuthor

    More evidence, from a single batch of three PRs merged tonight — all three were wrong, in three different ways:

    PR shipped as problem
    #8981 8958-dynamic-function-refusal-unwind.md named for the issue it fixes, not the PR
    #8982 (none) touches crates/, no skip-changelog label — the gate would have rejected it
    #8983 8981-feedback-gate-and-shape-field.md carries #8981's number, a different PR in the same batch

    Note the last one: left alone, #8983's fragment would have collided with #8981's own fragment at release time, and both landed within minutes of each other.

    Running total for 2026-08-28 is eight fragment-naming fixes across the day (three 0000- placeholders, four wrong-PR numbers, one missing). Only the missing one was catchable by the current gate.

    The asymmetry is the point: the gate reliably catches an absent fragment and never catches a misattributed one, and misattribution is the failure that survives to the release notes.

  2. added a commit that references this issue on Aug 29, 2026
    765f1dc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions