Skip to content

docs(changelog): bring ## [Unreleased] to Keep a Changelog conformance - #583

Merged
pbean merged 3 commits into
fix/changelog-release-contractfrom
chore/changelog-conformance
Aug 14, 2026
Merged

docs(changelog): bring ## [Unreleased] to Keep a Changelog conformance#583
pbean merged 3 commits into
fix/changelog-release-contractfrom
chore/changelog-conformance

Conversation

@pbean

@pbean pbean commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Rewrites ## [Unreleased] to the shape the format actually specifies. 1193 → 835 lines, 149 → 124 entries, no user-facing fact lost.

The section had drifted into a flat list of multi-paragraph engineering narratives: each entry re-derived its own root cause, restated mechanism a reader cannot act on, and duplicated fixes already shipped in ## [0.9.1]. Keep a Changelog asks for something else — "for humans, not machines", a terse statement of what changed and why it matters to someone deciding whether to upgrade.

Scope: released sections are deliberately untouched

scripts/release.py pipes a released section's prose verbatim into the published GitHub release notes (release.py:417-437). Editing ## [0.9.1] or earlier would silently rewrite the body of a release that is already published, so every commit here is confined to ## [Unreleased]. The diff is one file.

Three passes

1. Subtractive (0007a33) — dedup, deflate, reference. No prose rewritten.

2. Added / Changed / Removed (7c3a205) — 259 → 183 lines.

3. Fixed (94f8d8d) — 768 → 645 lines, 93 entries.

Passes 2 and 3 apply the same rule: bold subject lead, then a short statement of user-facing impact and why. Mechanism, root-cause narration and internals move back to the issues and docstrings.

Kept deliberately, because a reader acts on them: symptoms you would recognize having hit, config knobs, CLI flags, --json field names, journal and finding ids you would grep for, the CLEANUP_SCHEMA_VERSION bump, behavior changes and contributor credits. Dropped: private function names, code-level mechanism, and "why the old code did that".

Structural fixes worth calling out

Wrapping stays hand-maintained at 100 columns — prettier.config.mjs sets proseWrap: preserve, so no formatter reflows this file and nothing enforces it but review.

Stacked on #582

Based on fix/changelog-release-contract so the diff is exactly these three commits. #582 should merge first; this retargets to main automatically when it does. That PR is the natural pair — it makes a release promote ## [Unreleased] rather than author a new section beside it, which is what makes conformance of this section load-bearing rather than cosmetic.

Verification

  • trunk check --all: clean, 254 files
  • uv run pytest: 5411 passed, 44 skipped, 5 xfailed
  • scripts/release.py check: clean
  • Mechanically re-verified: 93 Fixed entries in, 93 out; every issue reference in the pre-rewrite text still present (or deliberately dropped and listed above); no bold span straddling a line; no line over 100 columns; code-span and link integrity preserved across the reflow; ## [0.9.1] onward byte-identical to HEAD.

t added 3 commits August 13, 2026 17:31
Session 2 of 4 on the [Unreleased] conformance program, subtractive only:
no entry's prose was rewritten, only removed, merged, or given a missing
issue reference.

Handoff facts for session 4:
  surviving [Unreleased] entries: 124 (Added 16, Changed 14, Removed 1, Fixed 93)
  ### Fixed: lines 274-1040 (heading at 274, ## [0.9.1] at 1042)

1192 -> 1033 lines; 149 -> 124 entries; 209 deletions against 50 insertions.

- Dedup against ## [0.9.1]. That section is the release/0.9.x hotfix line and
  the preamble already points at it, so a bullet restating a 0.9.1 fix with no
  main-specific difference is dropped: the five byte-identical subject leads
  plus eight near-identical pairs. Where the port needed a genuinely different
  fix the bullet stays and keeps the underlying issue number rather than
  [0.9.1]'s blanket #405 -- #433, #420, #422, #414, #410, #393, #421, #425 and
  #458 each still appear at least once.

