Skip to content

Epic: Sequential stacked PR chains (chain orchestrator) #52

@chanakyav

Description

@chanakyav

Summary

Run a batch of related sub-issues as a sequential stacked PR chain — each PR building on the previous. When upstream PRs change (review feedback, CI fixes), downstream tasks automatically rebase and re-run.

autopilot chain --epic 52          # fetch sub-issues of #52, run as stacked chain
autopilot chain --issues 51,52,53  # explicit issue list, run as stacked chain

Motivation

Today, autopilot-loop handles one task at a time. For larger features that decompose into multiple sub-tasks, users must manually:

  1. Run each sub-task sequentially, waiting for completion
  2. Manually set PR base branches for stacking
  3. Manually rebase downstream PRs when upstream changes
  4. Type out issue numbers instead of referencing an epic

This is exactly the kind of repetitive coordination that should be automated.

Architecture: Sequential Stacked Chain with Branch Checkout

V1 uses standard git checkout for branch switching, not git worktrees.

We evaluated git worktrees extensively. While they provide workspace isolation (agent and user don't share the same working tree), they have a critical practical problem: every worktree is a full copy of the working tree (minus .git). For large repos with expensive dependency bootstrapping (Rails apps needing bundle install, Node projects needing npm install, etc.), each worktree requires a full re-bootstrap of dependencies. This can take 10+ minutes per worktree, making chains impractical.

Branch checkout keeps installed dependencies in place — git checkout <branch> swaps source files but leaves node_modules/, vendor/, .venv/, and other gitignored dependency directories untouched. Zero bootstrap overhead between tasks.

Trade-off: The repo's working directory is occupied while the agent runs (same as today — no regression). Worktrees remain a future optimization option for repos where dependency bootstrapping isn't a concern.

Flow

autopilot chain --epic 52
  1. Fetch sub-issues via GraphQL (issue.subIssues connection)
  2. Create tasks for each sub-issue in order, with dependency chain:
    • Task 1: base_branch = default branch, checkout new branch
    • Task 2: base_branch = task_1_branch, parent_task_id = task_1_id
    • Task 3: base_branch = task_2_branch, parent_task_id = task_2_id
  3. Run sequentially: Task 1 → wait for COMPLETE → checkout task 2's branch → Task 2 → wait → Task 3
  4. Each task runs the full review-fix loop (IMPLEMENT → CCR review → FIX → ... → UPDATE_DESCRIPTION → COMPLETE)
  5. If upstream changes later (user restarts task 1 after reviewer feedback):
    • Cascade engine detects the SHA change
    • Checks out task 2's branch, rebases onto task 1's new HEAD
    • Re-runs task 2's agent
    • Cascades to task 3, etc.

Architecture Diagram

┌────────────┐     ┌────────────┐     ┌────────────┐
│  Task 1    │     │  Task 2    │     │  Task 3    │
│  Issue #51 │────▶│  Issue #52 │────▶│  Issue #53 │
│  base:main │     │  base:t1   │     │  base:t2   │
└────────────┘     └────────────┘     └────────────┘
      │                  │                  │
      ▼                  ▼                  ▼
   PR #101           PR #102           PR #103
   base:main         base:t1-branch    base:t2-branch

Sequential: Task 1 completes → checkout t2 branch → Task 2 → ...
Cascade: Task 1 changes → checkout t2, rebase → checkout t3, rebase

What This Builds On (v0.3.0)

The current codebase (schema v8) already has:

  • Structured state machine with bounce detection and context carry-forward
  • UPDATE_DESCRIPTION state for auto-updating PR descriptions after fixes
  • CIOrchestrator for CI fix loops
  • Crash-safe retry counts (retry_counts_json) and pre_fix_sha tracking
  • Branch locking to prevent concurrent tasks on same branch
  • Codespace idle timeout management with save/restore

Sub-Issues (Essential for V1)

Ordered by dependency:

  1. Schema: parent_task_id, epic_id, base_branch, upstream_sha columns #55 — Schema: parent_task_id, epic_id, base_branch, upstream_sha columns (no dependencies, do first)
  2. base_branch support for stacked PRs #54base_branch support for stacked PRs (PR targeting, diff context, get_default_branch())
  3. autopilot chain command with --epic and --issues flags #57autopilot chain command (CLI entry point, --epic with GraphQL sub-issue fetching, --issues fallback, sequential runner)
  4. Sequential cascade engine: rebase and re-run on upstream changes #59 — Sequential cascade engine (rebase + re-run when upstream changes)

Deferred (Future Enhancements)

Hard Problems

1. Sub-Issues API

GitHub sub-issues are GraphQL-only (issue.subIssues). The codebase already uses GraphQL extensively (review threads, comment resolution). Graceful handling when the feature isn't available — bail early: "Issue #52 has no sub-issues. Use autopilot chain --issues 51,52,53 instead."

2. Sub-Issue Ordering

GitHub returns sub-issues in the order they were added. V1 uses this order as the dependency chain. Users who want different ordering use --issues with explicit numbers.

3. Cascade After Human Review

The primary cascade scenario: human reviewer gives feedback on PR #1, user restarts task 1, it pushes new commits. The cascade engine detects the change and propagates downstream. This must work reliably — it's the core value of stacking.

4. Rebase Conflicts

When downstream rebases onto updated upstream, conflicts are possible. The agent gets a conflict resolution prompt. If it can't resolve after 2 attempts, the task pauses for manual attention.

Verification Scenarios

  1. autopilot chain --epic 52 with 3 sub-issues → 3 stacked PRs created sequentially
  2. autopilot chain --issues 51,52,53 → same result from explicit issue list
  3. --epic with no sub-issues → clear error message, bail
  4. Task 1 completes → Task 2 starts automatically on Task 1's branch
  5. User restarts Task 1 after review feedback → Tasks 2 and 3 cascade (rebase + re-run)
  6. Rebase conflict in cascade → agent resolves, or pauses after 2 attempts
  7. autopilot status shows all chain tasks with their states

Differentiation from Agent Orchestrator (Composio)

Agent Orchestrator is a general-purpose agent fleet manager (agent-agnostic, runtime-agnostic, parallel-first). autopilot-loop differentiates by:

  • Deep Copilot Review integration: request CCR → poll → parse unresolved comments → fix → reply → resolve threads → update description → loop. No other tool has this.
  • Context carry-forward: tracks what was fixed vs. skipped across iterations, detects bouncing review loops
  • Codespace-native: idle timeout management, designed for constrained cloud environments
  • Issue-to-PR pipeline: --issue or --epic reads GitHub issues directly
  • Sequential-first: optimized for Codespace resource constraints, not local workstation fleets

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestepicMulti-issue feature initiative

Projects

Status

Ready

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions