-
Notifications
You must be signed in to change notification settings - Fork 39
t1072, t1073: Multi-commit rebase loop + sequential subtask dispatch #1558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2129,6 +2129,66 @@ RULES: | |
| # Args: task_id | ||
| # Returns: 0 on success, 1 on rebase failure, 2 on force-push failure | ||
| ####################################### | ||
|
|
||
| ####################################### | ||
| # t1072: Resolve rebase conflicts in a loop for multi-commit branches. | ||
| # When a branch has N commits and multiple conflict with main, we need | ||
| # to resolve each one and continue until the rebase completes. | ||
| # Args: git_dir task_id | ||
| # Returns: 0 on success, 1 on failure (rebase aborted) | ||
| ####################################### | ||
| _resolve_rebase_loop() { | ||
| local git_dir="$1" | ||
| local task_id="$2" | ||
| local max_iterations=10 | ||
| local iteration=0 | ||
|
|
||
| while ((iteration < max_iterations)); do | ||
| iteration=$((iteration + 1)) | ||
| log_warn "rebase_sibling_pr: rebase conflict for $task_id — attempting AI resolution (commit $iteration/$max_iterations)" | ||
|
|
||
| if ! resolve_rebase_conflicts "$git_dir" "$task_id"; then | ||
| log_warn "rebase_sibling_pr: AI resolution failed for $task_id at commit $iteration — aborting" | ||
| git -C "$git_dir" rebase --abort 2>>"$SUPERVISOR_LOG" || true | ||
| return 1 | ||
| fi | ||
|
|
||
| # t1048: Check if rebase is still in progress — the AI agent | ||
| # may have already run `git rebase --continue` itself | ||
| local git_state_dir | ||
| git_state_dir="$(git -C "$git_dir" rev-parse --git-dir 2>/dev/null)" | ||
|
Comment on lines
+2158
to
+2159
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| if [[ ! -d "$git_state_dir/rebase-merge" && ! -d "$git_state_dir/rebase-apply" ]]; then | ||
| # AI agent already completed the entire rebase | ||
| log_success "rebase_sibling_pr: rebase completed (AI resolved all commits) for $task_id" | ||
| return 0 | ||
| fi | ||
|
|
||
| log_info "rebase_sibling_pr: AI resolved commit $iteration for $task_id — continuing rebase" | ||
| if git -C "$git_dir" rebase --continue 2>>"$SUPERVISOR_LOG"; then | ||
| # Rebase completed successfully — no more conflicts | ||
| log_success "rebase_sibling_pr: rebase completed after resolving $iteration conflict(s) for $task_id" | ||
| return 0 | ||
| fi | ||
|
|
||
| # rebase --continue failed — check if it's another conflict or a real error | ||
| git_state_dir="$(git -C "$git_dir" rev-parse --git-dir 2>/dev/null)" | ||
| if [[ -d "$git_state_dir/rebase-merge" || -d "$git_state_dir/rebase-apply" ]]; then | ||
| # Still in rebase state — another commit has conflicts, loop continues | ||
| log_info "rebase_sibling_pr: commit $iteration resolved but next commit also conflicts for $task_id" | ||
| continue | ||
| fi | ||
|
|
||
| # rebase --continue failed and no rebase in progress — unexpected state | ||
| log_warn "rebase_sibling_pr: rebase --continue failed unexpectedly for $task_id at commit $iteration" | ||
| return 1 | ||
| done | ||
|
|
||
| # Exhausted max iterations | ||
| log_warn "rebase_sibling_pr: exhausted $max_iterations conflict resolution attempts for $task_id — aborting" | ||
| git -C "$git_dir" rebase --abort 2>>"$SUPERVISOR_LOG" || true | ||
| return 1 | ||
| } | ||
|
|
||
| rebase_sibling_pr() { | ||
| local task_id="$1" | ||
|
|
||
|
|
@@ -2201,30 +2261,7 @@ rebase_sibling_pr() { | |
| if [[ "$use_worktree" == "true" ]]; then | ||
| # Worktree is already on the branch — rebase in place | ||
| if ! git -C "$git_dir" rebase origin/main 2>>"$SUPERVISOR_LOG"; then | ||
| log_warn "rebase_sibling_pr: rebase conflict for $task_id — attempting AI resolution" | ||
| # Try AI-assisted conflict resolution before aborting | ||
| if resolve_rebase_conflicts "$git_dir" "$task_id"; then | ||
| # t1048: Check if rebase is still in progress — the AI agent | ||
| # may have already run `git rebase --continue` itself, leaving | ||
| # no rebase in progress for us to continue. | ||
| local git_state_dir | ||
| git_state_dir="$(git -C "$git_dir" rev-parse --git-dir 2>/dev/null)" | ||
| if [[ -d "$git_state_dir/rebase-merge" || -d "$git_state_dir/rebase-apply" ]]; then | ||
| log_info "rebase_sibling_pr: AI resolved conflicts for $task_id — continuing rebase" | ||
| if git -C "$git_dir" rebase --continue 2>>"$SUPERVISOR_LOG"; then | ||
| log_success "rebase_sibling_pr: rebase completed after AI resolution for $task_id" | ||
| else | ||
| log_warn "rebase_sibling_pr: rebase --continue failed after AI resolution for $task_id" | ||
| git -C "$git_dir" rebase --abort 2>>"$SUPERVISOR_LOG" || true | ||
| return 1 | ||
| fi | ||
| else | ||
| # AI agent already completed the rebase — treat as success | ||
| log_success "rebase_sibling_pr: rebase completed (AI resolved and continued) for $task_id" | ||
| fi | ||
| else | ||
| log_warn "rebase_sibling_pr: AI resolution failed for $task_id — aborting" | ||
| git -C "$git_dir" rebase --abort 2>>"$SUPERVISOR_LOG" || true | ||
| if ! _resolve_rebase_loop "$git_dir" "$task_id"; then | ||
| return 1 | ||
| fi | ||
| fi | ||
|
|
@@ -2240,31 +2277,7 @@ rebase_sibling_pr() { | |
| fi | ||
|
|
||
| if ! git -C "$git_dir" rebase origin/main 2>>"$SUPERVISOR_LOG"; then | ||
| log_warn "rebase_sibling_pr: rebase conflict for $task_id — attempting AI resolution" | ||
| # Try AI-assisted conflict resolution before aborting | ||
| if resolve_rebase_conflicts "$git_dir" "$task_id"; then | ||
| # t1048: Check if rebase is still in progress (see worktree path above) | ||
| local git_state_dir | ||
| git_state_dir="$(git -C "$git_dir" rev-parse --git-dir 2>/dev/null)" | ||
| if [[ -d "$git_state_dir/rebase-merge" || -d "$git_state_dir/rebase-apply" ]]; then | ||
| log_info "rebase_sibling_pr: AI resolved conflicts for $task_id — continuing rebase" | ||
| if git -C "$git_dir" rebase --continue 2>>"$SUPERVISOR_LOG"; then | ||
| log_success "rebase_sibling_pr: rebase completed after AI resolution for $task_id" | ||
| else | ||
| log_warn "rebase_sibling_pr: rebase --continue failed after AI resolution for $task_id" | ||
| git -C "$git_dir" rebase --abort 2>>"$SUPERVISOR_LOG" || true | ||
| # Return to original branch | ||
| git -C "$git_dir" checkout "${current_branch:-main}" 2>>"$SUPERVISOR_LOG" || true | ||
| return 1 | ||
| fi | ||
| else | ||
| # AI agent already completed the rebase — treat as success | ||
| log_success "rebase_sibling_pr: rebase completed (AI resolved and continued) for $task_id" | ||
| fi | ||
| else | ||
| log_warn "rebase_sibling_pr: AI resolution failed for $task_id — aborting" | ||
| git -C "$git_dir" rebase --abort 2>>"$SUPERVISOR_LOG" || true | ||
| # Return to original branch | ||
| if ! _resolve_rebase_loop "$git_dir" "$task_id"; then | ||
| git -C "$git_dir" checkout "${current_branch:-main}" 2>>"$SUPERVISOR_LOG" || true | ||
| return 1 | ||
| fi | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -926,30 +926,66 @@ cmd_next() { | |
|
|
||
| ensure_db | ||
|
|
||
| local candidates | ||
| if [[ -n "$batch_id" ]]; then | ||
| local escaped_batch | ||
| escaped_batch=$(sql_escape "$batch_id") | ||
|
|
||
| db -separator $'\t' "$SUPERVISOR_DB" " | ||
| candidates=$(db -separator $'\t' "$SUPERVISOR_DB" " | ||
| SELECT t.id, t.repo, t.description, t.model | ||
| FROM batch_tasks bt | ||
| JOIN tasks t ON bt.task_id = t.id | ||
| WHERE bt.batch_id = '$escaped_batch' | ||
| AND t.status = 'queued' | ||
| AND t.retries < t.max_retries | ||
| ORDER BY t.retries ASC, bt.position | ||
| LIMIT $limit; | ||
| " | ||
| LIMIT $((limit * 3)); | ||
| ") | ||
| else | ||
| db -separator $'\t' "$SUPERVISOR_DB" " | ||
| candidates=$(db -separator $'\t' "$SUPERVISOR_DB" " | ||
| SELECT id, repo, description, model | ||
| FROM tasks | ||
| WHERE status = 'queued' | ||
| AND retries < max_retries | ||
| ORDER BY retries ASC, created_at ASC | ||
| LIMIT $limit; | ||
| " | ||
| LIMIT $((limit * 3)); | ||
| ") | ||
| fi | ||
|
|
||
| [[ -z "$candidates" ]] && return 0 | ||
|
|
||
| # t1073: Filter out subtasks whose earlier siblings are still in-flight. | ||
| # Subtasks (IDs like t1063.2) should run sequentially — dispatching them | ||
| # in parallel causes merge conflicts because they modify the same files. | ||
| # Skip a subtask if any sibling with a lower suffix is not yet terminal. | ||
| local count=0 | ||
| while IFS=$'\t' read -r cid crepo cdesc cmodel; do | ||
| [[ "$count" -ge "$limit" ]] && break | ||
|
|
||
| # Check if this is a subtask (contains a dot) | ||
| if [[ "$cid" == *.* ]]; then | ||
| local parent_id="${cid%.*}" | ||
| local suffix="${cid##*.}" | ||
|
|
||
| # Check if any earlier sibling (same parent, lower suffix) is non-terminal | ||
| local earlier_active | ||
| earlier_active=$(db "$SUPERVISOR_DB" " | ||
| SELECT count(*) FROM tasks | ||
| WHERE id LIKE '$(sql_escape "$parent_id").%' | ||
| AND id != '$(sql_escape "$cid")' | ||
| AND CAST(REPLACE(id, '$(sql_escape "$parent_id").', '') AS INTEGER) < $suffix | ||
| AND status NOT IN ('verified','cancelled','deployed','complete'); | ||
| " 2>/dev/null || echo "0") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suppressing stderr with References
|
||
|
|
||
| if [[ "$earlier_active" -gt 0 ]]; then | ||
| log_info " cmd_next: deferring $cid — earlier sibling(s) of $parent_id still active" | ||
| continue | ||
| fi | ||
| fi | ||
|
|
||
| printf '%s\t%s\t%s\t%s\n' "$cid" "$crepo" "$cdesc" "$cmodel" | ||
| count=$((count + 1)) | ||
| done <<<"$candidates" | ||
|
Comment on lines
+962
to
+988
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
|
|
||
| return 0 | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function violates the repository's shell script style guide. Line 11 requires declaring local variables and assigning values from positional parameters in separate statements to ensure exit code safety (e.g.,
local var; var="$1").References
local var="$1"pattern in functions (declare and assign separately for exit code safety) (link)