ADR-0004: Version-keyed changelog, written at release time
- Status: Accepted
- Date: 2026-05-30
- Scope: core (every repo that releases)
Context
The Expenses backend once kept rich, hand-written per-feature “patch notes”
(docs/patch-notes/YYYY-MM-DD-topic.md) — endpoints, payloads, validation, a
frontend-summary table. That format was a mini-spec per change and didn’t
survive the release cadence: it lapsed at the v1.0 era while the backend reached
v1.41.0, and the surviving notes described a since-replaced architecture
(ddl-auto: update, pre-Flyway). The lesson: a change log only stays current if
producing it is nearly free and tied to a moment that always happens.
We already have the ingredients for that: conventional-commit messages
(feat:/fix:/refactor:…), version tags on main, and the /release skill
that inspects commits since the last tag to decide the bump.
Decision
Each repo maintains a CHANGELOG.md at its root, keyed to released
versions (newest first), in Keep a Changelog
style:
## vX.Y.Z — YYYY-MM-DD
### Added (from feat:)
### Changed (from refactor: / perf: / build:)
### Fixed (from fix:)
- Entries are written/updated at release time, derived from the conventional
commits since the previous tag — not hand-authored per feature mid-development. - One changelog per repo (independent version histories — see
0001-three-step-git-flow). - The detailed per-feature
docs/patch-notes/practice is superseded and
removed; deep design context lives in ADRs instead. - History was backfilled from git tags (best-effort; terse old commits yield
sparse entries).
Consequences
- The changelog is a near-free byproduct of releasing, so it should actually
stay current this time. - Quality tracks commit-message hygiene — another reason to keep writing clear
conventional subjects. - Follow-up: the
/releaseskill should append the new version’s section as
part of the release-branch step, so it’s automatic rather than remembered.
Related
- 0001-three-step-git-flow — release flow that produces each version
- Backend changelog:
expenses/CHANGELOG.md(backfilled across 88 tags)