Policy is a Move shared object. It holds the budget, the scope, and the live state for one agent. Because it is shared, its cumulative spend persists across transactions: an agent cannot bypass a cap by splitting a spend across multiple PTBs.

Shape
Per-asset caps
Caps govern budget deployment, not what the vault may hold. The funded budget asset (for example SUI) carries anAssetCap. Each gated spend of a capped asset checks per_tx_cap and per_day_cap, then records the amount against spent_today. The day window rolls forward 24h after day_window_started_ms.
An asset with no cap entry is default-deny for transfer-out, but a position the agent acquired through a permitted swap is uncapped: it can be sold back, because the proceeds settle into the vault. Exfiltration of an uncapped asset is blocked by assert_transferable.
| Cap | Type | Meaning |
|---|---|---|
per_tx_cap | u64 (base units) | Max per single action. 0 disables the per-tx check. |
per_day_cap | u64 (base units) | Max cumulative spend in a rolling 24h window. |
50_000_000 is 0.05 SUI (9 decimals).
Allowed actions
allowed_actions is a default-deny VecSet<u8>. The SDK action ids mirror altheia::actions:
| Action | Id | Builder |
|---|---|---|
transfer | 0 | — |
deepbookSwap | 1 | buildSwap, buildSellSwap |
deepbookLimitOrder | 2 | buildPlaceLimit |
deepbookCancel | 3 | buildCancelAll |
action_not_allowed.
Protocol scope
allowed_packages is the set of package or pool addresses the agent may touch. check_and_consume asserts the target is in the set before any coin leaves the vault. An out-of-scope target aborts package_not_allowed.
Expiry, pause, revoke
| State | Field | Abort | Reversible |
|---|---|---|---|
| Expired | expires_at_ms | policy_expired | no |
| Paused | paused | agent_paused | yes (unpause) |
| Revoked | revoked | policy_revoked | no |
revoked is set, every gated action aborts. There is no path back. Provision a new agent.
Value-guard
max_slippage_bps and base_scalar are operator-set. The agent cannot supply them. For swaps, the per-action params (set with buildSetValueGuard or at provision time) define a minimum output rate, so a swap that would settle below the operator’s floor reverts on-chain rather than executing at a bad price.
Reading the policy
readPolicyObject(client, policyId) reads the live caps, actions, scope, expiry, and state straight from chain — no backend dependency. See the SDK reference.
Next: Vault and AgentCap
Where funds live, and the capability that binds the agent to one vault and one policy.