Skip to content
Architecture

Human-in-the-Loop That Actually Holds: Write Gates, Blast Radius, and Replay Protection

Most human-in-the-loop is a confirmation dialog. Three properties separate a real approval gate from a checkbox that manufactures consent.

3 min read

Most human-in-the-loop implementations are a confirmation dialog with extra steps. They produce a signature without producing a decision, which is worse than no gate at all — the organization now believes a control exists.

The phrase appears on every enterprise AI slide. It very rarely survives contact with the code, because a gate that genuinely constrains an agent is harder to build than one that merely interrupts it. Three properties separate the two.

From the standard

“a framework to better manage risks to individuals, organizations, and society associated with artificial intelligence (AI)”
NIST, on the AI Risk Management Framework — nist.gov

Property one: the change is shown, not described

A gate that says "the agent would like to update your CRM records — proceed?" is asking the reviewer to approve a category of action, not an action. There is no information in that prompt on which a person could reasonably decline.

What a reviewer needs is the diff: which fields change, from what to what, across how many records, and which specific records those are. That is blast radius, and rendering it is the difference between review and ceremony. Twelve named opportunity records with before-and-after values is reviewable. "Your CRM" is not.

The rejection test

Look at your approval logs. If the rejection rate is zero across thousands of approvals, the gate is not working — either the reviewer cannot see enough to object, or approval has become a reflex. A functioning gate produces rejections, and the rejections are where you learn what the agent is getting wrong.

Property two: the approval cannot be replayed

This is the property most implementations lack, and the one that turns a gate into a genuine control. If an approval is a boolean — approved, therefore execute — then it can be applied to whatever the plan happens to be at execution time, which need not be the plan the reviewer saw.

distributed trace · one governed run
router84ms
tokenize102ms
discover240ms
aggregate310ms
policy check61ms
manifest check38ms
human gate4m 12s
crm.update155ms
machine waiting on a person the write
The machine work is milliseconds. The decision is minutes. That asymmetry is the gate being real.

The gap is usually seconds and entirely benign. Occasionally it is not: a retry regenerates the plan, a concurrent session mutates shared state, or a connector's tool definition is updated between approval and dispatch. In each case an approval granted against one action authorises a different one.

The fix is to bind the approval to an optimistic-concurrency version token and to the tool schema it was granted against. At dispatch, both are re-checked. A mismatch refuses the write and returns to the gate rather than proceeding. This costs one comparison and closes the entire class.

Property three: escalation is a real outcome

Approve and reject are not sufficient, because they assume the person at the gate is the right person to decide. Often they are not — the action is legitimate but touches a system they do not own, or the amount exceeds what they are comfortable authorising.

Given only two buttons, that reviewer approves. Rejecting discards work someone else asked for, and there is no mechanism to say "not my call". A binary gate quietly converts uncertainty into approval, which is precisely the failure mode the gate exists to prevent.

Escalation routes the decision to someone with the authority or context to make it, keeps the work alive, and records that the first reviewer declined to decide — which is itself useful signal about where the permission model is wrong.

Where the gate belongs

In the execution path, not beside it. A gate implemented in the user interface is advisory: anything that calls the underlying tool directly — a retry, a scheduled run, a second client — bypasses it entirely. The check has to live at the point of dispatch, where every caller passes through regardless of origin.

This is why retrofitting a real gate late is expensive. Approval state has to be threaded through every tool call, and a system that was not built with it has no place to put the token.

Reads should stay free

A gate on every action trains reviewers to click through, which destroys the control you were trying to build. The asymmetry is the point: reads are reversible and cheap, so they run freely. Writes are not, so they stop — every time, without exception, because an exception list is where the incident eventually comes from.

One mechanism, every surface

The same gate should serve every workflow: the review queue before a test is written to an ALM tool, the write gate before a CRM record is updated, the diff before a dashboard version is overwritten. One implementation means a security review of one workflow carries over to the rest — and it means the audit trail has a single shape.

Axionalytics

Production agentic AI for enterprise engineering, data, and revenue teams.

Keep reading

Facing this in your own environment?

Forty-five minutes with the engineers who build these systems. Bring the constraint that has been blocking you — you will leave with an architecture opinion whether or not you work with us.