Escalations
A verdict that a person has to answer, how it reaches them, and where their answer is recorded.
Escalations
An ESCALATE is the gate saying a person has to decide this one. The agent waits. It cannot approve itself, and silence is not a yes.
How it reaches someone
In Claude Code an escalation is a permission prompt, in the session, at the moment it happens. Answering there is the fast path.
● Read(.env)
Coco: The agent is reading a file that holds a credential
Approve? y/nOn the SDK road the verdict comes back as ESCALATE and your harness decides where it goes. Park the action, put it in front of whoever holds the decision, and do not let the agent proceed while it waits.
verdict = gate.check("payment.send", payload)
if verdict.escalated:
park_for_a_person(verdict.reason)The person answers on the dashboard, where the escalation queue shows what the agent wanted, the rule that paused it and the reason, and their decision is written next to the receipt. Resuming the parked action afterwards is your harness's job, because the gate authorises calls and does not schedule them. There is no webhook that pushes a decision back to your harness today, so a harness that needs to resume automatically polls the receipt it parked on, and saying otherwise would be wrong.
Working the queue
Everything held is also in the ledger.
coco escalations1 waiting on a decision
#2 2026-08-24T05:57:45Z Read
rule baseline.credential_access/credential_read_needs_a_person
reason The agent is reading a file that holds a credential
action /tmp/.env
coco approve 2 | coco deny 2Each item shows what the agent wanted to do, the contract that paused it, and the reason in a sentence.
coco approve 41 --comment "second pair confirmed with the customer"
coco deny 42 --comment "no mandate line covers this"The decision is written next to the receipt it answers, so the record shows what was held, who released it and why. Write the comment for the person reading the record in a year.
A receipt that already carries a decision keeps it. A second approve on the same
id is refused rather than silently overwriting the first, because an audit trail
where a decision can be replaced is not an audit trail.
When an escalation cannot reach anyone
A permission mode that never prompts has nobody to ask. The gate converts the escalation itself rather than relying on the runtime, so the receipt says what actually happened.
This needed an operator decision and permission mode 'bypassPermissions'
does not prompt, so it was denied insteadWhich way it goes is escalate_fallback in your mandate, and deny is the only
answer that keeps an escalation meaningful.
Choosing escalate over block
Reach for ESCALATE when a person legitimately can approve the action and there is somebody to ask. Reach for BLOCK when nobody inside this mandate should be able to.
The trap is escalating everything. A queue nobody works is a queue that trains people to approve without reading, and at that point the escalation is a slower allow. If a rule escalates constantly on ordinary work, the rule is drafted wrong.
Next
- Reading the ledger for the record the decision lands on
- Modes for what enforcement does to the queue