Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Scenario runner

The runner (crates/scenario-runner) executes a Scenario through a ScenarioContext and produces a classified ScenarioOutcome. It is the only place a scenario’s operations touch the adapter services; packs, the harness, and the CLI all go through it.

Responsibilities

  • Lifecycle — validate → prepare → initialize → execute → observe → assert → invariants → classify → report → cleanup. The executor records a per-phase timing for each stage on the outcome (spec §67), so reports can decompose time instead of collapsing it.
  • Isolation — the harness that wires the runner builds a fresh simulator per run, so a failed scenario cannot contaminate the next.
  • Timeout & cancellation — a whole-run deadline derived from the configured clock, and a cancellation token the executor checks between operations.
  • Controlled retries — a RetryPolicy that only retries explicitly configured infrastructure-level failures. Deterministic failures never retry and never get hidden.
  • Cleanup — a Cleanup chain that runs after the outcome is fixed; cleanup problems are recorded as observations, never silently dropped.
  • HooksHookChain with before/after phase hooks for instrumentation.
  • Invariant evaluation — the executor runs the scenario’s declared invariants through an InvariantRegistry and records held/violated counts on the outcome.

Classification

The executor never returns “the scenario errored” for a failed expectation. It classifies the run: expected rejections in negative/adversarial packs are successful runs of a failing scenario, distinct from real failures (see scenario-core’s failure model).

Determinism

The runner is clock-driven. The mock harness injects a fixed clock, so every phase timing and outcome is byte-deterministic. Real deployments inject a wall clock; the structure is identical.