# Release Notes & Changelog

Turns a set of merged changes into what a reader needs: an entry for the record, and notes for the person the change happens to.

## Deliverable

One Markdown document, `release-notes.md`, in the structure set out under **Output** below. It carries both forms: section 2 is the entry appended to the project's changelog, and section 4 onward is what is published to readers.

## Required inputs

- **The set of merged changes** — the commits, merges or tickets included in this release, and the boundary they sit inside.
- **The version identifier** — what this release is called, supplied by whoever names releases here. It is never invented.
- **The reader** — who the notes are published to: the people running the software, the people integrating against it, or both.

If the change set or the version identifier is missing, stop and report it. Notes assembled from a memory of what was worked on will omit exactly the change that breaks someone.

## Optional inputs

- The tickets or issues the changes close, and what they said
- The previous release's notes, for continuity of terminology
- Migration steps already written by the people who made the change
- Deprecation decisions and the date a removal is planned for
- Measurements taken before and after a performance change
- The channel the notes are published to, and the length limits it imposes

Absent optional inputs reduce what the notes may claim. Without measurements a change is described but never called faster; without a removal date a deprecation is recorded as planned with `unknown` beside it.

## Execution

**1 — Take the change set from the record, not from recollection.** List every merged change inside the boundary. Each entry in the output traces to one of them, and a change that reaches the output with nothing behind it is removed.

**2 — Sort by what it is.** Added, changed, fixed, removed, security. Sort by effect on the reader rather than by the component that was touched: a reader looks for what happened to them, not for which module it happened in.

**3 — Separate visible from internal.** A change the reader can observe goes in the notes. A refactor, a test or a build change is recorded as internal and stays out of the reader's section. Dressing an internal change as a user-facing improvement is how release notes lose their readers.

**4 — Pull the breaking changes to the front.** Anything that stops working, changes shape or requires action goes at the top, with the action spelt out. A migration step buried under a feature list is a migration step that will be missed.

**5 — Write each entry as its effect.** State what is different for the reader and what they do about it, not which function was edited. Where an entry has a ticket or a change behind it, cite it so a reader can go further.

**6 — Claim only what was measured.** A change may be called faster, smaller or more reliable only with a measurement behind it. Without one, describe what changed and leave the judgement to the reader.

**7 — Record the deprecations and what is next.** What is deprecated, what replaces it, and when it will be removed — `unknown` where no date has been decided. Then check every entry against the change set one last time.

## Output

`release-notes.md`, in this order:

- **1. Release identity** — the version identifier as supplied, the date, and the boundary of the change set
- **2. Changelog entry** — grouped `Added`, `Changed`, `Fixed`, `Removed`, `Security`; one line per change, each citing what it came from
- **3. Internal changes** — changes with no reader-visible effect, recorded and kept out of section 4
- **4. Breaking changes and required action** — what stops working, and the exact steps to take; empty only if there are none, and it says so
- **5. What is new** — per entry: the effect on the reader, and what they can now do
- **6. Fixes** — the symptom the reader would have seen, and that it is gone
- **7. Deprecations** — what is deprecated, its replacement, and the removal date or `unknown`
- **8. Unverified claims** — anything asserted with no measurement or traceable change, listed rather than published

## Validation

The document is ready when all of these hold:

- Every entry in sections 2 and 4 to 7 traces to a change in the input set
- Every change in the input set appears once, in section 2 or section 3
- Section 4 comes before section 5 and states its steps as actions the reader takes
- No entry claims a measurable improvement with no supplied measurement
- The identifier in section 1 is the one that was supplied, unchanged
- Section 3 is used for internal work rather than leaving it out

Fail the run if an output entry traces to no change in the input set, or if an improvement is claimed with no measurement behind it.

## Failure handling

- **No change set supplied** — stop. Report that release notes cannot be reconstructed from what people remember doing.
- **No version identifier** — produce the document with section 1 marked `VERSION NOT ASSIGNED` and name who assigns it. Do not invent an identifier and do not increment the previous one.
- **A change's effect on the reader is unclear** — list it in section 8 with the question and ask the person who made it. Do not describe it vaguely to fill a line.
- **A breaking change with no migration path** — record it in section 4, state plainly that no migration is available, and raise it as blocking the release. A breaking change with no path is a decision, not a note.
- **Partial change set** — produce the document for the range that is known, state the boundary in section 1, and mark it `INCOMPLETE — covers <range> only`.
