From 76c652337d03d4b0b04a1c0af23c8858cd904f5e Mon Sep 17 00:00:00 2001 From: furiosa Date: Wed, 21 Jan 2026 10:16:27 -0800 Subject: [PATCH] fix(witness): run convoy check regardless of cleanup status Move convoy check to run after verifyCommitOnMain succeeds, before the cleanup_status switch. This ensures convoys can close when tracked work is merged, even if polecat cleanup is blocked (has_uncommitted, etc.). Previously the convoy check only ran after successful nuke, meaning blocked polecats would prevent convoy completion detection. Co-Authored-By: Claude Opus 4.5 --- internal/witness/handlers.go | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/internal/witness/handlers.go b/internal/witness/handlers.go index 30a2d365..6cab607d 100644 --- a/internal/witness/handlers.go +++ b/internal/witness/handlers.go @@ -247,6 +247,17 @@ func HandleMerged(workDir, rigName string, msg *mail.Message) *HandlerResult { return result } + // Redundant convoy observer: check if completed issue is tracked by a convoy. + // Run this after verifyCommitOnMain succeeds, regardless of cleanup status. + // The work is confirmed merged at this point, so convoys tracking this issue + // can potentially close even if polecat cleanup is blocked. + if onMain && payload.IssueID != "" { + townRoot, _ := workspace.Find(workDir) + if townRoot != "" { + convoy.CheckConvoysForIssue(townRoot, payload.IssueID, "witness", nil) + } + } + // ZFC #10: Check cleanup_status before allowing nuke // This prevents work loss when MERGED signal arrives for stale MRs or // when polecat has new unpushed work since the MR was created. @@ -265,14 +276,6 @@ func HandleMerged(workDir, rigName string, msg *mail.Message) *HandlerResult { result.Handled = true result.WispCreated = wispID result.Action = fmt.Sprintf("auto-nuked %s (cleanup_status=clean, wisp=%s)", payload.PolecatName, wispID) - - // Redundant convoy observer: check if completed issue is tracked by a convoy - if payload.IssueID != "" { - townRoot, _ := workspace.Find(workDir) - if townRoot != "" { - convoy.CheckConvoysForIssue(townRoot, payload.IssueID, "witness", nil) - } - } } case "has_uncommitted": @@ -308,14 +311,6 @@ func HandleMerged(workDir, rigName string, msg *mail.Message) *HandlerResult { result.Handled = true result.WispCreated = wispID result.Action = fmt.Sprintf("auto-nuked %s (commit on main, cleanup_status=%s, wisp=%s)", payload.PolecatName, cleanupStatus, wispID) - - // Redundant convoy observer: check if completed issue is tracked by a convoy - if payload.IssueID != "" { - townRoot, _ := workspace.Find(workDir) - if townRoot != "" { - convoy.CheckConvoysForIssue(townRoot, payload.IssueID, "witness", nil) - } - } } }