Skip to content

t1029: Auto-retry blocked merge-conflict tasks in supervisor pulse#1355

Merged
marcusquinn merged 1 commit intomainfrom
feature/t1029
Feb 13, 2026
Merged

t1029: Auto-retry blocked merge-conflict tasks in supervisor pulse#1355
marcusquinn merged 1 commit intomainfrom
feature/t1029

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 13, 2026

Summary

Implements auto-retry mechanism for tasks blocked with merge conflicts. When a task is blocked with "Merge conflict — auto-rebase failed", the supervisor now periodically re-attempts the rebase after main advances.

Changes

  • Database migration: Added last_main_sha column to tasks table to track main branch advancement
  • Phase 3.5: New pulse phase between Phase 3b and Phase 4 that:
    1. Finds tasks blocked with merge_conflict error
    2. Checks if main has advanced since last attempt
    3. Re-runs rebase_sibling_pr when main advances
    4. Transitions back to pr_review on success
    5. Caps at 3 total retry cycles to prevent infinite loops

Rationale

Other PRs merging often resolve the conflict context. Instead of requiring manual intervention for every merge conflict, the supervisor now automatically retries when the conflict context changes (main advances).

Testing

  • Syntax check: ✅ Passed
  • ShellCheck: ✅ No violations in modified sections
  • Logic review: ✅ Follows existing rebase_attempts pattern from t298

Ref #1354

Summary by CodeRabbit

  • New Features
    • Introduced automatic retry mechanism for blocked tasks affected by merge conflicts, with safety limits (max 3 attempts per task).
    • Tasks can now transition directly from blocked status to PR review upon successful automatic resolution.
    • System intelligently tracks main branch state to avoid unnecessary retries when no new changes exist.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

Walkthrough

A database migration adds a last_main_sha column to the tasks table. A new state transition "blocked:pr_review" is added to the state machine. Phase 3.5 in the pulse cycle implements automatic retry logic for blocked tasks with merge-conflict errors, with safeguards capping retries at 3 attempts and checking main SHA progression.

Changes

Cohort / File(s) Summary
State Machine Enhancement
.agents/scripts/supervisor-helper.sh
Added new valid state transition "blocked:pr_review" to VALID_TRANSITIONS, enabling blocked tasks to progress to PR review stage.
Database Schema Migration
.agents/scripts/supervisor-helper.sh
Migration t1029 adds last_main_sha column to tasks table with existence check and success logging.
Pulse Phase 3.5 Implementation
.agents/scripts/supervisor-helper.sh
New Phase 3.5 detects blocked merge-conflict tasks, attempts automatic rebase via rebase_sibling_pr against origin/main, updates last_main_sha, increments rebase_attempts, and transitions to pr_review on success or remains blocked on failure. Includes safeguards: max 3 retries and skips if main SHA unchanged.

Sequence Diagram

sequenceDiagram
    participant Pulse as Pulse Cycle
    participant Phase35 as Phase 3.5<br/>Auto-Retry
    participant Rebase as rebase_sibling_pr
    participant DB as Tasks Table
    participant Git as origin/main

    Pulse->>Phase35: Execute Phase 3.5
    Phase35->>DB: Query blocked tasks<br/>with merge-conflict error
    DB-->>Phase35: Return matching tasks
    
    loop For each task (max 3 retries)
        Phase35->>DB: Read current main SHA
        DB-->>Phase35: Return main SHA
        
        alt Main SHA changed
            Phase35->>Git: Fetch origin/main
            Git-->>Phase35: Latest main branch
            
            Phase35->>Rebase: Invoke rebase against<br/>origin/main
            Rebase-->>Phase35: Rebase success/failure
            
            alt Rebase Successful
                Phase35->>DB: Update last_main_sha
                Phase35->>DB: Increment rebase_attempts
                Phase35->>DB: Transition to pr_review
            else Rebase Failed
                Phase35->>DB: Keep blocked status
                Phase35->>DB: Increment rebase_attempts
            end
        else Main SHA unchanged
            Phase35->>Phase35: Skip retry
        end
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related Issues

Possibly Related PRs

Poem

