The first version of Ava's workflow gate required a user to see and approve the exact plan before anything was signed. That is the right answer for one request. It is the wrong answer for the request that makes an autonomous agent worth having:
Every hour, find the best yield and rotate my money.
Nobody is awake for that. A product that wakes them fourteen times a day is not the product they asked for, and quietly dropping the approval is how agents end up with unbounded wallets.
Sign the envelope, not the plan
The user is still the only source of authority. What changes is WHAT they authorize.
a plan names exact actions checked by a human
an envelope names the outer limits checked by code, every timeAn envelope carries the operations, venues and chains permitted, a per-move cap, a cumulative cap, an expiry, revocation, and a minimum gain a rotation must beat. That last one is not a nicety. Without a floor, an agent can rotate forever with every single move individually legal and the sequence a fee-extraction machine.
Anything outside the envelope is refused, never escalated. Escalation would mean the agent stops at the first edge case, which is the same failure as asking per rotation.
Two ways the check nearly became decorative
An independent critic found both, and they share a shape worth naming.
The first: checkStandingMove took its caps from its CALLER. Anything wanting
to move more than the user signed could pass a larger ceiling and be told yes.
The signature verified perfectly; the limits it was compared against were
simply not the signed ones.
The second was subtler and we found it while attacking the fix. Decimals were
also caller-supplied, and decimals decide what a limit MEANS. A signed cap of
"200 USDC" is 200e6. Declare the asset has 18 decimals and the same cap becomes
200e18, so a 1000 USDC move sails through. Reproduced against the running API,
permitted: true.
Both now live inside the signed envelope. The rule they taught:
Anything that changes what a limit means has to be inside what the user signed, or the check is grading its own homework.
Negation, which inverted the whole thing
The worst bug of the batch was in the parser. "Never use Aave" produced an envelope that ALLOWED Aave, because a keyword sweep counted every mention as permission. The user's explicit refusal became an authorization.
It took two rounds to fix properly. The first attempt still failed on "never use Aave and never move more than 200 per rotation", where the prohibition span swallowed the size clause and the guard protecting numeric caps then discarded the whole thing. Prohibition spans now end where the next clause begins, and postfix forms like "Aave is not allowed" are read by looking behind the trigger rather than after it.
What is proven, and what is not
bash scripts/standing-e2e.sh walks the real loop against the running API,
signing with a secp256k1 key the server never sees: bounds parsed from plain
English, only what the user permitted, tampering refused, and five distinct
refusals for cap, venue, chain, gain floor and operation.
Nothing executes. There is no path from a signed envelope to a transaction yet. That is the next thing, and until it exists the honest description is that the authorization half is done.