Skip to main content
Every rollout writes a directory:
Run ids are collision-free, so concurrent runs and --runs sweeps never overwrite each other.

trace.jsonl

The record of what actually happened, one JSON object per line, in order. It is written to stand alone: it opens with the task, the resolved config and every tool name that was offered, and closes with the agent’s output, how the run ended, and how it was graded.
callId pairs a call with its result, so interleaved or concurrent calls stay attributable. The trace is always written. A run that dies before its first tool call still produces a readable account of what it was asked to do and how it failed.
When debugging, read trace.jsonl first. It tells you whether the model picked the wrong tool, sent bad arguments, or looped — which result.json alone cannot.

state-diff.json

What the rollout changed, as a shallow structural diff:
Collections keyed by id report added, removed and changed. Top-level scalars report their before and after. Arrays whose rows carry a string id are diffed as collections too — which is what makes append-only logs like auditLog visible instead of silently absent. An empty diff alongside a failure is diagnostic on its own: the agent read but never wrote.

result.json

Checks, reward, the agent’s output, and the tool error count. Covered in Scoring.

run.json

Everything the rollout was configured with, plus timings:
The task is embedded in full, so a run stays interpretable even if the task file is later edited.

Two files carry no timestamps

result.json and state-diff.json contain no timestamps and no run ids, by design. That makes them an exact regression oracle: any difference between two runs of the same task with the same agent is a real behavioural change, not noise. This is what lets you record a run as a baseline and byte-compare against it later:
It is worth protecting. A timestamp added to either file would make them useless for comparison.
Verifiers that derive their expected answers protect against stale data — edit a seed value and grading follows. They do not protect against changed logic: if a verifier and a tool share a helper and that helper changes, both move together and the check still passes.A recorded baseline is what catches that, because a frozen artifact cannot follow a formula change. Derivation and baselines cover different failures; a setup you intend to rely on wants both.

.silo/ is generated

Runs accumulate. .silo/ is runtime data, not source — add it to .gitignore and commit only the baselines you deliberately record.