Skip to main content

crewship eval

Two distinct evaluation surfaces share the crewship eval namespace:
  1. Mission-level — replay a single mission deterministically or regression-diff two missions. Uses the Quartermaster engine. See Quartermaster guide.
  2. Routine-level — sweep the workspace’s eval-* routines × tier matrix, head-to-head tier compare, save/diff regression baselines. Built on top of the Routines runtime. See Routines guide and Routines cookbook.
Mission-level replay and regression enqueue work asynchronously and return a run_id (poll completion via crewship eval runs). The runs subcommand itself is a synchronous list query against existing eval runs; get fetches one run’s full record. Routine-level subcommands all run synchronously and emit results inline.

Subcommands


crewship eval replay <mission-id>

Replay a single mission deterministically. Enqueues asynchronously and returns a run_id — poll completion via eval runs.
Sample output:
Requires OWNER or ADMIN role (403 otherwise). Mission must belong to your workspace (404 otherwise, same shape as “not found” so existence isn’t leaked).

crewship eval regression <baseline-id> <candidate-id>

Regression-diff two missions. Enqueues asynchronously and returns a run_id.
No flags. Both mission IDs must belong to your workspace — a partial spoof (valid baseline + foreign candidate) still 404s. Sample output:

crewship eval runs

Sample output:
Status progresses queued -> running -> completed | failed. For regression runs, the result field (now included in --format json/yaml/ndjson, not just the table) contains either no_regression or regressed: <delta summary> like regressed: tool success -8% cost +22%. The table view stays scannable (six columns); use eval get <id> for one run’s full record.

crewship eval get <run-id>

Fetch a single run by id and print what it found — the piece eval runs’ table intentionally leaves out.
Aliased as crewship eval show <run-id>. Sample output (replay):
Sample output (regression):
--format json/yaml/ndjson return the full quartermaster.RunRecord — the same shape eval runs rows now include (see Eval API).
A run id that doesn’t exist, or belongs to another workspace, 404s with the same “eval run not found” message either way — existence isn’t leaked cross-tenant.

Routine-level eval

The routine-level commands target the eval suite seeded under the eval- slug prefix (see the Routines migration guide for the framework concept and cookbook recipe 6 for the eval-driven promotion workflow). Unlike the mission commands, these run synchronously and emit pass/fail and stats inline.

crewship eval scenarios

Batch-run the workspace’s eval-* routines across one or more tiers and report a pass-rate matrix. The canonical “weak vs strong agent same outcome?” harness — same DSL, same inputs, only the resolved tier differs across cells.
Output (table format): rows = scenarios, columns = tiers, cells = pass/total $avg-cost. A cell with 5/5 $0.0012 means every run passed the routine’s gate at that tier. Use the JSON or Markdown formats for downstream tooling. All eval subcommands (runs, scenarios, compare, baseline list|show|diff) also honour --format yaml and --format ndjson alongside json; the YAML form of eval scenarios carries the same generated metadata as the JSON form.

crewship eval compare <slug>

Run ONE eval scenario back-to-back on two tiers and report a head-to-head verdict. Use this when investigating a specific scenario rather than sweeping the whole suite.
Verdict (top of output):
--tier-a and --tier-b MUST differ — passing the same value on both errors out.
Output text identity is NOT asserted — two LLM runs are rarely identical at the byte level. The verdict is about gate-pass agreement, not text agreement.
Both sides now pin the same archived recipe version, resolved once before either run. --version N selects an explicit archive; otherwise the server’s is_head marker selects the published version, including after rollback. Missing archive evidence stops the comparison before any run. Publication between A and B does not change the selected version. This is live execution, with real effects and costs. JSON/YAML/NDJSON reports include execution_mode, pipeline_version, definition_hash, and agreement_basis: execution_status. Agreement is about execution status, not proof of semantic quality or identical model behavior. WAITING/RUNNING/QUEUED results are AMBIGUOUS; finish the underlying run before drawing conclusions.

crewship eval baseline

File-local snapshots of the eval matrix (~/.crewship/eval-baselines/<name>.json) plus regression diff. Per-developer / per-CI-run state — no server-side migration, no RBAC surface. Designed to be the CI gate that fails the build when a model swap or DSL refactor changes gate-pass behaviour.

baseline save <name>

Run the eval matrix once and persist it as a regression baseline.
Baselines record the source workspace ID at save time. diff refuses to compare across workspaces — reusing a baseline name in another workspace would silently report bogus regressions. Names are restricted to [A-Za-z0-9_-]{1,64} to prevent path-traversal in the on-disk file location.

baseline list

Columns: NAME, GENERATED, SCENARIOS, TIERS, RUNS/CELL.

baseline show <name>

Prints the full matrix from the stored baseline (cells = pass/total $avg-cost). Use -f json for the raw record.

baseline diff <name>

Re-run the matrix against the same scenario / tier / runs combo and diff each cell against the stored baseline. Exits non-zero on any regression beyond --tolerance.
Per-cell verdict: Cells that exist in NEITHER baseline nor current are skipped (they get no row).

baseline delete <name>

Permanently removes the on-disk baseline file. No confirmation prompt — the file is per-developer state.

Comparing from the routine editor

The Test view also offers a live comparison over published recipe versions. Load the archive list, select a version and worker tier for each side, and provide a JSON dataset of 1–20 {id, inputs, expected_output?} cases. Import and export preserve typed values. Draft edits are not used until published. Each accepted run uses the regular execution engine and appears in History. The comparison shows cost, duration, run links and an exact text check when expected_output is supplied; otherwise it explicitly leaves quality ungraded. Results export includes the pinned versions/hashes and input snapshots. If a run waits for a human, resolve it in the run detail or Inbox, then Continue. Continue reads the accepted run instead of starting it again. After an unclear start response it retains the same request key within the server’s idempotency window. Leaving the Test view stops future client-side starts, while accepted runs continue independently. The comparison queue itself is not a durable job.