> ## 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.

# Schemas

> The shape of every file Silo reads and writes

## Environment manifest

`.silo/environments/<name>/silo.environment.json`

```json theme={null}
{
  "name": "demo",
  "template": "crm",
  "templateVersion": "0.3.0",
  "entrypoint": "./index.ts",
  "tools": []
}
```

| Field             | Type       | Meaning                                                                      |
| ----------------- | ---------- | ---------------------------------------------------------------------------- |
| `name`            | `string`   | Environment name, matching the directory                                     |
| `template`        | `string`   | Which template it was scaffolded from                                        |
| `templateVersion` | `string`   | The Silo version that scaffolded it                                          |
| `entrypoint`      | `string`   | Module exporting the contract, relative to the environment                   |
| `tools`           | `string[]` | Tool packs chosen at `init`. Recorded only; nothing reads it at runtime yet. |

## Task

`.silo/environments/<name>/tasks/<id>.json`

```json theme={null}
{
  "id": "TASK-001",
  "title": "Convert a qualified maritime lead",
  "instruction": "Ingrid Halvorsen at Fjord Maritime Group has been qualified...",
  "difficulty": "easy",
  "verifierId": "VER-001",
  "entities": ["LEAD-004"]
}
```

| Field         | Type                           | Required | Meaning                                        |
| ------------- | ------------------------------ | -------- | ---------------------------------------------- |
| `id`          | `string`                       | yes      | Task id, used on the command line              |
| `title`       | `string`                       | yes      | Short label for listings                       |
| `instruction` | `string`                       | yes      | The only text the agent receives               |
| `verifierId`  | `string`                       | yes      | Which verifier grades it                       |
| `difficulty`  | `"easy" \| "medium" \| "hard"` | no       | Metadata; Silo does not read it                |
| `entities`    | `string[]`                     | no       | Ids the task concerns. Not shown to the agent. |

## Environment contract

The module at `entrypoint` must export three things:

```typescript theme={null}
createState(): State
bindTools(state: State): Tool[]
verifiers: SiloVerifier[]
```

Tasks are **not** exported — they are discovered from `tasks/*.json`.

## Tool

```typescript theme={null}
defineTool<State>({
  name: string;
  description: string;
  inputSchema: JsonSchema;
  run(state: State, input: ToolInput): unknown;
})
```

`inputSchema` is JSON Schema. Silo validates every call against it before `run` executes. Return values are cloned before reaching the agent.

## Verifier

```typescript theme={null}
defineVerifier<State>({
  id: string;
  taskId: string;
  name: string;
  check(
    finalState: State,
    initialState: State,
    context: { agentOutput: string; task: SiloTask },
  ): VerifierCheck[];
})
```

```typescript theme={null}
check(label: string, passed: boolean, detail?: string)     // required
optional(label: string, passed: boolean, detail?: string)  // optional
```

At least one required check is mandatory — a verifier returning none throws.

## Agent

```typescript theme={null}
export default async function agent(input: {
  task: string;
  tools: Array<{ name: string; description: string; inputSchema: Record<string, unknown> }>;
  callTool: (name: string, input: unknown) => Promise<{ output: unknown; isError?: boolean }>;
  signal: AbortSignal;
}): Promise<{ output: unknown }>;
```

<Note>
  This shape is not currently exported as a type, so agents declare it locally. See [Bring Your Own Agent](/silo/agents/overview).
</Note>

## Run artifacts

### `result.json`

```json theme={null}
{
  "passed": true,
  "reward": 1,
  "requiredPassed": 1,
  "requiredTotal": 1,
  "failedRequired": [],
  "checksPassed": 3,
  "checksFailed": 0,
  "toolCalls": 1,
  "toolErrors": 0,
  "terminationReason": "completed",
  "agentOutput": "The weighted value of open pipeline is $507500",
  "error": null,
  "checks": [
    { "label": "...", "passed": true, "detail": "...", "required": true }
  ]
}
```

### `state-diff.json`

```json theme={null}
{
  "scalars": [{ "field": "now", "from": "...", "to": "..." }],
  "collections": {
    "opportunities": { "added": [], "removed": [], "changed": ["OPP-005"] }
  }
}
```

<Warning>
  `result.json` and `state-diff.json` contain **no timestamps and no run ids**, deliberately. That is what makes them an exact regression oracle — any difference between two runs is a real behavioural change. Do not add either.
</Warning>

### `run.json`

```json theme={null}
{
  "runId": "run_20260915020238_9s01",
  "environment": "demo",
  "taskId": "TASK-002",
  "task": { "id": "TASK-002", "title": "...", "instruction": "...", "verifierId": "VER-002" },
  "verifierId": "VER-002",
  "verifierName": "Departed rep's open deals moved to the new owner",
  "config": { "maxToolCalls": 100, "timeoutMs": 120000, "agentPath": "./solver.ts" },
  "startedAt": "2026-09-15T02:02:38.161Z",
  "finishedAt": "2026-09-15T02:02:38.168Z",
  "durationMs": 5,
  "terminationReason": "completed",
  "toolCallCount": 3
}
```

The task is embedded in full, so a run stays interpretable even if the task file is later edited.

### `trace.jsonl`

One JSON object per line, in order, each with `seq`, `type` and `at`.

| `type`            | Additional fields                                                     |
| ----------------- | --------------------------------------------------------------------- |
| `run_start`       | `runId`, `environment`, `task`, `config`, `tools[]`                   |
| `tool_call`       | `callId`, `tool`, `input`                                             |
| `tool_result`     | `callId`, `tool`, `output`, `durationMs`                              |
| `agent_output`    | `output`                                                              |
| `run_end`         | `terminationReason`, `error`, `toolCalls`, `toolErrors`, `durationMs` |
| `verifier_result` | `verifierId`, `passed`, `reward`, `checks[]`                          |

`callId` pairs a call with its result.

## Termination reasons

| Value            | Meaning                     |
| ---------------- | --------------------------- |
| `completed`      | The agent returned normally |
| `max_tool_calls` | Tool-call budget exhausted  |
| `timeout`        | Time budget exhausted       |
| `agent_error`    | The agent threw             |

## Validation report

```json theme={null}
{
  "environment": "demo",
  "ok": true,
  "findings": [],
  "counts": { "data": 9, "tasks": 6, "tools": 42, "verifiers": 6 }
}
```

Each finding carries a `level`, a `code` and a `message`.
