Epic 17 — moving the signing key out of the agent and into the overseer
2026-05-29
Epic 17 was a single architectural change carried all the way through: make the agent a pure advisor that can propose a move but can never sign one. Before this, the hot key and the entire signing path lived inside the agent — which meant the component making autonomous decisions was also the one holding the ability to broadcast them. So we moved the key. The signer, the nonce and gas machinery, and the policy-guarded signing all relocated into the overseer; what is left in the agent is the ability to emit a structured intent — deposit this much of this asset into that protocol — and then block, waiting through approval, execution, and receipt.
The choice that mattered is what the epic calls Model B. The overseer does not trust calldata handed to it by the agent; it rebuilds the calldata itself, from the persisted structured intent, so the agent's vocabulary — the finite set of intents it is allowed to express — is the policy. The tempting alternative was to let the agent build the calldata and have the overseer decode and re-check it after the fact. We rejected that: a decoder is a parser, and a parser is a more fragile place to enforce safety than a constructor that only ever emits known-good shapes. Approval then runs in two tiers — a set of trusted policy gates (kill-switch, whitelist, supply cap, gas ceiling, and a per-transaction and daily value cap) that fire on every signed transaction, plus an optional human tier. Auto-approve, when on, only ever skips the human tier; an over-cap intent still goes to a human or is blocked outright.
To share the on-chain plumbing without handing the agent any signing power, the protocol adapters and read sources moved into a new domain package, chain — it depends on viem but holds no wallet client, and both sides import it: the agent for reads, the overseer for reads plus calldata-building plus signing. Two invariants are now enforced by the boundaries test: the agent has zero signing capability, and the chain package holds no wallet client. The sequencing was deliberate. The operator's call on 2026-05-29 was to land this before any mainnet transaction, because building agent-side signing stopgaps first would only mean deleting them again when the agent's signer came out for good. By the end of the epic the agent has no key, no signer, and no signing code at all. It proposes, and it waits.