# Changelog

> Use when asked to write, draft, or update the changelog for a NegPy release — e.g. "changelog for 0.42.0", "draft release notes since the last tag", "what changed since 0.41.0". Pulls every commit since the previous git tag, summarizes them into concise user-facing bullets, credits outside contributors by @handle, and drafts the entry into docs/CHANGELOG.md for approval. Keywords: changelog, release notes, CHANGELOG.md, version bump, since tag, PRs, contributors.

- Skill: `marcinz606/changelog` (Agent Skill)
- Install (CLI): `npx skillmds@latest add marcinz606/changelog`
- Raw SKILL.md: https://api.skillmd.com/api/skills/marcinz606/changelog/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: marcinz606 (https://skillmd.com/u/marcinz606)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/marcinz606/changelog

---


# Draft a release changelog

## Overview

Turn the commits since the last release tag into a `docs/CHANGELOG.md` entry:
concise user-facing bullets, contributors credited, in the house style.

**Core principle:** always draft first and show the user — apply to
`docs/CHANGELOG.md` only after they accept. The user asked for a draft to
review, not an automatic edit.

## Workflow

1. **Get the target version** from the request (e.g. `0.42.0`) and find the range:
   ```bash
   git tag --sort=-v:refname        # newest tag first
   ```
   - Target is **not yet a tag** (drafting an unreleased version, the usual case) → range is `<newest-tag>..HEAD`.
   - Target **is** an existing tag → range is `<tag-immediately-before-it>..<target-tag>`.

2. **List commits with authors + emails** (email carries the GitHub handle):
   ```bash
   git log <range> --format='%h|%an|%ae|%s'
   ```
   For a commit whose body matters (root cause, what actually changed), read it:
   ```bash
   git show -s --format='%s%n%b' <hash>
   ```

3. **Derive contributor handles** from the author email:
   - `NNN+handle@users.noreply.github.com` → `@handle` (e.g. `175231748+linkmodo@...` → `@linkmodo`).
   - Other emails: reuse the handle that person already got in earlier `docs/CHANGELOG.md` entries (`git log`/grep the file); ask the user if unknown.
   - Known map: Paul Glover=@paulglover, jboneng=@jboneng, Robin/light-sntchr=@light-sntchr, Henning Ullrich=@hullrich.
   - **`marcinz606` is the owner — never credit them.**

4. **Drop housekeeping commits** — no changelog line for: README/badge edits, changelog typo fixes, merge/revert/"rogue file" cleanups, pure internal log-noise fixes, version bumps.

5. **One bullet per feature, never one per commit.** A feature built over
   several commits — the feature, then its fixes, follow-ups and polish — gets a
   single bullet describing the shipped state. Fold anything the user should
   know into that bullet and write no extra `Fix:` or `Change:` line: a bug that
   never reached a build is not news. Group the range's commits by feature
   first, then write. Check every candidate bullet against the range's other
   bullets *and* the entries already in the section, not only the new commits.

   The same holds for a fix to an existing panel or control touched more than
   once in the range: one bullet naming the end state, not a line per commit.

6. **Check what's already documented** — the top `##` section may already hold a few entries. Merge into it; don't duplicate.

7. **Write one bullet per feature** in the house style (below), grouped New → Change → Fix.

8. **Show the draft in the reply.** On approval, insert into `docs/CHANGELOG.md` under the target `## X.X.X` heading (create it if absent), merged with any entries already there.

9. **Set `VERSION` to the requested version** — the repo-root `VERSION` file holds
   the bare number (`0.56.0`, no `v`, trailing newline). Write it in the same
   change as the accepted changelog entry.

## House style

(Established preference — see the user's changelog-style memory.)

- **One entry per feature**, not per commit — the shipped state, with its in-cycle fixes folded in.
- **One line per entry**, no explanatory paragraphs: `Prefix: **bold lead** — terse clause naming what was done.` Skip the failure-mode/root-cause narrative even on fixes. The long multi-sentence bullets in old sections are **not** the target.
- Prefix each with `New:` / `Change:` / `Fix:` (use `Change/Fix:` if genuinely both). Group in that order.
- **No PR/issue numbers** (`(#604)`) — user-facing notes, not a dev index.
- US **"color"** in prose, matching the UI labels (Color Negative, colour spellings were swept out in 0.50.0).
- Plain, factual, non-salesy — it's an open-source project. No marketing framing, no dunking on other tools.
- Credit code/idea contributors with a trailing `@handle`; **never** credit whoever merely requested or reported it.

## Example (0.41.0, accepted)

```markdown
- New: **Manage Database…** — dialog to inspect and clear stored data; Clear Saved Edits or Reset Everything, both guarded. @linkmodo
- Change: **Bottom toolbar streamlined** — zoom slider removed, GPU/CPU toggle moved to the overflow menu, tooltips on every item; Before/After and Peak Flat are now mutually exclusive and survive rotate/flip. @linkmodo
- Fix: **Saved export destination restored on reopen** — the Folder mode no longer resets to "Subfolder of source". @paulglover
```

## Gotcha

`git log`/`git show` output is piped through the RTK hook, which **truncates
long output and garbles it**. If a log looks cut off, rerun with `rtk proxy git …`
to bypass the filter, or dump to a file and open it with the Read tool (Read is
unhooked). Trust exit codes over rendered text.

