policy::check_and_consume, which asserts the policy is live and the spend is in scope before any coin leaves the vault. A failed assertion aborts the whole transaction. No coin moves, and on a dry-run no gas is spent.
The gate
Abort codes
Each abort code maps to a stable reason.decodePolicyAbort reads the abort out of a thrown error or a dry-run failure status and returns the reason.
Denied without spending gas
A denied action aborts on-chain and emits no event, so a chain indexer never sees it. The agent records the denial itself: dry-run the transaction withclient.devInspectTransactionBlock, decode the policy abort, log it, and skip submitting. guardedSubmit does exactly this — dry-run, and on a policy abort record the denial and return without submitting; otherwise submit for real.
A non-policy dry-run failure (DeepBook liquidity, gas) is not a policy decision. decodePolicyAbort returns null for it and guardedSubmit surfaces it rather than recording a denial.
Pause and revoke
Both are owner operations signed with theOwnerCap. Both take effect on the next agent action.
- Pause sets
paused. The next action abortsagent_paused. Unpause clears it and the agent resumes. - Revoke sets
revokedand emitsPolicyRevoked. The next action abortspolicy_revoked. There is no path back.killAndDrainrevokes and sweeps every vault asset to the owner in one transaction.
Next: audit trail
The on-chain events every decision emits, and how denials reach the Chronicle.