> ## Documentation Index
> Fetch the complete documentation index at: https://jephalabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Approval/Risk Policy Guide

> How to design predictable approval, trusted target, budget, and cost policies in QTG

# Approval/Risk Policy Guide

This guide is for operators and product builders who need to decide which QTG movements can be automatic and which ones must remain manual.

The short rule:

> Auto-approve only when the target, amount, budget, and cost are all bounded and explainable.

<Note>
  The current release records policy trace evidence and supports trusted EVM target preview. It does not yet expose a full policy-editor UI or customer-authored rule DSL. Treat DB-seeded trusted targets and existing Free/Pro auto-approve settings as the active configuration surfaces.
</Note>

## The mental model

Think of every movement as passing through four operator questions:

<Steps>
  <Step title="Is this structurally safe?">
    Does the route have a valid destination, signer/source alignment, executor coverage, and address allowlist coverage? If not, QTG denies or blocks before funds move.
  </Step>

  <Step title="Is this target merely allowed or also trusted?">
    Allowed means the destination may receive funds. Trusted means it may be considered for auto-approval under additional bounds.
  </Step>

  <Step title="Is the amount inside an explicit budget?">
    Per-request caps, rolling windows, Agent Wallet envelopes, and Pro budget ledgers decide whether automation has remaining capacity.
  </Step>

  <Step title="Are route costs acceptable and fresh?">
    Fees, bridge quotes, gas, slippage, and venue limits can force manual review or a refresh before approval.
  </Step>
</Steps>

If any answer is ambiguous, the system should not silently auto-approve.

## Policy building blocks

| Building block   | What it answers                                          | Auto-approve role                                                                                                         |
| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Hard safety gate | Can QTG prove the movement is structurally safe?         | Required. Failure denies.                                                                                                 |
| Allowed target   | May this destination receive funds?                      | Required for execution. Not enough for auto-approval.                                                                     |
| Trusted target   | Is this allowed destination eligible for automation?     | Can create an auto-eligible path.                                                                                         |
| Eligibility rule | Does this subject/template/strategy qualify?             | Narrows who can use automation.                                                                                           |
| Budget/limit     | Is there remaining capacity?                             | Prevents runaway volume. See the [Outflow Velocity Cap](/guide/outflow-velocity-cap) for the per-token aggregate ceiling. |
| Cost guard       | Are fees and slippage acceptable?                        | Prevents economically bad automation.                                                                                     |
| Dispatch guard   | Does the prepared action still match the approved facts? | Last line of defense before funds move.                                                                                   |

## Recommended policy patterns

### Pattern 1: Manual by default

Use this for new strategies, new destinations, new chains, new bridge routes, or anything with weak evidence.

```text theme={null}
allowed target: yes
trusted target: no
budget: none or manual-only
cost guard: informational
result: manual_required
```

This lets QTG execute after operator approval while preventing accidental automation.

### Pattern 2: Trusted target plus small budget

Use this for repeated, low-risk operational transfers to a known wallet.

```text theme={null}
allowed target: yes
trusted target: yes, exact chain/address/token tuple
per-request cap: small
rolling budget: enabled
cost guard: fee/slippage cap
result: auto_eligible when all evidence passes
```

Example:

| Field           | Example                                         |
| --------------- | ----------------------------------------------- |
| Chain           | Base Sepolia or Base mainnet                    |
| Destination     | Dedicated treasury-controlled operations wallet |
| Token key       | USDC contract address, not `USDC` symbol        |
| Per-request cap | Small operational amount                        |
| Rolling budget  | Daily or hourly cap                             |
| Cost guard      | Max bridge fee or max gas budget                |

### Pattern 3: Trusted target with refresh gate

Use this when the destination is safe but route economics change quickly.

```text theme={null}
allowed target: yes
trusted target: yes
fee quote: required and fresh
slippage quote: required and fresh
result: needs_refresh when quote is stale
```

The operator or caller refreshes quote evidence, then previews again.

### Pattern 4: Allowed target with manual cost review

Use this for larger transfers where the address is correct but automation should not decide economic risk.

```text theme={null}
allowed target: yes
trusted target: no
budget: operator-reviewed
cost guard: manual fallback on high fee
result: manual_required
```

This is a good default for new bridge lanes, volatile gas conditions, and exchange-maintenance periods.

### Pattern 5: Agent Wallet top-up envelope

Agent Wallet Top-Up should remain envelope-bound:

```text theme={null}
allowed target: approved Agent Wallet
trusted target: only after exact envelope match
budget: envelope cap + cooldown + rolling limit
source/signer/token: resolved server-side
result: bounded auto eligibility only inside the envelope
```

Never let the agent provide source address, token, signer selector, or treasury authority. The agent proposes a top-up; QTG resolves the funding envelope.

## Policies to avoid