🔄 When conflicts block the pull request flow,

Phase 3.5 springs to life with gusto and go,

Rebasing on main with smart retry gates,

Three attempts at grace before sealed fates—

Merge conflict blues fade to pr_review hues. ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ⚠️ Unable to check for merge conflicts: Failed to fetch base branch: From https://github.com/marcusquinn/aidevops
! [rejected] main -> main (non-fast-forward)
+ e76cb8f...01f333d main -> origin/main (forced update)
✅ Passed checks (3 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: adding an auto-retry mechanism for blocked merge-conflict tasks in the supervisor pulse workflow.
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/t1029
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch feature/t1029
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

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.

@gemini-code-assist
Copy link

Summary of Changes

Hello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces an automated mechanism to handle pull requests that are blocked due to merge conflicts. By periodically checking for advancements in the main branch and retrying the rebase process, it aims to reduce manual intervention required for resolving transient merge conflicts, thereby streamlining the development workflow and improving efficiency.

Highlights

  • Database Migration: Added a new last_main_sha column to the tasks table in the supervisor database to track the last known SHA of the main branch for each task.
  • New Supervisor Pulse Phase (Phase 3.5): Introduced a new phase in the cmd_pulse function to automatically identify and retry tasks that are blocked due to 'Merge conflict — auto-rebase failed'.
  • Automated Rebase Retry Logic: Implemented logic to check if the main branch has advanced since the last rebase attempt. If main has advanced, the system attempts to rebase the blocked PR again. Retries are capped at 3 cycles to prevent infinite loops.
  • Task State Transition: Upon a successful auto-rebase retry, the task is transitioned back to the pr_review status, allowing CI to run. If the rebase still fails, the task remains blocked, and the retry counter is incremented.
Changelog
  • .agents/scripts/supervisor-helper.sh
    • Added a database migration to include the last_main_sha column in the tasks table.
    • Inserted a new 'Phase 3.5' into the cmd_pulse function to manage auto-retries for merge-conflict blocked tasks.
    • Implemented logic within Phase 3.5 to fetch current main SHA, compare it with last_main_sha, and trigger rebase_sibling_pr if main has advanced.
    • Added retry capping mechanism to limit auto-rebase attempts to three cycles.
    • Included updates to task status and rebase_attempts count based on the success or failure of the auto-rebase.
Activity
  • No human activity has occurred on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a useful auto-retry mechanism for tasks blocked by merge conflicts, which should reduce the need for manual intervention. The implementation, including the database migration and the new pulse phase, is well-structured and follows the existing patterns in the script. I've identified a minor opportunity to refactor some duplicated code in the new logic to improve maintainability. Overall, this is a solid addition to the supervisor's capabilities.

Comment on lines +11808 to +11818
if rebase_sibling_pr "$blocked_id" 2>>"$SUPERVISOR_LOG"; then
log_success " Auto-rebase retry succeeded for $blocked_id — transitioning to pr_review"
# Increment rebase_attempts counter
db "$SUPERVISOR_DB" "UPDATE tasks SET rebase_attempts = $((blocked_rebase_attempts + 1)) WHERE id = '$escaped_blocked_id';" 2>/dev/null || true
# Transition back to pr_review so CI can run
cmd_transition "$blocked_id" "pr_review" --error "" 2>>"$SUPERVISOR_LOG" || true
else
# Rebase still failed — increment counter and stay blocked
log_warn " Auto-rebase retry failed for $blocked_id — staying blocked"
db "$SUPERVISOR_DB" "UPDATE tasks SET rebase_attempts = $((blocked_rebase_attempts + 1)) WHERE id = '$escaped_blocked_id';" 2>/dev/null || true
fi

Choose a reason for hiding this comment

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

medium

There's an opportunity to deduplicate code here. The db command to update rebase_attempts is called in both the if and else blocks. You can move this line to before the if statement to make the code more concise and easier to maintain, since the counter is incremented for every attempt regardless of the outcome.

Suggested change
if rebase_sibling_pr "$blocked_id" 2>>"$SUPERVISOR_LOG"; then
log_success " Auto-rebase retry succeeded for $blocked_id — transitioning to pr_review"
# Increment rebase_attempts counter
db "$SUPERVISOR_DB" "UPDATE tasks SET rebase_attempts = $((blocked_rebase_attempts + 1)) WHERE id = '$escaped_blocked_id';" 2>/dev/null || true
# Transition back to pr_review so CI can run
cmd_transition "$blocked_id" "pr_review" --error "" 2>>"$SUPERVISOR_LOG" || true
else
# Rebase still failed — increment counter and stay blocked
log_warn " Auto-rebase retry failed for $blocked_id — staying blocked"
db "$SUPERVISOR_DB" "UPDATE tasks SET rebase_attempts = $((blocked_rebase_attempts + 1)) WHERE id = '$escaped_blocked_id';" 2>/dev/null || true
fi
# Increment rebase_attempts counter before the attempt.
# This is done for both successful and failed rebases.
db "$SUPERVISOR_DB" "UPDATE tasks SET rebase_attempts = $((blocked_rebase_attempts + 1)) WHERE id = '$escaped_blocked_id';" 2>/dev/null || true
if rebase_sibling_pr "$blocked_id" 2>>"$SUPERVISOR_LOG"; then
log_success " Auto-rebase retry succeeded for $blocked_id — transitioning to pr_review"
# Transition back to pr_review so CI can run
cmd_transition "$blocked_id" "pr_review" --error "" 2>>"$SUPERVISOR_LOG" || true
else
# Rebase still failed — stay blocked
log_warn " Auto-rebase retry failed for $blocked_id — staying blocked"
fi

- Add last_main_sha column to tasks table for tracking main advancement
- Add Phase 3.5 between Phase 3b and Phase 4 in pulse cycle
- Find blocked tasks with merge_conflict error
- Reset and retry rebase when main advances
- Cap at 3 total retry cycles to prevent infinite loops
- Transition back to pr_review on successful rebase
@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, 0 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Fri Feb 13 13:29:47 UTC 2026: Code review monitoring started
Fri Feb 13 13:29:48 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 0

📈 Current Quality Metrics

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

Generated on: Fri Feb 13 13:29:50 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

@marcusquinn marcusquinn merged commit d388a67 into main Feb 13, 2026
9 of 11 checks passed
marcusquinn added a commit that referenced this pull request Feb 13, 2026
@marcusquinn marcusquinn deleted the feature/t1029 branch February 13, 2026 13:33
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: 2

🤖 Fix all issues with AI agents
In @.agents/scripts/supervisor-helper.sh:
- Around line 1764-1771: ensure_db returns early after init_db so fresh installs
never get later migrations (missing last_main_sha and rebase_attempts), causing
Phase 3.5 to disable itself; update the initial tasks table creation in init_db
to include the missing columns (add last_main_sha TEXT and rebase_attempts
INTEGER/appropriate type) so new DBs have the same schema as migrated DBs and
subsequent logic referencing last_main_sha and rebase_attempts won't break.
Locate the tasks table CREATE statement in init_db within
.agents/scripts/supervisor-helper.sh and add the two columns with sensible
defaults/nullability to match the ALTER TABLE migrations already applied.
- Around line 11904-11955: The current logic reads origin/main SHA without
ensuring the repo exists or that origin/main is up-to-date; before calling git
-C "$blocked_repo" rev-parse origin/main, first verify the repo exists (e.g.,
check "$blocked_repo/.git" or git -C "$blocked_repo" rev-parse
--is-inside-work-tree) and if present run a fetch (git -C "$blocked_repo" fetch
origin main) and guard fetch errors; if the repo is missing or fetch/rev-parse
fails, log via log_warn and continue, otherwise assign current_main_sha from the
freshly-fetched origin/main and proceed to the existing comparison and
rebase_sibling_pr flow, keeping existing db updates and logging (references:
blocked_repo, current_main_sha, blocked_last_main_sha, rebase_sibling_pr,
log_warn, log_info, db).

Comment on lines +1764 to +1771
# Migrate: add last_main_sha column to tasks (t1029)
local has_last_main_sha
has_last_main_sha=$(db "$SUPERVISOR_DB" "SELECT count(*) FROM pragma_table_info('tasks') WHERE name='last_main_sha';" 2>/dev/null || echo "0")
if [[ "$has_last_main_sha" -eq 0 ]]; then
log_info "Migrating tasks table: adding last_main_sha column (t1029)..."
db "$SUPERVISOR_DB" "ALTER TABLE tasks ADD COLUMN last_main_sha TEXT;" 2>/dev/null || true
log_success "Added last_main_sha column to tasks (t1029)"
fi
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

New DBs won’t get last_main_sha (and rebase_attempts), so Phase 3.5 silently disables itself.
ensure_db returns after init_db, so migrations won’t run on fresh installs. Add these columns to the init_db tasks table to keep schema parity.

🔧 Suggested schema update (init_db)
 CREATE TABLE IF NOT EXISTS tasks (
     id              TEXT PRIMARY KEY,
     repo            TEXT NOT NULL,
     description     TEXT,
     status          TEXT NOT NULL DEFAULT 'queued'
                     CHECK(status IN ('queued','dispatched','running','evaluating','retrying','complete','pr_review','review_triage','merging','merged','deploying','deployed','verifying','verified','verify_failed','blocked','failed','cancelled')),
     session_id      TEXT,
     worktree        TEXT,
     branch          TEXT,
     log_file        TEXT,
     retries         INTEGER NOT NULL DEFAULT 0,
+    rebase_attempts INTEGER NOT NULL DEFAULT 0,
     max_retries     INTEGER NOT NULL DEFAULT 3,
     deploying_recovery_attempts INTEGER NOT NULL DEFAULT 0,
     model           TEXT DEFAULT 'anthropic/claude-opus-4-6',
     error           TEXT,
     pr_url          TEXT,
+    last_main_sha   TEXT,
     issue_url       TEXT,
     diagnostic_of   TEXT,
     triage_result   TEXT,
     escalation_depth INTEGER NOT NULL DEFAULT 0,
     max_escalation  INTEGER NOT NULL DEFAULT 2,
     created_at      TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')),
     started_at      TEXT,
     completed_at    TEXT,
     updated_at      TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now'))
 );

As per coding guidelines, Automation scripts should focus on reliability and robustness.

🤖 Prompt for AI Agents
In @.agents/scripts/supervisor-helper.sh around lines 1764 - 1771, ensure_db
returns early after init_db so fresh installs never get later migrations
(missing last_main_sha and rebase_attempts), causing Phase 3.5 to disable
itself; update the initial tasks table creation in init_db to include the
missing columns (add last_main_sha TEXT and rebase_attempts INTEGER/appropriate
type) so new DBs have the same schema as migrated DBs and subsequent logic
referencing last_main_sha and rebase_attempts won't break. Locate the tasks
table CREATE statement in init_db within .agents/scripts/supervisor-helper.sh
and add the two columns with sensible defaults/nullability to match the ALTER
TABLE migrations already applied.

Comment on lines +11904 to +11955
# Phase 3.5: Auto-retry blocked merge-conflict tasks (t1029)
# When a task is blocked with "Merge conflict — auto-rebase failed", periodically
# re-attempt the rebase after main advances. Other PRs merging often resolve conflicts.
local blocked_tasks
blocked_tasks=$(db "$SUPERVISOR_DB" "SELECT id, repo, error, rebase_attempts, last_main_sha FROM tasks WHERE status = 'blocked' AND error LIKE '%Merge conflict%auto-rebase failed%';" 2>/dev/null || echo "")

if [[ -n "$blocked_tasks" ]]; then
while IFS='|' read -r blocked_id blocked_repo blocked_error blocked_rebase_attempts blocked_last_main_sha; do
[[ -z "$blocked_id" ]] && continue

# Cap at 3 total retry cycles to prevent infinite loops
local max_retry_cycles=3
if [[ "${blocked_rebase_attempts:-0}" -ge "$max_retry_cycles" ]]; then
log_info " Skipping $blocked_id — max retry cycles ($max_retry_cycles) reached"
continue
fi

# Get current main SHA
local current_main_sha
current_main_sha=$(git -C "$blocked_repo" rev-parse origin/main 2>/dev/null || echo "")
if [[ -z "$current_main_sha" ]]; then
log_warn " Failed to get origin/main SHA for $blocked_id in $blocked_repo"
continue
fi

# Check if main has advanced since last attempt
if [[ -n "$blocked_last_main_sha" && "$current_main_sha" == "$blocked_last_main_sha" ]]; then
# Main hasn't advanced — skip retry
continue
fi

# Main has advanced (or this is first retry) — reset counter and retry
log_info " Main advanced for $blocked_id — retrying rebase (attempt $((blocked_rebase_attempts + 1))/$max_retry_cycles)"

# Update last_main_sha before attempting rebase
local escaped_blocked_id
escaped_blocked_id=$(sql_escape "$blocked_id")
db "$SUPERVISOR_DB" "UPDATE tasks SET last_main_sha = '$current_main_sha' WHERE id = '$escaped_blocked_id';" 2>/dev/null || true

# Attempt rebase
if rebase_sibling_pr "$blocked_id" 2>>"$SUPERVISOR_LOG"; then
log_success " Auto-rebase retry succeeded for $blocked_id — transitioning to pr_review"
# Increment rebase_attempts counter
db "$SUPERVISOR_DB" "UPDATE tasks SET rebase_attempts = $((blocked_rebase_attempts + 1)) WHERE id = '$escaped_blocked_id';" 2>/dev/null || true
# Transition back to pr_review so CI can run
cmd_transition "$blocked_id" "pr_review" --error "" 2>>"$SUPERVISOR_LOG" || true
else
# Rebase still failed — increment counter and stay blocked
log_warn " Auto-rebase retry failed for $blocked_id — staying blocked"
db "$SUPERVISOR_DB" "UPDATE tasks SET rebase_attempts = $((blocked_rebase_attempts + 1)) WHERE id = '$escaped_blocked_id';" 2>/dev/null || true
fi
done <<<"$blocked_tasks"
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

Fetch origin/main and guard repo existence before SHA comparison.
Without a fetch, origin/main can be stale and the retry loop may never trigger. Also, git -C on a missing repo risks mis-targeting the current directory.

🛠️ Suggested hardening
 		while IFS='|' read -r blocked_id blocked_repo blocked_error blocked_rebase_attempts blocked_last_main_sha; do
 			[[ -z "$blocked_id" ]] && continue
+			if [[ -z "$blocked_repo" || ! -d "$blocked_repo/.git" ]]; then
+				log_warn "  Skipping $blocked_id — repo not found: $blocked_repo"
+				continue
+			fi
+
+			if ! git -C "$blocked_repo" fetch origin main 2>>"$SUPERVISOR_LOG"; then
+				log_warn "  Failed to fetch origin/main for $blocked_id in $blocked_repo"
+				continue
+			fi
 
 			# Get current main SHA
 			local current_main_sha
 			current_main_sha=$(git -C "$blocked_repo" rev-parse origin/main 2>/dev/null || echo "")

As per coding guidelines, Automation scripts should focus on reliability and robustness, clear logging and feedback, proper exit codes, and error recovery mechanisms.

🤖 Prompt for AI Agents
In @.agents/scripts/supervisor-helper.sh around lines 11904 - 11955, The current
logic reads origin/main SHA without ensuring the repo exists or that origin/main
is up-to-date; before calling git -C "$blocked_repo" rev-parse origin/main,
first verify the repo exists (e.g., check "$blocked_repo/.git" or git -C
"$blocked_repo" rev-parse --is-inside-work-tree) and if present run a fetch (git
-C "$blocked_repo" fetch origin main) and guard fetch errors; if the repo is
missing or fetch/rev-parse fails, log via log_warn and continue, otherwise
assign current_main_sha from the freshly-fetched origin/main and proceed to the
existing comparison and rebase_sibling_pr flow, keeping existing db updates and
logging (references: blocked_repo, current_main_sha, blocked_last_main_sha,
rebase_sibling_pr, log_warn, log_info, db).

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.

1 participant