Skip to content

CHANGELOG.md has a second, empty [Unreleased] heading buried in the release history #157

Description

@macanderson

Problem

CHANGELOG.md contains two ## [Unreleased] headings. The second one is
empty and sits in the middle of the released history, between the [0.1.2] and
[1.0.0] sections:

## [Unreleased]        <- line 20, the real one, has content
...
## [0.1.2] — 2026-08-01 (crate release)
...
## [Unreleased]        <- empty, and out of chronological order
## [1.0.0] — 2026-08-11 (stable protocol and crate release)

Two things are wrong with it:

  • It is empty, so it renders as a heading with nothing under it.
  • It is in the wrong place. Unreleased means "not yet shipped"; this one is
    pinned between two shipped versions, below a release that came after it.

The likely cause is a release cut that added the new version heading without
removing the [Unreleased] placeholder above it, but that is a guess from the
shape — I did not confirm it against the commit that introduced it.

Why it is worth fixing rather than ignoring

.github/workflows/changelog.yml drafts missing entries into [Unreleased]
when a merge forgets them. Any tool — that workflow, a release script, or a
person — that searches for the [Unreleased] heading and takes the first or
last match now has two answers to choose between, and only one is right.
Nothing has picked the wrong one yet as far as I can tell, which makes this
cheap to fix now and awkward to debug later.

Worth checking as part of the fix: does changelog-ai.sh (or whatever the
workflow calls) anchor on this heading, and if so, which match does it take?

What done looks like

  • The stray empty ## [Unreleased] between [0.1.2] and [1.0.0] is deleted.
  • Exactly one ## [Unreleased] remains, at the top.
  • If any script anchors on that heading, it is confirmed to still work — and
    ideally asserts there is exactly one, so this cannot silently return.

Verify

rg -c '^## \[Unreleased\]' CHANGELOG.md    # expect 1

Files

  • CHANGELOG.md
  • .github/workflows/changelog.yml and .github/scripts/changelog-ai.sh — check
    whether either anchors on the heading.

Context

Noticed in PR #109 while checking that CHANGELOG.md had auto-merged sensibly
after a rebase. It is pre-existing on maingit show origin/main:CHANGELOG.md
has both headings, at lines 20 and 178 — and was left alone there to keep that
PR about schema identity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Next cycle

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions