# 02 · PDP ⇄ PEP Split

> Deciding and enforcing are never the same component.

## Overview

Arcana separates the question *"may this run?"* (PDP) from the statement
*"this will now run, exactly once"* (PEP). Collapsing the two is how agent
frameworks end up with security that depends on the model's cooperation.
Splitting them gives three properties the merged design cannot have:
determinism, auditability, and single-effect guarantees.

## PDP — Policy Decision Point

A **pure function**: decision = f(request, immutable policy snapshot).

- Reads no stores, mutates nothing, calls nothing.
- Evaluated against a frozen serializable snapshot of policy, contracts, and
  capability state.
- Same input ⇒ same verdict, every time, on every machine. Verdicts are
  reproducible in CI and in court.

## PEP — Policy Enforcement Point

The component standing at the effect boundary (just before the shell spawns,
the file writes, the HTTP call fires):

- Obtains a **fresh context** — re-reads current policy/capability state at
  execution time, not at proposal time.
- **Rejects stale decisions**: if policy moved between decision and execution,
  the old verdict is void and the request re-enters evaluation.
- **Atomically claims** the grant/approval/use — concurrent claims produce
  exactly one winner.
- Invokes the protected effect **exactly once**, then records the receipt.

## Decision lifecycle

```text
propose q
  → PDP evaluates q against snapshot S₁        → verdict d
  → PEP re-reads state at execution moment S₂
  → S₂.policyVersion ≠ S₁.policyVersion?       → STALE → re-decide
  → claim grant/approval (atomic)              → loser blocked
  → effect executes exactly once
  → receipt appended to evidence
```

## Fail-closed modes

| Mode | Behavior when required stores are unavailable |
|---|---|
| REQUIRED | Deny. The policy provider fails closed; nothing executes without its brain. |
| LEGACY_COMPAT | Explicit migration behavior only. Assurance is degraded by definition and must be visible as degraded. |

LEGACY_COMPAT exists so existing projects can adopt incrementally; it is never
a silent default and never counts toward assurance claims.

## Why the split matters

- **Testability**: the PDP is pure, so thousands of hostile requests can be
  evaluated in CI without touching a filesystem (see the conformance vectors).
- **Auditability**: decisions are functions of (request, snapshot) — both are
  recorded, so any verdict can be re-derived later.
- **Safety under concurrency**: two racing executions cannot both consume the
  same approval; the claim is atomic.

## Related

- Previous: [The Authorization Request](/governance/request.md)
- Next: [Risk Classes](/governance/risk.md)