- Drop eight internal-churn entries -- test/CI/refactor bookkeeping outside
  Keep a Changelog's user-visible scope, two of which said so themselves
  ("No violation existed; it is a tripwire" / "Test-only; no runtime change").

  NOTE for session 3: one of the eight, "The last two bare git spawns route
  through the _run_git chokepoint (#390)", also carried a user-visible fact --
  an undecodable byte in a commit subject crashed the TUI's story-checkpoint
  modal. Dropped as instructed; restore that one sentence if it should stay.

- Collapse fragmented entries. #433 goes from 11 bullets to 2 (the drops above
  plus folding "Only the deterministic skill contract can pause that run" into
  the entry that supplies its antecedent -- "A state file predating THAT
  DIGEST" and its dangling siblings are gone). #335's parts 3->2->1 become one
  entry; #393's two become one; #357 no longer straddles Changed and Fixed and
  its remaining parts run 1 then 2 with the stale "part N of 3" labels dropped.

- Add 13 issue references, each traced with `git log -S` to the introducing
  commit and its PR: #226 x4 (adapter registry), #332, #433 x3, #335 x2, #340,
  #343, #321. The other 16 unreferenced entries have no issue behind them --
  each landed inside a PR with no closing issue -- so per the brief they stay
  unreferenced rather than carry an invented number. Most notable: the `gate:`
  feature (PR #502) and the bmad-auto compat removal (PR #297, whose closing
  issues #258/#259 are a different change).

trunk check --all: clean (254 files). scripts/release.py check: clean.
…hangelog style

Each entry is now a bold subject lead plus 1-2 sentences of user-facing
impact and why; mechanism, root-cause narration and internals a reader
cannot act on move back to the issues and docstrings. Added/Changed/
Removed drop from 259 to 183 lines with no user-facing fact lost.

- Flatten the #494 sub-bullet tree; split the new `bmad-loop relay`
  command into its own entry.
- Fold the four #226 profile-dispatch entries into three: the
  pre-`adapter` fallback and the refused hookless/`generic` pair are one
  change with two outcomes.
- State the `BMAD_LOOP_*` env-var entry declaratively, matching every
  other lead, and move it to Changed with the other no-behavior-change
  docs entries (docs/testing.md, tmux floor, #567) - Keep a Changelog
  has no `Docs` section.
- Unwrap the bold leads that broke across source lines (#356 and the
  `deferred.ledger-unreadable` entry), which defeated the one scannable
  element.

Subsection order was already Added -> Changed -> Removed -> Fixed.
`### Fixed` and every released section are untouched.
Session 4 of 4 on the [Unreleased] conformance program, completing the
pass Added/Changed/Removed took in 7c3a205. Each of the 93 entries is now
a bold subject lead plus a short statement of user-facing impact and why;
mechanism, root-cause narration and internals a reader cannot act on move
back to the issues and docstrings. 768 -> 645 lines with no user-facing
fact lost.

Kept deliberately: symptoms a reader would recognize, config knobs, CLI
flags, `--json` field names, journal and finding ids, the
CLEANUP_SCHEMA_VERSION bump, behavior changes and contributor credits.
Dropped: private function names, code-level mechanism, and the "why the
old code did that" narration.

- Unwrap the seven bold leads that broke across source lines, which
  defeated the one scannable element. Two needed shortening to fit:
  #471 ("A codex stage ..." -> "An isolated codex stage ...") and #302
  ("... burning dev attempts" -> "... burning attempts").
- Move the upgrade runbook. The #384 entry filed a nested procedure list
  under Fixed, and the only precedent for a standalone section is the
  non-standard `### Migration` at [0.8.0] — Keep a Changelog has neither.
  The instruction now rides the entry it applies to (the git-add shield
  fix whose old behavior left the residue) in two sentences naming
  `git rev-parse --git-path info/exclude` and `git check-ignore -v`, and
  points at #384 for the full account. The caveats entry's redundant
  "delete them by hand" clause goes with it.
- Give #420's entry its antecedent. "The ledger snapshot degrades
  loudly" had lost the mechanism naming what snapshot; it now says which
  one — the one a rollback restores from.
- Fold #350's dangling "Without it `_pick_next` ..." tail into the entry
  that supplies its subject.
- Restore the TUI fact session 2 flagged when it dropped the #390
  chokepoint entry as internal churn: a commit subject undecodable in the
  run's codec crashed the story-checkpoint modal. Verified against
  tui/app.py:855-873 and fd0d41f before restoring.
- Restore two cross-references lost in the rewrite: #130 (the
  charged-attempt regression #302 left live on win32) and #380 (the
  decode half of #419's tag).

Wrapping stays hand-maintained at 100 columns — prettier.config.mjs sets
proseWrap: preserve, so no formatter reflows this file.

Released sections are untouched: release.py pipes their prose verbatim
into published GitHub release notes.

trunk check --all: clean (254 files). uv run pytest: 5411 passed.
scripts/release.py check: clean.
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 724c4f1f-3620-4aaf-8ed0-7cf9772231e6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pbean
pbean merged commit debe92a into fix/changelog-release-contract Aug 14, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant