bug(release): failed pending cut leaves subsequent main pushes red after release-relevant commits #882

Closed
opened 2026-08-26 01:46:33 +02:00 by pullings · 5 comments
Owner

Finding

The merge of PR #881 was green on its exact head, but the push-to-main release workflow failed on run #6001 (commit 56b90a6050d2efdfbe1236b36f89cb4fdcca01e2). The two red contexts are the reusable release caller and its underlying release / decide + act (push) job; all ordinary PR contexts were successful.

The exact merged tree reproduces the failure read-only:

manifest: last_released_version=0.45.1, last_released_sha=de927aad...
CHANGELOG.md top released section: v0.46.0
pending prepare commit: 7d248947... chore(release): prepare v0.46.0
later release-relevant commits: a74a4c9..., 56b90a6...
rt decide: exit 1
release-toolkit#417 orphan CHANGELOG section ... complete the pending release + update the manifest, or move the v0.46.0 section back under [Unreleased]

This is the intended fail-closed orphan guard, not a flaky CI context and not a missing runner capability. The unresolved state was created by the earlier v0.46.0 cut failing before manifest bookkeeping; merging #881 then supplied the later release-relevant commit that makes the guard refuse recovery by ordinary rolling-release logic.

Gap

The guard prevents duplicate changelog generation, but the current workflow offers no typed, durable recovery path for a prepared version that is still uncut while later release-relevant work reaches main. A subsequent push therefore goes red before it can present a safe next action. The fix must not weaken the orphan guard or silently turn the pending state into a new release.

This is the concrete follow-up to #862 AC6 and the current-run evidence recorded there; #417 is the historical origin of the orphan invariant and is already closed.

Acceptance criteria

  • Add an exact regression fixture for the measured state above: manifest v0.45.1 at de927aad..., prepared v0.46.0 at 7d248947..., and a later release-relevant commit; the old behavior must be captured as the failing baseline.
  • Implement a typed, machine-readable recovery/blocked outcome at the rt decide/reusable-release boundary. It must identify the pending version and prepare SHA, state the operator action required, and prevent creation of a later rolling release from the orphaned tree.
  • Preserve fail-closed behavior: no tag, release, manifest rewrite, or release PR is created without the existing explicit cut authorization; no noop or ordinary update may hide the pending cut.
  • Preserve the legitimate prep-merge skip and the existing #417 duplicate-prevention behavior, with positive and negative controls for both paths.
  • Verify the merged-tree workflow path and record the exact output/exit disposition on this tracker; include full Go tests, relevant Bats/workflow checks, and git diff --check.

Dispatch

Filed by Pullings under the explicit deputy handover after release workflow run #6001. Implementer: Carpenter. No live release is authorized by this tracker.

Closeout

PR #883 merged fast-forward-only at a9563b4263de0ae97661304661efee44143953a8 after official Lookout approval 5611 at the exact head and an independent merge-gate PASS.

The merged-tree release workflow run #6023 (push event, release.yml, exact commit a9563b4...) reached the new typed blocked path and ended failure as designed: it must fail closed after publishing the pending-cut evidence. The branch is before rt prep, rt release, rt post-cut, manifest writes, and rolling-PR work. Read-only merged-tree replay emits mode=blocked for v0.46.0 / prepare 7d248947..., with the required recovery action. No new tag, release, manifest, or rolling PR was created; no live cut was fired.

All five acceptance criteria are ticked. Closed by Pullings under the explicit deputy handover; #862 AC6 remains separate and operator-blocked on an authorized end-to-end cut.

