Skip to content

feat: auto-resolve merge conflicts with escalating strategy (t302)#1203

Merged
marcusquinn merged 1 commit intomainfrom
feature/t302-conflict-resolution
Feb 12, 2026
Merged

feat: auto-resolve merge conflicts with escalating strategy (t302)#1203
marcusquinn merged 1 commit intomainfrom
feature/t302-conflict-resolution

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 12, 2026

Summary

  • Adds escalating conflict resolution to rebase_sibling_pr(): plain rebase → -Xtheirs → AI CLI fallback
  • Adds resolve_rebase_conflicts() for AI-assisted per-file conflict resolution (Strategy 3)
  • Cleans up stale worktree state (stuck rebases, detached HEAD) before attempting rebase
  • Creates temporary worktrees when none exist (avoids dirty working tree in main repo)
  • Adds CONFLICTING to the t298 handler (previously only handled BEHIND/DIRTY)
  • Adds Phase 7b to the pulse cycle: retries merge-conflict-blocked tasks every 30 minutes

Testing

Tested live against 4 blocked PRs (#1171, #1187, #1188, #1191) — all resolved successfully with -Xtheirs (Strategy 2). The AI CLI fallback (Strategy 3) was not needed for these cases but is available for more complex conflicts.

Closes

Closes #1176

Summary by CodeRabbit

Release Notes

  • New Features
    • Added AI-powered automatic conflict resolution during rebase operations to reduce manual intervention and improve workflow reliability.
    • Introduced automated retry mechanism for tasks blocked by merge conflicts, leveraging AI assistance with configurable limits and comprehensive error handling.
    • Enhanced workflow automation to handle edge cases like stale worktree states, ensuring more robust conflict resolution.

Add escalating conflict resolution to rebase_sibling_pr():
1. Plain rebase (no conflicts)
2. Rebase with -Xtheirs (feature branch wins on conflicts)
3. AI CLI resolution for complex cases (Strategy 3 fallback)

Also adds:
- resolve_rebase_conflicts() for AI-assisted per-file resolution
- Stale worktree cleanup (abort stuck rebases, fix detached HEAD)
- Temp worktree creation when no worktree exists (avoids dirty tree)
- CONFLICTING added to t298 handler (was only BEHIND/DIRTY)
- Phase 7b: periodic retry of merge-conflict-blocked tasks (30min)

Tested: resolved 4 blocked PRs (#1171, #1187, #1188, #1191) that
were stuck with merge conflicts — all resolved with -Xtheirs.
@gemini-code-assist
Copy link

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Walkthrough

This change introduces AI-assisted git rebase conflict resolution to the supervisor helper script. A new resolve_rebase_conflicts() function detects conflicting files during rebase operations and uses an AI CLI to automatically resolve them. The rebase_sibling_pr() function is extended to attempt AI-based resolution when standard rebase strategies fail, and a new Phase 7b adds retry logic for previously blocked merge-conflict tasks.

Changes

Cohort / File(s) Summary
AI-Assisted Conflict Resolution
.agents/scripts/supervisor-helper.sh
Added resolve_rebase_conflicts() function that collects conflicting files via git diff, invokes AI CLI with conflict-resolution rules, validates marker removal, and stages resolved content. Extended rebase_sibling_pr() with _do_rebase() helper to attempt plain, -Xtheirs, and AI-assisted rebase strategies. Introduced Phase 7b to retry merge-conflict-blocked tasks with up to 3 rebase attempts, updating task state and rebase_attempts counter on resolution.

Sequence Diagram

sequenceDiagram
    participant Supervisor as Supervisor Script
    participant Git as Git Operations
    participant AI as AI CLI
    participant Worktree as Worktree Manager

    Supervisor->>Git: Attempt rebase (plain)
    Git-->>Supervisor: Conflicts detected
    Supervisor->>Git: Attempt rebase with -Xtheirs
    Git-->>Supervisor: Conflicts persist
    Supervisor->>Git: Abort rebase, reset to origin/main
    Supervisor->>Worktree: Prepare worktree (cleanup/create)
    Supervisor->>Git: Detect conflicting files
    Git-->>Supervisor: Return conflict file list
    Supervisor->>Git: Read conflicting file content
    Git-->>Supervisor: File with conflict markers
    Supervisor->>AI: Send file + conflict resolution rules
    AI-->>Supervisor: Resolved file content
    Supervisor->>Git: Validate marker removal
    Supervisor->>Git: Stage resolved file
    Supervisor->>Git: Rebase --continue
    Git-->>Supervisor: Rebase complete
    Supervisor->>Supervisor: Log outcome, update task state
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🤖 When merge conflicts arise in the git flow,
AI steps in with wisdom's glow—
Rebasing grace with markers cleared,
Once-blocked tasks now persevered. ✨
Automation's dance, conflict resolved!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: implementing an auto-resolve feature for merge conflicts using an escalating strategy, with the task reference (t302) providing context.
Linked Issues check ✅ Passed The PR implements the escalating conflict-resolution strategy (plain rebase → -Xtheirs → AI fallback) which goes beyond the original issue's scope of TODO.md-specific resolution but comprehensively addresses the root problem.
Out of Scope Changes check ✅ Passed All changes align with conflict resolution automation: resolve_rebase_conflicts() function, rebase_sibling_pr() enhancement, worktree cleanup, Phase 7b pulse addition, and CONFLICTING status handling are all within scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/t302-conflict-resolution

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 15 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Feb 12 02:46:05 UTC 2026: Code review monitoring started
Thu Feb 12 02:46:05 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 15

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 15
  • VULNERABILITIES: 0

Generated on: Thu Feb 12 02:46:08 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

@marcusquinn marcusquinn merged commit 7b2f984 into main Feb 12, 2026
9 of 11 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.agents/scripts/supervisor-helper.sh (2)

9059-9063: ⚠️ Potential issue | 🟠 Major

Align merge-conflict error token with Phase 7b filter

Phase 7b retries only error LIKE '%merge_conflict%', but this path writes "Merge conflict — auto-rebase failed", so those tasks won’t be picked up for retry. Standardize the error token (or broaden the Phase 7b filter).

🔧 Suggested fix
-                            cmd_transition "$task_id" "blocked" --error "Merge conflict — auto-rebase failed" 2>>"$SUPERVISOR_LOG" || true
+                            cmd_transition "$task_id" "blocked" --error "merge_conflict:auto_rebase_failed" 2>>"$SUPERVISOR_LOG" || true

10821-10827: ⚠️ Potential issue | 🟠 Major

TODO.md conflict auto‑resolve (Issue #1176) is still missing

commit_and_push_todo() aborts on rebase conflicts and retries, but the required behavior is to detect TODO.md conflict markers, keep the longer line, stage, and rebase --continue (single attempt, then abort on failure). Without this, concurrent TODO.md edits still block the pipeline.

🛠️ Minimal implementation sketch
 commit_and_push_todo() {
     local repo_path="$1"
     local commit_msg="$2"
     local max_retries="${3:-3}"
+    local auto_resolve_attempted=false
@@
-        if ! git -C "$repo_path" pull --rebase --autostash 2>>"$SUPERVISOR_LOG"; then
+        if ! git -C "$repo_path" pull --rebase --autostash 2>>"$SUPERVISOR_LOG"; then
             log_warn "Pull-rebase failed (attempt $attempt/$max_retries)"
-            # Abort rebase if in progress and retry
-            git -C "$repo_path" rebase --abort 2>>"$SUPERVISOR_LOG" || true
+            # Single auto-resolve attempt for TODO.md conflicts (t302/t1176)
+            if [[ "$auto_resolve_attempted" == "false" ]] && _auto_resolve_todo_conflict "$repo_path/TODO.md" "$repo_path"; then
+                auto_resolve_attempted=true
+                if ! git -C "$repo_path" rebase --continue 2>>"$SUPERVISOR_LOG"; then
+                    git -C "$repo_path" rebase --abort 2>>"$SUPERVISOR_LOG" || true
+                fi
+            else
+                git -C "$repo_path" rebase --abort 2>>"$SUPERVISOR_LOG" || true
+            fi
             sleep "$attempt"
             continue
         fi
# helper sketch (place near commit_and_push_todo)
_auto_resolve_todo_conflict() {
  local todo_file="$1"
  local repo_path="$2"
  [[ -f "$todo_file" ]] || return 1
  grep -q '<<<<<<<' "$todo_file" || return 1

  local tmp_file
  tmp_file=$(mktemp)
  local state=0 head="" other=""
  while IFS= read -r line || [[ -n "$line" ]]; do
    case "$line" in
      "<<<<<<<"*) state=1; head=""; other=""; continue ;;
      "=======") state=2; continue ;;
      ">>>>>>>") 
        if [[ ${`#head`} -ge ${`#other`} ]]; then echo "$head" >> "$tmp_file"; else echo "$other" >> "$tmp_file"; fi
        state=0; continue ;;
    esac
    if [[ "$state" -eq 1 ]]; then head="$line"; elif [[ "$state" -eq 2 ]]; then other="$line"; else echo "$line" >> "$tmp_file"; fi
  done < "$todo_file"

  mv "$tmp_file" "$todo_file"
  git -C "$repo_path" add "$todo_file" 2>>"$SUPERVISOR_LOG" || true
  return 0
}
🤖 Fix all issues with AI agents
In @.agents/scripts/supervisor-helper.sh:
- Around line 8169-8178: The branch that handles successful git -C "$git_dir"
diff --check -- "$conflict_file" should explicitly stage the file before
counting it resolved: run git -C "$git_dir" add "$conflict_file" (redirect
errors to "$SUPERVISOR_LOG" or || true as in the other branch), only increment
resolved_count and call log_info "Resolved: $conflict_file" after the add
succeeds (or still increment but ensure add is attempted), mirroring the
fallback branch that already stages files with git -C "$git_dir" add
"$conflict_file" 2>>"$SUPERVISOR_LOG" || true.

Comment on lines +8169 to +8178
# Check if the file was resolved (no more conflict markers)
if git -C "$git_dir" diff --check -- "$conflict_file" 2>/dev/null; then
# diff --check returns 0 if no conflict markers remain
resolved_count=$((resolved_count + 1))
log_info " Resolved: $conflict_file"
elif ! grep -q '<<<<<<<' "$full_path" 2>/dev/null; then
# Fallback check: no conflict markers in file
# Ensure it is staged
git -C "$git_dir" add "$conflict_file" 2>>"$SUPERVISOR_LOG" || true
resolved_count=$((resolved_count + 1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Stage AI-resolved files before continuing the rebase

git diff --check can pass even when the file is still unmerged/unstaged (if the AI didn’t run git add), which makes rebase --continue fail and abort the escalation. Stage explicitly after the clean check to keep the automation deterministic.

🔧 Suggested fix
-        if git -C "$git_dir" diff --check -- "$conflict_file" 2>/dev/null; then
-            # diff --check returns 0 if no conflict markers remain
-            resolved_count=$((resolved_count + 1))
-            log_info "  Resolved: $conflict_file"
+        if git -C "$git_dir" diff --check -- "$conflict_file" 2>/dev/null; then
+            # diff --check returns 0 if no conflict markers remain
+            git -C "$git_dir" add "$conflict_file" 2>>"$SUPERVISOR_LOG" || true
+            resolved_count=$((resolved_count + 1))
+            log_info "  Resolved: $conflict_file"
🤖 Prompt for AI Agents
In @.agents/scripts/supervisor-helper.sh around lines 8169 - 8178, The branch
that handles successful git -C "$git_dir" diff --check -- "$conflict_file"
should explicitly stage the file before counting it resolved: run git -C
"$git_dir" add "$conflict_file" (redirect errors to "$SUPERVISOR_LOG" or || true
as in the other branch), only increment resolved_count and call log_info
"Resolved: $conflict_file" after the add succeeds (or still increment but ensure
add is attempted), mirroring the fallback branch that already stages files with
git -C "$git_dir" add "$conflict_file" 2>>"$SUPERVISOR_LOG" || true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t302: Auto-resolve TODO.md merge conflicts in commit_and_push_todo()

1 participant