| Avoid                                   | Why                                                                   |
| --------------------------------------- | --------------------------------------------------------------------- |
| Global "trusted USDC" rule              | Symbols are display metadata and can drift across chains and wrappers |
| VIP strategy bypasses allowlist         | Subject priority cannot make a destination safe                       |
| Low fee means auto-approve              | Cost is not receiver safety                                           |
| Trusted target with no token key        | Same address can receive different assets with different risk         |
| Broad chain-wide trusted target         | Too hard for users to predict and too large a blast radius            |
| Auto-approve without budget reservation | A loop or compromised client can drain the full source balance        |

## User-facing predictability checklist

Before enabling auto-approval for a route, you should be able to answer these questions in plain language:

* Which subject, strategy, or agent can request it?
* Which exact template or route can it use?
* Which exact destination tuple is trusted?
* Which asset key is trusted?
* What is the maximum amount per request?
* What is the rolling budget window?
* What happens when fee data is missing or stale?
* What happens when the target is allowed but not trusted?
* What event or API response explains the decision after creation?

If an operator cannot answer those questions, keep the route manual.

## Reading a policy trace

A movement's persisted `auto_approve_result.policy_trace` explains the preview evidence used at creation.

Look at:

| Field              | What to check                                                                           |
| ------------------ | --------------------------------------------------------------------------------------- |
| `outcome`          | Overall preview result: `deny`, `needs_refresh`, `manual_required`, or `auto_eligible`  |
| `machine_reason`   | Stable reason selected by the reducer                                                   |
| `trace[].layer`    | Which layer produced the evidence                                                       |
| `trace[].outcome`  | Whether the check passed, failed, was unknown, or was not applicable                    |
| `trace[].severity` | Whether this entry can deny, refresh, require manual fallback, or mark auto eligibility |
| `trace[].evidence` | The actual normalized facts used for the decision                                       |

Example interpretations:

| Trace clue                                     | Meaning                                                                                                            |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `machine_reason=destination_not_allowlisted`   | Destination is not allowed. Do not solve with auto-approve policy. Add or reject the allowlist entry deliberately. |
| `machine_reason=trusted_target_match`          | Destination tuple is trusted and may contribute to auto eligibility. Budgets and costs still matter.               |
| `machine_reason=trusted_target_not_configured` | Destination is allowed but not trusted. Manual approval is expected.                                               |
| `machine_reason=trusted_target_token_missing`  | QTG cannot prove the exact asset key for trusted-target automation.                                                |
| `machine_reason=evm_target_not_applicable`     | This movement does not use an EVM target action, so EVM trusted-target policy did not participate.                 |
| `machine_reason=refresh_required`              | Refreshable evidence is missing or stale. Refresh evidence and preview again.                                      |

## Example policy decisions

| Request                                                   | Trace shape                                                | Expected decision                                                |
| --------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------- |
| Upbit to Bithumb CEX transfer with no EVM destination     | EVM target layers are `not_applicable`                     | Manual or existing auto-approve hook result, not EVM target deny |
| Base USDC transfer to allowlisted but not trusted address | hard safety pass, allow pass, trust not configured         | Manual required                                                  |
| Base USDC transfer to trusted address under cap           | hard safety pass, allow pass, trust pass, budget/cost pass | Auto-eligible, then existing hook may auto-approve               |
| Base USDC transfer to trusted address over budget         | trust pass, budget fail/manual fallback                    | Manual required or deny by budget policy                         |
| EVM transfer with missing destination address             | hard safety structural unknown                             | Deny                                                             |
| Bridge route with stale fee quote                         | cost guard refreshable unknown                             | Needs refresh                                                    |

## Current implementation notes

* Trusted targets are stored in the network-scoped `approval_policy_targets` table.
* EVM target values are normalized to lowercase where appropriate.
* Legacy allowlist rows with `chain_id = NULL` are treated consistently with current creation-time allowlist behavior.
* CEX-only and other non-EVM movements do not get denied by EVM target policy.
* The trace is persisted as evidence. It is not yet the sole authority for final auto-approval.

## Change management

When adding a new policy idea, classify it first:

| If the idea is about...                                            | Put it in...                  |
| ------------------------------------------------------------------ | ----------------------------- |
| Receiver validity, signer/source equality, allowlist, network mode | Hard safety                   |
| Which destinations can execute at all                              | Allowed target                |
| Which safe destinations can be automatic                           | Trusted target or eligibility |
| Amount/count exposure                                              | Budget or limit               |
| Fees, gas, slippage, route quotes                                  | Cost guard                    |
| Finality, stuck states, retry safety                               | Observe/recovery guard        |

Do not implement it as a broad high-priority override unless it belongs inside a bounded leaf layer and cannot weaken upstream safety.

## Related pages

* [Approval/Risk Policy Plane](/concepts/approval-risk-policy-plane)
* [Outflow Velocity Cap](/guide/outflow-velocity-cap)
* [Security Model](/concepts/security-model)
* [Auto-Approve](/reference/auto-approve)
* [Agent Wallet Top-Up](/guide/agent-wallet)