## Finding The merge of PR #881 was green on its exact head, but the push-to-main release workflow failed on run #6001 (commit `56b90a6050d2efdfbe1236b36f89cb4fdcca01e2`). The two red contexts are the reusable release caller and its underlying `release / decide + act (push)` job; all ordinary PR contexts were successful. The exact merged tree reproduces the failure read-only: ```text manifest: last_released_version=0.45.1, last_released_sha=de927aad... CHANGELOG.md top released section: v0.46.0 pending prepare commit: 7d248947... chore(release): prepare v0.46.0 later release-relevant commits: a74a4c9..., 56b90a6... rt decide: exit 1 release-toolkit#417 orphan CHANGELOG section ... complete the pending release + update the manifest, or move the v0.46.0 section back under [Unreleased] ``` This is the intended fail-closed orphan guard, not a flaky CI context and not a missing runner capability. The unresolved state was created by the earlier v0.46.0 cut failing before manifest bookkeeping; merging #881 then supplied the later release-relevant commit that makes the guard refuse recovery by ordinary rolling-release logic. ## Gap The guard prevents duplicate changelog generation, but the current workflow offers no typed, durable recovery path for a prepared version that is still uncut while later release-relevant work reaches `main`. A subsequent push therefore goes red before it can present a safe next action. The fix must not weaken the orphan guard or silently turn the pending state into a new release. This is the concrete follow-up to #862 AC6 and the current-run evidence recorded there; #417 is the historical origin of the orphan invariant and is already closed. ## Acceptance criteria - [x] Add an exact regression fixture for the measured state above: manifest v0.45.1 at `de927aad...`, prepared v0.46.0 at `7d248947...`, and a later release-relevant commit; the old behavior must be captured as the failing baseline. - [x] Implement a typed, machine-readable recovery/blocked outcome at the `rt decide`/reusable-release boundary. It must identify the pending version and prepare SHA, state the operator action required, and prevent creation of a later rolling release from the orphaned tree. - [x] Preserve fail-closed behavior: no tag, release, manifest rewrite, or release PR is created without the existing explicit cut authorization; no `noop` or ordinary `update` may hide the pending cut. - [x] Preserve the legitimate prep-merge skip and the existing #417 duplicate-prevention behavior, with positive and negative controls for both paths. - [x] Verify the merged-tree workflow path and record the exact output/exit disposition on this tracker; include full Go tests, relevant Bats/workflow checks, and `git diff --check`. ## Dispatch Filed by Pullings under the explicit deputy handover after release workflow run #6001. Implementer: Carpenter. No live release is authorized by this tracker. ## Closeout PR #883 merged fast-forward-only at `a9563b4263de0ae97661304661efee44143953a8` after official Lookout approval 5611 at the exact head and an independent merge-gate PASS. The merged-tree release workflow run #6023 (push event, `release.yml`, exact commit `a9563b4...`) reached the new typed blocked path and ended `failure` as designed: it must fail closed after publishing the pending-cut evidence. The branch is before `rt prep`, `rt release`, `rt post-cut`, manifest writes, and rolling-PR work. Read-only merged-tree replay emits `mode=blocked` for v0.46.0 / prepare `7d248947...`, with the required recovery action. No new tag, release, manifest, or rolling PR was created; no live cut was fired. All five acceptance criteria are ticked. Closed by Pullings under the explicit deputy handover; #862 AC6 remains separate and operator-blocked on an authorized end-to-end cut.
Author
Owner

Dispatch\n\nCarpenter was dispatched by Pullings via tmux-tell message b454 after the exact read-only reproduction. Delivery was confirmed. He is to implement the typed recovery/blocked path and report an exact-head PR. No live cut, review request, or merge was authorized.

## Dispatch\n\nCarpenter was dispatched by Pullings via tmux-tell message `b454` after the exact read-only reproduction. Delivery was confirmed. He is to implement the typed recovery/blocked path and report an exact-head PR. No live cut, review request, or merge was authorized.
Author
Owner

Review\n\nLookout was requested once by Pullings for PR #883 at exact head ae165439f0dafd1604d33d2fcd7cf6a1a1b9f4bb; tmux-tell delivery was confirmed (e804). No merge action.

## Review\n\nLookout was requested once by Pullings for PR #883 at exact head `ae165439f0dafd1604d33d2fcd7cf6a1a1b9f4bb`; tmux-tell delivery was confirmed (`e804`). No merge action.
Author
Owner

Head correction / review\n\nForgejo and git ls-remote confirm PR #883 at 2595394fe2e883b7a5faef0862719ab35131a6ce; the prior 2595394f0daf... value was a reporting typo, with no additional code change. A fresh Lookout request was queued as tmux-tell message 0584; delivery is waiting while his pane is working. No merge action.

## Head correction / review\n\nForgejo and `git ls-remote` confirm PR #883 at `2595394fe2e883b7a5faef0862719ab35131a6ce`; the prior `2595394f0daf...` value was a reporting typo, with no additional code change. A fresh Lookout request was queued as tmux-tell message `0584`; delivery is waiting while his pane is working. No merge action.
Author
Owner

Review finding\n\nLookout review 5610 is REQUEST_CHANGES, official and bound to PR #883 head 2595394fe2e883b7a5faef0862719ab35131a6ce. The sole finding is documentation: docs/architecture/contracts/cli-surface.md:33 must add blocked to the public rt decide mode list. Carpenter was dispatched via tmux-tell cd44; no merge action.

## Review finding\n\nLookout review 5610 is `REQUEST_CHANGES`, official and bound to PR #883 head `2595394fe2e883b7a5faef0862719ab35131a6ce`. The sole finding is documentation: `docs/architecture/contracts/cli-surface.md:33` must add `blocked` to the public `rt decide` mode list. Carpenter was dispatched via tmux-tell `cd44`; no merge action.
Author
Owner

Fresh review\n\nPR #883 moved to server head a9563b4263de0ae97661304661efee44143953a8; prior reviews 5609/5610 are stale. The backlog-fenced old request and ping were acknowledged without deletion, and Lookout was re-requested at the corrected head via tmux-tell 186b; delivery was confirmed. No merge action.

## Fresh review\n\nPR #883 moved to server head `a9563b4263de0ae97661304661efee44143953a8`; prior reviews 5609/5610 are stale. The backlog-fenced old request and ping were acknowledged without deletion, and Lookout was re-requested at the corrected head via tmux-tell `186b`; delivery was confirmed. No merge action.
Sign in to join this conversation.
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#882
No description provided.