t247.2: Supervisor auto-PR for orphaned branches#988
Conversation
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.
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
WalkthroughThis 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
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Tue Feb 10 19:48:10 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
There was a problem hiding this comment.
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.
| 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="" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check the file size and locate the function
wc -l .agents/scripts/supervisor-helper.shRepository: 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.shRepository: 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 5Repository: 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 -50Repository: 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 shRepository: 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
+ fiOptional 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.
| 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.



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 returningtask_onlyor triggering a full retry (~300s saved per occurrence).Changes
auto_create_pr_for_task()(supervisor-helper.sh:5303): Pushes branch to remote if needed, creates draft PR viagh pr createwith commit summary and task description, persists URL vialink_pr_to_task()evaluate_worker()(supervisor-helper.sh:5914): Whenbranch_commits > 0and no PR exists, callsauto_create_pr_for_task()before falling back totask_onlyFlow
Design Decisions
cmd_pr_lifecycledraft auto-promotion logic handles the ready transition (worker is dead → auto-promote)ghis unavailable or PR creation fails, falls back to existingtask_onlybehavior — no regressionlink_pr_to_task()(t232) for persistence,detect_repo_slug()for repo identificationTesting
bash -npassesSummary by CodeRabbit