Escalation & enforcement
Each violation carries a severity that decides what happens next. There are three, and only two of them block.
flagNoted, not blocked — a $5,000 transfer is logged for review and still goes through.escalateRedirected to a safer path — a $60,000 wire gets a second-approver dialog instead of a confirm button.rejectRefused outright — a fabricated “Confirm” button simply never renders.flagis informational. It is recorded on the decision for review and reporting, but blocks nothing. A $5,000 transfer is flagged for SAR review and still goes through.escalateblocks the standard render and names a stricter component inrequiredComponent. The over-limit wire escalates toSecureWireDialog, which collects a second approver. The request is redirected, not refused.rejectis a hard block: nothing mounts. A fabricated field, smuggled card data, or a self-approved transfer gets this.
A decision can carry several
One intent can trip multiple violations. The unapproved $60,000 wire carries two flags (CTR-reportable, SAR review) and one escalation. The flags are recorded; the escalation is what forces the dialog.
Severity is a property of each rule's code, not a global switch. Loosening enforcement means editing a rule or routing fewer intents through the gate, which happens in code review rather than in a runtime setting.
What mounts on a clean pass
A display verb that passes mounts its registered presentational component. A
governed verb that passes cleanly mounts nothing: the decision returns
mount: null and your app supplies its own confirm step, composed from core
primitives. A governed component only mounts when an escalation names it.
{ intent: "wire_transfer", props, result: { valid: true /* … */ }, mount: null }Rules are independent, so you can route a single intent through the gate and expand later. See Adopt incrementally.
Next: The audit trail.