Changelog Generator
A changelog is release notes for people who did not read the commits — users deciding whether to upgrade, support engineers triaging "did this change?", and future maintainers dating a regression. This skill turns a span of history (two tags, a release branch, a sprint of merges) into entries written in the language of consequences: what a user of the software will notice, gain, or need to do. Commits are the raw material, never the output.
When to use this skill
- Cutting a release and drafting its notes from merged work
- Backfilling a changelog that has drifted several releases behind
- Turning a batch of merged requests into an announcement or upgrade guide
- The user asks "what changed between version A and version B?"
Workflow
- Establish the exact range:
git log <last-release-tag>..HEAD, or the two refs the user names. Confirm the previous release point rather than guessing it; a wrong baseline produces confidently wrong notes. - Collect merge titles and commit subjects, then read the diff or description of anything ambiguous. You are classifying by effect, and commit authors rarely label effects honestly — a "refactor" that renames a config key is a breaking change wearing a lab coat.
- Sort every item into exactly one bucket: Breaking changes, New, Improvements, Fixes, Security, Internal. When one merge belongs in two buckets, split it into two entries rather than blending them.
- Rewrite each entry from the user's side of the glass. "Fix crash when the export folder is read-only" — not "handle permission error in exporter". Name the conditions under which the reader would have hit the problem, because that is how they recognize themselves.
- For every breaking change, write the migration line: what breaks, who is affected, and the exact action to take, including old and new syntax where relevant. A breaking change without a migration step is an unfinished entry.
- Drop or demote true noise (dependency churn with no user effect, test-only changes) into Internal, or omit that section entirely for end-user-facing notes. Decide the audience before deciding the cut.
- Read the finished list top to bottom and ask: would a cautious operator now know whether this upgrade is safe for them? If not, the gap is usually a missing "who is affected" clause.
Output format
## <version> — <date>
### Breaking changes
- <what breaks> — affects <who>. Migration: <exact step>.
### New
- <capability, phrased as what the user can now do>
### Improvements
- <existing behavior, better — with the visible difference>
### Fixes
- <symptom fixed> when <condition that triggered it>
### Security
- <issue class fixed; disclose per your policy, no exploit recipes>
Omit any empty section. Keep entries to one line each, except breaking changes, which may take two.
Guardrails
- Never write an entry you could not defend by pointing at a specific commit or merge; invented entries are how changelogs lose trust permanently.
- Version numbers and dates come from the repository or the user — fabricate neither.
- Security entries state the class of issue and the affected versions, never a step-by-step exploit.
- Order buckets by reader importance and entries by impact; alphabetizing is abdication.
- Work that shipped behind a disabled feature flag goes under Internal or nowhere — announcing invisible features breaks the "what will I notice" contract.