0003 — tp release may wait a bounded time for the merge; the two-run model stays underneath

Status: accepted (amends 0001) Date: 2026-10-06 Story: stories/008-release-waits-for-the-merge-and-completes-in-one.md

Context

ADR 0001 rejected a tp release that polls until the pull request is merged, because an unbounded wait makes the release hostage to a terminal staying alive, and the resume path has to exist anyway. Three releases on it showed the other cost: on a one-person project the merge is a click within minutes, and the second run is ceremony that gets forgotten.

Options

Option Complexity Testability Domain clarity Operational risk
A. Keep two runs (0001 as is) none as today the forge's PR list is the state a merged heading sits untagged until someone remembers
B. One run that waits indefinitely 0001's objections a clock and a forge that changes state mid-run "run the release" is one command a closed laptop aborts a half-done release
C. A bounded, opt-in wait; on timeout fall back to the two-run model unchanged a poll loop and one continuation that reuses the tag run; publishing questions move before the PR the loop is a pure function of a poll and a clock; the continuation is the existing tag run on the existing harness the forge is still the only state; the wait is a convenience, not a mechanism the timeout is the project's choice; a dead terminal costs nothing because the next run is the tag run

Decision

C. merge_wait in task-plus.yml opts a project in; the wait polls the pull request, and a merge within the window makes the run fetch, fast-forward the base branch, re-run the checks and continue as the tag run. Any other ending — timeout, closed, Ctrl-C — leaves the state exactly as 0001 describes, so the second run is always there.

Consequences

Easier: a one-person project releases with one command and one click. The publishing questions are answered before the pull request exists, so the tag needs no attention.

Harder: the questions come before the review, so a reviewer who changes the plan (no deploy, say) means a timeout and a second run. The merged base branch is checked again before the tag, which costs a second check on a merge that may carry other stories' commits.