Gates
Every scored event produces one gate decision and one enforcement action. The API answers synchronously. What it does not do is withhold anything: the producer holds the output, and the SDKs make that the default.
The four statuses
Seed thresholds, from policy version 1. Your org's active policy may differ; the digest on every record says which numbers were in force.
| Gate | BII | What VIGIL records | What the producer must do |
|---|---|---|---|
pass | at or above 0.75 | An enforcement action with requires_human_review: false | Let the output propagate. |
hold | 0.60 to 0.7499 | An action flagged for human review; a gate.hold webhook | Withhold the output. Show the user the review path. Wait for a reviewer or a timeout you choose. |
alert | 0.41 to 0.5999 | An action flagged for review and escalation; a gate.alert webhook | Withhold the output. Treat as an incident: page the on-call reviewer. |
collapse | at or below 0.40 | An action flagged for review; composite trust forced to 0; a gate.collapse webhook | Withhold the output. Stop the agent's further actions until a reviewer decides. |
requires_human_review is true for hold, alert and collapse.
Honoring the gate
The contract is the same on every surface. The API returns gate_status and action_id. The producer either honors the gate or records that it did not.
- Python and TypeScript SDKs:
gate.honor()raisesHeldOutputon hold, alert or collapse.honor(allow_propagation=True)lets the output through after emitting anoutput_generatedevent withsource: "vigil"and{"gate_ignored": true, ...}, so the override is on the ledger. - Claude Code hooks:
PreToolUseexits 2 and the tool does not run. - OpenAI Agents SDK: the output guardrail trips and the SDK raises instead of returning the output.
- LangGraph:
hook.last_gate.heldis set; you park the result.
What happens to a held action
A held action stays pending until a reviewer decides it through vigil-gate, a separate service with its own database role. Outcomes are released, rejected or escalated. The decision is terminal and appends a review record to the org's ledger chain.
Your code learns the outcome one of two ways:
- Poll
GET /enforcement/{action_id}and readreview_outcome. The SDKs wrap this aswait_for_release(action_id, timeout). - Subscribe a webhook to
review.released,review.rejected,review.escalated.
Which gate is an agent under right now
curl -sf -H "Authorization: Bearer $VIGIL_KEY" "$VIGIL_URL/enforcement/agent/docs-quickstart/latest"
The latest action's gate_status is the agent's current gate. review_outcome is null while a hold is pending. Run the quickstart first so the agent has an action.