Skip to main content

Approval/Risk Policy Plane

The approval/risk policy plane is QTG’s decision model for answering one question:
Can this movement execute automatically, should an operator review it, does it need fresher evidence, or must it be denied?
QTG already has many safety controls: address allowlists, signer/source checks, template auto-approve caps, Pro budget ledgers, bridge fee checks, executor guards, and Agent Wallet Top-Up envelopes. The policy plane turns those controls into a predictable trace instead of a pile of disconnected checks.
The current implementation is the first tranche. It adds deterministic trace DTOs, preview evaluation, trusted EVM target classification, and persisted policy trace evidence on movement creation. Existing Free and Pro auto-approve hooks still decide whether a movement is actually auto-approved.

Why this exists

Automation is useful only when the user can predict it. “This destination is trusted” is not enough. A safe automatic approval needs all of these to be true:
  • the movement intent was normalized into canonical facts
  • hard safety passed
  • the target is allowed
  • the target is trusted for auto-approval, if auto-approval is desired
  • budget and limit checks can reserve capacity
  • cost guards do not require review
  • dispatch-time executor guards will still enforce the receiver and signer constraints
The policy plane provides a common language for these checks.

Layered Evaluation Trace

QTG uses a fixed Layered Evaluation Trace as the top-level spine. Each layer can add evidence, but downstream policy cannot undo an upstream hard deny. This is deliberately not a generic top-level rule engine. A generic engine with global priority can make behavior surprising, especially when product policy grows. QTG keeps safety as deterministic code and allows rule-like flexibility only inside bounded leaf layers such as eligibility and cost guards.

Trace entry shape

Every policy layer returns trace entries. The reducer decides from those entries alone. Example trusted-target evidence:

Reducer outcomes

The reducer returns one of four preview outcomes: The current movement creation path persists this trace on the movement’s auto-approve result as a policy_trace. That trace is evidence. It does not replace the existing approval hooks yet.

Unknown data rule

Unknown data is split into two classes: This distinction matters because not all unknowns are equal. If QTG cannot prove where funds are going, it must deny. If QTG only needs a fresher fee quote, the right outcome is to refresh evidence and evaluate again.

Allowed vs trusted targets

Targets use a two-tier model: Trusted targets are always a subset of allowed targets. A trusted row must never bypass the allowlist. For EVM targets, the canonical key is:
  • chain_family
  • chain_id
  • destination_address
  • token_contract_or_native_id
  • target_level
  • is_active
Display symbols such as USDC are not policy keys. They are labels only.

EVM target policy in the current tranche

The first tranche evaluates EVM target policy for action types that actually sign or dispatch to EVM receivers, including CCTP, CCIP, Stargate, Gateway, and native/ERC-20 transfers. For non-EVM or CEX-only movements, EVM target policy is not_applicable. That avoids false deny traces for movements where an EVM destination is not part of the route.

Good policy shape

Good policies compose layers in a way users can predict:

Bad policy shape

These rules are intentionally rejected:
  • “trusted destination always approves”
  • “VIP strategy can skip address allowlist”
  • “USDC symbol means safe”
  • “low fee overrides unknown receiver validation”
  • “priority 100 rule overrides a hard deny”
Those policies make safety depend on rule ordering or display metadata. QTG’s safety model depends on resolved movement facts.

Relationship to dispatch safety

The policy plane is an approval-time explanation layer. Dispatch-time executor guards remain mandatory. If an address is removed from the allowlist after a movement is created, dispatch must still fail before funds move. For the operator-facing workflow, see Approval/Risk Policy Guide. For the older auto-approve hook reference, see Auto-Approve.