Two paired updates:
1. **`CLAUDE.md` § Releases** — rewritten to match the actual workflow now
that #436's auto-promote step lands the entries automatically.
The old text told Claude to 'Add a new `## [X.Y.Z] - YYYY-MM-DD`
block at the top of CHANGELOG.md' as the first step. That instruction
is the exact pattern that caused the v0.9.5 sparse-release-notes
incident — a hand-added sparse `[X.Y.Z]` block (one early fix
pre-staged) is what the extractor picked, ignoring everything under
`[Unreleased]` above it.
New default: write entries under `## [Unreleased]` during normal
work. The Release workflow promotes them at release time. The
formatting rules (sub-section grouping, user-perspective wording,
issue/PR refs) are preserved. The link-reference rule moves to 'don't
add it yourself' since `prepare-release.mjs` now appends it.
2. **`scripts/prepare-release.mjs`** — extended to also append a
`[X.Y.Z]: https://github.com/colbymchenry/codegraph/releases/tag/vX.Y.Z`
link reference at the end of CHANGELOG.md when promoting (idempotent
— no-op if one already exists, regardless of where in the file it
sits). This is what makes the `## [X.Y.Z]` heading text auto-link
to its release tag in GitHub's renderer; without it the heading still
renders, just unlinked. 3 new tests cover Case A append, Case B
append-when-merging, and no-double-add.
940/942 existing tests still pass (2 pre-existing skips); +3 new tests.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>