Goal
Convert CHANGELOG.md to a CPAN::Changes::Spec-compliant Changes file so MetaCPAN renders the structured "Changes for version X.Y.Z — DATE" panel at the top of the dist page (compare with SPVM).
Background
MetaCPAN scans the dist root for a file matching ^Changes(\.[a-zA-Z]+)?$ and parses it via CPAN::Changes (which implements CPAN::Changes::Spec). If parsing succeeds the dist page shows a per-version panel. If it fails — or the file is just recognized by name but not Spec-shaped — the file is shown as a plain doc link only.
Today our CHANGELOG.md is Keep-a-Changelog / git-cliff Markdown:
## [0.400] - 2026-05-09 — Markdown brackets + dash → Spec parser rejects the version line.
### Bug Fixes — Markdown heading → groups not detected (Spec wants [Bug Fixes]).
*(cli)* italic scope marker → renders as literal * in plain text.
So MetaCPAN finds the file (link visible in the Code section) but does not give us the SPVM-style panel.
Spec target
0.400 2026-05-09
[Features]
- cli: short-help via -h and informative unknown-subcommand error
- validator: per-call overrides for purpose ID lists
[Bug Fixes]
- cli: provide concise usage errors
- cmp-validator: make JSON::PP and Time::Piece optional
0.391 2026-05-07
[Features]
- cli: integrate CMPValidator into iabtcfv2 validate
Hard rules:
- Version + date on the left margin, no Markdown adornments.
- One blank line between releases.
- Group names in
[Brackets], not ### Markdown headings.
- Entries indented (4 spaces is conventional), bulleted with
-.
- Date is
YYYY-MM-DD (or W3CDTF YYYY-MM-DDTHH:MM:SSZ).
Proposed approach (option B from the discussion)
Single source of truth, driven by git-cliff:
- Write a custom
cliff.toml body template that emits CPAN::Changes::Spec instead of the current Markdown.
- Rename
CHANGELOG.md → Changes (keep the file at the dist root; add to MANIFEST).
- Regenerate from the existing tag history so all past releases (v0.270 → v0.400) come out Spec-shaped.
- Verify with MetaCPAN's public Changes Parser before tagging the next release.
- Update
CONTRIBUTING.pod step 4 (the changelog regeneration step) to reference the new file name.
- Drop
CHANGELOG.md from any references in README, CONTRIBUTING.pod, TODO.pod, MANIFEST.SKIP defenses, etc.
Out of scope
- Switching away from git-cliff as the generator (it can target either format with a template change).
- Maintaining two parallel changelog files (Option C in the discussion — rejected as too much drift risk under maintenance mode).
Definition of done
- A
Changes file exists at the dist root, parses cleanly via CPAN::Changes->load_string, and lists every released version from v0.270 onward with the same content currently in CHANGELOG.md.
CHANGELOG.md is removed; references elsewhere in the tree updated.
- A dev tarball uploaded (or a draft PAUSE upload from a fork) renders the structured "Changes for version" panel on MetaCPAN.
CONTRIBUTING.pod reflects the new filename + the validation step against metacpan.org/changes_parser.
When to do this
Post-v0.400. Mid-release format swaps add risk for no PAUSE-side benefit (PAUSE doesn't care about the format; only humans browsing MetaCPAN do).
Goal
Convert
CHANGELOG.mdto a CPAN::Changes::Spec-compliantChangesfile so MetaCPAN renders the structured "Changes for version X.Y.Z — DATE" panel at the top of the dist page (compare with SPVM).Background
MetaCPAN scans the dist root for a file matching
^Changes(\.[a-zA-Z]+)?$and parses it viaCPAN::Changes(which implementsCPAN::Changes::Spec). If parsing succeeds the dist page shows a per-version panel. If it fails — or the file is just recognized by name but not Spec-shaped — the file is shown as a plain doc link only.Today our
CHANGELOG.mdis Keep-a-Changelog / git-cliff Markdown:## [0.400] - 2026-05-09— Markdown brackets + dash → Spec parser rejects the version line.### Bug Fixes— Markdown heading → groups not detected (Spec wants[Bug Fixes]).*(cli)*italic scope marker → renders as literal*in plain text.So MetaCPAN finds the file (link visible in the Code section) but does not give us the SPVM-style panel.
Spec target
Hard rules:
[Brackets], not### Markdown headings.-.YYYY-MM-DD(or W3CDTFYYYY-MM-DDTHH:MM:SSZ).Proposed approach (option B from the discussion)
Single source of truth, driven by git-cliff:
cliff.tomlbody template that emits CPAN::Changes::Spec instead of the current Markdown.CHANGELOG.md→Changes(keep the file at the dist root; add toMANIFEST).CONTRIBUTING.podstep 4 (the changelog regeneration step) to reference the new file name.CHANGELOG.mdfrom any references inREADME,CONTRIBUTING.pod,TODO.pod,MANIFEST.SKIPdefenses, etc.Out of scope
Definition of done
Changesfile exists at the dist root, parses cleanly viaCPAN::Changes->load_string, and lists every released version from v0.270 onward with the same content currently inCHANGELOG.md.CHANGELOG.mdis removed; references elsewhere in the tree updated.CONTRIBUTING.podreflects the new filename + the validation step againstmetacpan.org/changes_parser.When to do this
Post-v0.400. Mid-release format swaps add risk for no PAUSE-side benefit (PAUSE doesn't care about the format; only humans browsing MetaCPAN do).