Four kinds of AEGL
Not every layer that says no is the same thing. These are ordered by what each can express, and each type can do everything the ones above it can.
The four types
| Type | Decides on | Catches | Cannot catch |
|---|---|---|---|
| 1 · Per-payment cap | one amount, in isolation | a single payment that is too large | ten payments that are each fine |
| 2 · Cumulative envelope | amount + history | a budget exhausted over a day, a month, a window | an affordable purchase of the wrong thing |
| 3 · Governed budget | amount, history, counterparty, purpose, identity | drift from the task; an untrusted counterparty; a delegate exceeding its parent | the shape of a sequence |
| 4 · Behavioural | all of the above + sequence shape | structuring — many payments below every limit | — |
Type 1 · A per-payment cap
One number, checked against one amount. Refuse anything above it.
This is genuinely useful and it is also the easiest thing in the category to build, which is why
it is now table stakes — the x402 SDKs ship maxAmountPerPayment, the
Claude Agent SDK ships max_budget_usd, and several standalone tools do the same. If a
per-payment cap is all you need, you probably already have one.
What it cannot express, concretely. Forty payments of one cent pass every per-payment cap ever written. So do five identical purchases when only the sixth exhausts a daily total. The limit has no memory, so every decision is the first decision.
Type 2 · A cumulative envelope
Now the layer remembers. An envelope is a limit plus the consumption against it — a daily total, a monthly total, a per-counterparty ceiling over thirty days.
purchase 1: $0.01 APPROVE
purchase 2: $0.01 APPROVE daily: $0.02 of $0.05 used
purchase 3: $0.01 APPROVE
purchase 4: $0.01 APPROVE
purchase 5: $0.01 APPROVE daily: $0.05 of $0.05 — exhausted
purchase 6: $0.01 REVIEW ← binding: daily
The refused payment is byte-for-byte identical to the five approved before it. That outcome is unreachable for type 1 at any threshold — and it is worth being precise about why tightening does not substitute: lowering the per-payment ceiling to one cent would still admit all six, and would refuse every legitimate purchase above a cent.
Type 2 also introduces a question type 1 never has to answer: which limit bound? With four envelopes in play, “refused” is not actionable and “refused by the daily envelope, which has $0.00 headroom” is.
Type 3 · A governed budget
Everything above, plus the facts that are not amounts: who the counterparty is, what the agent was sent to do, and whose authority it acts under.
This is where a whole class of failure becomes catchable, and the cleanest example is one where every economic control is satisfied:
# an agent sent to buy market data buys a follower count instead.
# same amount. same counterparty. same resource shape.
treasury : ok=True binding=nothing ← affordable
trust : 0.4800 no flags ← counterparty is fine
risk : 0.2100 no flags ← nothing unusual
policy : matched rule 'auto-approve-micro'
intent : /social/followers is outside the intent's declared resources
REVIEW — attributed to: intent
Four controls say yes. One says no, and it is the only one that could — because nothing about the purchase is a money problem. No amount of tightening a budget catches this, which is the argument for declaring intent up front: without it, “within budget” and “doing the job” collapse into the same question, and they are not the same question.
Type 3 typically adds:
Intent
What the agent was sent to do, declared before it acts, with a budget and a scope. Drift becomes detectable.
Counterparty trust
Earned over settlements rather than asserted. A new counterparty is not a bad one, but it is not an established one either.
Identity & delegation
Who is acting, under whose authority — and a sub-agent that can never exceed its parent.
Attribution
Which control decided. With several controls able to refuse, this becomes the only actionable field in the record.
Type 4 · Behavioural
Everything above, plus the shape of a sequence rather than the size of any action.
Two attacks make the case, and neither is exotic:
- Structuring. Forty payments of a tenth of a cent, paced five minutes apart. No value envelope is breached, no rate limit is breached, and the total is trivial. Money moves with nothing refused.
- Velocity evasion — closed. Pacing under a rate limit was unbounded in total: 97 actions an hour against a ceiling of 100 is 2,328 a day, and every one of them compliant. Closed by a count envelope over a day rather than an hour. The lesson kept here because it generalises: a rate limit bounds the rate, and an hourly ceiling of 100 implies no daily ceiling of 2,400 — it implies none at all.
No type-3 layer catches either, and Tesoro does not. It ships the structuring case as a runnable demonstration of its own gap rather than a paragraph about it — 40 payments, 0.08% of a daily envelope, nothing refused.
What would catch it is a control examining count, variance and distribution instead of magnitude: forty identical payments is not forty independent decisions. Every envelope in a type-3 layer answers how much, and the thing wrong with structuring is its shape.
Which type do you need?
| If your situation is | Then |
|---|---|
| one agent, one counterparty you chose, small amounts, a human watching | Type 1 is honestly enough. Use what your SDK already ships |
| an agent running unattended, or repeatedly, against a budget that matters | Type 2 minimum — a cap with no memory will not bound your total spend |
| an agent choosing its own counterparties, or sub-agents, or you need to explain a refusal later | Type 3. This is where attribution and evidence start mattering |
| you have an adversary, or a regulator, or the sequence itself is the risk | Type 4 — and nobody has built one. Be sceptical of claims otherwise |
A note on reading vendor claims in this space, including this one: “spend limits” is used for all four types. The question that separates them is “can it refuse a payment that is individually within every limit?” — type 1 cannot, by construction.