Start with
POST /v1/policy/explain. It is pure — no side effect, no ledger
row, nothing enqueued, nothing metered — and it calls the same helpers the
enforcing path calls. It is the thing to run before you decide whether to act.What is real, and what refuses
Seven of seventeen serve real data. The other ten answer
501 not_configured and
name the missing table — see the
durable runtime refusal contract for why that
shape, not {"items": []}.
Naming the tenant
Every tenant-scoped operation here takes an optional?tenant=<tenant_user_id>.
Omit it and the caller’s own subject answers.
Verdict vocabulary
The engine’s verdicts, and the one word that is not one of them:approve is not a verdict. It is what a rule author writes; when the
condition is unsatisfied it folds to park. Rendering approve as an outcome is
how a UI ends up showing a state the engine never produces.
The layers, and which of them exist here
The design has six policy layers. This build represents three, and the snapshot says which:Related
- Durable runtime API —
/v1/teams - Approvals — the queue policy parks work into
- AccountKits — where company-layer policy is written