Common Changelog
Write human-facing changelog entries in Common Changelog format.
When to use
Use this skill when asked to generate, update, or normalize CHANGELOG.md from commits, PRs, or
release notes.
When not to use
- Do not use for commit message wording; route to
git-commits.
- Do not use for branch/rebase/PR process guidance; route to
git-trunk-based-workflow.
Goal
Help readers answer: what changed and how it affects them.
Output contract
Choose exactly one output mode:
- Full-file mode:
- Use when the user asks to create, replace, or normalize an entire
CHANGELOG.md.
- Output MUST be a complete markdown file that starts with
# Changelog.
- Release-fragment mode:
- Use when the user asks for a single release entry (for example
1.4.0 or Unreleased).
- Output MUST contain exactly one release heading and its non-empty groups, unless
FMT-9
applies and the release should be skipped due to no user-facing changes.
If user intent is ambiguous, default to release-fragment mode.
When metadata is incomplete, keep producing output and append:
Warnings:
- <warning 1>
- <warning 2>
Only include Warnings: when at least one warning exists.
Warnings are out-of-band metadata and MUST appear after the primary changelog artifact.
Normative language
MUST: mandatory requirement; fail output if violated
SHOULD: recommended default; may be overridden only by explicit user instruction
MAY: optional behavior
Canonical rules table
Use this table as the single source of truth for output structure and bullet formatting.
| ID |
Scope |
Requirement |
FMT-1 |
Output scope |
In full-file mode, output MUST be a valid CHANGELOG.md and first heading MUST be # Changelog; in release-fragment mode, output MUST contain exactly one release block. Optional trailing Warnings: metadata MAY appear after the artifact when needed. |
FMT-2 |
Release ordering |
If present, Unreleased MUST be the first release heading and MUST NOT be included in semantic version ordering. |
FMT-3 |
Release ordering |
Released versions (excluding Unreleased) MUST be sorted latest-first by semantic version. |
FMT-4 |
Release headings |
Released version headings MUST include ISO date YYYY-MM-DD; linked format ## [1.2.3] - YYYY-MM-DD is SHOULD, plain ## 1.2.3 - YYYY-MM-DD is MAY. Unreleased SHOULD be undated (## [Unreleased] or ## Unreleased) unless the user explicitly asks for a dated form. |
FMT-5 |
Link refs |
If any release heading is linked (## [<label>] - YYYY-MM-DD), trailing link references MUST be present at file end and define each linked label exactly once. |
FMT-6 |
Unreleased link |
If Unreleased is a linked heading, its reference MUST use a compare URL ending with ...HEAD. |
FMT-7 |
Release links |
Linked released versions SHOULD point to release tags (matching repository tag conventions). |
FMT-8 |
Sections |
Release groups MUST use only, and in this order: Changed, Added, Removed, Fixed; empty groups MUST NOT be emitted. |
FMT-9 |
No user-facing changes |
If a release has no user-facing changes, default is skip (including release-fragment mode). If explicitly requested, MAY add a one-line maintenance notice under the release heading. |
BUL-1 |
Writing style |
Use imperative style (Add, Fix, Remove, Bump), keep bullets concise, and describe user impact (not internal trivia). |
BUL-2 |
Breaking changes |
Breaking changes MUST be prefixed with **Breaking:**. |
BUL-3 |
Bullet group order |
Every bullet MUST follow this order: optional references group, required commit-links group, required final authors group. Commit-links group MUST contain at least one commit link when available; otherwise use source unavailable and emit a warning. |
BUL-4 |
Group formatting |
References, commit links, and authors MUST each appear in one parentheses group; multi-item groups MUST use comma-separated lists. |
BUL-5 |
Template source |
Bullet shape and full file layout MUST follow references/CHANGELOG.md. |
BUL-6 |
Missing metadata |
If author metadata is missing, authors group MUST be (Unknown author) and a warning MUST be emitted. |
Input model
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Recognize trailers and reference keywords:
Category:
Ref:
Re:
Co-authored-by:
BREAKING CHANGE:
Also recognize GitHub issue-linking keywords:
close, closes, closed
fix, fixes, fixed
resolve, resolves, resolved
For Ref, Re, and the keywords above:
- matching is case-insensitive
: is optional (for example Ref ABC-123 and Ref: ABC-123 are both valid)
- treat GitHub keywords as reference signals only when an issue target is present (for example
Fixes #123)
Classification algorithm
Apply in this order:
Category: trailer override
- Conventional Commit type mapping
- Semantic fallback
1) Category override (highest priority)
If Category: maps to a group, use it:
change, changed -> Changed
add, added -> Added
remove, removed -> Removed
fix, fixed -> Fixed
Rules:
- case-insensitive matching
- if multiple
Category: trailers exist, use the last recognized one
- ignore unknown values and continue
2) Conventional Commits mapping
feat -> Added
fix -> Fixed
perf -> Changed only if user-facing; otherwise skip
refactor -> Changed only if user-facing; otherwise skip
revert -> Changed or Fixed based on actual user effect
docs, style, test, chore, ci, build -> skip unless user-facing
Type compatibility notes
- This skill classifies commit history, so it accepts both the strict type set used by
git-commits and broader Conventional Commit variants observed in existing repositories.
- Accepted history-only variants include:
perf, style, test, ci, build.
- This does NOT change the output type policy of
git-commits; it only affects changelog
classification of existing commits.
3) Semantic fallback
If type is missing or unclear:
- Existing behavior changed ->
Changed
- New capability ->
Added
- Capability removed ->
Removed
- Bug corrected ->
Fixed
Conflict examples
fix(api): ... + Category: add -> Added
feat!: + Category: remove -> Removed + **Breaking:**
docs: + Category: fixed -> Fixed
Classification decision tree
- If there is a recognized
Category: value, map it and stop.
- Else, if Conventional Commit type is recognized, apply the type mapping.
- Else, classify by semantic user impact (
Changed/Added/Removed/Fixed).
- If breaking signal exists (
! or BREAKING CHANGE:), prefix with **Breaking:**.
Breaking change handling
- If header has
! or body/footer contains BREAKING CHANGE:, prefix with **Breaking:**
- Keep the entry in
Changed/Added/Removed/Fixed by impact (no extra section)
User-facing quick test
Usually include:
- API contract or output changed
- CLI flags/defaults changed
- Config shape/defaults changed
- Runtime/performance behavior users notice
- Dependency bump that fixes production bug/security issue
Usually skip:
- Internal refactor without behavior change
- CI/test/style-only updates
- Dev tooling and internal docs only
- Dependency bump for dev/test-only tooling
References and authors
- Commit hash SHOULD be a markdown link when available:
[`d23ba8f`](https://github.com/OWNER/REPO/commit/d23ba8f)
- Group formatting for references, commit links, and authors MUST follow
BUL-3 and BUL-4
- Build references from:
- explicit PR/issue links
Ref and Re trailers
- GitHub keywords (
close*, fix*, resolve*) with issue targets
- Normalize before deduplication:
- treat
#123 and https://github.com/OWNER/REPO/issues/123 as the same issue reference
- normalize case for keyword-style references (for example
jira-123 -> JIRA-123)
- Reference order is deterministic:
- first: one high-signal repository reference (prefer PR, otherwise issue)
- then: remaining unique references in first-seen order
- Commit-link order is deterministic:
- deduplicate by commit hash
- keep first-seen order
- Use commit author as primary author
- Append
Co-authored-by: names (extract name before <email>)
- Authors MUST be deduplicated in stable first-seen order
- For aggregated bullets, authors MUST be the deduplicated union of commit authors and
Co-authored-by: names from all included commits, preserving stable first-seen order
- If commit author is a bot and merger is known, prefer the human merger name
Metadata fallback policy
- If author cannot be determined from metadata, use
(Unknown author) and emit a warning.
- If no commit link can be determined, use
(source unavailable) as the commit-links group and emit
a warning.
- Missing metadata MUST NOT be a sole reason to drop user-facing bullets.
Fail policy
- If any structural
MUST rule is violated and cannot be recovered with fallback policy, fail.
- Missing author/commit metadata alone MUST NOT trigger hard fail.
- If changelog scope is unclear, default to release-fragment mode instead of failing.
Authoring workflow
- Collect input: commits, PRs, issues, release notes.
- Parse commit headers, body, and trailers.
- Classify each change using rules above.
- Remove non-user-facing noise and no-op pairs (change + immediate revert).
- Rewrite into concise user-facing bullets.
- Group by
Changed, Added, Removed, Fixed in that order.
- Validate against
Canonical rules table and references/CHANGELOG.md.
Anti-patterns
- Raw technical commit text with no user context
- Non-standard sections (
Security, Docs, Chore, etc.)
- Internal-only noise in public changelog
- Missing
**Breaking:** marker for incompatible changes
Quality checklist
- Validate all applicable
FMT-* and BUL-* requirements from Canonical rules table.
- Verify output shape against
references/CHANGELOG.md.
- Ensure warning messages exist for every metadata fallback.
- Any checklist failure MUST trigger
Fail policy.
Prompt templates
Generate a Common Changelog entry for version <VERSION> from these commits and PRs. Keep only user-facing changes, include references, and mark breaking changes.
Normalize this existing changelog fragment to Common Changelog format without losing important user-impact details.
Classify these Conventional Commits into Changed/Added/Removed/Fixed and explain any skipped items.
References
1---2name: common-changelog3description: Draft and normalize user-facing CHANGELOG.md entries in Common Changelog format from release notes, pull requests, and Conventional Commits (including git trailers like Category, Ref, and Co-authored-by). Use this skill whenever the user asks for changelog text, release notes, "what changed", version summaries, or Unreleased notes, even if they do not explicitly mention CHANGELOG.md.4---56# Common Changelog78Write human-facing changelog entries in Common Changelog format.910## When to use1112Use this skill when asked to generate, update, or normalize `CHANGELOG.md` from commits, PRs, or13release notes.1415## When not to use1617- Do not use for commit message wording; route to `git-commits`.18- Do not use for branch/rebase/PR process guidance; route to `git-trunk-based-workflow`.1920## Goal2122Help readers answer: what changed and how it affects them.2324## Output contract2526Choose exactly one output mode:27281. Full-file mode:29 - Use when the user asks to create, replace, or normalize an entire `CHANGELOG.md`.30 - Output MUST be a complete markdown file that starts with `# Changelog`.312. Release-fragment mode:32 - Use when the user asks for a single release entry (for example `1.4.0` or `Unreleased`).33 - Output MUST contain exactly one release heading and its non-empty groups, unless `FMT-9`34 applies and the release should be skipped due to no user-facing changes.3536If user intent is ambiguous, default to release-fragment mode.3738When metadata is incomplete, keep producing output and append:3940```text41Warnings:42- <warning 1>43- <warning 2>44```4546Only include `Warnings:` when at least one warning exists.47Warnings are out-of-band metadata and MUST appear after the primary changelog artifact.4849## Normative language5051- `MUST`: mandatory requirement; fail output if violated52- `SHOULD`: recommended default; may be overridden only by explicit user instruction53- `MAY`: optional behavior5455## Canonical rules table5657Use this table as the single source of truth for output structure and bullet formatting.5859| ID | Scope | Requirement |60| ------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |61| `FMT-1` | Output scope | In full-file mode, output MUST be a valid `CHANGELOG.md` and first heading MUST be `# Changelog`; in release-fragment mode, output MUST contain exactly one release block. Optional trailing `Warnings:` metadata MAY appear after the artifact when needed. |62| `FMT-2` | Release ordering | If present, `Unreleased` MUST be the first release heading and MUST NOT be included in semantic version ordering. |63| `FMT-3` | Release ordering | Released versions (excluding `Unreleased`) MUST be sorted latest-first by semantic version. |64| `FMT-4` | Release headings | Released version headings MUST include ISO date `YYYY-MM-DD`; linked format `## [1.2.3] - YYYY-MM-DD` is SHOULD, plain `## 1.2.3 - YYYY-MM-DD` is MAY. `Unreleased` SHOULD be undated (`## [Unreleased]` or `## Unreleased`) unless the user explicitly asks for a dated form. |65| `FMT-5` | Link refs | If any release heading is linked (`## [<label>] - YYYY-MM-DD`), trailing link references MUST be present at file end and define each linked label exactly once. |66| `FMT-6` | `Unreleased` link | If `Unreleased` is a linked heading, its reference MUST use a compare URL ending with `...HEAD`. |67| `FMT-7` | Release links | Linked released versions SHOULD point to release tags (matching repository tag conventions). |68| `FMT-8` | Sections | Release groups MUST use only, and in this order: `Changed`, `Added`, `Removed`, `Fixed`; empty groups MUST NOT be emitted. |69| `FMT-9` | No user-facing changes | If a release has no user-facing changes, default is skip (including release-fragment mode). If explicitly requested, MAY add a one-line maintenance notice under the release heading. |70| `BUL-1` | Writing style | Use imperative style (`Add`, `Fix`, `Remove`, `Bump`), keep bullets concise, and describe user impact (not internal trivia). |71| `BUL-2` | Breaking changes | Breaking changes MUST be prefixed with `**Breaking:**`. |72| `BUL-3` | Bullet group order | Every bullet MUST follow this order: optional references group, required commit-links group, required final authors group. Commit-links group MUST contain at least one commit link when available; otherwise use `source unavailable` and emit a warning. |73| `BUL-4` | Group formatting | References, commit links, and authors MUST each appear in one parentheses group; multi-item groups MUST use comma-separated lists. |74| `BUL-5` | Template source | Bullet shape and full file layout MUST follow `references/CHANGELOG.md`. |75| `BUL-6` | Missing metadata | If author metadata is missing, authors group MUST be `(Unknown author)` and a warning MUST be emitted. |7677## Input model7879```text80<type>[optional scope]: <description>8182[optional body]8384[optional footer(s)]85```8687Recognize trailers and reference keywords:8889- `Category:`90- `Ref:`91- `Re:`92- `Co-authored-by:`93- `BREAKING CHANGE:`9495Also recognize GitHub issue-linking keywords:9697- `close`, `closes`, `closed`98- `fix`, `fixes`, `fixed`99- `resolve`, `resolves`, `resolved`100101For `Ref`, `Re`, and the keywords above:102103- matching is case-insensitive104- `:` is optional (for example `Ref ABC-123` and `Ref: ABC-123` are both valid)105- treat GitHub keywords as reference signals only when an issue target is present (for example106 `Fixes #123`)107108## Classification algorithm109110Apply in this order:1111121. `Category:` trailer override1132. Conventional Commit type mapping1143. Semantic fallback115116### 1) Category override (highest priority)117118If `Category:` maps to a group, use it:119120- `change`, `changed` -> `Changed`121- `add`, `added` -> `Added`122- `remove`, `removed` -> `Removed`123- `fix`, `fixed` -> `Fixed`124125Rules:126127- case-insensitive matching128- if multiple `Category:` trailers exist, use the last recognized one129- ignore unknown values and continue130131### 2) Conventional Commits mapping132133- `feat` -> `Added`134- `fix` -> `Fixed`135- `perf` -> `Changed` only if user-facing; otherwise skip136- `refactor` -> `Changed` only if user-facing; otherwise skip137- `revert` -> `Changed` or `Fixed` based on actual user effect138- `docs`, `style`, `test`, `chore`, `ci`, `build` -> skip unless user-facing139140### Type compatibility notes141142- This skill classifies commit history, so it accepts both the strict type set used by143 `git-commits` and broader Conventional Commit variants observed in existing repositories.144- Accepted history-only variants include: `perf`, `style`, `test`, `ci`, `build`.145- This does NOT change the output type policy of `git-commits`; it only affects changelog146 classification of existing commits.147148### 3) Semantic fallback149150If type is missing or unclear:151152- Existing behavior changed -> `Changed`153- New capability -> `Added`154- Capability removed -> `Removed`155- Bug corrected -> `Fixed`156157### Conflict examples158159- `fix(api): ...` + `Category: add` -> `Added`160- `feat!:` + `Category: remove` -> `Removed` + `**Breaking:**`161- `docs:` + `Category: fixed` -> `Fixed`162163## Classification decision tree1641651. If there is a recognized `Category:` value, map it and stop.1662. Else, if Conventional Commit type is recognized, apply the type mapping.1673. Else, classify by semantic user impact (`Changed`/`Added`/`Removed`/`Fixed`).1684. If breaking signal exists (`!` or `BREAKING CHANGE:`), prefix with `**Breaking:**`.169170## Breaking change handling171172- If header has `!` or body/footer contains `BREAKING CHANGE:`, prefix with `**Breaking:**`173- Keep the entry in `Changed`/`Added`/`Removed`/`Fixed` by impact (no extra section)174175## User-facing quick test176177Usually include:178179- API contract or output changed180- CLI flags/defaults changed181- Config shape/defaults changed182- Runtime/performance behavior users notice183- Dependency bump that fixes production bug/security issue184185Usually skip:186187- Internal refactor without behavior change188- CI/test/style-only updates189- Dev tooling and internal docs only190- Dependency bump for dev/test-only tooling191192## References and authors193194- Commit hash SHOULD be a markdown link when available:195 - ``[`d23ba8f`](https://github.com/OWNER/REPO/commit/d23ba8f)``196- Group formatting for references, commit links, and authors MUST follow `BUL-3` and `BUL-4`197- Build references from:198 - explicit PR/issue links199 - `Ref` and `Re` trailers200 - GitHub keywords (`close*`, `fix*`, `resolve*`) with issue targets201- Normalize before deduplication:202 - treat `#123` and `https://github.com/OWNER/REPO/issues/123` as the same issue reference203 - normalize case for keyword-style references (for example `jira-123` -> `JIRA-123`)204- Reference order is deterministic:205 1. first: one high-signal repository reference (prefer PR, otherwise issue)206 2. then: remaining unique references in first-seen order207- Commit-link order is deterministic:208 1. deduplicate by commit hash209 2. keep first-seen order210- Use commit author as primary author211- Append `Co-authored-by:` names (extract name before `<email>`)212- Authors MUST be deduplicated in stable first-seen order213- For aggregated bullets, authors MUST be the deduplicated union of commit authors and214 `Co-authored-by:` names from all included commits, preserving stable first-seen order215- If commit author is a bot and merger is known, prefer the human merger name216217## Metadata fallback policy218219- If author cannot be determined from metadata, use `(Unknown author)` and emit a warning.220- If no commit link can be determined, use `(source unavailable)` as the commit-links group and emit221 a warning.222- Missing metadata MUST NOT be a sole reason to drop user-facing bullets.223224## Fail policy225226- If any structural `MUST` rule is violated and cannot be recovered with fallback policy, fail.227- Missing author/commit metadata alone MUST NOT trigger hard fail.228- If changelog scope is unclear, default to release-fragment mode instead of failing.229230## Authoring workflow2312321. Collect input: commits, PRs, issues, release notes.2332. Parse commit headers, body, and trailers.2343. Classify each change using rules above.2354. Remove non-user-facing noise and no-op pairs (change + immediate revert).2365. Rewrite into concise user-facing bullets.2376. Group by `Changed`, `Added`, `Removed`, `Fixed` in that order.2387. Validate against `Canonical rules table` and `references/CHANGELOG.md`.239240## Anti-patterns241242- Raw technical commit text with no user context243- Non-standard sections (`Security`, `Docs`, `Chore`, etc.)244- Internal-only noise in public changelog245- Missing `**Breaking:**` marker for incompatible changes246247## Quality checklist248249- Validate all applicable `FMT-*` and `BUL-*` requirements from `Canonical rules table`.250- Verify output shape against `references/CHANGELOG.md`.251- Ensure warning messages exist for every metadata fallback.252- Any checklist failure MUST trigger `Fail policy`.253254## Prompt templates255256- `Generate a Common Changelog entry for version <VERSION> from these commits and PRs. Keep only user-facing changes, include references, and mark breaking changes.`257- `Normalize this existing changelog fragment to Common Changelog format without losing important user-impact details.`258- `Classify these Conventional Commits into Changed/Added/Removed/Fixed and explain any skipped items.`259260## References261262- `references/CHANGELOG.md` (local formatting template)263- https://common-changelog.org/264- https://github.com/vweevers/common-changelog265- https://www.conventionalcommits.org/266- https://git-scm.com/docs/git-interpret-trailers267- https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword