Exception queue before happy-path automation
A reference build for the moment an agent cannot safely decide. Instead of hiding uncertainty behind a retry or a generic “needs review” flag, the system turns the exception into owned operational work: classified, assigned, recoverable, auditable, and measurable.
The problem
Teams usually automate the happy path first. Production starts where that flow stops: the input is ambiguous, policy has an unseen boundary, a downstream system disagrees, or the agent has enough evidence to propose an action but not enough authority to take it safely.
The common response is to treat the exception as an implementation detail—retry it, drop it into a dead-letter queue, or ask a human to “take a look.” That preserves the illusion of automation while making unresolved work invisible. No one owns the next action, and the original context is often lost before a reviewer sees it.
The constraints
Every exception must retain the triggering request, relevant evidence, proposed action, risk and priority, policy version, current owner, and a clear next step. Reviewers need enough context to decide without reconstructing the run from logs.
The system also has to be safe under delay. Work may be reassigned, escalated, paused for evidence, resolved, or reopened after new evidence arrives. Each transition must remain visible, and stale approval must not silently authorize a changed request.
The decisions
Four decisions make the operating contract concrete.
The exception is a work item, not an error. ExceptionRecord stores request identity, evidence, proposed action, risk, priority, owner, and policy version. Opening an item emits an opened event.
Escalation is an explicit policy action. An overdue item moves to a named next owner and emits an escalated event. The owner change is not an overwritten field with no explanation.
Recovery is a typed state machine. Review can request evidence, approve, correct, reject, resolve, or reopen. Invalid state edges raise InvalidTransition instead of allowing an impossible workflow.
Metrics measure unresolved work. The queue derives total, open, resolved, and recurring-reason counts. A fluent response that creates a growing unresolved queue is not success.
The outcome
The build answers the questions a production agent must answer when it cannot safely decide: what is unresolved, why was it stopped, who owns the next decision, and what happens after that decision. The append-only JSONL ledger records every open, assignment, escalation, and state transition when configured.
The honest caveat: this is a reference build, not a deployed operations service with production traffic. It has no claims about throughput, reviewer productivity, authentication, distributed locking, or retention guarantees. It proves the queue and workflow contract; those deployment concerns remain explicit next decisions.
What is implemented
The public repository at github.com/Dhristhi/agent-exception-queue contains the queue core, typed states, policy-driven overdue escalation, append-only ledger writer, derived metrics, four self-checking scenario scripts, and behavioral tests. It runs without a model, API key, database server, or external service.
git clone https://github.com/Dhristhi/agent-exception-queue
cd agent-exception-queue
uv sync --extra dev
uv run pytest -q
uv run python -m exception_queue.demo
for s in scripts/scenario_*.py; do uv run python "$s"; done
The verified demo covers structured handoff, escalation after an approval deadline, recovery after new evidence, and metrics that keep unresolved work visible.