The production problem
A lot of teams discuss safety after an incident and discover the same pattern: the control that fired was post-hoc. The action already ran.
Pre-dispatch governance for AI agents exists to move the decision boundary earlier, before side effects. If the decision runs after execution, you can quarantine output, but you cannot un-run a command.
What top sources cover vs miss
| Source | Strong coverage | Missing piece |
|---|---|---|
| OpenAI: Safety in Building Agents | Layered guardrails, tool risk ratings, and human escalation for high-risk actions. | No queue-level contract for when a request is denied vs persisted vs dispatched in a multi-service control plane. |
| LangChain Guardrails | Middleware for before-agent and after-agent checks, plus PII and human-in-the-loop patterns. | No centralized out-of-process scheduler/gateway sequencing that proves denied actions never reach worker queues. |
| AEGIS (arXiv 2603.12621) | Direct statement that post-execution observability cannot stop side effects; reports 8.3ms median latency with pre-execution interception. | Research prototype; does not specify production gateway/scheduler fail-mode defaults and operator runbook design. |
Timing Model for Pre-Dispatch Governance for AI Agents
| Layer | Decision point | Stops side effects? | Primary strength | Primary blind spot |
|---|---|---|---|---|
| Pre-dispatch governance | Before persistence/publish or before scheduler dispatch | Yes | Blocks unsafe actions before any tool executes. | Depends on accurate metadata and policy quality. |
| Post-hoc output safety | After worker execution, before final release | No | Catches secret leakage/unsafe output content that input checks could not predict. | Cannot reverse external side effects already executed by tools. |
| Observability-only monitoring | After events are emitted | No | Great for forensics and trend analysis. | Detection without prevention. |
Pre-Dispatch Governance for AI Agents in Cordum
In current Cordum docs, input policy is evaluated at gateway submit time and scheduler dispatch time. Output policy is evaluated on successful results before final release.
Submit-time policy (pre-dispatch)
// Gateway submit-time check (before state persistence)
decision := evaluateSubmitPolicy(...)
switch {
case decision.Denied:
// HTTP 403 / gRPC PermissionDenied
// no Redis state, no bus publish
case decision.Throttled:
// HTTP 429 / gRPC ResourceExhausted
case decision.ApprovalRequired:
// state = APPROVAL, persist request/context
// no bus publish until approve endpoint
default:
// persist + publish
}
// Unavailable safety kernel: POLICY_CHECK_FAIL_MODE=open|closedDispatch + output policy behavior
// Scheduler input fail mode
engine.WithInputFailMode(os.Getenv("POLICY_CHECK_FAIL_MODE"))
// closed (default): deny/requeue when kernel is unavailable
// open: allow through with warning
// Output safety (post-execution)
checked, err := e.outputSafety.CheckOutputMeta(res, req)
// QUARANTINE -> OUTPUT_QUARANTINED + DLQ reason output_quarantined
// REDACT -> success state with redacted pointer when available
// checker error -> fail-open on hot path (record skipped metric)This is the critical split: pre-dispatch decides whether execution happens, post-hoc decides whether results are releasable.
Limitations and tradeoffs
- Pre-dispatch checks add latency and can block legitimate actions when rules are too broad.
- Output safety is required but does not replace prevention; it only evaluates what was produced after execution.
- In current scheduler behavior, output safety checker failures are fail-open on the hot path, so monitor `cordum_output_policy_skipped_total` carefully.
- Fail-open vs fail-closed is not a philosophical argument. It is a per-stage operational decision that should be explicit in environment config.
Validation runbook
# 1) Start with fail-closed
export POLICY_CHECK_FAIL_MODE=closed
# 2) Submit a job
API=http://127.0.0.1:8081
KEY=<api-key>
JOB_ID=$(curl -sS -X POST "$API/api/v1/jobs" -H "Content-Type: application/json" -H "X-API-Key: $KEY" -H "X-Tenant-ID: default" -d '{"topic":"job.demo","prompt":"run health check"}' | jq -r '.job_id')
curl -sS "$API/api/v1/jobs/$JOB_ID" -H "X-API-Key: $KEY" -H "X-Tenant-ID: default" | jq .
# 3) Inspect pipeline state and safety metadata
curl -sS "$API/api/v1/status" -H "X-API-Key: $KEY" -H "X-Tenant-ID: default" | jq '.pipeline'
# 4) Check output-safety counters
curl -sS http://127.0.0.1:9090/metrics | rg "cordum_output_policy_"Run the same job through fail-closed and fail-open configurations in staging. Compare prevention rate, false positives, and skipped output checks.
FAQ
Frequently Asked Questions
Is post-hoc monitoring enough for AI agent safety?
Why use pre-dispatch governance for AI agents and not only worker-side checks?
Where does Cordum apply pre-dispatch checks?
Does pre-dispatch replace output safety?
Next step
Pick one high-risk agent action this week, enforce fail-closed pre-dispatch policy for it, and measure incident rate plus approval latency for seven days.
- Start with pre-dispatch governance patterns.
- Then review prompt-injection-resistant control patterns.
- Validate evidence quality using the audit trails compliance guide.