fix: say the release notes come from changelog.d fragments #7

Merged
engineer merged 1 commit from fix/1-readme-release-notes into master 2026-10-08 01:26:54 +02:00
Member

Refs #1

A genuine README fix, and the commit that turns the merged-but-uncut v0.2.0 into the stranded state recovery (B) repairs. It is the staging step for release-toolkit#1166's field test.

The fix

The Releases section said every feat:/fix: commit makes up the release notes. Since #2 the notes come from changelog.d/ fragments, and subjects render only in a cut with no fragment and no [Unreleased] text. Fragment: changelog.d/1-readme-release-notes.fixed.md.

Why it matters for the test

master is at e0d43fa6 chore(release): prepare v0.2.0. The rolling PR #4 was merged with the release workflow disabled, so no cut ran, and there is no v0.2.0 tag or release. In that state rt decide says mode=cut: a cut that is due, not a stranded one. The next release run would cut v0.2.0. Recovery refuses ("not the state recovery (B) repairs").

The #417 orphan check (internal/decide/decide.go, checkOrphanChangelog) reports a stranded cut only when a release-relevant commit (one with a semver bump, touching more than CHANGELOG/manifest/VERSION) sits above the prepare. That is the #417 shape: rolling PR merged, cut not run, a fix: lands. A docs-only push would instead let the cut fire.

Measured locally, with this commit on top of e0d43fa6 (rt built from tag v0.67.0)

  • rt decide --dry-run: mode=blocked, reason=pending_cut, pending_version=0.2.0, pending_prep_sha=e0d43fa6, pending_tag_exists=false, pending_release_published=absent.
  • rt recover-pending-cut --dry-run:
    • restores 2 fragments, 1-release-toolkit-v0.67.0.changed.md and 5-readme-links.fixed.md, with their bodies, which the rendered CHANGELOG does not carry;
    • folds back only the [Unreleased] prose (Added: version display; Fixed: keyboard cells).
  • rt fragment-check (content mode): PASS.

So merging this does not cut. If release is enabled, the push run should fail with blocked (pending_cut) and write nothing. If it is disabled, nothing runs. Either way, the recovery is then dispatched by hand.

Not measured

  • The live push run after merge, and whether release is currently enabled.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TaK1qBbnCPpuc7FYj4pZG1

Refs #1 A genuine README fix, and the commit that turns the merged-but-uncut v0.2.0 into the stranded state recovery (B) repairs. It is the staging step for release-toolkit#1166's field test. ## The fix The Releases section said every `feat:`/`fix:` commit makes up the release notes. Since #2 the notes come from `changelog.d/` fragments, and subjects render only in a cut with no fragment and no `[Unreleased]` text. Fragment: `changelog.d/1-readme-release-notes.fixed.md`. ## Why it matters for the test `master` is at `e0d43fa6 chore(release): prepare v0.2.0`. The rolling PR #4 was merged with the `release` workflow disabled, so no cut ran, and there is no v0.2.0 tag or release. In that state `rt decide` says **`mode=cut`**: a cut that is due, not a stranded one. The next `release` run would cut v0.2.0. Recovery refuses ("not the state recovery (B) repairs"). The #417 orphan check (`internal/decide/decide.go`, `checkOrphanChangelog`) reports a stranded cut only when a release-relevant commit (one with a semver bump, touching more than CHANGELOG/manifest/VERSION) sits above the prepare. That is the #417 shape: rolling PR merged, cut not run, a `fix:` lands. A docs-only push would instead let the cut fire. ## Measured locally, with this commit on top of `e0d43fa6` (`rt` built from tag `v0.67.0`) - `rt decide --dry-run`: `mode=blocked`, `reason=pending_cut`, `pending_version=0.2.0`, `pending_prep_sha=e0d43fa6`, `pending_tag_exists=false`, `pending_release_published=absent`. - `rt recover-pending-cut --dry-run`: - restores **2 fragments**, `1-release-toolkit-v0.67.0.changed.md` and `5-readme-links.fixed.md`, with their bodies, which the rendered CHANGELOG does not carry; - folds back only the `[Unreleased]` prose (Added: version display; Fixed: keyboard cells). - `rt fragment-check` (content mode): PASS. **So merging this does not cut.** If `release` is enabled, the push run should fail with `blocked (pending_cut)` and write nothing. If it is disabled, nothing runs. Either way, the recovery is then dispatched by hand. ## Not measured - The live push run after merge, and whether `release` is currently enabled. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01TaK1qBbnCPpuc7FYj4pZG1
fix: say the release notes come from changelog.d fragments
All checks were successful
pr / plan, and run every gate when combined (pull_request) Successful in 6s
pr / manifest (pull_request) Has been skipped
pr / fragments (pull_request) Has been skipped
pr / changelog_body (pull_request) Has been skipped
pr / register (pull_request) Has been skipped
pr / ac_closure (pull_request) Has been skipped
pr / workflow_parse (pull_request) Has been skipped
pr / split result (pull_request) Has been skipped
pr / gates (pull_request) Successful in 0s
d0c24f2c6f
The README's Releases section said every feat:/fix: commit accumulates
into the release notes. Since the v0.67.0 migration (#2) the notes come
from changelog.d fragments, and commit subjects render only in a cut
with no fragment and no [Unreleased] text.

Refs #1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TaK1qBbnCPpuc7FYj4pZG1
surveyor approved these changes 2026-10-08 01:25:36 +02:00
surveyor left a comment

Verdict: APPROVE at d0c24f2c6f

Measured with rt built from release-toolkit v0.67.0, on master e0d43fa6 and this head.

The claim that merging this cannot cut: holds, measured

rt decide --dry-run for each way the PR could land:

tree mode
master e0d43fa6 as it stands cut
this head (fast-forward or rebase) blocked, pending_cut, 0.2.0, prep e0d43fa6
a --no-ff merge commit, "Merge pull request 'fix: …' (#7)", like #5's blocked, same
a squash commit, fix: … (#7) blocked, same

The order you read is right. In internal/decide/decide.go@v0.67.0, Decide calls checkOrphanChangelog (l. 253) before detectCut (l. 274), and a pending-cut orphan comes back as mode=blocked. reusable-release.yml reads the mode from rt decide (l. 543). Its blocked) arm fails without a tag, release, manifest write or rolling PR, and the cut step runs only on mode == 'cut' (l. 952).

The recovery it sets up

On this head, rt recover-pending-cut --dry-run exits 0:

  • it folds [v0.2.0] back, leaving only the [Unreleased] prose (Added: the version display; Fixed: keyboard cells);
  • it restores 1-release-toolkit-v0.67.0.changed.md and 5-readme-links.fixed.md, bodies included;
  • it writes nothing.

The fix itself

  • The README's Releases section now matches how notes are built: fragments, not commit subjects.
  • The fragment passes fragment-check in content mode.
  • manifest-check passes.
  • pr / gates is green.

For Alex: the window before this merges

master decides cut right now. Until this PR lands, any release run on master cuts v0.2.0: a dispatch, or a push of a commit that moves no version (docs:, chore:). Keep release disabled, and merge this before anything else.

Not measured

The live push run, and whether release is enabled.

Verdict: APPROVE at d0c24f2c6f17cdb86175d82a03d1ca93e815d843 Measured with `rt` built from release-toolkit `v0.67.0`, on master `e0d43fa6` and this head. ## The claim that merging this cannot cut: holds, measured `rt decide --dry-run` for each way the PR could land: | tree | mode | |---|---| | master `e0d43fa6` as it stands | **`cut`** | | this head (fast-forward or rebase) | `blocked`, `pending_cut`, 0.2.0, prep `e0d43fa6` | | a `--no-ff` merge commit, "Merge pull request 'fix: …' (#7)", like #5's | `blocked`, same | | a squash commit, `fix: … (#7)` | `blocked`, same | The order you read is right. In `internal/decide/decide.go@v0.67.0`, `Decide` calls `checkOrphanChangelog` (l. 253) before `detectCut` (l. 274), and a pending-cut orphan comes back as `mode=blocked`. `reusable-release.yml` reads the mode from `rt decide` (l. 543). Its `blocked)` arm fails without a tag, release, manifest write or rolling PR, and the cut step runs only on `mode == 'cut'` (l. 952). ## The recovery it sets up On this head, `rt recover-pending-cut --dry-run` exits 0: - it folds `[v0.2.0]` back, leaving only the `[Unreleased]` prose (Added: the version display; Fixed: keyboard cells); - it restores `1-release-toolkit-v0.67.0.changed.md` and `5-readme-links.fixed.md`, bodies included; - it writes nothing. ## The fix itself - The README's Releases section now matches how notes are built: fragments, not commit subjects. - The fragment passes `fragment-check` in content mode. - `manifest-check` passes. - `pr / gates` is green. ## For Alex: the window before this merges `master` decides **`cut`** right now. Until this PR lands, any `release` run on master cuts v0.2.0: a dispatch, or a push of a commit that moves no version (`docs:`, `chore:`). Keep `release` disabled, and merge this before anything else. ## Not measured The live push run, and whether `release` is enabled.
engineer merged commit 8c63cebf76 into master 2026-10-08 01:26:54 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
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/tic-tac-toe!7
No description provided.