AI coding

The Approval Queue: Routing and Expiring Decisions

Antonio Evans9 min read

A horizontal pipeline diagram with three lanes labeled by severity.
Key points

Key points

  1. 1Route every approval request by severity tier, and let the tier, not the reviewer, set the timeout and the behavior on expiry.
  2. 2Make timeouts fail closed for anything irreversible: when the clock runs out, the action is denied, the requester is told why, and the item never silently executes.
  3. 3Batch similar low-risk requests into a single grouped item so reviewers spend their attention on the calls that carry blast radius.
  4. 4Instrument approve time, deny time, and expiry rate per tier, because those three numbers show exactly where the queue stalls under load.

The approval queue is a service with a critical path

Most teams describe "human in the loop" as a safety property. Operationally it is a dependency: a queue with arrivals, service times, finite workers and an availability profile. A documented case of blanket approval grew a backlog to fourteen thousand pending items in forty-eight hours against a three-person review team processing about two hundred items an hour, and average approval latency landed at six and a half hours 16. The agent had not failed. The reviewer pool had been sized for design-doc traffic rather than production traffic.

That reframing drives every design decision that follows. If the queue is a service, it needs an owner, a capacity model, timeouts and dashboards. If it is a checkbox, it gets none of those and the first real load turns it into the incident. Human service times have heavy tails too: a routine approval takes thirty seconds and a confusing one takes twenty minutes, and the same reviewer handles both, so queue depth grows faster under load than the mean would suggest 16.

The decision rule that follows is simple. Before you add an approval gate, name the queue owner, the reviewer pool size, the expected arrival rate and the tier timeouts. If you cannot fill those four blanks, you have not designed a gate; you have deferred a capacity problem into production.

Severity tiers: four controls, not one

A single approval flow cannot serve a dashboard tag post and a production data deletion. The practical approach is to sort every action the agent can take into tiers, where the tier decides the control at the gate. The OWASP AI Agent Security Cheat Sheet asks for explicit approval on high-impact or irreversible actions and for action previews before execution, and sorts actions into four risk levels from reads up to irreversible or security-sensitive changes 13.

TierTypical actionsControl at the gateTimeout behaviorWho decides
0 ReadLogs, metrics, kubectl getAllow and recordNonePolicy
1 Low-risk write, reversibleTag a ticket, save a draft, internal dashboard postBatch and allow after batch review, or auto-approve on timeoutApproveOne reviewer, or policy
2 Reversible, wide reachRestart a shared service, rollback on checkout pathHold with blast radius attachedEscalate to named backupOne named approver
3 Irreversible or money-movingSchema migration, data deletion, refund, customer emailHold with a restore planDeny and notify requesterTwo or more named approvers
4 Security-sensitiveIAM change, disabling audit logs, production access from stagingRefuse at the gateRefuseA person outside the agent

This table is a first draft, not a standard. The tiers come from the OWASP-inspired pattern that places reads, reversible narrow-reach, reversible wide-reach, irreversible and security-sensitive actions under different controls 13. Tier assignment is a product decision, written before launch. One database update should not grant indefinite access to every database, and authorizing a specific action, resource, destination, session or time window keeps the grant narrow 12.

Classify calls including their arguments. A restart in a staging namespace and a restart in the payments namespace are different actions and belong in different tiers 13. That argument-level classification is what stops a tier 1 action from being used as a disguise for tier 3 impact.

Choosing the timeout, and what happens when it fires

The timeout is where most designs quietly fail. There are two default failure modes. The graveyard: nothing happens on timeout, items pile up, the agent stalls, and after a few weeks people stop looking at the queue. The global auto-approve: someone tires of the backlog and adds a rule that anything older than twenty-four hours is approved, which means the most dangerous item in the queue, the one nobody felt comfortable approving, now goes through automatically 18.

One timeout per tier does not work either, because a refund and a dashboard update do not deserve the same patience. Start with rough values per action type, for example thirty minutes for time-sensitive customer replies, four working hours for refunds and twenty-four hours for internal changes, then tune them from real data 18. The useful calibration numbers are the median and the ninetieth percentile of actual approval time per type. If the ninetieth percentile is longer than the timeout, the timeout fires on normal days and reviewers learn to ignore it. If the median is only a few seconds, reviewers are probably not reading, which is the more serious problem 18.

The rule for expiry behavior follows from reversibility. The question to ask is how expensive it is to undo the action if the default turns out to be wrong 18:

  • Approve: for internal, reversible, low-impact actions where the cost of doing it is roughly zero.
  • Hold and escalate: for anything that leaves your system or moves money. These never go through on silence; they go to the next named person and keep waiting.
  • Cancel: for actions whose value expires, such as same-day bookings or replies after a customer deadline.
  • Re-plan: for proposals built on data that may now be stale. The item goes back to the agent, which rechecks the facts and files a fresh request.

