Coco

State reference

Every field a contract can read, and which of them make a verdict depend on where the work has got to.

State reference

Six namespaces. Every field is a fact rather than a model's opinion, and a rule that reads a name the state does not carry gets nothing rather than an error, so the check fails instead of the gate crashing.

tool

This call, flattened out of the runtime's tool input.

FieldWhat it holds
tool.nameThe tool name as the runtime gave it
tool.normalisedLowercased, with a functions. prefix and an (Explore) specifier stripped
tool.familyThe family this tool routed to
tool.commandThe shell command, for a command call
tool.pathThe file path, for a read or a write
tool.urlThe URL, for an egress call
tool.queryThe search query
tool.descriptionThe description, prompt or task text
tool.subagent_typeWhich subagent is being spawned

Facts the gate has already worked out, so a contract does not re-derive them.

FieldTrue when
tool.is_read tool.is_write tool.is_commandThe call is that kind of action
tool.is_agent tool.is_mcp tool.is_paymentThe same
tool.touches_secretThe path matches a credential file. Environment files, private keys, cloud profiles, keyrings
tool.is_egressThe call moves data off the machine, by tool or by command
tool.is_destructiveThe command has no safe reading. A recursive delete of the root, a write to a block device, a download piped into a shell, a force push, a cleared history
tool.destructive_reasonWhich of those it was
tool.path_existsThe target already exists, which separates creating a record from rewriting one
tool.path_ext tool.path_abs tool.path_sizeThe extension, the absolute path, and the size on disk

A payment call carries the offer the agent wants to accept, lifted as facts so a contract compares numbers to numbers.

FieldWhat it holds
tool.amountThe amount, as a number, or nothing if it would not parse
tool.currencyUppercased
tool.payee_addressWho the money goes to
tool.merchantWho is being paid
tool.resourceWhat is being bought
tool.networkThe chain or network
tool.offer_idThe offer or nonce
tool.offer_expires_epochHow long the offer stands
tool.is_renewalWhether this is a renewal

An amount that is not a finite number arrives as nothing rather than as a string, so a rule comparing it to a limit fails its check instead of comparing a string to a number and passing by accident.

The derived facts are pattern lists, not classifiers. touches_secret matches the paths that hold credentials, environment files, private keys, cloud profiles and keyrings. is_destructive matches a fixed list of commands with no safe reading, and is_egress matches the tools and commands that move data off the machine. A pattern list misses what it does not name, which is exactly why a contract can add its own conditions on the raw tool.path and tool.command instead of relying on the derived flag.

session

What this session already did, before this call.

FieldCounts
session.tool_callsEvery governed call
session.files_read session.files_writtenReads and writes
session.secrets_read session.secrets_writtenCredential files touched
session.commands_runShell commands
session.destructive_attemptsDestructive commands attempted
session.egress_callsCalls that sent data off the machine
session.subagents_spawnedSubagents started
session.case_files_readFiles touched inside the case this call resolved to
session.payments_attemptedPayments attempted

The counters read the state before the current call, so reading a credential does not count itself and the egress two calls later is the one that sees it. A contract about reading a credential and then sending data reads session.secrets_read for the history and tool.is_egress for now.

A call that was stopped does not advance the counters. A blocked read never happened, so it must not count towards what this session has seen.

case

Live workflow state, read off disk for the case this call touches.

FieldWhat it holds
case.presentWhether any case state could be read at all
case.idThe case folder's name
case.rootThe resolved case folder
case.case_rootThe root every case lives under
case.touched_by_this_callWhether this call's own path resolved the case
case.<marker>Whether that marker's files exist
case.<marker>_countHow many
case.<marker>_sizeThe largest, in bytes

Markers come from the mandate. See The mandate.

case.touched_by_this_call matters more than it looks. An egress call carries no path and still needs the open case's state, so the gate falls back to the case folder most recently touched. That fallback must not make an unrelated file read look like someone opened the customer's file.

platform

Live ledger state supplied by the runtime that embeds the gate. Every field is whatever the platform put in the snapshot, plus one the gate adds.

FieldWhat it holds
platform.presentWhether a snapshot arrived at all

Missing state is a fact. When no snapshot arrives, platform.present is false and the contract decides what that means, which keeps an absent provider fail-closed in the contract rather than quietly allowed in the gate.

The trust boundary is the payload's author. In a Claude Code install that is the harness, and over HTTP it is the platform service calling the gate. It is never the agent whose call is being judged.

env

FieldWhat it holds
env.permission_modeThe permission mode this call is running under
env.can_askWhether that mode can surface a prompt to a person
env.cwdThe working directory
env.session_idThis session
env.agent_id env.agent_typeWhich agent, when the runtime says
env.mandate_idThe mandate governing this call
env.modeA mode field on the mandate, when one is set. The gate's operating mode comes from config and sits on every receipt as gate_mode, so read the receipt for which mode actually governed a call

mandate

Whatever is under limits in your mandate file, read directly.

limits:
  max_files_written: 40
  max_payment_usd: 50
rule: session.files_written < mandate.max_files_written

Why the split matters

tool alone is what a stateless gate sees, and a check written against tool alone can be defeated by splitting one bad action into two allowed ones.

session, case and platform are the parts that make a verdict depend on where the work actually sits. They are also the parts that can be absent, which is why every one of them carries a present field or a count you can check first.

On this page