Durable runs and resume
A run is designed to survive a killed process. evalctl writes durable metadata before and during execution so an interrupted run can be reconstructed and finished without redoing completed work.
What gets written
run.json— written once, before any case executes. It snapshots the suite and the run parameters.cases/<case_id>/state.json— a terminal marker written only after the case’s report artifacts are complete.manifest.json— finalized from that durable state.
Because a case is only marked terminal once its artifacts are whole, a resume can trust the marker: a case is either fully done or not counted.
Resume
evalctl run --resume <run-id> --acknowledge-unsandboxed-runner --json
Resume re-executes local runner code, so it needs the invoker’s acknowledgment
(--acknowledge-unsandboxed-runner or EVALCTL_ACKNOWLEDGE_UNSANDBOXED_RUNNER=1)
just like a fresh run, or it refuses with exit 2.
Resume reuses the original suite snapshot and run parameters from run.json,
skips terminal cases, deletes partial unfinished case directories, executes only
the remainder, and finalizes the original run id.
Reservations
Concurrency safety is a liveness file, not a lock server. Each run holds a
.reservation.json with a TTL and a background heartbeat:
- A live reservation makes a competing
runreturnE_RUN_BUSY(retryable, exit4). - A stale reservation is reclaimed by an explicit
--resume, which emitsW_RESERVATION_RECLAIMED.
No daemon or lock server is required.
Inspecting run state
evalctl jobs list --json
evalctl jobs get <run-id> --json
evalctl jobs prune --yes --json
jobs inspects completed, running, stale, and orphaned local run state and
prunes only with explicit confirmation (--yes/--force).
Sidecars are operational, not canonical
run.json, .reservation.json, .spoolctl.db, state.json, and job.json are
operational state. Reports and artifact replay do not require them — scores
are recomputed from report artifacts, and report_hash stays based on the report
projection. SOURCE_DATE_EPOCH controls created_ts so manifest-parity tests are
deterministic. See Artifact replay.