For irreversible actions the timeout must fail closed: the request is denied, the requester is told why, and the item is not approved by delay. A documented escalation pattern puts it the same way: if the timeout expires before any decision arrives, the workflow unblocks and follows the timeout path, which typically results in rejection or escalation 17. Rejection is a real outcome, not an error path, and it should be logged as a decision.

Data model: eight fields that make expiry work

You cannot enforce a policy you did not store. The minimum useful schema records the tier, how long the item may wait, and what its expiry does. A shape that holds up in practice:

CREATE TABLE approval_item (
  id              TEXT PRIMARY KEY,
  action_type     TEXT NOT NULL,              -- "refund", "customer_email", "dashboard_post"
  severity_tier   INTEGER NOT NULL,           -- 0..4
  requested_by    TEXT NOT NULL,              -- agent identity, not a shared key
  action_args     JSONB NOT NULL,             -- full arguments, including target resource
  blast_radius    TEXT NOT NULL,              -- predicted effect, human readable
  cost_to_undo    TEXT NOT NULL,              -- "zero" | "minutes" | "irreversible"
  created_at      TIMESTAMPTZ NOT NULL,
  expires_at      TIMESTAMPTZ NOT NULL,       -- created_at + tier policy
  on_timeout      TEXT NOT NULL,              -- "approve" | "escalate" | "cancel" | "deny"
  escalate_to     TEXT,
  batch_key       TEXT,                       -- groups similar low-risk items
  status          TEXT NOT NULL,              -- "pending" | "approved" | "denied" | "expired"
  decided_by      TEXT,
  decided_at      TIMESTAMPTZ,
  decision_reason TEXT
);

Four fields carry more weight than the rest. action_args makes tier classification possible, because the target resource is part of the risk. cost_to_undo makes the timeout default checkable rather than a matter of opinion. expires_at is computed at creation from policy, so expiry does not depend on a scheduler that may skip a run. decided_by plus decided_at gives you the audit event SOC 2-style reviews ask for, evidence that access controls were functioning at the time of the action 11.

A rule to add early: any action type not present in the policy table defaults to hold, never to approve 18. New action types arrive constantly as agents gain tools, and an unknown type should wait for a human rather than inherit a permissive default.

Routing rules: who gets the item and what they see

Routing is two problems: which person, and what context. On the person, tier 3 and 4 items need named approvers, and irreversible actions commonly need two or more named approvers while security-sensitive changes are refused at the gate and handled through a change outside the agent 13. A common range for escalation SLAs in regulated environments is fifteen minutes for real-time gates, four hours for batch gates and twenty-four hours for complex review, and below fifteen minutes reviewer fatigue starts to dominate 16. That is a load-bearing constraint: if your product needs sub-minute approvals on consequential actions, you do not have a human gate, you have a rubber stamp.

On the context, a vague "allow this agent?" prompt protects nobody. An approval request should identify the agent, the requesting user, the tool, the target resource, the data involved, the requested permission and the expected result, showing proposed configuration changes, code, privileges or external recipients as applicable 12. In the queue pattern that context commonly comes down to four fields: the action, the justification, the blast radius, and the confidence with an alternative 18. The alternative matters because approve and reject is often too limited; modify and escalate are decision types reviewers actually need 8.

One more routing rule belongs in the gate, not the prompt. An instruction in a system prompt is text the model reads, and a prompt injection can override it; a rule at the gate sits outside the model's reach 13. The pattern of delegating permission is for the agent to pause and ask, and resume only on explicit approval 9. Routing the pause is your job; trusting the model to remember the pause is not a control.

Batching: fewer items, same judgment

Reviewer attention is the scarce resource, and approval fatigue makes oversight meaningless 8. Batching is the tool for low-risk volume. The same batching logic used in creative review applies directly: group related items so reviewers assess them together, apply consistent feedback in one action, and avoid the repetitive per-item loop that creates inconsistency and slows the pipeline 19.

The rule: batch only within a tier and a batch_key. Group tier 1 items that share an action type, target family and argument shape, such as fifty internal dashboard posts from one reporting job or twenty tag updates on tickets in one project. A batch is one decision on the envelope plus the list, and it should expire as a unit. Never batch across tiers, never batch irreversible actions, and never let a batch hide a single item with an unusual argument. If one item in the batch fails the shape check, split it out and route it alone.

A worked example shows the arithmetic. Suppose an agent produces 1,200 tier 1 requests a day at twenty seconds of review each, and 40 tier 2 escalation requests at three minutes each. Unbatched, that is roughly 6.7 hours of reviewer time for tier 1 alone. Batched twenty to one, tier 1 costs about twenty minutes of review time with spot checks, and the 40 escalations get the attention they need. The savings are not cosmetic; they are the difference between a reviewer who reads tier 2 items and a reviewer who clicks through everything.

