Embedded supervision for the agent layer

Every action was permitted. The outcome was not.

An agent can assemble an exposure nobody authorised out of steps that each pass. AMW checks the composition before settlement, holds it, and hands a named human the case file.

0Actions fired in one epoch
0Notional on each, USDC
0Per-action cap, clause 2.1
0Aggregate reached, against 2,000,000
The gap

Per-action controls cannot see a sequence.

One question, asked nine times and answered honestly. Nobody asks the tenth.

“Is this action allowed?”

240,000 against a 250,000 cap. Classified venue, named agent, unexpired mandate.

Answered nine times: yes

“What do these nine amount to?”

2,160,000 against a 2,000,000 bound. 3,333 bps off-primary against 2,500. All of it from permitted parts.

Asked by nothing on chain

Finance named this fifty years ago and made it an offence: structuring — a reportable amount cut into unreportable slices. An agent needs no intent to produce it. A sizing loop will do.

One epoch, sixty minutes

Move the numbers. Watch where it stops.

The contract’s own arithmetic, running here. Move a bound; the hold moves with it.

The ninth action is held. Tier 1 clean on all nine. A hold debits nothing.
2,000,000 — clause 3.4
1,920,000 settled and untouched. A hold spends nothing.
0 tier-1 breaches, whatever you set. The composition is what fails.
How it runs

Four steps, and only one of them involves a model.

01

The owner signs a mandate

EIP-712, identified by its own digest, so one signed elsewhere cannot be replayed here. A child may only narrow its parent — widening is impossible, not flagged.

02

The agent may ask, and may not spend

The guard is the sole approved spender; the agent holds no tokens and no allowance. Every intent is recorded before it passes or fails, so a hold leaves a trace instead of vanishing in a revert.

03

Composition is evaluated before execution

Aggregate, count and off-primary share are checked against what the action intends, across every ancestor — so delegating is not the way around it. A breach returns a hold: no revert, nothing debited.

04

A named human decides

Workers draft and challenge the language; the arithmetic and the striking gate use no model. A claim whose citation does not resolve never reaches the page, and a struck one stays visible with its reason. The authoriser signs the release.

The instrument

A mandate is a document, and it reads like one.

Tier 1 is what an action is. Tier 2 is what a sequence becomes. Same instrument, same contract, both enforced before value moves.

Signature recovered on chain EIP-712 · 65 bytes · depth 0
0x54b681a521198a593c74d5753452c1f8f71aa052…
2.1Per-action notional cap250,000 USDCtier 1
2.2Instrument pairUSDC → EURCtier 1
2.3Venue classificationprimary / secondarytier 1
2.4Mandate expirysame daytier 1
3.4Aggregate notional per window2,000,000 USDCtier 2
3.5Action count per window12tier 2
3.7Off-primary venue share2,500 bpstier 2
4.2Named release authoriserrequired on any holdhuman

The three marked clauses are properties of a sequence. No per-action guardrail can evaluate them.

The question that always comes

Assume the agent’s key is stolen.

Not misconfigured. Held by someone hostile who can sign anything the agent could.

What it cannot do

Move the owner’s tokens: the guard is the sole spender. Reclassify a venue: the map is keyed by owner. Widen the mandate: the terms are the owner’s signature or nothing. Release its own hold: no agent can become an authoriser.

What it can do

Exactly what the mandate permits, and every unit of it recorded before it happens.

1,920,000 moved by the stolen key, all of it inside the mandate.
0 taken away. Proceeds go to the owner, and the guard holds no balance between actions.
Live on Hedera testnet

Every claim on this page is a command away.

Source-verified contracts: bytecode a reader cannot check is bytecode they are asked to trust. The incident, the commitments and the decision are on chain.

MandateGuard
0.0.10308333 0xb390ffd5…cc30
MandateRegistry
0.0.10308330 0xd246d86d…7959
VenueRegistry
0.0.10308332 0x6fc3aa33…eee2
Intent commitments
0.0.10309023 HCS topic

Every contract has two names: the native 0.0.x id and the 0x EVM address, one contract behind both. Mandates are signed against the EVM address, because that is what the guard reads.

npm run -w @amw/relay gate10 A key funded with nothing signs six things and sends no transaction.
npm run -w @amw/contracts gate2 Nine actions from an agent key holding nothing. The ninth is held.
npm run -w @amw/contracts gate7 The compromised-agent drill, in fifteen seconds.
npm run verify 270 tests, each named after the attack it refuses.
Stated before they are found

What AMW does not do.

A mandate bounds size, not price. No execution-quality clause, no oracle. An agent willing to lose value can lose it inside every clause.

Recovery is ecrecover only. A multisig treasury needs EIP-1271 — named here, not built.

The window is a fixed epoch, not rolling — cheaper to run, at the cost of a boundary an attacker can see.

One chain, one tenant, synthetic instruments. Each limit carries a test that fails the day it stops being true.

Read the record

Check every figure yourself

The incident, the case file behind the hold, and a preview answered by the enforcement bytecode itself. No wallet needed.