Skip to main content
A check is a named condition that Ancha evaluates when an attempt ends. An attempt passes when every required check passes. Without checks, an attempt is ungraded: it ran, but nothing says whether it did the right thing.

Four kinds

Prefer state checks for outcomes. They pass however the agent got there, while trace checks depend on which endpoint it chose.

Examples

In a scene file, checks are YAML:
scene.yaml
In the hosted console and in playground task files, the same checks are a JSON list on each task:

Required checks

pass lists the IDs of the required checks. It defaults to every check. A check outside pass is still evaluated and reported, but it does not decide the outcome. Use that for advisory checks, such as a judge rubric you are still tuning.

Trace patterns

A trace pattern is "<METHOD> <PATH>", for example "POST /api/chat.postMessage".
  • The path is relative to the tool’s base URL and has no query string: /repos/acme/starter, not the full URL.
  • The method is compared without regard to case. * as the method accepts any method. The path must match exactly, including case.
  • * in the path matches any run of characters, including /. "POST /crm/*" matches every POST under /crm/. The pattern "*" matches any call.
  • Only the agent’s own calls count. Actions taken by the world, such as a person posting in Slack, never match.
With both fields set, both must hold.
Use * as the method when the verb does not matter. Slack’s official SDKs call every Web API method with POST, while plain fetch code often uses GET, and Slack accepts both. The starter scene’s checks are written this way, for example * /api/*.*. Check the agent’s calls with ancha explain or in trace.jsonl when a trace check surprises you.

State checks

State checks count every record in the final state, including starter data. Set from on a slack.message check so a message from the starter history cannot satisfy it. See Checks reference for every field.

Process checks

A scene can hold people: a customer who holds back details until asked, an engineer who knows the workaround, a manager who decides the priority. A model writes what they say, but the world’s engine decides who receives a message, which facts a person may share, what they decide and when they answer, and it records every one of those events. Process checks read those records. Because the checks read the engine’s records and never the model’s text, a person who writes something unexpected cannot pass or fail an attempt by wording alone. A milestone that never happened fails before and within, so an attempt that did nothing cannot pass them. See Process checks.

Judge checks

A judge check is a rubric in plain language. After the attempt, Ancha sends a model a bounded copy of the evidence: the agent’s API calls to Slack, GitHub, Datadog and PagerDuty with their requests and responses, and the final Slack messages, channels and users. The model returns passed or failed with a reason and the trace entries it relied on. Credentials, the scene’s seed and the other checks are never sent.
  • Judge checks need OPENROUTER_API_KEY in the environment of the ancha run or ancha check command. Ancha calls the model through OpenRouter. The agent does not get the key unless you list it in agent.pass_env.
  • Set judge.model in ancha.yaml to the OpenRouter model you want the judge to use.
  • Without a key, judge checks are skipped. A skipped check never passes, so a required judge check fails the attempt. Keep advisory rubrics out of pass.
  • If the model call fails, the trial is marked invalid instead of failed.
  • Judge checks run in ancha run and ancha check only. The hosted console and playground tasks accept state and trace checks.

Refs

Checks name records with refs such as $slack_support, not with generated IDs. Refs come from the world’s starter data or from your scene’s seed, and people from its people. Saving a task in the hosted console checks every ref against its world. See Worlds.

Results

Every check result has the same fields: ancha explain prints these for failed checks, ancha check --json prints them all for a live world, and each trial’s checks.json holds them all.