*Part 11 of An OS Where the AI Is Never a Principal.*
This series began with a twelve-part tutorial on object capabilities with Endo and Agoric. That one taught the machinery — SES, hardened compartments, CapTP, ERTP, Zoe — from a car key up to an on-chain wallet. This one took that machinery and pointed it at an AI agent. This post is where the two meet again, because it turns out I have been retelling, in the language of models and prompts, a story Mark Miller already told in the language of money.
The story is Zoe, Agoric's framework for running financial smart contracts. And Zoe is the Aegis thesis again — the same architecture, the same one move, transplanted from AI to finance.
The same move, two untrusted actors
Here is the thesis as it has run through this whole series: the model is never a principal. It proposes; the capability graph disposes. The worst case of a prompt injection is misuse of least authority, never escalation.
Now read the financial version. In Zoe, a smart contract is *untrusted code* — written by whoever, doing arbitrary math, possibly buggy, possibly malicious. You want to run it without letting it steal. So Zoe never hands the contract any assets. The contract *proposes* a reallocation — who should end up with what — and a small trusted framework *disposes*, checking the proposal before anything moves. The worst case of a malicious contract is a refund, never theft.
Line them up and they are the same sentence twice:
| Aegis (AI) | Zoe (DeFi) |
| --- | --- |
| the model is never a principal | the contract is never trusted with assets |
| the model proposes, the capability graph disposes | the contract proposes a reallocation, Zoe disposes (checks it) |
| worst case of a prompt injection = misuse of least authority, never escalation | worst case of a malicious contract = a refund, never theft |
| confine an untrusted *reasoner*, still let it participate | confine an untrusted *contract*, still let it run |
A malicious smart contract is the same kind of threat as a prompt-injected model. Both are powerful, flexible, untrustworthy components you nonetheless want to *use*. And the same architecture defeats both: let the untrusted thing propose, and put a small trusted layer between its proposal and any real authority. Zoe is the financial dual of the membrane.
What Zoe actually guarantees
The mechanism is called offer safety, and it is worth seeing precisely.
Each party makes an *offer*: a proposal = { give, want } plus the actual payments they put in. Zoe escrows the payments. From that moment the untrusted contract never touches a real asset — it sees only Amounts, which in the miniature ERTP are just { brand, value } descriptions that carry no value. (Value lives in the issuer's closure-private ledger, never in a reference; you cannot forge an asset by copying a description of it. That is the mint-and-purse pattern from the earlier post on owning and selling a post.)
The contract proposes a reallocation. Before paying anyone out, Zoe enforces two invariants:
// 1. Offer safety, per seat: you got everything you `want`ed, OR a full refund.
function offerSafe(seat, got) {
const gotAllWanted = every(seat.proposal.want, (kw, w) => isGTE(got[kw], w));
if (gotAllWanted) return true;
return every(seat.proposal.give, (kw, g) => isGTE(got[kw], g)); // full refund
}
// 2. Rights conservation, per brand: total out === total escrowed in.
// The contract cannot create or destroy value.If the proposed reallocation violates either — or the contract throws, or hangs — Zoe rejects it and refunds everyone. That last clause is the whole point: in the real runContract, the call into the untrusted contract is wrapped in a try/catch, and a throw routes straight to refundAll. The contract's power is reduced to "propose a reallocation Zoe will check." It has no other capability over the escrowed assets, because it was never handed one.
You cannot end up worse than your stated offer, no matter what the contract does. That is offer safety: a structural guarantee, not a behavioral hope — exactly like "the worst case is misuse of least authority."
The demo: an untrusted contract sells a deed
pnpm demo:zoe runs Alice selling the deed to post EF342 to Eve, through an *untrusted* contract. Four runs, one trusted Zoe path:
- Honest atomic swap → the trade completes. Alice gets 70 Coin, Eve gets the EF342 Deed.
- Thief — the contract tries
Eve gets nothing, Alice keeps the deed and takes the coin. Rejected by offer safety; Eve is fully refunded her 70 Coin. - Counterfeiter — the contract tries to hand Eve 1000 Coin minted from nothing. Rejected by rights conservation; total out exceeded total escrowed in.
- Buggy — the contract throws. Rejected; both parties refunded. The assets were never at risk because they were never in the contract's hands.
Three different attacks, three different guards, one invariant. Notice the contract is identically untrusted in all four runs — Zoe doesn't audit it, doesn't try to tell honest from malicious. It just bounds the outcome.
But does it survive a contract that does real math?
The swap is almost too easy — the honest reallocation is just "give each party the other's escrow." A skeptic should ask whether offer safety is an artifact of a trivial contract. So pnpm demo:amm runs a contract that does genuine computation: a constant-product automated market maker, x · y = k, the Uniswap pricing mechanism. The contract reads the pool, computes a price off the curve, and proposes a reallocation. Zoe still bounds it:
- honest AMM → the trader spends 100 Coin and gets the curve amount, rounded so
knever decreases (the pool keeps the dust). Trade completes. - shortchange AMM — gives 50 Tok when the trader's
wantfloor was 90. Rejected by offer safety. Here is the elegant part: the trader's slippage protection *is* theirwant. A below-floor fill isn't a special case Zoe checks for; it's just an offer that didn't get what it wanted, so it's refunded. - counterfeit AMM — mints 5000 Tok out of a 1000-Tok pool. Rejected by rights conservation.
- vanish AMM — silently drops the trader's 100 Coin. Rejected by rights conservation again — value destroyed is as forbidden as value created.
Real pricing math in the loop, and a buggy-or-malicious AMM is still bounded to *refund, never theft*. The slippage limit is enforced by the trusted framework, not by trusting the AMM to honor it. That is the financial mirror of the property I keep returning to: safety that holds whether the untrusted component is brilliant or broken.
Why this is the bridge
The earlier ownership sale used a *trusted* escrow agent — both parties had to believe it wouldn't cheat. Zoe deletes that trust. The framework is trusted (small, auditable, like the membrane); the contract is not (arbitrary, like the model). That is the same progression Aegis makes everywhere: don't trust the powerful flexible component, confine it behind a small fixed one.
And seeing it arrive *independently* in Miller's blockchain work — years before anyone was worried about prompt injection — is the strongest evidence I have that the pattern is fundamental, not a quirk of the AI setting. The confinement move predates the threat I'm applying it to. I didn't discover the architecture; I noticed that Zoe and the Aegis membrane are the same thing.
It also closes a symmetry the series has been building. Least authority joined least knowledge. The authority graph turned out to be the label lattice. The social graph turned out to be the capability graph. And now the membrane turns out to be offer safety — confining a model and confining a contract are one move, seen twice.
Honest scope
This is a *miniature* ERTP and Zoe — kernel/src/ertp.ts and kernel/src/zoe.ts, a few hundred lines between them. Enough to demonstrate offer safety and rights conservation faithfully; not the full Agoric system. There is no on-chain consensus, no real zcf/seat API surface, no invitation objects, no auction or priced mechanisms, and it runs in one process rather than across a chain of vats. The production version lives at agoric.com and in the Agoric SDK, written by Mark Miller and the Agoric team, running real value on a live chain. MetaMask ships the SES layer underneath it. None of that is mine.
What the demos show is narrower and, I think, more interesting: that Aegis and Agoric are the same idea pointed at two different untrusted actors — a model, and a contract. If you want the machinery in full, the Endo and Agoric tutorial series builds the real thing from the ground up. This post was the bridge back to it.
One post remains. The next one is the one I've been most careful about: what this design *can't* do, and why that's the honest place to end.
End of Transmission.