Running a Sprint

/gaia-run-sprint executes the committed sprint phase by phase. Stories that share a dependency phase carry no ordering constraint between them, so they can run at the same time; a story in a later phase never starts until every story of the current phase has finished.

Each slot runs one story through the ordinary story workflow, in its own worktree. Nothing about how a single story is developed changes — this command only decides what runs when.

How it runs

The scheduler admits and tracks stories, but only a live turn can actually drive a story's dev agent — no background process can send it a message on its own. So the command works as a loop: it plans once, then repeatedly asks the scheduler which stories are ready, spawns a dev agent for each one, and reports back what happened once that agent finishes.

  1. Plan runs every degradation check up front and prints mode=parallel or a mode=sequential reason=<token> line (see the table below).
  2. Admit asks the scheduler which stories are ready to start. Each one gets a real worktree and a real dev-agent slot; a barrier line means the current phase is full or still finishing, and a complete line means the sprint is done.
  3. Dispatch spawns the story's stack developer against its own worktree, in the background.
  4. Report tells the scheduler what happened once a dispatched agent finishes — done, failed, timed out, or merged (in which case the scheduler independently confirms the review gate closed before it counts the story as finished).

Steps 2-4 repeat until every story in every phase has reported a final outcome.

Turning concurrency on

Concurrency is opt-in on three independent switches. All three must be set; if any one is missing the sprint runs one story at a time.

SwitchMeaning
GAIA_PARALLEL_EXECUTION=1you are asking for concurrency
GAIA_WORKTREE_MODE=1per-story worktree isolation is available
parallel_execution.max_parallel_dev_slots > 1the budget allows it

Worktree isolation is a precondition rather than an option: several developers editing one checkout simultaneously is exactly the cross-contamination the isolation prevents. The command will not switch the mode on for you — it explains that it is off and runs sequentially.

Two further keys live in the same configuration section: teammate_dispatch_ceiling, the total number of concurrent agents of every class, which must leave headroom above the slot budget for gate agents; and story_timeout_minutes, the per-story wall-clock budget, 90 by default.

When it runs sequentially

Running sequentially is a normal outcome, never a failure, and it is always explained. One of these reasons is printed and the sprint proceeds:

ReasonWhat happened
parallel-opt-in-offconcurrency was not requested
flock-unavailablethe locking primitive is missing, or forced off
worktree-mode-offper-story isolation is not switched on
slots-1the budget allows no concurrency
sprint-unreadablethe sprint file is missing, malformed or unparseable
no-phase-fieldsthe sprint parses but carries no phase assignments
ceiling-cannot-admitthe agent ceiling is saturated with no headroom
admission-lock-timeoutthe admission lock could not be acquired, so no story was admitted without it
mode-b-fallbackthe persistent-agent substrate is unavailable
admission-erroran unclassified admission failure

A sprint planned before execution phases existed reports no-phase-fields. Re-plan it, or assign phases to its rows, and concurrency becomes available.

On a machine without the locking primitive, note one deliberate difference: the sprint-state writer refuses when concurrency is requested without it, because a single state write has nothing to fall back to. This command instead reports the reason and keeps going, because it does have somewhere to fall back to — a sprint that does not run is a worse outcome than one that runs slowly.

What happens when things go wrong