Loops & Autopilots
agents-fleet can run continuously — driving a fleet toward a goal or a definition-of-done without you typing a new prompt each cycle. There are two layers:
- Loops (
/loop,/loop-target) — a generic scheduler that re-prompts the coordinator on an interval until you stop it or the goal is met. - Autopilots (
/fixer-loop,/github-issue-worker-autopilot,/code-review-autopilot,/bug-autopilot) — purpose-built multi-stage workflows that wrap a specific job (fix the build, ship an issue, review a diff, fix a bug) in a self-driving loop.
This guide covers both, when to reach for each, the sub-coordinator bridge that runs autopilots deterministically, and the killswitches.
Loops
Task-driven loop — /loop-target
A task-driven loop keeps executing until the current task DAG reaches its definition-of-done. It does not need a natural-language goal — it drains ready tasks each cycle.
❯ /loop-target 5mThe argument is the interval between cycles (5m, 30s, 1h). On each tick the coordinator picks up ready tasks, spawns workers, and reconciles progress.
Goal-driven loop — /loop
A goal-driven loop re-prompts the coordinator with a freeform goal each cycle and keeps going until the goal is satisfied:
❯ /loop "polish docs until every public type is annotated" 10mThe form is /loop "<goal>" <interval>. There is also a goal-driven variant of /loop-target that takes a trailing goal string:
❯ /loop-target 10m "finish the auth module"Required flag under Claude — --unattended
Goal-driven loops are refused under --provider claude unless you pass --unattended:
❯ /loop-target 10m "finish auth module"
✖ Goal-driven loops require --unattended under --provider claude.
❯ /loop-target 10m "finish auth module" --unattendedWhy: under Claude, full-trust agent types (coder, general-purpose, custom) can bypass permission prompts, so an unattended goal loop could take destructive actions with no human in the loop. The guard forces you to opt in explicitly. Non-Claude providers and task-driven loops are not gated.
Stopping loops
❯ /loops # list active loops
❯ /loops stop <id> # stop one loop
❯ /loops stop-all # stop every loopLoops are not persisted across --resume
The session schema persists tasks but not active loops/goals. After --resume you'll see a one-line dim warning; restart the loop manually with /loop "<goal>" <interval> or /loop-target <interval>.
When to use loops — and when not to
Use loops for multi-hour or overnight work toward a clear goal, batch processing, or watch-and-react patterns. Don't use them for anything that needs your input mid-cycle (the loop won't pause), exploratory work where the next step depends on your review, or sessions you intend to resume later.
Autopilots
Autopilots are bundled workflows invoked as slash commands. Each one wraps a review → fix → validate style loop tuned for a specific job. They differ from a raw /loop in that the stage list, convergence criteria, and artifacts are predefined.
| Command | What it does | When to use |
|---|---|---|
/fixer-loop | Reviews, triages, fixes, and verifies — iterating until the build/tests converge or the iteration budget is exhausted. | The build or test suite is red and you want it driven back to green hands-off. |
/github-issue-worker-autopilot | Triages open GitHub issues, fixes them, validates with tests, generates proof artifacts, and ships each as a draft PR. | You have a backlog of well-specified issues and want them worked autonomously. |
/code-review-autopilot (aliases /cr-auto, /review-loop) | Iterative review → triage → fix → validate over a diff (or the whole codebase with --scope=full); optional PR handoff via --ship. | Continuous self-review of changes before they go up for human review. |
/bug-autopilot (alias /bugfix-autopilot) | End-to-end: reproduce → fix → regression-test → code-review loop → open PR → wait for human approval → iterate on feedback → merge. | You have a concrete bug or repro and want it taken from report to merged fix. |
Usage at a glance
❯ /fixer-loop [--max-iterations <N>] [--legacy-workflow-dispatch]
❯ /github-issue-worker-autopilot [--max-stage-visits <N>] [--legacy-workflow-dispatch]
❯ /code-review-autopilot [target] [--scope=diff|full] [--ship] [--legacy-workflow-dispatch]
❯ /bug-autopilot "<bug description or repro>" [--scope diff|full] [--legacy-workflow-dispatch]--ship + --scope=full is rejected
/code-review-autopilot --scope=full audits the entire codebase and is not allowed with --ship — a full-codebase audit must be reviewed by a human before anything is shipped. The guard fires at argument-parse time.
The sub-coordinator bridge
All four autopilots are members of SUBCOORD_DISPATCH_COMMANDS, which means they run through the workflow-runner sub-coordinator bridge. Instead of an LLM session emulating the workflow, the command executes deterministically in-process via runWorkflowAsSubCoordinator():
- A dedicated sub-coordinator owns the workflow's stages.
- Stage-worker reports route to that sub-coordinator (not the main coordinator) — visible via
/statusand the worker view switcher. - Each autopilot carries a per-workflow watchdog window. The dispatcher widens the auto-abort/hang thresholds to cover the workflow's
phaseTimeoutMs(e.g. code-review and issue-worker run with a 30-minute phase budget, bug-autopilot 60 minutes) so long legitimate phases don't trip a false-positive auto-abort.
This bridge is the default. It improves determinism and observability over the legacy LLM-driven path.
Progress, stalls, and escalation
Multi-stage autopilots can reach zero-active-worker boundaries between stages. Two safety nets cover the "silent freeze" gap:
- Wake-on-completion — when the coordinator is idle with no active workers but outstanding work remains, one debounced wake prompt is enqueued to nudge the next stage. A no-progress cap latches a
stuckstate after repeated identical wakes, and re-arms once forward progress resumes. - Escalation — a genuine stuck episode fans out one channel notification plus an in-app chip so a human can step in.
Killswitches & rollback
| Control | Effect |
|---|---|
--legacy-workflow-dispatch | Per-call: run this one invocation via the legacy LLM-driven path instead of the bridge. |
AGENTS_FLEET_WORKFLOW_SUBCOORD_BRIDGE=0 | Global: disable the bridge; all SUBCOORD_DISPATCH_COMMANDS fall back to the legacy path. |
AGENTS_FLEET_WAKE_ON_COMPLETION=0 | Disable the wake-on-completion nudge. |
AGENTS_FLEET_AUTOPILOT_ESCALATION=0 | Disable the stuck-episode notify + chip. |
Choosing between a loop and an autopilot
| You want to… | Reach for |
|---|---|
| Drain the current task DAG to its definition-of-done | /loop-target <interval> |
| Make continuous progress toward a freeform goal | /loop "<goal>" <interval> (+ --unattended under Claude) |
| Get a red build/tests back to green | /fixer-loop |
| Work a backlog of GitHub issues into draft PRs | /github-issue-worker-autopilot |
| Self-review changes before human review | /code-review-autopilot |
| Take a single bug from repro to merged fix | /bug-autopilot |
See also
- Orchestration Tutorial — Part 7 walks loops in context.
- Building Workflows — author your own loop-style workflows.
- Commands Manual — full slash-command surface.