Skip to content
nikcli
Docs
Documentation

Missions

High-altitude workflows: decompose a goal into milestones, each holding a DAG of features, with a validation checkpoint per milestone. Source: packages/nikcli/src/mission/.

Overview

A Mission is a higher-altitude workflow than a Loop: instead of a flat list of stages, it decomposes work into milestones, each holding a directed acyclic graph of features, with a validation checkpoint at the end of every milestone. The orchestrator drives one feature at a time through the same goal worker the Loop engine uses, then runs a validation worker before advancing to the next milestone.

Like Loops, missions are persisted in SQLite and run on the headless server. They keep working while the TUI is closed, survive process restarts (via lease/heartbeat), and emit bus events for the TUI to subscribe to.

Composition

Reuses primitives

The orchestrator does not reimplement iteration, budgets, persistence, or autonomy — it reuses the existing goal worker, Session runtime, and Scheduler.

Isolation

Per-project scoping

Missions are scoped by the active project so definitions from different projects cannot collide. Definitions and execution records are persisted through MissionRepo.

Persistence

Crash-safe

Feature and milestone status is persisted on the definition after every step. A restart resumes exactly where it left off. Orphaned runs are reconciled on the next boot through a lease/heartbeat (MISSION_EXEC_LEASE_MS = 15s).

Back-pressure

Concurrency cap

A synchronous single-flight claim per mission prevents overlapping runs of the same mission. A global cap of MAX_CONCURRENT_MISSIONS = 2 keeps the host from spawning unbounded workers.

Concepts

TermDefinition
MissionThe top-level unit: a name, a brief, an ordered list of milestones, and a record of execution state.
MilestoneAn ordered checkpoint that groups one or more features and applies a validation policy when they are all settled.
FeatureA leaf unit of work: name, objective, agent, optional model, optional token budget, optional dependsOn list of sibling features in the same milestone.
ValidationThe policy that runs after every milestone's features are settled — scrutiny, user-test, or none.
WorkerThe goal command driving a single feature. The validation policy drives a separate validation worker per milestone.
Exec / leaseA MissionExec record carries a lease/heartbeat so a crashed orchestrator can be reconciled by the next boot.

Mission schema

All persisted types are defined in packages/nikcli/src/mission/schema.ts as zod schemas. The shape is deliberately close to the Loop schema so the two engines can share tooling.

Feature

FieldTypeNotes
idstringUnique within the milestone.
namestringDisplay label.
objectivestringThe prompt fed to the goal worker.
agentstringAgent name (e.g. build, plan).
model"provider/model"Optional. Defaults to the session default.
tokenBudgetnumberOptional per-feature cap.
dependsOnstring[]Sibling feature IDs in the same milestone that must reach done first.
statusFeatureStatuspending | running | done | blocked | skipped | error.
errorstringLast surfaced error, if any.

Milestone

FieldTypeNotes
idstringUnique within the mission.
namestringDisplay label.
featuresFeature[]One or more features per milestone.
validation"scrutiny" | "user-test" | "none"Policy applied when features settle.
statusMilestoneStatuspending | running | validating | done | blocked.

Mission

FieldTypeNotes
idstringStable identifier.
namestringDisplay label.
briefstringHigh-level description of the mission's intent.
milestonesMilestone[]Ordered list of milestones.
modelsMissionModelsPer-role model overrides (worker, validation, orchestrator).
statusMissionStatuspending | running | paused | complete | error | cancelled.
createdAtnumberEpoch ms.

Lifecycle

A mission moves through these states as the orchestrator walks it. The full MissionStatus schema in packages/nikcli/src/mission/schema.ts also carries planning and ready for the brief-to-milestones phase; the states below are the ones you see in the TUI and in bus events.

  1. running — the orchestrator is actively driving features and validation.
  2. paused — held by user request. No new features start; in-flight work is not aborted.
  3. frozen — held automatically when a feature or validation worker has been aborted by a timeout or external error. Use mission resume to continue.
  4. complete — every milestone reached done and the final validation (if any) passed.
  5. error — a feature or the validation worker surfaced an unrecoverable error.

Per-feature timeouts

A hung feature can never hold the single-flight slot forever. Each feature run is capped (DEFAULT_FEATURE_TIMEOUT_MS = 60min), bridged to prompt.cancel on expiry. Bounds:

ConstantValuePurpose
MIN_FEATURE_TIMEOUT_MS1_000Smallest accepted override.
DEFAULT_FEATURE_TIMEOUT_MS60 * 60_000Default cap when the feature omits one.
MAX_FEATURE_TIMEOUT_MS24 * 60 * 60_000Largest accepted override.
MISSION_EXEC_LEASE_MS15_000Lease/heartbeat for orphan detection.
MAX_CONCURRENT_MISSIONS2Global cap on simultaneously orchestrating missions.
HISTORY_LIMIT100How many historical exec records to retain per mission.

Validation policy

When every feature in a milestone has settled, the orchestrator runs a validation worker according to the milestone's validation policy. The validation worker is itself a goal command targeting the mission's validation model (or the worker model if unset).

