| name | autopilot |
| description | Autonomous spec execution with subagents (planner, coder, tester, reviewer). |
| model | opus |
Autopilot v3.5 — Fresh Subagents + Loop Mode
Autonomous execution: Plan → Fresh subagent per task → commit → next.
Activation:
autopilot — process all queued specs (interactive)
autopilot SPEC_ID — process single spec only (loop mode)
autopilot --no-worktree — skip worktree (for tiny fixes only)
Loop Mode (Single Spec)
When called with autopilot TECH-069 (specific SPEC_ID):
- Process ONLY that spec — ignore other queued specs
- Exit after completion — do NOT continue to next spec
- Let external orchestrator handle next — fresh context per spec
This is the mode the VPS orchestrator (scripts/vps/orchestrator.py → pueue → claude-runner.py via Agent SDK) uses: it dispatches one spec at a time as a fresh Agent SDK session.
Detection: If first argument matches pattern (TECH|FTR|BUG|ARCH)-\d+, enter loop mode.
Quick Reference
PHASE 0: Worktree Setup → worktree-setup.md
└─ CI check → worktree → env copy → baseline
PHASE 1: Plan (ALWAYS) → subagent-dispatch.md
└─ [Plan Agent] opus → re-reads codebase → tasks in spec
PHASE 2: Execute (per task) → task-loop.md
└─ [Coder] sonnet → files
└─ [Tester] sonnet → pass?
└─ fail? → [Debugger] opus (max 3) → escalation.md
└─ PRE-CHECK (deterministic)
└─ [Spec Reviewer] sonnet → approved?
└─ [Code Quality] opus → approved?
└─ COMMIT (no push)
└─ LOCAL VERIFY (if AV section) → warn only
PHASE 3: Finish → finishing.md
└─ Final test → Exa verification → status done → push feature → POST-DEPLOY VERIFY → merge develop → push develop → cleanup
Limits & Escalation: See escalation.md
Safety Rules: See safety-rules.md
Modules
| Module | Content |
|---|
worktree-setup.md | Git worktree creation, env setup, cleanup |
subagent-dispatch.md | Subagent types, dispatch templates, model routing |
task-loop.md | PHASE 2 execution flow, decision trees after each step |
finishing.md | Pre-done checklist, status sync, merge flow |
escalation.md | Limits, debug/refactor loops, Spark/Council |
safety-rules.md | Forbidden actions, file/test/git safety |
Architecture
PHASE 0: WORKTREE SETUP
See: worktree-setup.md
PHASE 1: PLAN (ALWAYS — even if spec has plan)
[Plan Subagent] → re-reads codebase → writes/overwrites plan
WHY: specs queued earlier have stale line numbers after prior specs execute
See: subagent-dispatch.md#plan-subagent
PHASE 2: FOR EACH TASK (fresh subagent per task!)
[CODER] → code → files_changed
[TESTER] → Smart Testing
PRE-CHECK → deterministic validation
[SPEC REVIEWER] → Stage 1
[CODE QUALITY] → Stage 2
COMMIT (NO PUSH yet!)
See: task-loop.md (SSOT for execution flow)
PHASE 3: FINISHING
Push feature branch → merge develop → push develop
See: finishing.md
Plan vs Workflow Separation
Plan defines WHAT:
- What code to write
- Which files to create/modify
- Acceptance criteria
Autopilot defines HOW:
- Fixed workflow for EACH task
- Gates and checkpoints
- Review process
Task Execution Template
For EACH task from plan:
┌─────────────────────────────────────────────────────┐
│ 1. CODER → files_changed │
│ 2. TESTER → Smart Testing │
│ 3. PRE-CHECK → deterministic validation │
│ 4. SPEC REVIEWER (Stage 1) → matches spec? │
│ 5. CODE QUALITY (Stage 2) → architecture ok? │
│ 6. COMMIT (NO PUSH yet!) │
│ 7. LOCAL VERIFY → smoke + functional (warn only) │
└─────────────────────────────────────────────────────┘
SSOT: See task-loop.md for detailed decision trees after each step.
⛔ Skipping any step = VIOLATION
Commit Format (MANDATORY)
Every PHASE 2 task commit MUST use Conventional Commits with the spec_id in scope:
<type>(SPEC_ID): <imperative description>
type ∈ {feat, fix, chore, docs, refactor, test}; SPEC_ID UPPERCASE inside (), NOT in trailing text.
✅ feat(FTR-1076): add WB API key schemas ✅ fix(BUG-439): restore constraint
❌ feat(billing): ... (FTR-1076 Task 3) ❌ fix(db): ... (BUG-439)
Why: callback gate parses ONLY the scope. Non-compliant subjects cause false demote and burn compute on re-dispatch (BUG-192 night incident 2026-05-24/25 — 5 specs blind-demoted).
PHASE 3 merge commits: Merge feature/SPEC_ID: … (or autopilot/, fix/) is accepted by gate.
Full rules: .claude/agents/coder.md § Commit Format.
Main Loop
Interactive Mode (no SPEC_ID)
while (queued/resumed tasks in ai/backlog.md):
1. Read backlog → find first queued/resumed (P0 first)
2. (Status written by callback only — do NOT edit spec/backlog Status field)
3. PHASE 0: Worktree Setup
See: worktree-setup.md
4. PHASE 1: Plan (ALWAYS runs)
ALWAYS dispatch Plan Subagent — even if spec has plan
Planner re-reads codebase, validates/regenerates plan
WHY: prior specs changed code → old plans have stale refs
After PHASE 1: plan MUST exist → else blocked
5. PHASE 2: Execute (see task-loop.md for SSOT)
FOR EACH TASK:
a. CODER → files_changed
b. TESTER → pass? (debug loop if fail)
c. PRE-CHECK → deterministic validation
d. SPEC REVIEWER → matches spec?
e. CODE QUALITY → architecture ok?
f. COMMIT (no push)
6. PHASE 3: Finishing
See: finishing.md
7. Continue to next spec
Loop Mode (SPEC_ID provided)
1. Validate SPEC_ID exists in backlog
2. Verify status is queued or resumed (not in_progress!)
3. (Status written by callback only — do NOT edit spec/backlog Status field)
4. PHASE 0-3: Same as interactive (including push in Phase 3!)
5. EXIT (do NOT continue to next spec)
└─ External orchestrator provides fresh context
Why loop mode? Prevents context accumulation. Each spec = fresh Claude session.
Pre-flight Check
Before taking a spec from backlog:
-
Status: Must be queued or resumed → skip otherwise
-
Already-implemented detection (BUG-188): Before invoking the Plan Agent,
check whether the spec's ## Allowed Files already have implementation commits.
Algorithm (LLM-driven, run in current session via Bash tool):
a. Read ## Allowed Files from the spec body. Extract every backticked
path under a <!-- callback-allowlist v1 --> marker (canonical) or any
backticked path inside the section (legacy fallback). Mirrors
callback._parse_allowed_files.
b. Get spec file creation time:
SPEC_CREATED=$(git log --reverse --format=%ai -- "ai/features/${SPEC_ID}"*.md | head -1)
c. Check whether any commit since SPEC_CREATED (on any branch) both:
- has
${SPEC_ID} in its subject line (first line) — canonical form,
e.g. feat(BUG-188): ... or BUG-188 ...
- AND touches at least one path in Allowed Files
git log --all --since="$SPEC_CREATED" --pretty="%h %s" -- $ALLOWED_FILES \
| grep -E "^[a-f0-9]+ (feat|fix|chore|docs|refactor|test)?\(?${SPEC_ID}\)?[: ]" \
| head -5
d. If 1+ qualifying commits found → early-exit immediately:
Why: This mirrors callback._spec_has_merged_implementation (TECH-176)
on the front side so autopilot does not burn 30+ turns re-doing work that
callback would auto-close anyway. Saves ~$5/run × every false-fail retry.
False-skip protection: the subject-line regex requires canonical
<type>(SPEC-ID): or SPEC-ID prefix. Bare mentions in commit body /
cross-references in Refs:/See also: lines do NOT count (TECH-177 lesson).
After PHASE 1 (planner always runs):
- Plan: Must have
## Implementation Plan
- If plan missing after PHASE 1 → set
blocked, skip spec
Skip if status check fails, with warning to user:
SKIP: {TASK_ID}
Status: {current_status} (expected: queued or resumed)
Fix the issue and re-run autopilot.
⛔ Skipping planner = VIOLATION. Planner runs before EVERY spec, no exceptions.
How to Read Feature Doc
## Problem/Solution ← context
## Scope ← what to do
## Allowed Files ← ONLY these can be modified!
## Implementation Plan ← YOUR TASKS!
### Task 1 ← execute in order
## Definition of Done ← check AFTER all tasks!
Statuses
Flow: draft → queued → in_progress → done
Recovery: in_progress → blocked → resumed → in_progress
Context Management
Interactive Mode (current session)
/autopilot (no SPEC_ID) runs directly in the current Claude Code session.
It uses native Agent/Skill tools for subagent dispatch — NO external bash
wrapper, NO claude --print subprocess. After each spec: /compact (optional,
user-triggered) and continue to the next queued spec.
⛔ Do NOT invoke ./scripts/autopilot-loop.sh from inside an interactive
session. That wrapper calls claude --print as a subprocess, which runs
in headless mode without --setting-sources — subagents don't resolve and
costs explode. The script is DEPRECATED; kept only for manual operator use
outside Claude Code.
Single-Spec Mode (VPS orchestrator)
Each spec = fresh Agent SDK session dispatched via pueue:
orchestrator.py → pueue add → run-agent.sh → claude-runner.py (SDK)
└─ /autopilot TECH-065 → fresh session, exits after done
└─ /autopilot TECH-066 → fresh session, exits after done
└─ ...
Memory persists via files:
ai/backlog.md — task status
ai/diary/autopilot-progress.md — learnings
- Git history — code changes
References
- Agent roles:
.claude/agents/*.md
- Creating skills:
/skill-creator create skill
- Smart Testing:
.claude/agents/tester.md
Notification Output Format
Your final JSON result_preview is sent to the user via Telegram. Keep it concise and actionable:
Что сделано: {1-2 sentence summary of actual changes}
Файлы: {N} изменено
Spec: {SPEC_ID} → done
BAD: "Все функциональные чекбоксы в Definition of Done отмечены как выполненные..."
GOOD: "Добавлены кнопки отменить/пауза для кампаний. Файлы: 3 изменено. FTR-0063 → done
The final JSON output MUST include task_status:
{
"task_status": "complete" | "blocked" | "needs_review",
"result_preview": "..."
}
Status field is written by callback only (TECH-172). Autopilot emits task_status in final JSON; never Edits **Status:** in spec or backlog."