0005 — A release branch collects stories; progress is git ancestry, the CHANGELOG is fragments
Status: accepted (amends 0002); amended by 0006 (no longer opt-in: code level 1 and up) Date: 2026-10-17 Story: stories/021-release-branch-collects-stories-in-dependency.md
Context
ADR 0002 prepares the release in the story's own pull request, so one
story is one release. Two ready stories (gobank-deploy #46, #47) meant two
runs in a hand-picked order, a conflict on the shared [Unreleased], a
.tp-release-comment that names one branch, and the version worked out by
hand. A plain issue shipped on a story branch was never closed (#91).
Options
| Option | Complexity | Testability | Domain clarity | Operational risk |
|---|---|---|---|---|
| A. Keep one story per release | none | as today | a release is a story | serial releases; CHANGELOG conflicts between parallel stories |
B. Merge story PRs through the forge API into release, then check |
a merge call per forge; failures after the merge need reverting on the remote | needs a forge that merges | the forge's PR state is the record | a story that breaks the build is already on the remote release |
C. Merge locally into release, check, push; progress by ancestry; CHANGELOG lines as per-story fragment files |
a merge loop and a fragment package | real git in a temp dir, fake forge for PRs only | the batch is a list, the order is the fragments' after:, done is "tip reachable from release" |
only what passed check is pushed; a crash leaves nothing to reconcile |
Decision
C, opt-in by fragments: true. The batch is the gitignored
.tp-release.yml; nothing records "merged", so a manual merge or a crash
cannot leave stale state. Fragments changes/<n>.<kind>.md replace the
shared [Unreleased] and .tp-release-comment; their names give the
issues the release closes, which absorbs #91. release is cut from the
base per batch and deleted after the tag.
Consequences
Easier: stories are prepared in parallel without touching shared files; the version and comment follow from the fragments; a stopped batch resumes by running again.
Harder: tp merges the stories itself, so their review gate is the one
pull request from release to the base, and a forge without "autodetect
manual merge" leaves story PRs open for the human to close. release/*
branches (story 005) cannot coexist with release, so they are refused.