feat(#651): auto-recover BLOCKED-by-merge-conflict tasks via worktree rebase (Option A)#656
Conversation
PR #653 marked tasks BLOCKED on merge fail (closed kanban/filesystem divergence) but left them unrecoverable. verify-snake-8 (test71, 2026-05-25) hit one such conflict; the runner spawned 49 ephemeral agents chasing the unclaimed downstream task before the 20-min stall watchdog gave up — ~$25-50 wasted spawn cost. Most "conflicts" in DAG-based parallel work are stale-base false conflicts. Rebase resolves these mechanically. Real content conflicts abort the rebase and leave the task BLOCKED. New helpers in src/marcus_mcp/tools/task.py: - _attempt_merge_recovery(task, state): runs git rebase main in the agent's worktree; on clean rebase fast-forwards main and transitions task to DONE + clears merge_conflict source_context. Returns None on real conflict (worktree cleaned via rebase --abort). - _sweep_blocked_merge_conflicts(state): iterates project_tasks, attempts recovery on each BLOCKED+merge_conflict task. Wired into request_next_task: when no optimal_task, sweep BEFORE returning no_task_ready. If recovery unblocks downstream tasks, the current agent claims directly — no spawn-thrash cycle. Bright-line: rebasing the agent's branch onto main is environment shaping, not HOW dictation. Same primitive as git pull --rebase. 5 new tests with real tmp_path git repos. 408 unit tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude finished @lwgray's task —— View job Code Review CompleteI've thoroughly reviewed this PR implementing auto-recovery for merge-conflict blocked tasks. Here's my comprehensive feedback: Review Checklist:
✅ Strengths1. Excellent Problem Definition & Solution
2. Robust Implementation
3. Comprehensive Test Coverage
|
Why
PR #653 marked tasks BLOCKED on merge failure but left them unrecoverable. verify-snake-8 (test71, 2026-05-25) hit one such conflict and the runner spawned 49 ephemeral agents before the 20-min stall watchdog gave up — roughly $25-50 of wasted spawn cost from one recoverable conflict. On a commercial customer's API key the wasted spend could be $200-500 per stall event.
This PR implements Option A from Larry's 2026-05-25 decision: auto-recovery via worktree rebase. The proper architectural prevention (#206 baton arbitration) is the next sprint of work; this is the safety net that ships fast.
Most conflicts in DAG-based parallel work are stale-base false conflicts. Rebase resolves these mechanically. Real content conflicts abort the rebase and leave the task BLOCKED.
What changed
_attempt_merge_recovery(task, state)insrc/marcus_mcp/tools/task.py:source_context.merge_conflict(set by PR fix(#651): mark task BLOCKED when worktree merge to main fails #653's helper)<project_root>/../worktrees/<agent_id>git rebase mainin the worktreegit merge --ff-only <branch>+ kanban → DONE + clearmerge_conflictfrom source_contextgit rebase --abortto clean state; leave BLOCKED; return None_sweep_blocked_merge_conflicts(state)iteratesstate.project_tasksand runs recovery on each BLOCKED+merge_conflict task.Wired into
request_next_task: when nooptimal_taskfound, sweep fires before returningno_task_ready. If recovery unblocks downstream tasks, refresh state + re-select for the current agent. Eliminates the spawn-thrash cycle.Bright-line check
Marcus rebasing the agent's branch onto main is environment shaping, not HOW dictation. Same primitive as
git pull --rebase. Agent's code unchanged; Marcus just integrates cleanly against advanced main. Passes Invariant #2.Test plan
Automated (green)
tests/unit/marcus_mcp/test_merge_conflict_recovery.pyusing realtmp_pathgit repostests/unit/marcus_mcp+tests/unit/mcpmypy src/marcus_mcp/tools/task.py— cleanEnd-to-end (reviewer to run)
Empirical motivation
From verify-snake-8 (test71) runner log:
This PR eliminates that failure mode.
What this PR does NOT do
Related
🤖 Generated with Claude Code