diff --git a/CLAUDE.md b/CLAUDE.md index 129973e..1b4855e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -37,6 +37,40 @@ current design: --- +## Changelog & release convention + +Adopted 2026-09-18, to match seismo-relay and Terra-View. SLMM had no written +practice before this — earlier releases used ad-hoc commits like +`chore: version bump`. This is the standard going forward. + +**Write the entry in the same commit as the work, under `## [Unreleased]`. Cut +the version on `dev` in a dedicated release commit. Never touch the changelog +at a merge boundary.** + +- **Entry goes in with the change**, not at merge or release time — that is the + only moment you still know *why*. Feature branches edit `CHANGELOG.md` + directly; the occasional conflict is two appended bullets and is trivial. +- **No preamble under `## [Unreleased]`** — just the `### Added` / `### Changed` + / `### Fixed` lists. The themed opening paragraph gets written at release + time, when the whole release is visible and can be named honestly. A theme + written when the first item landed is stale by the third. +- ⚠ **State the operational consequence**, **including when it is "none."** + Silence is ambiguous; "none" is information. For this repo that means: + - **DB migration** — whether a `migrate_*.py` script is needed, which one, + and whether it is safe to re-run. These live at the repo root and are + easy to forget at deploy time. + - **Meter-connection impact** — anything touching the NL-43/NL-53 TCP path, + polling cadence, or the monitor fan-out. The meter has a **single TCP + slot**, so a change that bounces the connection is an operational event, + not just a code change. +- **Cutting a release** is its own `chore(release): vX.Y.Z` commit on `dev`, + renaming `## [Unreleased]` → `## [X.Y.Z] - YYYY-MM-DD` and bumping the + version in `app/main.py` (the FastAPI `version=` argument). +- **`main` carries only released versions.** No `## [Unreleased]` section + there; it lands via the `dev` → `main` PR. + +--- + ## Layout ```