Lab Notes
Research

Mission Lifecycle

How a research mission is created, executed, paused, resumed, and completed — the lifecycle around the phases.

Purpose

This page is the canonical reference for mission lifecycle. The framework is in Framework; the phase graph is in Mission DAG; the artifacts written at each stage are in Artifacts.

A mission goes through the following high-level stages:

Loading diagram…
Mission lifecycle states and transitions.

Stage 1 — Created

A mission is created when:

  • The Coordinator forwards a research request to the Research Worker.
  • The user invokes the CLI directly with research_cli.py run.
  • An automated process triggers a mission (scheduled job, test, audit).

f0_init runs and:

  1. Creates <runs_dir>/<mission_id>/.
  2. Parses the raw query into a ParsedQuery.
  3. Writes task.json (typed: Task).
  4. Writes the initial phase.json with F0 marked as succeeded and the next phase as pending.

The mission is now Created and the orchestrator can pick it up.

Stage 2 — Running

The orchestrator's run_mission enters a loop:

  1. Load the current RunState from phase.json.
  2. Resolve the next phase(s) to run.
  3. For each phase:
    • Mark it as running in the state.
    • Execute the phase handler.
    • Capture the PhaseResult.
    • Update the state to reflect the result.
  4. Repeat until all phases are in a terminal state.

The StateStore writes the state after every transition. This is the checkpointing layer (see below).

Stage 3 — Checkpointed

After every phase transition, the orchestrator writes the new RunState to <run_dir>/phase.json. The state contains:

  • The mission_id and the overall status (running, paused, completed, failed).
  • The current_phase (the phase that was just executed or is about to run).
  • A list of per-phase records: name, status, started_at, ended_at, attempts, output_artifacts, error.

Checkpointing is synchronous and write-through. The StateStore uses a per-path RLock to allow safe concurrent writes from parallel phases.

Why checkpoint

Three reasons:

  1. Resumability. A mission can be paused and resumed at any phase boundary. A crashed mission can be restarted from the last checkpoint.
  2. Auditability. The state file is a complete record of what happened. The Coordinator can show it to the user on demand.
  3. Observability. The state file is the framework's primary telemetry. Tools can read it to build dashboards.

Checkpoint format

phase.json is a single JSON document. Excerpt:

{
  "mission_id": "hotel-barcelona-2026-09",
  "status": "running",
  "current_phase": "F2",
  "phases": {
    "F0": {
      "status": "succeeded",
      "started_at": "2026-06-10T20:15:00Z",
      "ended_at": "2026-06-10T20:15:01Z",
      "attempts": 1,
      "output_artifacts": ["task.json"]
    },
    "F1": {
      "status": "succeeded",
      "started_at": "2026-06-10T20:15:01Z",
      "ended_at": "2026-06-10T20:15:34Z",
      "attempts": 1,
      "output_artifacts": ["candidates.json"]
    },
    "F2": {
      "status": "running",
      "started_at": "2026-06-10T20:15:34Z",
      "attempts": 1
    }
  }
}

Stage 4 — Paused

A mission can be paused at any phase boundary by the user. The Coordinator sends a "pause" signal; the orchestrator finishes the current phase, updates the state to paused, and stops.

A paused mission can be:

  • Resumed. The orchestrator continues from the last checkpoint.
  • Cancelled. The run directory is moved to a cancelled/ subdirectory under runs_dir/.

Pausing is a soft stop: the orchestrator does not abort in-flight HTTP requests. The current phase completes before the pause is acknowledged.

Stage 5 — Partial

A mission is partial when one or more phases ended in succeeded_partial. The orchestrator continues, but the final report is flagged.

Partial missions are not failures. They are a normal outcome when:

  • An adapter is rate-limited and returns fewer results than requested.
  • A review or price source is unavailable.
  • The YouTube phase finds no relevant content.

The report includes a "Limitations" section that lists the phases that were partial and the artifacts that are missing or incomplete.

Stage 6 — Failed

A mission is failed when a phase is failed_terminal and the orchestrator cannot continue. The state is updated, the run directory is moved to runs_dir/failed/, and the Coordinator is notified.

Failures are different from partials in two ways:

  1. The orchestrator cannot produce a report that meets the minimum contract.
  2. The user is expected to take action: retry, change the query, or accept the failure.

A failed mission is not deleted. It is preserved for post-mortem. The Coordinator can be asked to show the state file, the error message, and the partial artifacts.

Stage 7 — Completed

A mission is completed when F6 has written report.md and the state has been updated to succeeded. The Coordinator is notified with a summary of the report and a link to the file.

Completed missions are kept in runs_dir/. The retention policy is configurable (SCOUTE_RETENTION_DAYS, default 30). After retention expires, the mission is moved to runs_dir/archive/.

Resuming a Mission

To resume a mission, the user calls:

python -m scout.tools.research_cli resume \
  --mission-id hotel-barcelona-2026-09 \
  --runs-dir /tmp/scoute/runs

The orchestrator:

  1. Loads the state from phase.json.
  2. Validates the state (the mission must be paused or failed).
  3. Identifies the next phase(s) to run.
  4. Continues from there.

Resuming is the same code path as a fresh start — the orchestrator just reads the state and picks up where it left off.

Cancellation

A mission can be cancelled at any phase. Cancellation is hard: the orchestrator aborts the current phase, writes a cancelled state, and moves the run directory to runs_dir/cancelled/.

Cancellation does not undo work that was already checkpointed. If the user wants to undo a mission, they must cancel and then start a new one.

Retention and Archival

StatusDefault locationRetention
runningruns_dir/<mission_id>/Indefinite
pausedruns_dir/<mission_id>/30 days
completedruns_dir/<mission_id>/30 days
partialruns_dir/<mission_id>/30 days
failedruns_dir/failed/<mission_id>/90 days
cancelledruns_dir/cancelled/<mission_id>/7 days
archiveruns_dir/archive/<mission_id>/Indefinite

The retention is enforced by a daily cleanup task. The Coordinator can be asked to run the cleanup on demand.

See Also

On this page