blank. Every command and every output below is from an actual session — you can follow along and get the same results.
The order matters. Each step depends on the one before it, and doing them out of sequence means editing generated files by hand.
1. Scaffold
2. Add data
Facts only — no computed values.tickets.json
agents.json
3. Write state.ts before anything else
This is the step people skip, and it costs the most. Scaffolded tools and verifiers import State and are generated against it, so writing state first means the stubs come out correct.
state.ts
now is in state because the domain has a clock, and isUnassigned is a helper because both a tool and a verifier will need that definition.
4. Build the world
environment.ts
5. Scaffold the tools
6. Implement them
The generated stub throws on purpose. Replace theTODO:
tools/assign-ticket.ts
assign_ticket refuses an unavailable agent, “assign these to someone who can take them” becomes a real task rather than a formality.
7. Add a task
8. Scaffold and write the verifier
verifiers/VER-001.ts
initial, not listed here. Add another unassigned ticket to the seed data and this check strengthens automatically.
9. Validate — this is the stopping condition
10. Run it
helpdesk.agent.ts
11. Prove the verifier can fail
A gate that cannot fail is worse than no gate. Point a different agent at the same task — one that does not do the work:What to do next
- Add a second task that produces an answer rather than a change — “how many tickets have been open more than 30 days?” — and derive the expected figure in the verifier using
daysOpen. - Add the awkward rows: a ticket assigned to an agent who has since become unavailable.
- Record a passing run’s
result.jsonas a baseline, so a change in behaviour shows up as a diff.
Silo