Public changelog → public-changelog.md
Draft a release-notes entry and write it into public-changelog.md at the repo
root. Focus only on functional user-facing changes, or on new features.
This is not the contributor-facing changelog. Where a project also keeps a
CHANGELOG.md in Keep-a-Changelog format, that one is the dense internal record
(file paths, class names, flags) and is a separate step. public-changelog.md is
a short, plain-language announcement for people who use the product.
Step −1. Read the project profile — do this before anything else
Read ${CLAUDE_PROJECT_DIR}/.claude/public-changelog.md. It names the four
things that differ per project:
- Language the entry is written in.
- Audience — who counts as a user here.
- Jargon glossary — the internal names to avoid and the plain words to use instead.
- File header to create
public-changelog.mdwith if it does not exist.
If the profile is missing, say so and ask the user for the language and audience before drafting — do not guess, and in particular do not default to English on a Romanian-facing product.
Steps
- Read the PR title, description, and diff.
- Prefer
gh pr view <id> --json title,body,urlandgh pr diff <id>. - If no PR exists yet, use the branch diff (
git diff main...HEAD) and ask the user for the PR id — the entry must reference it. - Identify the user-visible change: a new feature, a bug fix, a breaking change, or an internal-only refactor.
- Prefer
- Stop for internal-only changes. If the change is internal only — tests,
CI, build tooling, comments, dead-code removal, pure refactors, dependency
bumps with no visible effect, admin-panel plumbing nobody notices — do not
draft an entry and do not touch
public-changelog.md. Report: "Internal change — no release note." and stop. - Otherwise draft a one-paragraph entry for end users, not contributors.
- Write in the profile's language.
- Use the imperative voice.
- Avoid jargon and internal codenames — apply the profile's glossary.
- Say where in the product the change lives, so readers can find it.
- Do not mention file paths, function names, class names, or commit SHAs.
- Classify the entry under exactly one label: New / Improved / Fixed / Breaking, translated per the profile (Romanian: Nou / Îmbunătățit / Rezolvat / Modificare majoră).
- Breaking changes: explicitly list what users need to do to migrate — concrete steps, not a warning.
- Determine the entry date (
YYYY-MM-DD). Use the PR's merge date when the PR is merged (gh pr view <id> --json mergedAt); otherwise use today's date fromdate +%F. Never guess or infer the date — always read it from one of those two commands. - Write it into
public-changelog.md, newest entry first, mentioning the date and the PR id. Create the file with the profile's header if it does not exist yet. Never rewrite or reorder existing entries.
Length
Keep drafts short — 2 to 4 sentences. Long release notes don't get read.
Entry format
Prepend each new entry directly under the file header:
## <YYYY-MM-DD> — [New | Improved | Fixed | Breaking] — <short title> (#<PR id>)
<2–4 sentence paragraph, imperative voice, in the profile's language>
<breaking changes only: the steps users need to take>
When one PR carries several unrelated user-visible changes that need different labels, write one entry per change — each with its own label, and all sharing the same date and PR id.
Output
Show the user the exact entry you added, plus the date and PR id it references. If you stopped at step 2, say so explicitly and leave the file untouched.