Skip to main content
Version: latest

waves

Waves are the parallel execution unit in kasmos. A multi-wave plan runs wave 1 to completion, then wave 2, and so on. All tasks within a single wave run concurrently as separate agent instances on isolated git worktrees.

wave execution flow

the following diagram shows the high-level wave execution lifecycle — from plan content through architect elaboration, parallel coder waves, and into the review/verify pipeline:

wave orchestration states

The orchestration.WaveOrchestrator in orchestration/engine.go tracks five states:

statevaluemeaning
WaveStateIdle0not started; waiting for the first StartNextWave() call
WaveStateElaborating1architect agent is enriching task bodies before execution begins
WaveStateRunning2current wave's tasks are running
WaveStateWaveComplete3all tasks in the current wave resolved; awaiting user confirmation to advance
WaveStateAllComplete4all waves finished
Idle
├─ SetElaborating() ──► Elaborating
│ └─ UpdatePlan() ──► Idle
└─ StartNextWave() ──► Running
├─ tasks complete ──► WaveComplete (if more waves remain)
│ └─ user confirms ──► Running (next wave)
└─ all tasks complete ──► AllComplete

elaboration phase

Before wave 1 begins, kasmos optionally runs an architect agent to decompose the plan into coder-ready task bodies. While elaboration is in progress, the orchestrator moves to WaveStateElaborating. StartNextWave() returns nil in this state — no tasks are launched until UpdatePlan() is called with the enriched plan.

When elaboration completes, UpdatePlan() replaces the plan and resets the orchestrator to WaveStateIdle so waves can begin.

wave confirmation

When a wave completes, kasmos shows a confirmation dialog before advancing to the next wave. This gives you a chance to review what was done and abort if something went wrong. NeedsConfirm() returns true once per completion — calling it marks the dialog as shown. If you cancel, ResetConfirm() re-arms the latch so the dialog reappears.

blueprint skip (single-agent mode)

For small tasks, wave orchestration adds unnecessary overhead. ShouldBlueprintSkip in orchestration/engine.go returns true when the total number of tasks across all waves is at or below the configured threshold:

func ShouldBlueprintSkip(plan *taskparser.Plan, threshold int) bool {
if plan == nil || threshold <= 0 {
return false
}
total := 0
for _, wave := range plan.Waves {
total += len(wave.Tasks)
}
return total <= threshold
}

Configure this in .kasmos/config.toml:

[orchestration]
blueprint_skip_threshold = 2

When blueprint skip is active, the task goes directly to a single coder agent — no elaboration, no wave confirmation dialogs.

task statuses within a wave

Each task in a wave tracks its own state:

statemeaning
taskPendingallocated but not yet started
taskRunningagent is executing
taskCompleteagent finished successfully
taskFailedagent exited with an error

Failed tasks do not block the wave from completing — other tasks continue. Once all tasks in a wave have resolved (either complete or failed), the wave transitions to WaveStateWaveComplete. You can retry failed tasks with RetryFailedTasks().

subtask persistence

Task states within a wave are persisted to the task store via store.UpdateSubtaskStatus, so the TUI can display accurate per-task status even after a restart. The orchestrator is restored via RestoreToWave(), which fast-forwards to the target wave and re-applies saved task states.

file conflict detection

The architect agent produces metadata that lists which files each task intends to modify. DetectFileConflicts() checks for files claimed by multiple tasks in the same wave and surfaces them as warnings in the TUI, helping you spot potential merge conflicts before they happen.