Lesson 5 — An agent in a cage, tested offline
think() asks a model. In Soma the answer cannot decide what happens next on its own. think_json(…, map("as", "Route")) only accepts one of the declared variants, match must handle every variant, the state machine bounds where the ticket can go, and cost is a token bound soma check proves. Tests mock the model, so they run without a key and without a network.
triage.cell
cell type Route { variants { Billing Tech Human { reason: String } } }
cell agent Triage {
face { signal route(ticket: String, text: String) -> String }
cost { tokens: 300 }
memory { routed: Map<String, String> [persistent] }
state ticket {
initial: new
new -> routed
new -> escalated
}
on route(ticket: String, text: String) {
set_budget(2000)
let r = try { think_json("Route this ticket: {text}", map("as", "Route", "max_tokens", 300)) }
if r.error != () {
transition(ticket, "new", "escalated")
return "human: the model failed ({r.kind})"
}
match r.value {
Billing -> { routed.set(ticket, "billing") transition(ticket, "new", "routed") }
Tech -> { routed.set(ticket, "tech") transition(ticket, "new", "routed") }
Human { reason } -> { transition(ticket, "new", "escalated") return "human: {reason}" }
}
return routed.get(ticket)
}
}
cell test TriageTests {
rules {
mock think "{\"variant\": \"Billing\"}"
assert route("t1", "I was charged twice") == "billing"
mock think "{\"variant\": \"Refund\"}" // a variant that does not exist
assert route("t2", "?") == "human: the model failed (json)"
mock think error "timeout"
assert route("t3", "help") == "human: the model failed (llm)"
assert get_status("t3") == "escalated"
}
}$ soma check triage.cell
✓ cost: 'tokens' bound proven — peak 300 reply tokens (the max_tokens caps) ≤ declared 300 (prompts are not counted: cap them with set_budget)
✓ All checks passed (1 note above).
$ soma test triage.cell
test TriageTests ...
✓ assert route("t1", "I was charged twice") == "billing"
✓ assert route("t2", "?") == "human: the model failed (json)"
✓ assert route("t3", "help") == "human: the model failed (llm)"
✓ assert get_status("t3") == "escalated"
4 tests: 4 passed, 0 failedThe model invented a Refund variant; the program sent the ticket to a human. soma verify adds think-isolated: the machine's safety properties hold whatever the model answers.