Skip to main content
The governance pipeline is a sequential chain of safety gates that evaluates every agent dispatch request before execution begins. Each gate is a pure function that checks a specific constraint. The first rejection terminates the pipeline, records an audit event, and returns a structured error. Every decision is recorded in the append-only audit trail.

🛡️ Pipeline Overview

GOVERNANCE GATE SEQUENCE

1
gatewayHealthgateway_unreachable

Is the target gateway healthy? Blocks if offline.

2
agentStatusagent_unavailable

Is the agent available? Blocks if paused, terminated, or in error state.

3
concurrencyretryable
agent_busy

Is the agent below its concurrency limit? Retryable.

4
rateLimitrate_limit_exceeded

Is the agent within its rate limit? Checked via @convex-dev/rate-limiter.

5
budgetAgentbudget_exceeded

Has the agent exhausted its monthly budget? Not retryable.

6
budgetEnvelopesbudget_exceeded

Are all applicable budget envelopes (daily/weekly/monthly) within limits?

7
trustLeveltrust_insufficient

Does the agent’s trust level meet the gateway’s minimum?

8
contextTrustcontext_blocked

Context source class, freshness, and environment eligibility checks.

9
policyRulespolicy_blocked

Do configured governance policies allow this dispatch? May block or require approval.

10
approvalRequiredapproval_required

Does a policy or step require human approval? Returns “hold” if yes and not yet granted.

PASS
BLOCK
HOLD

FAIL-FAST: First block stops the pipeline. Remaining gates are skipped.

⚖️ Three Dispositions

Every governance evaluation produces a with one of three dispositions:
DispositionMeaningWhat happens
passAll gates passedStep is dispatched to the gateway for execution
blockA gate rejected the requestStep is marked failed. Error code and message are recorded. Retryable blocks trigger backoff retry.
holdA policy requires approvalAn approval record is created. The interpreter sleeps on a durable workflow event until the approval is resolved.

🔍 Gate Details

Gate 1: gatewayHealth

Input:  gatewayDoc.status
Pass:   status is "healthy" or "degraded"
Block:  status is "offline" → gateway_unreachable (not retryable)
Note:   Degraded gateways log a warning but are allowed

Gate 2: agentStatus

Input:  agentDoc.lifecycleStatus
Pass:   status is "idle", "running", or not set
Block:  status is "paused" → agent_unavailable (retryable)
Block:  status is "terminated" or "error" → agent_unavailable (not retryable)

Gate 3: concurrency

Input:  running step count, max from resolvedBounds or agentDoc.maxConcurrentSteps (default: 1)
Pass:   runningCount < maxConcurrentSteps
Block:  runningCount >= maxConcurrentSteps → agent_busy (retryable)
Skip:   Skipped for delegated_run_dispatch action type

Gate 4: rateLimit

Input:  agent rate limit configuration
Pass:   Within rate limit window
Block:  Limit exceeded → rate_limit_exceeded (retryable)
Method: Checked via @convex-dev/rate-limiter transactionally

Gate 5: budgetAgent

Input:  resolvedBounds.maxSpendCents or agentDoc.budgetMonthlyCents, agentDoc.spentMonthlyCents
Pass:   No budget set, or spent < budget
Block:  spent >= budget → budget_exceeded (not retryable)

Gate 6: budgetEnvelopes

Input:  Array of BudgetEnvelope (scope, period, amount, spentCents)
Pass:   All envelopes have spentCents < amount, or no envelopes
Block:  Any envelope exhausted → budget_exceeded (not retryable)
Note:   Checks the tightest constraint across all applicable envelopes

Gate 7: trustLevel

Input:  agentDoc.trustLevel (default: 1), gatewayDoc.minTrustLevel
Pass:   No gateway minimum set, or agent trust >= gateway minimum
Block:  agent trust < gateway minimum → trust_level_insufficient (not retryable)

Gate 8: contextTrust

Evaluates two sub-checks: Environment eligibility — If the worker role specifies allowed environments and the gateway has an environment, the gateway must be in the allowed list. Context trust — If the role has trustedContextConfig:
  • Context source class must be in acceptedSourceClasses
  • If requireFreshness is set, context cannot be stale or unknown
  • If maxFreshnessMinutes is set, context age is checked against the window (default: 30 minutes)
Block:  environment_not_eligible (not retryable)
Block:  context_source_rejected (not retryable)
Block:  context_freshness_blocked (retryable)
Block:  context_trust_blocked (not retryable)

Gate 9: policyRules

Input:  Matched policies from policies table
Pass:   No blocking policies match
Block:  A policy explicitly blocks → policy_blocked (not retryable)
Hold:   A policy requires approval → sets approval requirement
Method: Evaluated via evaluateDispatchPolicies hook

Gate 10: approvalRequired

Input:  Approval requirements from gates 9 + approval policies, existing approval status
Pass:   No approval required, or approval already granted
Hold:   Approval required and not yet granted → creates approval record
Skip:   If approval is already pending, returns existing hold
Method: Checked via getApprovalStatus hook

🎯 Action Types

The governance engine supports three action types, each with different gate sequences:
Action typeGate sequenceUse case
step_dispatchFull 10-gate sequenceStandard workflow step execution
delegated_run_dispatchFull sequence minus concurrency gateGoal-based sub-run dispatch
workflow_run_launchauthorityPosture → gatewayHealth → workflowReadiness → policyRules → approvalRequiredPre-launch preflight check
The launch gate sequence checks different things: whether the execution authority posture allows run creation, whether the workflow has a valid version, and whether any launch policies require approval.

⚡ Fail-Fast Behavior

The pipeline is fail-fast: if any gate blocks, all remaining gates are recorded as skipped with reason "blocked_by_previous_gate". This means:
  • A gateway health failure never reaches the budget check
  • A concurrency limit never reaches the trust level check
  • The first blocking gate determines the error code returned to the interpreter

📋 Audit Trail

Every governance decision is recorded in the auditEvents table:
EventRecorded when
governance_decisionEvery evaluation (pass, block, or hold) — includes full gate outcomes, snapshots, and structured explanation
step_dispatchedAfter a pass decision, when the step is dispatched to Bridge
safety_gate_rejectedWhen a gate blocks dispatch (includes error code and retryable flag)
approval_createdWhen a hold creates a new approval record
The GovernanceDecision object attached to audit events includes:
  • gates[] — outcome of each gate (pass, fail, skipped)
  • budgetSnapshot — agent budget and spend at decision time
  • trustSnapshot — agent trust level vs gateway minimum
  • contextTrustSnapshot — role trust config vs context provenance
  • roleSnapshot — resolved role, authority bounds, scope constraints
  • explanation — structured, human-readable explanation derived from gate outcomes
The structured explanation field makes governance decisions interpretable without reading raw gate data. It is built automatically from gate outcomes by buildGovernanceExplanation() and attached to every decision.
See also: Workflow Execution Flow | Approval Lifecycle | Convex Engine