> ## Documentation Index
> Fetch the complete documentation index at: https://docs.burn0.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Use Silo With Claude or Codex

> Have a coding agent build your environment, and check its own work

Silo's commands are non-interactive, take explicit flags, emit `--json`, and fail with specific messages and non-zero exits. That is deliberate: a coding agent can drive the whole authoring flow and verify the result without a human in the loop.

Copy the brief below, replace the bracketed block with your own use case, and hand the whole thing over.

## The brief

```
Create a Silo environment using the @burn0/silo CLI.

The world to simulate:

  [YOUR AGENT USE CASE — replace this block.
   Describe the domain, the records it holds, the actions an agent should be
   able to take, the rules that make an action illegal, and one or two jobs you
   want to test an agent on. Be concrete: real entity names, real statuses.]

Work in this order. Each step depends on the one before it:

  1. npx @burn0/silo init <name> --template blank
  2. npx @burn0/silo data add <collection> --env <name> --file <path>
  3. edit state.ts        — define the world's types and domain helpers
  4. edit environment.ts  — load data/ and return a fresh cloned world
  5. npx @burn0/silo tool add <tool_name> --env <name> --description "..."
  6. implement each tool's run()
  7. npx @burn0/silo task add --env <name> --id TASK-001 --title "..." \
       --instruction "..." --verifier VER-001 --difficulty easy
  8. npx @burn0/silo verifier add VER-001 --env <name> --task TASK-001
  9. implement each verifier's check()
 10. npx @burn0/silo env validate --env <name>   <- must print OK before you stop
 11. npx @burn0/silo run --env <name> --task TASK-001 --agent ./agent.ts

Rules that matter:

- Keep the state type named `State`. Scaffolded tools and verifiers import that
  name; renaming it means editing every generated file for no benefit.
- Write state.ts BEFORE scaffolding tools, so the generated stubs are correct
  as written.
- data/*.json holds facts only: quantities, prices, statuses, ids, dates. If a
  number can be computed from other fields, compute it instead of storing it.
  Never store a total.
- createState() must return structuredClone(...). Imported JSON is cached for
  the life of the process, and without the clone one rollout's changes leak
  into the next.
- If the domain has any notion of overdue, stale or expiring, put a fixed `now`
  in State and expose it through a tool. Never call new Date().
- The agent only ever sees the task instruction, the tool schemas and what your
  tools return. If it should be able to list something, write a tool for it.
- Business rules belong in tools, not verifiers. A tool that refuses an illegal
  action is what makes a task real.
- A task states the objective and nothing else — no solution path, no list of
  tools to use, no hidden answer.
- Verifiers:
    state-changing task   -> check finalState against initialState
    answer-producing task -> derive the expected answer from initialState using
                             your own domain helpers, then compare it against
                             context.agentOutput
  Never hardcode an answer that can be derived from the world. Do not grade
  which tools were called unless the process itself is the task.
- At least one check() per verifier must be required.
- Generated stubs fail on purpose. A verifier you have not implemented must
  never report a pass.

You are done when `silo env validate` prints OK and a run produces the result
you expect. Validate before you claim success: an environment can load and run
while still failing to compile, and validate catches that.
```

## Why validate is the stopping condition

`silo env validate` runs the real TypeScript compiler over the environment, not just a resource check. Type-only imports are erased before execution, so an environment can run perfectly while being uncompilable — **"it ran" is not evidence that it is correct.**

Telling the agent to stop at `OK` rather than at "the run worked" is what makes the loop self-checking. A run exercises one path; validation covers every tool and verifier, including the ones that task never touched.

```bash theme={null}
npx @burn0/silo env validate --env helpdesk --json
```

```json theme={null}
{
  "environment": "helpdesk",
  "ok": true,
  "findings": [],
  "counts": { "data": 2, "tasks": 1, "tools": 3, "verifiers": 1 }
}
```

The `--json` output is what makes this usable in an agent loop: a machine-readable `ok`, findings with codes and line numbers, and counts that catch a tool written but never registered.

## Ask for proof, not assertion

The most useful instruction you can add is that a passing verifier means nothing until it has been shown to fail:

```
After implementing each verifier, prove it discriminates: run the task with an
agent that does nothing, and confirm the run FAILS. A verifier that passes on
no work at all is not a check.
```

This catches the most common failure in generated environments — a verifier whose condition is accidentally always true. It looks identical to a working one in every passing run.

## Reviewing what it built

Regardless of who wrote it, these are worth checking by hand:

* **Does `createState()` clone?** Missing this is invisible in a single run and only appears as flaky grading across `--runs`.
* **Does any verifier hardcode an answer?** Search for literal numbers in `verifiers/`. A derivable value written as a constant is correct until the data changes.
* **Is anything derived stored in `data/`?** A stored total goes stale the moment a quantity is edited.
* **Do the tools cover what the tasks require?** If a task needs information no tool exposes, no agent can pass it.
* **Do the tasks have unique answers?** A tie makes a task ungradeable.

## Keeping an agent oriented later

Once the environment exists, the same properties make it a good target for iteration. `trace.jsonl` gives an agent the full record of a failed rollout — which tool was called, with what arguments, and what came back — so "here is the trace, work out why it failed" is a productive instruction rather than a guessing game.
