chore(release): retire .release-toolkit-release-notes.md sidecar — CHANGELOG.md as single source of truth #301

Closed
opened 2026-07-02 22:24:43 +02:00 by quartermaster · 0 comments

Diagnosis

draft-release.sh preferred a .release-toolkit-release-notes.md sidecar over the CHANGELOG section as the Forgejo release-body source (introduced in release-toolkit#77 to split "long-form developer prose" from "short consumer summaries"). The sidecar was written by release-prep.sh at rolling-PR-creation from fragment summaries.

Cold-Read compression fixes were silently discarded on 3 published releases (v0.20.0, v0.21.0, v0.22.0). All Cold-Read fix-passes (v0.20.0 → 9fdc60d, v0.21.0 → c5c610a, v0.22.0 → 9caa764) touched CHANGELOG.md only — the sidecar stayed stale. Operator caught this visually on the releases page 2026-07-02 post-v0.22.0-cut.

Meta-shape observation

This is the scoped-mechanism-vs-open-substrate class recursing on the very fix we declared closed 30 minutes before it fired (release-toolkit#295 sub-shape). The Cold-Read discipline was scoped to CHANGELOG.md; the release-body substrate uses a sidecar. n=3+ family instance under the meta-class. Retro material.

Operator directive (verbatim)

"I would prefer a single source of truth. And CHANGELOG.md looks like a better choice than an eventually unexpected sidecar, if this is feasible."

Immediate mechanical fixes (Phase 1)

Already done pre-tracker-file — v0.20.0, v0.21.0, v0.22.0 release-body PATCHed to match compressed CHANGELOG.md content via edit_release API.

Systemic elimination (Phase 2)

  • scripts/draft-release.sh L108-125: remove sidecar preference branch. CHANGELOG.md becomes the only source.
  • scripts/release-prep.sh L344-382: remove sidecar-write step. Replace with a rm of any legacy sidecar so the file stops shipping stale content.
  • scripts/release-prep.sh L619-627: staging block adjusted to note the retirement-transition behaviour (stages the sidecar deletion on first post-#301 cut; no-op thereafter).
  • scripts/lib/fragments.sh::fragment_get_summary + categorize_fragment_summaries: remove (dead code; only consumer was the sidecar-write).
  • tests/fragments.bats: remove fragment_get_summary + categorize_fragment_summaries tests.
  • tests/draft-release.bats: replace the "sidecar path bypasses CHANGELOG normalization" test with a regression guard asserting the sidecar is IGNORED even when present.
  • tests/release-prep.bats: replace the stale-carryover guard with a #301 regression guard asserting the sidecar is DELETED on every cut.
  • docs/integration.md L518: drop the sidecar row from the Three Surfaces table.
  • AGENTS.md L209: drop the sidecar stale-carryover note.
  • .release-toolkit-release-notes.md: delete the committed file.

External-consumer safety

Consumers with a committed sidecar are safe:

  • Post-#301, draft-release.sh always reads CHANGELOG.md regardless of sidecar presence.
  • No error if a legacy sidecar sits in a consumer's tree — it just becomes unused.
  • Migration note in Upgrade section: "delete .release-toolkit-release-notes.md from your repo if present."

Refs

  • Empirical anchor: operator catch 2026-07-02 post-v0.22.0-cut on release-page visual inspection.
  • Sibling class instance: release-toolkit#295 (scoped-mechanism-vs-open-substrate, wrapper-list sub-axis).
  • Retro framing (Bosun daea): "the class doesn't announce itself; it hides in the surface you didn't check."
  • Parent: release-toolkit#77 (the sidecar's origin).
## Diagnosis `draft-release.sh` preferred a `.release-toolkit-release-notes.md` sidecar over the CHANGELOG section as the Forgejo release-body source (introduced in [release-toolkit#77](https://git.frankenbit.de/frankenbit/release-toolkit/issues/77) to split "long-form developer prose" from "short consumer summaries"). The sidecar was written by `release-prep.sh` at rolling-PR-creation from fragment summaries. **Cold-Read compression fixes were silently discarded on 3 published releases** (v0.20.0, v0.21.0, v0.22.0). All Cold-Read fix-passes (v0.20.0 → `9fdc60d`, v0.21.0 → `c5c610a`, v0.22.0 → `9caa764`) touched CHANGELOG.md only — the sidecar stayed stale. Operator caught this visually on the releases page 2026-07-02 post-v0.22.0-cut. ## Meta-shape observation This is the **scoped-mechanism-vs-open-substrate class** recursing on the very fix we declared closed 30 minutes before it fired (release-toolkit#295 sub-shape). The Cold-Read discipline was scoped to CHANGELOG.md; the release-body substrate uses a sidecar. n=3+ family instance under the meta-class. Retro material. ## Operator directive (verbatim) > "I would prefer a single source of truth. And CHANGELOG.md looks like a better choice than an eventually unexpected sidecar, if this is feasible." ## Immediate mechanical fixes (Phase 1) Already done pre-tracker-file — v0.20.0, v0.21.0, v0.22.0 release-body PATCHed to match compressed CHANGELOG.md content via `edit_release` API. ## Systemic elimination (Phase 2) - `scripts/draft-release.sh` L108-125: remove sidecar preference branch. CHANGELOG.md becomes the only source. - `scripts/release-prep.sh` L344-382: remove sidecar-write step. Replace with a `rm` of any legacy sidecar so the file stops shipping stale content. - `scripts/release-prep.sh` L619-627: staging block adjusted to note the retirement-transition behaviour (stages the sidecar deletion on first post-#301 cut; no-op thereafter). - `scripts/lib/fragments.sh::fragment_get_summary` + `categorize_fragment_summaries`: remove (dead code; only consumer was the sidecar-write). - `tests/fragments.bats`: remove `fragment_get_summary` + `categorize_fragment_summaries` tests. - `tests/draft-release.bats`: replace the "sidecar path bypasses CHANGELOG normalization" test with a regression guard asserting the sidecar is IGNORED even when present. - `tests/release-prep.bats`: replace the stale-carryover guard with a #301 regression guard asserting the sidecar is DELETED on every cut. - `docs/integration.md` L518: drop the sidecar row from the Three Surfaces table. - `AGENTS.md` L209: drop the sidecar stale-carryover note. - `.release-toolkit-release-notes.md`: delete the committed file. ## External-consumer safety Consumers with a committed sidecar are safe: - Post-#301, `draft-release.sh` always reads CHANGELOG.md regardless of sidecar presence. - No error if a legacy sidecar sits in a consumer's tree — it just becomes unused. - Migration note in Upgrade section: "delete `.release-toolkit-release-notes.md` from your repo if present." ## Refs - Empirical anchor: operator catch 2026-07-02 post-v0.22.0-cut on release-page visual inspection. - Sibling class instance: [release-toolkit#295](https://git.frankenbit.de/frankenbit/release-toolkit/pulls/299) (scoped-mechanism-vs-open-substrate, wrapper-list sub-axis). - Retro framing (Bosun `daea`): "the class doesn't announce itself; it hides in the surface you didn't check." - Parent: [release-toolkit#77](https://git.frankenbit.de/frankenbit/release-toolkit/issues/77) (the sidecar's origin).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#301
No description provided.