@@ -380,7 +380,7 @@ func runDone(cmd *cobra.Command, args []string) (retErr error) {
380380 var mrID string
381381 var pushFailed bool
382382 var doneErrors []string
383- var mergeStrategy string // convoy merge strategy: "direct", "mr", "local", or "" (default mr)
383+ var convoyInfo * ConvoyInfo // Populated if issue is tracked by a convoy
384384 if exitType == ExitCompleted {
385385 if branch == defaultBranch || branch == "master" {
386386 return fmt .Errorf ("cannot submit %s/master branch to merge queue" , defaultBranch )
@@ -477,10 +477,10 @@ func runDone(cmd *cobra.Command, args []string) (retErr error) {
477477 // direct: push commits straight to target branch, bypass refinery
478478 // mr: default — create merge-request bead, refinery merges
479479 // local: keep on feature branch, no push, no MR (for human review/upstream PRs)
480- mergeStrategy = getConvoyMergeStrategyForIssue (issueID )
480+ convoyInfo = getConvoyInfoForIssue (issueID )
481481
482482 // Handle "local" strategy: skip push and MR entirely
483- if mergeStrategy == "local" {
483+ if convoyInfo != nil && convoyInfo . MergeStrategy == "local" {
484484 fmt .Printf ("%s Local merge strategy: skipping push and merge queue\n " , style .Bold .Render ("→" ))
485485 fmt .Printf (" Branch: %s\n " , branch )
486486 if issueID != "" {
@@ -492,7 +492,7 @@ func runDone(cmd *cobra.Command, args []string) (retErr error) {
492492 }
493493
494494 // Handle "direct" strategy: push to target branch, skip MR
495- if mergeStrategy == "direct" {
495+ if convoyInfo != nil && convoyInfo . MergeStrategy == "direct" {
496496 fmt .Printf ("%s Direct merge strategy: pushing to %s\n " , style .Bold .Render ("→" ), defaultBranch )
497497 directRefspec := branch + ":" + defaultBranch
498498 directPushErr := g .Push ("origin" , directRefspec , false )
@@ -664,6 +664,39 @@ func runDone(cmd *cobra.Command, args []string) (retErr error) {
664664 }
665665 }
666666
667+ // Check if issue belongs to an owned+direct convoy.
668+ // Owned convoys with direct merge strategy bypass the refinery pipeline —
669+ // the polecat already pushed to main. Skip MR creation and close directly.
670+ convoyInfo = getConvoyInfoForIssue (issueID )
671+ if convoyInfo .IsOwnedDirect () {
672+ fmt .Printf ("%s Owned convoy (direct merge): skipping merge queue\n " , style .Bold .Render ("→" ))
673+ fmt .Printf (" Convoy: %s\n " , convoyInfo .ID )
674+ fmt .Printf (" Branch: %s\n " , branch )
675+ fmt .Printf (" Issue: %s\n " , issueID )
676+ fmt .Println ()
677+ fmt .Printf ("%s\n " , style .Dim .Render ("Polecat already pushed to main. No MR needed." ))
678+
679+ // Close the issue directly — refinery won't process it.
680+ // Retry with backoff handles transient dolt lock contention.
681+ var closeErr error
682+ for attempt := 1 ; attempt <= 3 ; attempt ++ {
683+ closeErr = bd .ForceCloseWithReason ("Completed via owned+direct convoy (no MR needed)" , issueID )
684+ if closeErr == nil {
685+ fmt .Printf ("%s Issue %s closed (owned+direct)\n " , style .Bold .Render ("✓" ), issueID )
686+ break
687+ }
688+ if attempt < 3 {
689+ style .PrintWarning ("close attempt %d/3 failed: %v (retrying in %ds)" , attempt , closeErr , attempt * 2 )
690+ time .Sleep (time .Duration (attempt * 2 ) * time .Second )
691+ }
692+ }
693+ if closeErr != nil {
694+ style .PrintWarning ("could not close issue %s after 3 attempts: %v" , issueID , closeErr )
695+ }
696+
697+ goto notifyWitness
698+ }
699+
667700 // Determine target branch (auto-detect integration branch if applicable)
668701 // Only if refinery integration branch auto-targeting is enabled
669702 target := defaultBranch
@@ -857,8 +890,15 @@ afterDoltMerge:
857890 bodyLines = append (bodyLines , fmt .Sprintf ("Gate: %s" , doneGate ))
858891 }
859892 bodyLines = append (bodyLines , fmt .Sprintf ("Branch: %s" , branch ))
860- if mergeStrategy != "" && mergeStrategy != "mr" {
861- bodyLines = append (bodyLines , fmt .Sprintf ("MergeStrategy: %s" , mergeStrategy ))
893+ // Include convoy ownership info so witness can skip merge flow registration
894+ if convoyInfo != nil {
895+ bodyLines = append (bodyLines , fmt .Sprintf ("ConvoyID: %s" , convoyInfo .ID ))
896+ if convoyInfo .Owned {
897+ bodyLines = append (bodyLines , "ConvoyOwned: true" )
898+ }
899+ if convoyInfo .MergeStrategy != "" {
900+ bodyLines = append (bodyLines , fmt .Sprintf ("MergeStrategy: %s" , convoyInfo .MergeStrategy ))
901+ }
862902 }
863903 if len (doneErrors ) > 0 {
864904 bodyLines = append (bodyLines , fmt .Sprintf ("Errors: %s" , strings .Join (doneErrors , "; " )))
0 commit comments