Instrumentation: the three numbers per tier

The queue needs its own dashboards, separate from agent latency. Without a queue-depth dashboard alongside agent latency, the queue is invisible to the people who control the arrival rate, so they do not throttle, depth grows, and the first notice is a customer complaint 16. Measure per tier, not in aggregate:

  • Approve time: created_at to decided_at for approved items. Track median and ninetieth percentile.
  • Deny time: the same span for denied items. Denials that take longer than approvals usually mean the reviewer is missing context.
  • Expiry rate: expired items divided by created items. A rising rate in tier 2 or 3 means the timeouts are too tight or the reviewers are understaffed.
  • Queue depth and queue age: current pending count and the age of the oldest pending item per tier.
  • Batch size distribution: if batches shrink toward one, reviewers are working item by item and the batching rule is broken.

The most useful chart plots reviewer accuracy as a function of queue depth, queue age, items per hour and time of day; the point where accuracy crosses the agent's own error rate is where the human gate starts making things worse 16. That crossover point is your real capacity limit, and it belongs in the same capacity plan as the agent's throughput.

Two observability notes. First, approval items are events: emit one on creation, one on decision, one on expiry, and include tier, action type and batch key. Second, measure revalidation. When a reviewer approves an item after a long pause, external conditions may have changed, and approvals can go stale if the world moved while the workflow waited 8. Count how often a decision is rejected at resume because the state changed, and that count will tell you whether your timeouts are too long for fast-moving action types.

When the queue itself becomes the critical path

The final decision is whether a gate should exist at all. Approval placement should follow risk, not novelty. Lower-risk reads, summaries and drafts can proceed without individual approval inside established permissions, while sending external communications, deleting data, running generated code, spending money, changing security policy and taking production or safety actions should normally require a human 12. Use telemetry and incident findings to adjust thresholds, and retire a gate once the action is understood and bounded instead of leaving it to absorb reviewer attention forever.

Temporal, the everydaycalculation word missing: Sorry, I dropped a link there.

The principle that keeps this honest: the LLM proposes actions, policy authorizes them 15. The queue is where that authorization becomes a recorded decision with a timer attached. Once your requests, tiers and expiry rules are running through one API, the agent side benefits from a single endpoint for every model that files or resolves them. Quanta Inference (https://quantaintelligence.ai/inference) puts text, image, video, audio and embedding models behind one OpenAI-compatible key, so the reviewer-assist and classification steps in front of the queue use the same integration as the agent that creates the requests.

FAQ

FAQ

What does failing closed mean for an approval timeout?

Failing closed means the safe default wins when no one answers: the request is denied, the requester is told why, and the action does not execute. The alternative, approving on silence, lets the most dangerous pending item go through automatically 18. Reserve auto-approve on timeout for internal, reversible actions where undoing the mistake costs almost nothing.

How many severity tiers should an approval queue have?

Four working tiers cover most systems: reads, low-risk reversible writes, reversible changes with wide reach, and irreversible or security-sensitive actions. The tiers come from splitting actions by risk level and reversibility rather than by team or tool 13. Add a fifth only when a class of action needs a genuinely different control, such as two named approvers.

How do I pick the timeout for each tier?

Start with rough values per action type, then calibrate against the median and ninetieth percentile of actual approval time for that type. A timeout shorter than the ninetieth percentile fires on normal days and trains reviewers to ignore it 18. Common starting points range from thirty minutes for time-sensitive replies to four working hours for refunds and twenty-four hours for internal changes.

When is batching approvals safe?

Batching is safe for similar low-risk items that share an action type, target family and argument shape, because grouping lets reviewers assess them together and apply consistent judgment in one action 19. Never batch across severity tiers, never batch irreversible actions, and split out any item whose arguments look unusual. A batch should expire as a unit so its timeout behavior stays predictable.

Which metrics show that an approval queue is stalling?

Track approve time, deny time and expiry rate per tier, plus queue depth and the age of the oldest pending item. A rising expiry rate in higher tiers points to timeouts that are too tight or reviewers who are understaffed 18. Plot reviewer accuracy against queue depth to find the crossover point where the human gate stops adding value and starts adding delay 16.

Sources

Sources

  1. The Approval Queue That Became Your Critical Path
  2. How to implement runtime policy enforcement for AI agents
  3. What should require human approval when using AI agents?
  4. Approval Timeouts for AI Agents: Defaults by Reversibility
  5. Approval Pattern | Temporal Documentation
  6. Human-in-the-Loop Tool Calling: Approval Gates for AI ...
  7. Human-in-the-Loop AI Agents: Approval Workflows & Best ...
  8. Human in the Loop AI Agents: Approval Workflows That Work
  9. Batch Review & Approval | Admation - Simple.io
  10. How to Prevent Over-Permissioned Agents
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles