docs(changelog.d): header + body fragment shape, per Alex's revision #631

Merged
alex merged 1 commit from i/627-header-plus-body into main 2026-07-31 15:47:03 +02:00
Owner

Round 3 on #627, implementing Alex's revision: "the previous one-liner used as a header
plus the description which is currently the sole content of a fragment."

The composer measurement changed the format

Dispatched to check the composer before committing to a shape. It does not compose the
obvious draft:

_normalize_paragraph_continuations  JOINS an indented line onto the preceding line
                                    unless a blank line has flushed the unit first
fragment written as composes to
header, body directly beneath one run-on bullet — body swallowed into the header line
header, blank line, indented body header bullet + indented paragraph

The blank line is load-bearing and was undocumented. Verified by running the real
categorize_fragments on both variants, not by reading the awk.

Header-in-frontmatter rejected on evidence

_fragment_body_lines strips frontmatter from the composed body, and
fragment_get_summary + categorize_fragment_summaries were removed in #301. That
route means reviving a deleted feature. This shape needs no composer change at all.

Result

fragments        2855  →  1676 chars
composed body    2221  →  1840 chars      (current-on-rolling → this)
changelog-body-check   9/9 PASS, zero warnings
fragment-check         exit 0

Check 5 clears — every section is all-bullet now.

Editorial calls

  • Header carries the outcome; the body keeps only what the header does not say. The
    pre-existing bodies opened by paraphrasing their own headline — that redundancy is what
    read as bulky, and removing it is what makes header+body a net cut rather than an
    addition.
  • - **scope**: not - **scope** — . 49/50 of v0.34.0's bullets use the colon, and
    the commit-derived bullets sharing the section use it too. One separator per list.
  • 605's scope disclosure survives intact in the body — the second-bullet question
    from #630 is withdrawn.

Template updated in the same PR

changelog.d/.template.md restates the rule as one header bullet + blank line + indented
body of 1-3 sentences
, documents the load-bearing blank line, and names the
body-restates-header failure mode. Without this the next author writes the old shape and
no check complains
— the gate cannot see it, which is the same blindness #628 measured.

Refs #627. Supersedes #630 (pure one-liners — Alex backed off that; too lossy).

Round 3 on #627, implementing Alex's revision: *"the previous one-liner used as a header plus the description which is currently the sole content of a fragment."* ## The composer measurement changed the format Dispatched to check the composer before committing to a shape. It does not compose the obvious draft: ``` _normalize_paragraph_continuations JOINS an indented line onto the preceding line unless a blank line has flushed the unit first ``` | fragment written as | composes to | |---|---| | header, body directly beneath | **one run-on bullet** — body swallowed into the header line | | header, **blank line**, indented body | header bullet + indented paragraph ✅ | **The blank line is load-bearing and was undocumented.** Verified by running the real `categorize_fragments` on both variants, not by reading the awk. ## Header-in-frontmatter rejected on evidence `_fragment_body_lines` strips frontmatter from the composed body, and `fragment_get_summary` + `categorize_fragment_summaries` were **removed in #301**. That route means reviving a deleted feature. **This shape needs no composer change at all.** ## Result ``` fragments 2855 → 1676 chars composed body 2221 → 1840 chars (current-on-rolling → this) changelog-body-check 9/9 PASS, zero warnings fragment-check exit 0 ``` ✅ **Check 5 clears** — every section is all-bullet now. ## Editorial calls - **Header carries the outcome; the body keeps only what the header does not say.** The pre-existing bodies opened by paraphrasing their own headline — that redundancy is what read as bulky, and removing it is what makes header+body a net *cut* rather than an addition. - **`- **scope**: ` not `- **scope** — `.** 49/50 of v0.34.0's bullets use the colon, and the commit-derived bullets sharing the section use it too. One separator per list. - **`605`'s scope disclosure survives intact** in the body — the second-bullet question from #630 is withdrawn. ## Template updated in the same PR `changelog.d/.template.md` restates the rule as *one header bullet + blank line + indented body of 1-3 sentences*, documents the load-bearing blank line, and names the body-restates-header failure mode. **Without this the next author writes the old shape and no check complains** — the gate cannot see it, which is the same blindness #628 measured. Refs #627. Supersedes #630 (pure one-liners — Alex backed off that; too lossy).
docs(changelog.d): header + body fragment shape, per Alex's revision
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 3s
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 38s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 4s
register-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 2m9s
tests / shellcheck (pull_request) Successful in 8s
check-self-bootstrap / check (push) Successful in 3s
go-ci / lint + build + test (push) Successful in 31s
release / decide + act (push) Successful in 10s
release / release (push) Successful in 0s
tests / bats (push) Successful in 2m8s
tests / shellcheck (push) Successful in 8s
87a215324d
Alex revised the target from one-liners to "the previous one-liner used
as a header plus the description". This implements that shape and
restates the template rule so the next author writes it.

MEASURED THE COMPOSER FIRST, as dispatched — and it changed the format:

`_normalize_paragraph_continuations` JOINS an indented line onto the
preceding line unless a blank line has flushed it. A header with the
body written directly beneath it therefore collapses into ONE run-on
bullet. With a blank line between them the indent is preserved and the
body composes as a separate paragraph inside the bullet. The blank line
is load-bearing and was undocumented; the template now says so.

The header-in-frontmatter alternative was rejected on evidence rather
than taste: `_fragment_body_lines` strips frontmatter from the composed
body, and `fragment_get_summary` + `categorize_fragment_summaries` were
REMOVED in #301. That path means reviving a deleted feature; this shape
needs no composer change at all.

Header carries the outcome, body keeps only what the header does not
say. The pre-existing bodies opened by paraphrasing their own headline,
which is what read as bulky.

Used `- **scope**: ` rather than `- **scope** — `: 49/50 of v0.34.0's
bullets use the colon, and the commit-derived bullets sharing the
section use it too. One separator per list.

605's scope disclosure survives intact — the body has room, so the
second-bullet question is withdrawn.

fragments 2855 -> 1676 chars; composed body 2221 -> 1840.
changelog-body-check 9/9 PASS, no warnings (check 5 clears: all-bullet).

Refs #627. Supersedes #630.
alex merged commit 87a215324d into main 2026-07-31 15:47:03 +02:00
alex deleted branch i/627-header-plus-body 2026-07-31 15:47:03 +02:00
Author
Owner

⚠️ Scope correction on this PR's own verification claim.

The body above says changelog-body-check 9/9 PASS, zero warnings. That is true and it covers less than it reads as. Bosun found why (#632); reproduced independently against origin/main's checker:

scripts/changelog-body-check.sh, _iter_paragraphs:
  /^-[[:space:]]/ { if (buf != "") { print buf; buf = "" }; next }   ← bullet lines SKIPPED

Same 38-word sentence, four positions:

plain paragraph                  FAIL check 7   ← positive control fires
indented body under a bullet     FAIL check 7   ← this PR's BODIES are covered ✅
BULLET line                      PASS "all sentences ≤ 25 words"   🔴
collapsed bullet + joined body   PASS                              🔴

So checks 7 and 9 do not scan bullet text at all, and this PR makes every entry a bullet. The seven headers here are 8–17 words because I wrote them that way, not because anything enforces it. The bodies remain covered.

This does not change the content of this PR — headers measured against v0.34.0's envelope (min 7 / median 10 / max 17) and all seven sit inside it. It changes what the green means, and that belongs stated here rather than in a tracker, since this is where a reviewer reads the claim.

Enforcement gap tracked on #632 (bullet-scanning half). Per /srv/CLAUDE.md § Mechanism design: a pass must name its silence. This one's silence is the header line.

⚠️ **Scope correction on this PR's own verification claim.** The body above says `changelog-body-check 9/9 PASS, zero warnings`. That is true and it covers **less than it reads as**. Bosun found why (#632); reproduced independently against `origin/main`'s checker: ``` scripts/changelog-body-check.sh, _iter_paragraphs: /^-[[:space:]]/ { if (buf != "") { print buf; buf = "" }; next } ← bullet lines SKIPPED ``` Same 38-word sentence, four positions: ``` plain paragraph FAIL check 7 ← positive control fires indented body under a bullet FAIL check 7 ← this PR's BODIES are covered ✅ BULLET line PASS "all sentences ≤ 25 words" 🔴 collapsed bullet + joined body PASS 🔴 ``` **So checks 7 and 9 do not scan bullet text at all**, and this PR makes every entry a bullet. **The seven headers here are 8–17 words because I wrote them that way, not because anything enforces it.** The bodies remain covered. **This does not change the content of this PR** — headers measured against v0.34.0's envelope (min 7 / median 10 / max 17) and all seven sit inside it. It changes what the green means, and that belongs stated here rather than in a tracker, since this is where a reviewer reads the claim. Enforcement gap tracked on #632 (bullet-scanning half). Per `/srv/CLAUDE.md` § Mechanism design: **a pass must name its silence.** This one's silence is the header line.
Sign in to join this conversation.
No description provided.