Reusable changelog-body linter (Layer 1 mechanical checks) + fragment scaffolding (Layer 2) #282
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#282
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
The Cold-Read discipline (BookStack page 208, applied at release-toolkit#264 pre-cut) catches ~60-70% mechanical + structural issues in rolling-PR bodies. Automating those catches converts "manual Cold Read before every cut" into "automated linter on every PR + optional Cold Read for edge cases."
Scope
Layer 1 — Mechanical linter (this tracker's primary scope)
Reusable workflow
reusable-changelog-body-check.yml— sibling toreusable-changelog-fragment-check.yml(#278). Runs at pull_request time on release-prep/rolling PRs. Checks:## v?\d+\.\d+\.\d+(or fenced equivalent) present + date matches expected formatNone.allowedmanifest.last_released_version + 1(warn on suspected forward-refs like "since v0.22.0" in a v0.20.0 cut)### Sectionheaders: redundant guard on top of the #272 assembly fixFail-loud on violations; adopters wire it into their
pull_requestworkflow same shape as fragment-check.yml.Layer 2 — Fragment scaffolding (bundled scope)
changelog.d/.template.mdwith pre-baked structure (Outcome + Required action placeholders)Layer 3 — Reader-simulation (explicitly OUT of scope)
Severity ordering, semantic emphasis promotion, missing-context checks — these need judgment. Cold Read remains the opt-in discipline for major cuts + bodies exceeding the automated ceiling.
Empirical anchor
release-toolkit#264 Cold-Read pass (Pilot 2026-07-02, Bosun-routed) caught 5 structural issues that mostly fall under Layer 1:
4 of 5 catches would fire automatically under Layer 1 + Layer 2.
Refs
Reopened — auto-closed on PR #289 merge (
Closes #282 Layer 1close-keyword doesn't distinguish sub-scope). Per Bosun16:22:58ratification: "#282 stays open pending Layer 2 landing."Layer 1 status: ✅ DONE at PR #289 (merged as
ee679838). Delivered:.forgejo/workflows/reusable-changelog-body-check.yml— reusablescripts/changelog-body-check.sh— 6 mechanical checks (version header + date, standard sections present, forward-refs, length ceiling 5000, bullet/prose consistency, duplicate section headers)tests/changelog-body-check.bats— 10 mutation-verify testsdocs/integration.md— consumer wiring stanzaLayer 2 status: OPEN. Scope per issue body:
changelog.d/.template.mdwith pre-baked structure (Outcome + Required action placeholders)Layer 3: Explicit out-of-scope (reader-simulation, severity ordering, semantic emphasis, missing-context) — Cold Read remains opt-in.
Next PR against
i/282-layer2-fragment-scaffoldingwill close this on merge.