feat(tooling): one changelog file per pull request

`CONTRIBUTING.md` asks every runtime change to add an entry at the top of
`CHANGELOG.md`, so two pull requests in flight write into the same few lines and
git has nothing to merge on. Against `main` at `81eb443`, `git merge-tree` over
the 85 open pull requests GitHub reports as conflicting that aren't mine puts
`CHANGELOG.md` in the conflict set of 41 — more than any other path — and for 6
it is the only one. `docs/CURRENT-STATE.md`, the other file rule 3 names,
conflicts for 23, and merges cleanly for 23 of the 41: edits land in the section
for the area you touched, so they only collide when the areas do.

A pull request now adds `changelog.d/<pull request>-<slug>.md` instead. Distinct
filenames never conflict, and the pull request number makes them distinct for
free. `npm run changelog` splices the directory into `CHANGELOG.md` and empties
it; `npm run changelog:check` reports the batch and changes nothing.

Fragment text is copied through unchanged apart from trailing whitespace.
`src/annotations/drawTool.test.mjs` reads `CHANGELOG.md` as prose and slices a
fixed window after a heading, so an assembler that reflowed an entry could move
text across that window. Fragments are deliberately outside
`scripts/format-scope.json` for the same reason.

The assembler refuses a batch before writing anything when a filename is not
`<pull request>-<slug>.md` or two fragments claim one pull request number, and
a unit test runs that check over the real `changelog.d/`, so a fragment the
release could not assemble fails `npm test` in the pull request that adds it
rather than at release time.

Refs #781.
This commit is contained in:
daikaginza committed 2026-09-28 08:14:11 +07:00
1 parent 81eb44340d
commit 114b0eeaba
7 files changed
+359 -3

No files matched your search

+10 -1
View File
@@ -57,7 +57,8 @@ with a reason; usefulness can also be `decline` or `discuss`.
- Inspect removed tests, skipped tests, relaxed assertions, snapshot updates, mocks,
and test-runner changes. A green result from weakened tests is not acceptance.
- Check applicable documentation updates: runtime changes need `CURRENT-STATE.md`
and `CHANGELOG.md`; source changes need `DATA_SOURCES.md`.
and a `changelog.d/<pr-number>-<slug>.md` fragment rather than an edit to
`CHANGELOG.md`; source changes need `DATA_SOURCES.md`.
### 3. Security and supply chain
@@ -173,6 +174,14 @@ Before merging:
a stale merge. Verify the merged result matches the validated candidate tree
and record the resulting commit and PR URL. Stop and report any mismatch.
Pending release notes live in `changelog.d/` as one file per pull request, so an
integration never has to resolve the top of `CHANGELOG.md`. When cutting a release,
run `npm run changelog:check` to see the batch and the order it would take, then
`npm run changelog` to splice it into `CHANGELOG.md` and empty the directory. The
assembler refuses a malformed filename or two fragments claiming one pull request
number before it writes anything, and copies the text through unchanged, so the
contributor's own wording and credit are what ship.
Repository rules enforce only their configured requirements; this document and
the skill do not configure branch protection or CI. Maintainers should require
CI and review on `main` and dismiss stale approvals when changes are pushed.