Completion conditions
Completion conditions determine when a pact automatically ends. At least one is required. The pact completes when any condition is satisfied, after which access is revoked immediately. Types cannot be duplicated within a pact.Policies
Policies are the rules that constrain what an agent can do within a pact. Every operation the runtime submits is evaluated against the policies you define.How the engine works
The policy engine evaluates every operation against all applicable policies and outputs one of three decisions: allow, require_approval, or deny.Evaluation order (within a policy)
- Match
whenconditions — if not matched, the policy is skipped - Check
deny_if— if hit, deny immediately - Check
review_if/always_review— if hit, pause for owner approval - Otherwise, allow
Default-deny semantics
Pact-level policies use fail-closed semantics: if the operation does not match any policy’swhen conditions, it is automatically denied. Every operation the agent needs to perform must be explicitly covered by a policy.
Final decision
When multiple policies apply:- Any deny → deny
- No deny, but any review triggered → require_approval
- Otherwise → allow
Policy structure
Each policy in thepolicies array has this shape:
Constraints:
deny_iftakes priority overreview_if/always_reviewdenyeffect policies cannot havereview_iforalways_reviewallow+review_ifrequires a non-emptywhenallowrequires either a non-emptywhenoralways_review: true
Transfer policies
Use"type": "transfer" to control token transfers.
when — allowlist conditions
All fields are AND conditions. All specified fields must match.
deny_if — hard-block limits
Each rolling window supports:
amount_gt, amount_usd_gt, tx_count_gt.
review_if — approval thresholds
Supports the same fields as when (chain_in, token_in, destination_address_in), plus:
Examples
Contract call policies
Use"type": "contract_call" to control smart contract interactions. EVM and Solana use different target fields.
when — allowlist conditions (EVM)
when — allowlist conditions (Solana)
params_match rule
Used to match on decoded function parameters. Requires function_abis to be set.
params_match is only supported on EVM chains. Multiple rules are AND conditions.
function_abis
Required when using params_match. Provide the ABI fragment for each function selector you reference:
deny_if — hard-block limits
review_if — approval thresholds
Supports the same fields as when (chain_in, target_in, program_in, params_match), plus amount_gt and amount_usd_gt.
Examples
Message sign policies
Use"type": "message_sign" to control EIP-712 typed-data signing. There are no amount_gt / amount_usd_gt fields — rate limits use request_count_gt instead.
when — allowlist conditions
All
when fields are AND conditions.
Path syntax for domain_match and message_match
Use dot notation to address nested fields:
Wildcard semantics — for multi-value paths like
items.*.token:
eq,in,gt,gte,lt,lte: matches if any element satisfies the conditionneq,not_in: matches only if all elements satisfy the condition
eq, neq, in, not_in, gt, gte, lt, lte
Path resolution failures
When a path cannot be resolved, the rule does not match:deny_if — rate limits
review_if — approval thresholds
Supports the same fields as when (chain_in, primary_type_in, source_address_in, domain_match, message_match).
Chain ID validation
For EVM chains, the engine checks that the requestchain_id matches domain.chainId in the typed data. A mismatch results in an immediate deny with reason eip712_domain_chain_id_mismatch.
Examples
Amount units
amount_gt, amount_spent, and related fields use the token’s transfer unit — the same unit passed when submitting a transfer:
"1.5"for USDC means 1.5 USDC (not 1,500,000 micro-USDC)"0.01"for ETH means 0.01 ETH (not wei)
USD-based conditions (
amount_usd_gt, amount_spent_usd) only apply to tokens with available price data. For tokens without price data, use token-denominated limits (amount_gt, amount_spent) instead.