Skip to content

Comments

t247.2: Supervisor auto-PR for orphaned branches#988

Merged
marcusquinn merged 1 commit intomainfrom
feature/t247.2
Feb 10, 2026
Merged

t247.2: Supervisor auto-PR for orphaned branches#988
marcusquinn merged 1 commit intomainfrom
feature/t247.2

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 10, 2026

Summary

When a worker exits with commits on its branch but no PR (e.g., context exhaustion before gh pr create), the supervisor now auto-creates a draft PR instead of returning task_only or triggering a full retry (~300s saved per occurrence).

Changes

  • New function auto_create_pr_for_task() (supervisor-helper.sh:5303): Pushes branch to remote if needed, creates draft PR via gh pr create with commit summary and task description, persists URL via link_pr_to_task()
  • Modified Tier 2.5 git heuristic in evaluate_worker() (supervisor-helper.sh:5914): When branch_commits > 0 and no PR exists, calls auto_create_pr_for_task() before falling back to task_only

Flow

Before (t247.2):
  Worker dies → commits on branch, no PR → evaluate_worker returns "complete:task_only"
  → process_post_pr_lifecycle skips review → marks "deployed" (no review!)
  OR: → retry:clean_exit_no_signal → full re-dispatch (~300s wasted)

After (t247.2):
  Worker dies → commits on branch, no PR → auto_create_pr_for_task()
  → pushes branch → creates draft PR → returns "complete:<PR_URL>"
  → normal PR lifecycle (review, merge, deploy)
  → if auto-PR fails: falls back to "complete:task_only" (existing behavior)

Design Decisions

  • Draft PR: Created as draft so the existing cmd_pr_lifecycle draft auto-promotion logic handles the ready transition (worker is dead → auto-promote)
  • Graceful fallback: If gh is unavailable or PR creation fails, falls back to existing task_only behavior — no regression
  • Reuses existing infra: Uses link_pr_to_task() (t232) for persistence, detect_repo_slug() for repo identification
  • Handles unpushed branches: Checks if branch exists on remote and pushes if needed (worker may have committed but not pushed before context exhaustion)

Testing

  • ShellCheck: zero new violations (all warnings are pre-existing in other functions)
  • Syntax: bash -n passes

Summary by CodeRabbit

  • Chores
    • Improved automatic pull request creation for branches with unmerged commits, streamlining the workflow for orphaned branch management.

When a worker exits with commits on branch but no PR (e.g., context exhaustion),
the supervisor now creates a draft PR via gh pr create instead of returning
task_only or triggering a full retry (~300s saved per occurrence).

New function auto_create_pr_for_task() handles: push branch if needed, create
draft PR with commit summary, persist via link_pr_to_task(). Falls back to
existing task_only behavior if PR creation fails.
@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!

@marcusquinn marcusquinn marked this pull request as ready for review February 10, 2026 19:47
@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 10, 2026

Walkthrough

This PR enhances the supervisor-helper script by introducing automatic PR creation for workers' orphaned branches. When a branch has commits but no associated PR, the system now attempts to create a draft PR, persist the PR URL via the task link, and emit the PR URL for downstream processing instead of falling back to task-only completion.

Changes

Cohort / File(s) Summary
PR Auto-Creation Logic
.agents/scripts/supervisor-helper.sh
Adds auto_create_pr_for_task() function to automatically create draft PRs for branches with unpushed commits. Modifies evaluate_worker() control flow to invoke auto-creation when commits exist but no PR is present, emitting complete:${PR_URL} on success or complete:task_only on failure. Centralizes PR URL persistence through existing link_pr_to_task() integration.

Sequence Diagram

sequenceDiagram
    participant Worker
    participant evaluate_worker as evaluate_worker()
    participant auto_create_pr as auto_create_pr_for_task()
    participant Git
    participant GitHub as GitHub CLI (gh)
    participant Task as Task System

    Worker->>evaluate_worker: Check branch status
    evaluate_worker->>evaluate_worker: Detect commits ahead, no PR URL
    evaluate_worker->>auto_create_pr: Call with task_id, repo details
    
    auto_create_pr->>Git: Check if branch needs pushing
    alt Branch not pushed
        auto_create_pr->>Git: Push branch
    end
    
    auto_create_pr->>GitHub: Create draft PR via 'gh pr create'
    alt PR Creation Success
        GitHub-->>auto_create_pr: Return PR URL
        auto_create_pr->>Task: Persist PR URL via link_pr_to_task()
        auto_create_pr-->>evaluate_worker: Return PR URL
        evaluate_worker-->>Worker: Emit complete:${PR_URL}
    else PR Creation Fails
        GitHub-->>auto_create_pr: Error response
        auto_create_pr-->>evaluate_worker: Non-zero exit
        evaluate_worker-->>Worker: Emit complete:task_only (fallback)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #826 — Adds validate_pr_belongs_to_task() to verify PR attribution; directly complements this PR's auto-creation by ensuring created PRs are validated and gated.
  • PR #378 — Extends evaluate_worker outcome handling to emit complete:${PR_URL} signaling, which this PR now leverages in its auto-creation success path.
  • PR #917 — Modifies evaluate_worker to handle orphaned-PR situations; provides complementary eager linking of existing PRs alongside this PR's eager auto-creation of missing PRs.

Poem

🚀 A branch orphaned, commits adrift—
Now auto-created, a PR gift!
Draft PR blooms, URL persists,
Supervisor's touch—no branch is missed! ✨

🚥 Pre-merge checks | ✅ 3
✅ 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 directly matches the primary change: automatic PR creation for orphaned branches. It's concise, specific, and clearly identifies the feature (t247.2) and its core functionality.
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/t247.2

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, 37 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Feb 10 19:48:07 UTC 2026: Code review monitoring started
Tue Feb 10 19:48:07 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 37

📈 Current Quality Metrics

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

Generated on: Tue Feb 10 19:48:10 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

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

🤖 Fix all issues with AI agents
In @.agents/scripts/supervisor-helper.sh:
- Around line 5303-5371: The auto_create_pr_for_task function should verify
GitHub authentication before doing DB queries, git operations, or pushes; call
the existing check_gh_auth helper early in auto_create_pr_for_task (immediately
after the gh CLI availability check) and return non-zero on failure to avoid
wasted work. Also optionally harden base branch detection in the base_branch
assignment inside auto_create_pr_for_task by checking for origin/master as a
fallback before defaulting to "main" (i.e., try symbolic-ref
refs/remotes/origin/HEAD, then origin/master, then "main"). Ensure you reference
the same symbols: auto_create_pr_for_task, check_gh_auth, base_branch, and
SUPERVISOR_DB when making the change.

Comment on lines +5303 to +5371
auto_create_pr_for_task() {
local task_id="$1"
local repo_path="$2"
local branch_name="$3"
local repo_slug="$4"

if [[ -z "$task_id" || -z "$repo_path" || -z "$branch_name" || -z "$repo_slug" ]]; then
log_warn "auto_create_pr_for_task: missing required arguments (task=$task_id repo=$repo_path branch=$branch_name slug=$repo_slug)"
return 1
fi

if ! command -v gh &>/dev/null; then
log_warn "auto_create_pr_for_task: gh CLI not available — cannot create PR for $task_id"
return 1
fi

# Fetch task description for PR title/body
local escaped_id
escaped_id=$(sql_escape "$task_id")
local task_desc
task_desc=$(db "$SUPERVISOR_DB" "SELECT description FROM tasks WHERE id = '$escaped_id';" 2>/dev/null || echo "")
if [[ -z "$task_desc" ]]; then
task_desc="Worker task $task_id"
fi

# Determine base branch
local base_branch
base_branch=$(git -C "$repo_path" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' || echo "main")

# Ensure branch is pushed to remote
local remote_branch_exists
remote_branch_exists=$(git -C "$repo_path" ls-remote --heads origin "$branch_name" 2>/dev/null | head -1 || echo "")
if [[ -z "$remote_branch_exists" ]]; then
log_info "auto_create_pr_for_task: pushing $branch_name to origin for $task_id"
if ! git -C "$repo_path" push -u origin "$branch_name" 2>>"${SUPERVISOR_LOG:-/dev/null}"; then
log_warn "auto_create_pr_for_task: failed to push $branch_name for $task_id"
return 1
fi
fi

# Build commit summary for PR body (last 10 commits on branch)
local commit_log
commit_log=$(git -C "$repo_path" log --oneline "${base_branch}..${branch_name}" 2>/dev/null | head -10 || echo "(no commits)")

# Create draft PR
local pr_body
pr_body="## Auto-created by supervisor (t247.2)

Worker session ended with commits on branch but no PR (likely context exhaustion).
Supervisor auto-created this PR to preserve work and enable review.

### Commits

\`\`\`
${commit_log}
\`\`\`

### Task

${task_desc}"

local pr_url
pr_url=$(gh pr create \
--repo "$repo_slug" \
--head "$branch_name" \
--base "$base_branch" \
--title "${task_id}: ${task_desc}" \
--body "$pr_body" \
--draft 2>>"${SUPERVISOR_LOG:-/dev/null}") || pr_url=""
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 | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's check the file size and locate the function
wc -l .agents/scripts/supervisor-helper.sh

Repository: marcusquinn/aidevops

Length of output: 106


🏁 Script executed:

# Extract the auto_create_pr_for_task function and surrounding context
sed -n '5303,5385p' .agents/scripts/supervisor-helper.sh

Repository: marcusquinn/aidevops

Length of output: 2931


🏁 Script executed:

# Search for check_gh_auth function definition in the codebase
rg 'check_gh_auth' --type sh -B 2 -A 5

Repository: marcusquinn/aidevops

Length of output: 6473


🏁 Script executed:

# Run ShellCheck on the supervisor-helper.sh file to identify any violations
shellcheck .agents/scripts/supervisor-helper.sh 2>&1 | head -50

Repository: marcusquinn/aidevops

Length of output: 2812


🏁 Script executed:

# Check if there are tests or integration checks related to origin/HEAD handling
rg 'origin/HEAD|symbolic-ref' --type sh

Repository: marcusquinn/aidevops

Length of output: 1273


Add pre-check for GitHub authentication before attempting PR creation (Line 5314).

The function currently validates gh CLI availability but proceeds directly to gh pr create without confirming authentication. Adding a check_gh_auth call before expensive operations (db query, git log, push) improves reliability and avoids resource waste on guaranteed failures. This pattern is already established elsewhere in the script.

🔧 Suggested hardening
    if ! command -v gh &>/dev/null; then
        log_warn "auto_create_pr_for_task: gh CLI not available — cannot create PR for $task_id"
        return 1
    fi
+
+    if ! check_gh_auth; then
+        log_warn "auto_create_pr_for_task: gh auth unavailable — cannot create PR for $task_id"
+        return 1
+    fi

Optional refinement: The base branch fallback (line 5328) could also check for origin/master before defaulting to main, making it more robust for repos using non-standard defaults:

-    base_branch=$(git -C "$repo_path" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' || echo "main")
+    base_branch=$(git -C "$repo_path" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' || echo "")
+    if [[ -z "$base_branch" ]]; then
+        git -C "$repo_path" show-ref --quiet refs/remotes/origin/main && base_branch="main"
+        git -C "$repo_path" show-ref --quiet refs/remotes/origin/master && base_branch="master"
+        base_branch="${base_branch:-main}"
+    fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
auto_create_pr_for_task() {
local task_id="$1"
local repo_path="$2"
local branch_name="$3"
local repo_slug="$4"
if [[ -z "$task_id" || -z "$repo_path" || -z "$branch_name" || -z "$repo_slug" ]]; then
log_warn "auto_create_pr_for_task: missing required arguments (task=$task_id repo=$repo_path branch=$branch_name slug=$repo_slug)"
return 1
fi
if ! command -v gh &>/dev/null; then
log_warn "auto_create_pr_for_task: gh CLI not available — cannot create PR for $task_id"
return 1
fi
# Fetch task description for PR title/body
local escaped_id
escaped_id=$(sql_escape "$task_id")
local task_desc
task_desc=$(db "$SUPERVISOR_DB" "SELECT description FROM tasks WHERE id = '$escaped_id';" 2>/dev/null || echo "")
if [[ -z "$task_desc" ]]; then
task_desc="Worker task $task_id"
fi
# Determine base branch
local base_branch
base_branch=$(git -C "$repo_path" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' || echo "main")
# Ensure branch is pushed to remote
local remote_branch_exists
remote_branch_exists=$(git -C "$repo_path" ls-remote --heads origin "$branch_name" 2>/dev/null | head -1 || echo "")
if [[ -z "$remote_branch_exists" ]]; then
log_info "auto_create_pr_for_task: pushing $branch_name to origin for $task_id"
if ! git -C "$repo_path" push -u origin "$branch_name" 2>>"${SUPERVISOR_LOG:-/dev/null}"; then
log_warn "auto_create_pr_for_task: failed to push $branch_name for $task_id"
return 1
fi
fi
# Build commit summary for PR body (last 10 commits on branch)
local commit_log
commit_log=$(git -C "$repo_path" log --oneline "${base_branch}..${branch_name}" 2>/dev/null | head -10 || echo "(no commits)")
# Create draft PR
local pr_body
pr_body="## Auto-created by supervisor (t247.2)
Worker session ended with commits on branch but no PR (likely context exhaustion).
Supervisor auto-created this PR to preserve work and enable review.
### Commits
\`\`\`
${commit_log}
\`\`\`
### Task
${task_desc}"
local pr_url
pr_url=$(gh pr create \
--repo "$repo_slug" \
--head "$branch_name" \
--base "$base_branch" \
--title "${task_id}: ${task_desc}" \
--body "$pr_body" \
--draft 2>>"${SUPERVISOR_LOG:-/dev/null}") || pr_url=""
auto_create_pr_for_task() {
local task_id="$1"
local repo_path="$2"
local branch_name="$3"
local repo_slug="$4"
if [[ -z "$task_id" || -z "$repo_path" || -z "$branch_name" || -z "$repo_slug" ]]; then
log_warn "auto_create_pr_for_task: missing required arguments (task=$task_id repo=$repo_path branch=$branch_name slug=$repo_slug)"
return 1
fi
if ! command -v gh &>/dev/null; then
log_warn "auto_create_pr_for_task: gh CLI not available — cannot create PR for $task_id"
return 1
fi
if ! check_gh_auth; then
log_warn "auto_create_pr_for_task: gh auth unavailable — cannot create PR for $task_id"
return 1
fi
# Fetch task description for PR title/body
local escaped_id
escaped_id=$(sql_escape "$task_id")
local task_desc
task_desc=$(db "$SUPERVISOR_DB" "SELECT description FROM tasks WHERE id = '$escaped_id';" 2>/dev/null || echo "")
if [[ -z "$task_desc" ]]; then
task_desc="Worker task $task_id"
fi
# Determine base branch
local base_branch
base_branch=$(git -C "$repo_path" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' || echo "main")
# Ensure branch is pushed to remote
local remote_branch_exists
remote_branch_exists=$(git -C "$repo_path" ls-remote --heads origin "$branch_name" 2>/dev/null | head -1 || echo "")
if [[ -z "$remote_branch_exists" ]]; then
log_info "auto_create_pr_for_task: pushing $branch_name to origin for $task_id"
if ! git -C "$repo_path" push -u origin "$branch_name" 2>>"${SUPERVISOR_LOG:-/dev/null}"; then
log_warn "auto_create_pr_for_task: failed to push $branch_name for $task_id"
return 1
fi
fi
# Build commit summary for PR body (last 10 commits on branch)
local commit_log
commit_log=$(git -C "$repo_path" log --oneline "${base_branch}..${branch_name}" 2>/dev/null | head -10 || echo "(no commits)")
# Create draft PR
local pr_body
pr_body="## Auto-created by supervisor (t247.2)
Worker session ended with commits on branch but no PR (likely context exhaustion).
Supervisor auto-created this PR to preserve work and enable review.
### Commits
\`\`\`
${commit_log}
\`\`\`
### Task
${task_desc}"
local pr_url
pr_url=$(gh pr create \
--repo "$repo_slug" \
--head "$branch_name" \
--base "$base_branch" \
--title "${task_id}: ${task_desc}" \
--body "$pr_body" \
--draft 2>>"${SUPERVISOR_LOG:-/dev/null}") || pr_url=""
🤖 Prompt for AI Agents
In @.agents/scripts/supervisor-helper.sh around lines 5303 - 5371, The
auto_create_pr_for_task function should verify GitHub authentication before
doing DB queries, git operations, or pushes; call the existing check_gh_auth
helper early in auto_create_pr_for_task (immediately after the gh CLI
availability check) and return non-zero on failure to avoid wasted work. Also
optionally harden base branch detection in the base_branch assignment inside
auto_create_pr_for_task by checking for origin/master as a fallback before
defaulting to "main" (i.e., try symbolic-ref refs/remotes/origin/HEAD, then
origin/master, then "main"). Ensure you reference the same symbols:
auto_create_pr_for_task, check_gh_auth, base_branch, and SUPERVISOR_DB when
making the change.

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