feat: MergeFailureFinal → Coding via operator FixupRequested

MergeFailureFinal was unreachable from move_story: the only transitions
out were Freeze (→ Frozen) and a self-loop on MergemasterAttempted, so
once mergemaster exhausted its 3-retry budget the only way to get a
story coding again was to delete + recreate it.

The respawn budget is a mergemaster bookkeeping detail, not a hard
ceiling. A human operator inspecting a Final story can reasonably
decide the gate failure is fixable, so this adds the same
FixupRequested → Coding edge that already exists for plain
MergeFailure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Timmy
2026-05-13 20:21:48 +01:00
parent b6898886d7
commit 75dc1fc15a
2 changed files with 12 additions and 0 deletions
+9
View File
@@ -307,6 +307,15 @@ pub fn transition(state: Stage, event: PipelineEvent) -> Result<Stage, Transitio
// ── FixupRequested: MergeFailure → Coding (coder fixup) ────────
(MergeFailure { .. }, FixupRequested) => Ok(Coding),
// ── FixupRequested: MergeFailureFinal → Coding (operator override)
//
// The exhausted-respawn-budget terminal state is not actually
// terminal as far as the operator is concerned; a human can decide
// the gate failure is fixable and send the story back for another
// coder attempt. The budget counter is a mergemaster bookkeeping
// detail, not a hard ceiling.
(MergeFailureFinal { .. }, FixupRequested) => Ok(Coding),
// ── ReQueuedForQa: MergeFailure → Qa (re-review) ────────────────
(MergeFailure { .. }, ReQueuedForQa) => Ok(Qa),