Everything it can do
The current list, generated from the running system: every operation, the
networks it runs on, and the exact reference to copy.
A plan uses a fixed set of actions
A plan can only name something on the list. There is no way to write “call this contract with this data” into a plan. This rule is enforced, and it is what makes the whole thing safe to hand to a model. A plan naming anything else is refused when it is written, rather than attempted and failed halfway. Adding to the list is cheap. A new venue is a new entry, not a change to how plans work, so plans written before it existed keep their shape. The fixed set of actions is what keeps plans safe, and adding to it quickly does not weaken that.This is also why a step cannot reach a network any other way. Every transaction
has the same shape: the form the agent signs plus a signature, handed to one of the
approved operations, which checks the signature before doing anything. A step
arriving by another route is one your account’s permissions do not bound.
Every operation carries a version number
A step is written aslend.supply@v1.1. A bare name with no version is refused.
A workflow can wait a long time while the software underneath it changes. Without a
version pinned to it, a job that outlives an update could start doing
something different halfway through, and nobody would notice.
When several versions would do, it picks the oldest one that fits. The newest
is code your plan was never shown.
Network coverage is not uniform
Almost every operation runs on Ethereum, Base and Arbitrum. Buying and selling property, and the four rent operations, run on Base only. HyperEVM carries a small set: sending, receiving, moving USDC to another network, and trading on Hyperliquid. Networks shows what runs where. This changes as we deploy. Operations that once ran on one network now run on all three, so a plan refused last week can work today.Crossings between networks finish later
Most steps finish when their transaction goes through. Moving money to another network does not. It finishes when something outside the transaction happens, so the run has to wait rather than check a receipt. A crossing usually lands within a couple of minutes, and nothing here can hurry it. A plan is built around that wait, and a step on the far side cannot start early. Two crossings are in the catalogue: one moves USDC, the other moves USDC or WETH. Both finish the same out-of-band way, so the wait above applies to any crossing, not just one route. Moving between networks has the routes, the fee and the expected times.Steps that share a transaction
Steps that belong together are merged into one transaction. A merged group is all-or-nothing. If the last call fails, the first is undone too. This has two effects:- It is what makes “give permission, then supply” safe. The permission cannot survive a failed supply and sit there afterwards as a standing allowance.
- It is what makes a very long merge a bad idea. One failure at the end throws away everything before it.
Measured on a real plan: three transactions and 852k gas when split, two
transactions and 739k gas when merged, in the same two blocks.
Order is worked out, not taken from your list
You write steps top to bottom, but the run does not execute them that way. Steps that do not depend on each other run at the same time. What depends on what is derived from the plan itself, by looking at which steps touch the same balances and the same lending positions.What a step produces
Two questions look like one here, and confusing them produces a plan that does something nobody meant.- Does it produce anything? This decides whether a later step may refer to its result.
- What is that number? One step produces an amount of USDC. Another produces the identifier of a position. Both are large integers travelling down the same wire.
Under the hood
Useful if you are evaluating the design. Not needed to use the product.What a step can carry
A step’s fields have fixed kinds:
There is deliberately no “raw bytes” kind and no “anything” kind. Either would
let a caller smuggle a raw instruction through a field, and then the agent could
write instructions instead of only supplying these values.
Three of those need more explanation.
A market is a name, not an identifier. Some lending protocols let anybody
create a market. An identifier would let a plan reach a market nobody vetted. A
market decides the price at which you are liquidated, so that is a plan choosing
the terms of its own liquidation.
A property is separate from a market, even though both are curated lists,
because they are curated for different reasons. A market is curated because it
sets a price. A property is curated because it is a claim on a real building with
exactly one contract behind it. They were once the same kind, and the plan
designer offered lending markets for a field that wants a property token.
A price is two whole numbers, never a decimal. A decimal has to be converted
against two different token scales somewhere. Every place that happens is a place
a limit can be multiplied by a million by mistake. As a pair of whole numbers
there is nothing to convert.