SKILL.md
Keep a Changelog Assistant
Changelogs are for humans. A good one lets a reader answer "what does upgrading do to me?" without reading a diff. The agent maintains ## [Unreleased] and, when explicitly asked, prepares version sections; the human decides when to cut, tag and publish.
Format, categories, breaking changes, reverts, yanked releases, entry style, this repository's house rules, and both workflows are in [references/spec-and-workflows.md](references/spec-and-workflows.md) — load it before editing the file. scripts/validate_changelog.py enforces the mechanical half of it:
python3 skills/keep-a-changelog/scripts/validate_changelog.py CHANGELOG.md
python3 skills/keep-a-changelog/scripts/validate_changelog.py --house-rules CHANGELOG.md
It never edits. What it cannot judge is the whole of what follows.
Which changes earn an entry
Only changes meaningful to consumers. The test: does this affect how users install, import, use, or should trust the software? If not, leave it out — even when it was the largest thing in the release.
Typically in: public API changes, new or changed behavior, packaging and installation changes, deprecations, security fixes.
Typically out: test changes, CI and workflow updates, internal tooling, docs-only changes, formatting and lint-only changes, refactors with no observable impact, trivial renames.
Read the product-code boundary from the repository's own layout — wherever the shipped code lives (src/, cmd/ plus internal/, lib/, a package directory) — and treat user-relevant as changes inside it: public APIs and commands, domain primitives, contracts and schemas, behaviors, plus packaging. Never carry one layout's boundary into another repository.
Two judgements the validator will never make for you:
- Which category a change dominantly belongs to when it fits two. A rewrite that also fixes a bug is
Changedif the rewrite is the story andFixedif the fix is; putting it in both makes the release look twice as large as it was. - Whether an entry is true and outcome-shaped. A well-formed entry that describes the implementation instead of the effect passes every check and still fails the reader.
Every commit marked breaking (💥 / ! / a BREAKING CHANGE: footer, see gitmoji-conventional) must produce an entry that names the break, and implies MAJOR for the next release.
Related skills
gitmoji-conventional— commit messages and PR titles; its breaking-change markers are the signal that an entry must call out a break. Absent it, read the same signal off the diff: a removed or altered public symbol is a break whatever the commit subject says.