agents are markdown
Browse docs

Docs/The format

Evals

An eval is a markdown file under evals/ that runs an agent or a flow against a task and asserts something about the reply. It is how a change to a prompt stops being a guess.

---
name: writer-quality
agent: writer            # or `flow: publish`
model: fast              # the judge's model, not the agent's
---

## mentions the audience
task: Write a short draft about cleaning a rain gauge.
expect:
  - contains: farmer
  - not-contains: leverage
  - judge: speaks to working farmers, not to gardeners

## quotes the real price
task: Write one line quoting the price of the RG-40.
expect:
  - contains: $34

Each ## heading is one case: a task: and the expect: list it must satisfy. The heading is the case’s name, so make it the thing being checked.

Frontmatter

field
name the eval’s identity
agent or flow what runs. A flow eval runs the whole flow per case
model the judge’s tier, not the subject’s — cases run the agent on its own model
effort the judge’s effort. PASS/FAIL against one sentence is not deep work
trigger deploy (default) or manual

Assertions

contains: the text must appear
not-contains: the text must not appear
matches: a regular expression over the reply
file: the path exists and is non-empty
run: a shell command that must exit 0
judge: a model grades the reply against this sentence

Deterministic checks run first and cost nothing. The judge only runs if they pass — there is no point paying a model to grade output already known to be wrong. The same vocabulary is a step’s verify:, so a flow and an eval say “the output must mention the price” in one sentence.

When they run

trigger: deploy — the default — runs the eval on every deploy of the workspace, which is what makes it a regression test rather than a thing someone remembers to click. Results land in evals/.results/, and a dated line goes to history.jsonl so movement is visible across weeks.

trigger: manual keeps it off every push. Use it for flow: evals: a flow eval runs the entire flow once per case, so a three-case eval on an hour-long flow is three hours and the full cost, on every deploy.

Promoting a run

A run that went wrong is a case you already have — the task is on record, and so is the answer. Promote to eval on the run page writes it into evals/ with the task filled in, so the fix has a test before it has a diff. A run that was itself an eval case is refused: promote the run it was checking.

The loop

foldrun check           # free — no model is called
foldrun eval            # the assertions
foldrun run <agent>     # the real thing

check is the typecheck: a step naming an agent that does not exist, a tool or skill that resolves to nothing, a delegate: or on-fail: that names nobody, a cron that fires eleven times where you meant once. It costs nothing, so run it on every edit and let evals cover what only a model can answer.