ADR-0892: Conventional-Commits coverage + Changelog-fragment section hygiene¶
- Status: Accepted
- Date: 2026-05-30
- Deciders: Lusoris, Claude (Opus 4.7)
- Tags: process, release, changelog, ci, fork-local
Context¶
A scheduled audit of the last 50 commits on origin/master and of the changelog.d/ fragment tree surfaced two release-please correctness gaps that the existing pipeline silently absorbed:
- Three valid Conventional-Commits types had no release-please section configured for the root package —
revert,security,style. One commit on master (d0b697c6—revert: drop continue-on-error on release-please …) usedrevert, which falls through the configured-section list inrelease-please-config.jsonand lands under no heading in the generated CHANGELOG. The next time a security-flagged or style-only commit reaches the trunk it would hit the same drop. - Thirty-two changelog fragments lived under invalid section directories —
changelog.d/perf/(27 files) andchangelog.d/performance/(5 files). Keep-a-Changelog has no "Performance" section, and the renderer inscripts/release/concat-changelog-fragments.shiterates a hard-coded section list (added → changed → deprecated → removed → fixed → securityper ADR-0221). Both directories were therefore silently skipped at render time, so every performance entry written toperf/orperformance/would never appear in the renderedUnreleasedblock. The contributors clearly believedperfwas conventional — the Conventional-Commits spec listsperfas a recognised type, andrelease-please-config.jsoneven has a{ "type": "perf", "section": "Performance" }row for the commit-message lane. But the fragment lane is governed by ADR-0221 and the bash renderer, not by release-please, so the two pipelines disagreed.
The commit-side gap (gap 1) corrupts the rendered CHANGELOG by dropping section assignment for any future revert: / security: / style: commit. The fragment-side gap (gap 2) had already silently lost ~32 performance bullets that contributors had written in good faith — at release time those entries would not have appeared in any generated [Unreleased] block.
Decision¶
Two coordinated changes:
- Extend the root package's
changelog-sectionsinrelease-please-config.jsonto cover the three missing standard Conventional-Commits types:revert → Reverts,security → Security,style → Style. Theaipackage gets the same three entries (it inherits all root types in practice and the smallest release-please packages —dev-llm,mcp-server/vmaf-mcp— keep their minimal type sets, since their commit traffic is narrow and doesn't see these types in practice). - Merge
changelog.d/perf/andchangelog.d/performance/intochangelog.d/changed/with aperf-filename prefix so the entries sort together inside the rendered### Changedsection. The two source directories are removed entirely; thechangelog.d/README.mdis updated to call out that performance work belongs inchanged/perf-<topic>.md. Each migrated fragment had its leadingPerformance/perf(…)heading stripped (the renderer adds### Changeditself), and any other in-body heading was demoted to a bold-prefixed bullet so it sits cleanly under the rendered section heading.
The rule going forward is that the changelog.d/ section dirs are exactly the six Keep-a-Changelog sections — added, changed, deprecated, removed, fixed, security. Any other directory is a contributor mistake and the renderer will not emit its contents. The perf- filename prefix is the established convention for performance work, and the same pattern can be applied to other thematic groupings inside a Keep-a-Changelog section (e.g. build-, ci-) without changing the renderer.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
Move perf fragments to changed/ + extend release-please types (chosen) | Aligns the fragment tree with the documented ADR-0221 section list; restores 32 lost bullets to the rendered CHANGELOG; gives release-please a section for every type it will see on this branch | Touches 32 fragment files (mechanical rename + heading scrub) | Chosen |
Teach the renderer a performance/ section | Smaller diff (one bash array + the README) | Diverges from Keep-a-Changelog standard the rest of the docs reference; sets a precedent that any future ad-hoc directory ("research/", "ai/") can be added rather than mapped to a KaC section; ADR-0221 explicitly lists the six KaC sections — adding a seventh would need a supersedes-ADR | Rejected — ADR-0221's section list is the contract, not the renderer |
| Delete the orphan fragments outright | Trivially restores invariant | Throws away 32 contributor-written bullets that describe real merged work | Rejected — content is real history; loss is not acceptable |
Leave commit-side gap (revert/security/style) open, document workaround | Zero risk | Next revert: / security: commit on master silently loses its CHANGELOG section assignment; the audit just-now found one such commit already in tree | Rejected — the cost to add three section rows is two lines per package |
Consequences¶
- Positive: The rendered CHANGELOG is now self-consistent — every fragment lives in a directory the renderer iterates, and every Conventional-Commits type used on this branch maps to an explicit release-please section. Future drift is bounded by the README's explicit enumeration of the six allowed directories.
- Positive: Performance entries inside
### Changedare discoverable because theperf-filename prefix sorts them contiguously; readers see a perf-cluster inside the Changed section instead of a scattered mix. - Negative: 32 fragment files were renamed and their headings rewritten. Anyone holding a branch that touches one of the moved files will hit a rename-detection conflict on rebase. Mitigation: rebase early;
git diff --find-renamesresolves cleanly. - Neutral / follow-ups:
- The
--checklane is already in place via the renderer but is not yet a required CI status; tightening that to a required check is a separate (small) follow-up. _pre_fragment_legacy.mdstill encodes a 3500-line frozen archive; collapsing that block at the next release tag is tracked in ADR-0221's status-update note.
References¶
- ADR-0221 — fragment-file pattern, defines the six Keep-a-Changelog section list.
scripts/release/concat-changelog-fragments.sh— the renderer (hard-codedSECTIONS=(added changed deprecated removed fixed security)array).release-please-config.json— per-type section mapping for the commit-message lane.docs/research/0892-conventional-commits-audit-2026-05-30.md— full audit log (commit-by-commit table + fragment inventory).- Keep-a-Changelog — defines the six section types as the standard.
- Source: scheduled audit run on 2026-05-30 against
master@83698bd5b2; surfaced one in-treerevert:commit + 32 fragment files in undocumented directories.