# 08 · Scoped Approvals & Routing

> Exact, single-use, expiring, crash-recoverable.

## Overview

Some actions require a human. Scoped approvals are how humans say yes — in a
way that cannot be stretched, replayed, or survived past its meaning.

## State machine

```text
REQUIRE_APPROVAL
  → persist exact request as PENDING
  → user approves the exact requestHash
  → APPROVED
  → PEP atomically claims APPROVED → CLAIMED
  → fresh revalidation → effect executes once
  → execution receipt
  → CLAIMED → CONSUMED
```

| State | Meaning |
|---|---|
| PENDING | Exact request persisted; waiting on a human |
| APPROVED | Human approved this exact hash; unconsumed |
| CLAIMED | Atomically taken by a PEP; execution in flight |
| CONSUMED | Executed once; receipt recorded; dead |

## The five hard properties

1. **Exact** — the user approves the requestHash, not a description. Changing
   any covered field invalidates the approval and requires a new one.
2. **Single-use** — one approval, one execution. Concurrent claims produce
   exactly one winner; losers are blocked.
3. **Expiring** — approvals die on a timer; a yes from yesterday is not a yes
   for today.
4. **Fresh-revalidated** — between CLAIMED and execution, the PEP re-checks
   policy/capability state. Stale context kills the execution.
5. **Crash-recoverable** — recovery uses an idempotency key derived from
   approval ID + session ID + request hash. Uncertain irreversible effects
   enter a **recovery-required** state rather than blindly retrying.

## Approval routing

Where the prompt lands is itself governed:

| Mode | Behavior |
|---|---|
| LOCAL_TUI | Approved in the terminal console |
| DESKTOP_PREFERRED | Desktop companion if present, TUI fallback |
| DESKTOP_REQUIRED | Blocked until the desktop approves |
| CENTRAL_REQUIRED | Enterprise control plane decides |

Routing policy is configured per workspace (`.arcana/approval-routing.json`)
with a strict schema — invalid routing config fails closed.

## Related

- Previous: [Provenance & Sensitivity](/governance/provenance.md)
- Next: [Signed Envelopes](/governance/envelopes.md)