Stelladocs

Agent Fleets

Fan a dependency-ordered task DAG out to parallel worker agents in one shared tree, coordinated by cooperative file claims — with per-task worktree isolation as the opt-in, a SQLite ledger of every attempt and dollar, and an optional CI watch.

stella fleet runs many tasks at once — each task handled by a full Stella worker. By default the workers share one tree: every worker runs in the repository root, coordinated by cooperative file claims, so conflicts surface at write time with the rival named, commits interleave on one branch, and the build cache stays warm. A task marked isolation = "isolated" instead gets its own git worktree on its own branch, isolated from your working copy and from every other worker.

stella fleet \
  "Add unit tests for the parser module" \
  "Document every public function in src/api/" \
  "Fix the clippy warnings in the store crate"
Fleet fan-out over git worktreesbasepinned SHAfleet/t1 — its own worktreefleet/t2 — its own worktreefleet/t3 — its own worktreereviewmerge on your terms

How a fleet run works

  1. Plan. Task prompts (inline, or from a --plan file) form a DAG: tasks with depends_on wait for their dependencies. Plans are validated up front — a duplicate id, a self-dependency, an unknown dependency, or a dependency cycle is rejected before anything runs, with the offending task (or cycle path) named.
  2. Share — or isolate. By default every worker runs directly in the repository root under the cooperative claim discipline (see file claims below). A task marked isolation = "isolated" instead gets a fresh git worktree under .stella/worktrees/<slug>, branched from a pinned base commit (the current HEAD, or --base-ref, resolved to a SHA at start so mid-run commits can't drift the base) onto a fleet/<slug>-<hash> branch. The 16-hex-digit hash suffix keeps re-runs — which reuse task ids like t1 — from colliding with branches and worktrees you kept from an earlier fleet. Isolated workers can't see each other's uncommitted work and can't touch your checkout.
  3. Dispatch in waves. Dependency-ordered waves run up to --max-concurrency tasks at once (default 4). A failed task does not unblock its dependents — they end the run as skipped — and nothing is retried automatically: the ledger records every attempt, but re-running is your call.
  4. Work. Each worker is a full engine run — the staged pipeline with the standard toolbelt, honoring your agent-engine config. Workers are headless by design: no MCP, no interactive prompts, nothing that can block on stdin. Pass --no-pipeline to run the raw step loop instead of the staged pipeline.
  5. Record. Every attempt, commit, and dollar lands in the fleet ledger at .stella/fleet.db — local SQLite, like all Stella telemetry. Past runs (tasks, attempts, successes, commits) also surface on the Fleet runs card of the Observatory dashboard.
  6. Review. Shared-tree work lands directly on your current branch as interleaved commits. Isolated tasks' worktrees and fleet/* branches are deliberately left in place — those branches are the work product. Inspect, test, and merge them on your terms; git worktree list shows them all.

Plan files

For anything beyond a handful of independent prompts, declare a plan (.toml or .json):

release-prep.toml
[[tasks]]
id = "t1"
title = "Bump the version and changelog"
prompt = "Bump the workspace version to 1.4.0 and update CHANGELOG.md"
claims = ["Cargo.toml", "CHANGELOG.md"]

[[tasks]]
id = "t2"
title = "Update the release notes page"
prompt = "Update the release notes for 1.4.0 from the merged PRs"
depends_on = ["t1"]

Each task carries an id, title, and prompt, plus optionally:

  • depends_on — ids that must succeed before this task dispatches (orders the waves).
  • isolationshared_tree (the default: run directly in the repo root under the cooperative claim discipline) or isolated (own worktree, own branch — the explicit opt-in for genuinely divergent work: best-of-N attempts producing competing versions of the same files, or tasks that mutate checkout state. Claims can't help there — the conflict is the point — and the costs are real: a cold build cache per tree, and conflicts deferred to integration time).
  • claims — workspace-relative paths held as cooperative file locks.

File claims — cooperative locks

A task that declares claims (workspace-relative paths it intends to touch) holds them as cooperative file locks for the attempt's duration. A second task — or a second fleet run — that claims an already-held path fails that dispatch by name instead of silently racing another agent into the same file. The locks live in the file_locks table of .stella/store.db, separate from the fleet ledger, so they coordinate across concurrent fleet runs too.

Budget across a fleet

Budget comes from the global --budget flag (or STELLA_BUDGET), which goes before the subcommand:

stella --budget 5 fleet --plan release-prep.toml
# equivalently: STELLA_BUDGET=5 stella fleet --plan release-prep.toml

It is enforced twice: each child runs under its own guard — the aggregate cap divided across the concurrency width (budget ÷ max-concurrency), so one wave's in-flight children can't collectively overshoot — and the fleet stops launching new waves once total metered spend crosses the cap. In-flight siblings settle cleanly — never a mid-tool kill.

Watching CI: --watch

After the fan-out, --watch holds a fleet monitor on every branch that carries successful work: it watches each branch's CI to completion via the gh CLI, reconciles PR status live, and exits non-zero if any watched branch ends red. It polls every 30 seconds, allows CI 10 minutes of startup grace to appear, gives up on a branch after 20 minutes without progress, and caps the whole watch at 2 hours of wall time.

stella fleet --plan release-prep.toml --max-concurrency 2 --watch

--watch only has something to watch once branches are pushed — for example when your task prompts push and open PRs. It requires an installed, authenticated gh.

Flags

FlagMeaning
<task>...One or more task prompts. Required unless --plan is given.
--plan <FILE>A .json/.toml plan with [[tasks]] entries.
--max-concurrency <N>Max tasks running at once per wave. Default 4.
--base-ref <ref>Git ref the worktrees branch from. Default: current HEAD, pinned to a SHA at start so mid-run commits can't drift the base.
--watchWatch each successful branch's CI to completion after the fan-out.
--no-pipelineWorkers run the raw step loop instead of the staged pipeline.

Cleaning up

When you've merged (or rejected) the branches your isolated tasks left — the branch names carry a hash suffix, so list them rather than guessing:

git worktree list                 # what the fleet left in .stella/worktrees/
git worktree remove <path>        # per worktree
git branch --list 'fleet/*'      # the fleet branches
git branch -D fleet/<slug>-<hash> # per branch, exactly as listed

Stella is totally free and open source, dual-licensed MIT or Apache 2.0— your choice: MIT's three-paragraph simplicity, or Apache 2.0's explicit patent grant that enterprises prefer. Use it, fork it, embed it, ship it — no account, no phone-home, no strings. What that means →

On this page