Dataface Tasks

Resume conflicted task PRs in the same worktree — agent before human escalation

IDINFRA_TOOLING-RESUME_CONFLICTED_TASK_PRS_IN_THE_SAME_WORKTREE_AGENT_BEFORE_HUMAN_ESCALATION
Statuscompleted
Priorityp1
Milestonem1-ft-analytics-analyst-pilot
Ownersr-engineer-architect
Completed bytask-manager
Completed2026-03-27

Problem

When auto-rebase fails for a conflicted task PR, dispatch an agent to the existing worktree to resolve conflicts before escalating to a human operator.

Context

  • auto_rebase_conflicted_pr_tasks() in scripts/task_manager_lib.py handles conflicted PRs today:
  • Clean worktree + rebase succeeds → auto-rebased, no human needed
  • Dirty worktree or rebase failure → immediate tier1 escalation to human (pr_conflict_dirty_branch / pr_conflict_needs_manual_rebase)
  • The dirty-worktree and rebase-failure cases are the most common in practice. Often the conflict is resolvable by an agent that can read the merge markers and apply the right resolution — but today we skip straight to human escalation.
  • The scripts/dispatch script already supports --path to reuse an existing worktree, so we can dispatch an agent to the same worktree with a conflict-resolution prompt.
  • Key constraint: the agent dispatch must be optional and gated — not every caller wants to spawn a subprocess. The heartbeat and reconcile-pr-conflicts scripts should opt in explicitly.
  • Relevant files:
  • scripts/task_manager_lib.pyauto_rebase_conflicted_pr_tasks(), _note_attention()
  • scripts/task-manager-reconcile-pr-conflicts — standalone operator command
  • scripts/task-manager-heartbeat — main loop
  • scripts/dispatch — agent dispatch infrastructure
  • tests/scripts/test_task_manager_scripts.py — test suite

Possible Solutions

  • Option 1: Keep current behavior — auto-rebase or immediate human escalation. Simple but leaves resolvable conflicts sitting until a human intervenes. Rejected.
  • Option 2: Recommended Add a resume_conflicted_pr_via_agent() function that:
  • Takes the list of tasks that auto_rebase_conflicted_pr_tasks() placed into "skipped" or "failed"
  • For each, dispatches an agent to the existing worktree with a targeted conflict-resolution prompt (git fetch origin main && git rebase origin/main, resolve markers, commit, push)
  • On agent success → record as "agent_resolved"
  • On agent failure/timeout → escalate to human with pr_conflict_needs_human (tier1)
  • Controlled by a --agent-resolve flag so callers opt in
  • Option 3: Have the heartbeat auto-dispatch a full task-execute agent. Too heavyweight — we only need a narrow rebase-resolution prompt, not a full re-implementation. Rejected.

Plan

  1. Write failing tests for resume_conflicted_pr_via_agent(): - Agent dispatch succeeds → task recorded as "agent_resolved", no human escalation - Agent dispatch fails → task escalated with pr_conflict_needs_human - Agent dispatch times out → same escalation - Tasks without worktree path → skipped
  2. Implement resume_conflicted_pr_via_agent() in task_manager_lib.py: - Accept tasks + rebase results from auto_rebase_conflicted_pr_tasks() - Build a conflict-resolution prompt - Shell out to scripts/dispatch with --path <worktree> and a timeout - Collect results: agent_resolved, agent_failed, agent_skipped
  3. Wire into scripts/task-manager-reconcile-pr-conflicts behind --agent-resolve flag.
  4. Wire into heartbeat behind --agent-resolve flag (off by default).
  5. Update task worksheet with implementation progress.

Implementation Progress

Files modified

  • scripts/task_manager_lib.py — Added resume_conflicted_pr_via_agent() function with:
  • Targeted conflict-resolution prompt (fetch, rebase, resolve markers, push)
  • Dispatches agent to existing worktree via scripts/dispatch
  • On success → agent_resolved, no human escalation
  • On failure/timeout → pr_conflict_needs_human tier1 escalation
  • Skips tasks without worktree path
  • scripts/task-manager-reconcile-pr-conflicts — Added --agent-resolve and --agent-timeout flags. When --agent-resolve is passed, calls resume_conflicted_pr_via_agent() on tasks that auto-rebase skipped or failed. JSON and text output include agent results.
  • tests/scripts/test_task_manager_scripts.py — 4 new tests:
  • test_resume_conflicted_pr_via_agent_success — agent succeeds, no escalation
  • test_resume_conflicted_pr_via_agent_failure_escalates — agent fails, human escalation
  • test_resume_conflicted_pr_via_agent_timeout_escalates — agent times out, human escalation
  • test_resume_conflicted_pr_via_agent_skips_no_worktree — no worktree, skipped

Key decisions

  • Agent resolve is opt-in (--agent-resolve flag) — not enabled by default in heartbeat or reconcile
  • The prompt is narrow: only resolve merge conflicts, no logic changes
  • Escalation code is pr_conflict_needs_human (distinct from pr_conflict_needs_manual_rebase) to clearly indicate the agent path was tried first
  • Heartbeat wiring deferred to follow-up — heartbeat doesn't currently call auto-rebase, so adding both rebase + agent-resolve would be a larger scope change

QA Exploration

  • [x] QA exploration completed (or N/A for non-UI tasks)
  • N/A: backend/orchestration task

Review Feedback

  • [ ] Review cleared