PolicyBehavior
scrutinyDefault. The validation worker reviews the milestone's outputs and either confirms done or marks the milestone blocked.
user-testThe milestone is marked validating and held until a human (via TUI/CLI) approves or rejects it.
noneSkip the validation worker. The milestone moves directly to done when all its features are done.
What the validation worker can do

The validation worker has the same tool surface as any other session. It is given the milestone's name, the brief, and a list of feature outcomes. A user-test milestone pauses until you reply from the TUI mission dialog.

CLI subcommands

nikcli mission is a thin headless wrapper over the orchestrator. It accepts a brief from a file or flag, generates a draft plan, and lets you start, pause, resume, or cancel execution.

SubcommandPurpose
nikcli missionOpen the headless mission manager: list, status, quick actions.
nikcli mission new [-f file] [--model …] [--agent …]Create a mission from a brief. With -f, the brief is read from a Markdown or text file; otherwise it is read from --brief or stdin.
nikcli mission start <id>Begin orchestrating the mission. The mission moves from pending to running.
nikcli mission pause <id>Pause a running mission. In-flight features finish; no new features start.
nikcli mission resume <id>Resume a paused mission.
nikcli mission cancel <id>Cancel a mission. In-flight workers are aborted via prompt.cancel.
nikcli mission get <id>Show progress, current milestone, current feature, statuses, and last error.
nikcli mission listList all missions in the current project with their runtime status.
Terminal
bash
# Draft a mission from a brief file and start it
nikcli mission new -f ./brief.md --agent build --model anthropic/claude-sonnet-4.5
nikcli mission start mss_abc123

# Watch progress
nikcli mission get mss_abc123

# Pause and resume
nikcli mission pause mss_abc123
nikcli mission resume mss_abc123

# Cancel
nikcli mission cancel mss_abc123
Reserved objectives

The strings pause, resume, clear, and status are reserved feature objectives. Pick distinctive objectives for your features so the orchestrator never confuses them with a control command.

Bus events

The orchestrator publishes typed bus events for the TUI, mobile, and SDK clients to subscribe to. They live next to the orchestrator in packages/nikcli/src/mission/orchestrator.ts.

EventPayloadUse
mission.upserted{ missionID }Definition created or replaced.
mission.removed{ missionID }Definition deleted.
mission.started{ missionID }Orchestration started.
mission.finished{ missionID, status, error? }Orchestration ended (complete | error | paused | frozen; the pending state never fires this event).
mission.exec.started{ missionID, execID, kind, targetID, targetName, sessionID }A feature or validation worker started. kind is feature or validation.
mission.exec.finished{ missionID, execID, kind, status, sessionID?, error? }Worker ended.
mission.feature.updated{ missionID, milestoneID, featureID, status, error? }Single feature state changed.
mission.milestone.updated{ missionID, milestoneID, status }Milestone moved into validating, done, or blocked.

TUI surface

The TUI mission feature-plugin lives in packages/tui/src/feature-plugins/mission/. It mirrors the loop plugin and exposes:

  • Mission home view — list of all missions with status chips, last run time, and quick actions (start, pause, resume, cancel).
  • Mission detail view — per-milestone tree, per-feature rows, current feature highlight, validation status, and the live session id of the active worker.
  • Draft dialog — paste a brief, pick an agent and a model, and create a mission without leaving the TUI.
  • Validation review dialog — approve or reject user-test milestones. Approval advances the mission; rejection marks the milestone blocked.

The plugin subscribes to the bus events above and batches updates into Solid signals. The same source of truth is consumed by the mobile app and the web app.

Failure modes

SymptomLikely causeFix
Mission stuck in running after a crashThe orchestrator process died; the lease has expired.Restart the host. restore() reconciles orphaned runs to error and you can resume the mission from the failed feature.
Feature stays in running foreverThe feature worker exceeded the per-feature timeout.The orchestrator aborts the worker via prompt.cancel and marks the feature error. Inspect the worker session and resume the mission.
Milestone stays in validatingThe user-test policy is waiting for human approval.Open the mission detail view in the TUI and approve or reject the milestone.
Single-flight slot held by a previous runAn earlier process crashed without releasing the slot.The lease/heartbeat reaper releases the slot after MISSION_EXEC_LEASE_MS. If it persists, restart the host.
Model validation rejected at create timeThe model field on a feature or the models field on the mission does not match "provider/model".Use the canonical provider/model form, or omit the field to fall back to the session default.

Source anchors

FileWhat to inspect
packages/nikcli/src/mission/schema.tsZod schemas and pure helpers for Mission, Milestone, Feature, MissionModels, ValidationPolicy.
packages/nikcli/src/mission/manager.tsCRUD and execution-record persistence.
packages/nikcli/src/mission/orchestrator.tsHeadless engine, lease/heartbeat, single-flight, bus events.
packages/nikcli/src/cli/cmd/mission.tsCLI surface (nikcli mission …).
packages/tui/src/feature-plugins/mission/TUI feature plugin: store, SDK, runner, dialogs.
packages/nikcli/src/loop/engine.tsThe Loop engine whose operational guarantees the orchestrator reuses verbatim.