The changelog answers one question, for one reader: I just ran
pip install -U xmris — what is different? Nothing else on the site answers it. The
dev diary records why a decision was made and the roadmap records
what is next; both are about reasoning, and this page is about consequences.
It is written at release time, not per pull request — during the fifteen minutes the full
matrix runs, so the entry rides the version bump into main in a single pull request
(Publishing, step ②b).
There is no generator and there are no fragment files to collect. git log since the last tag is
raw material, not a draft: a squash-merge subject says what the diff did, and a bullet has to say
what the user got. Turning one into the other is the whole job. What replaces a generator’s
guarantee that nothing was silently missed is an accounting rule — every commit in the range ends
up either a bullet or a deliberate, stated drop — and what earns a bullet is user-visible
consequence, not commit type. A chore: that changes what pip install xmris pulls in earns
one; a feat: that only adds an internal helper does not.
Every bullet then carries its trail, in a fixed order: issues → pull requests → the docs page it
produced → the diary entry that argued it, so a reader can always get from a one-line consequence
back to the reasoning. The last two are MyST targets rather than URLs, which makes that half of the
trail machine-checkable — with one trap: an unresolved target is a warning, and --strict only
promotes errors, so the build log has to be grepped rather than trusted to its exit code.
Working with Claude Code¶
The changelog skill’s checklist:
- [ ] Range established from the last tag; **every commit in it is a bullet or a stated drop**
- [ ] Bullets describe user-visible consequence, naming the public symbol — never a module path
- [ ] Trail on every bullet, in order: issues → PRs → docs page → diary, the last two as MyST targets
- [ ] `chore(deps)` collapsed to one **Maintenance** bullet; `ci:`/internal `chore:`/`refactor:` dropped
- [ ] Groups in order, `**Breaking**` first where it applies; one H2 and one `(changelog-vX-Y-Z)=` per version, newest first
- [ ] `check_docs.py` clean, `myst build --strict` exits 0, **and** the build log is free of `No target for internal reference` — the exit code alone does not prove the targets resolve
- [ ] Rendered page read start to finish; no bullet requires the diff to understandQuote from the changelog/SKILL.md