DEV Community

SidClaw
SidClaw

Posted on

Human-in-the-loop is mostly a UI problem, and almost nobody builds it like one

Every agent governance pitch has the same three words in it: human in the loop. The agent proposes an action, a person approves or denies it, catastrophe averted. It sounds like a solved problem.

The intercept part is genuinely easy. You pause the tool call, drop it on a queue, fire a webhook, wait for a response. That's a couple hundred lines. We've written it, plenty of other tools have written it, and it's not where the difficulty lives.

The hard part is making the human's decision an actual decision.

The context-free approve button

Picture the approval prompt the way most systems ship it:

Agent support-bot wants to call a tool. Approve / Deny.

What does the reviewer do with that? They approve it. Every time. Not because they're lazy, but because they have no basis to do anything else. There is nothing in front of them to deny. By the third one they've stopped reading the tool name.

Now you have a checkbox that satisfies the literal phrase "human in the loop" and delivers zero actual oversight. FINRA's 2026 report has a name for the thing this is supposed to prevent: the "set-it-and-forget-it mindset." A context-free approve button is set-it-and-forget-it with an extra click and a worse audit trail, because now there's a person's name attached to a decision they never really made.

What a reviewer needs to actually decide

If you want the human to sometimes click deny (and if they never do, you don't have oversight, you have latency) they need enough in front of them to have a reason. In practice that means:

  • Which agent, acting for whom. support-bot on behalf of which customer, under whose account, with which permissions.
  • The concrete action, fully expanded. Not "send an email." The actual recipient, subject, and body. Not "run a query." The actual SQL. The thing that is about to happen, not a category label for it.
  • The agent's own stated reasoning. Why it decided this was the move. This is the single most useful field and the one most systems drop, because it's the difference between judging the action and judging the intent behind it.
  • Whether it's reversible. Can this be undone if the approval turns out wrong, or is it a one-way door: money sent, email delivered, row deleted. Reversibility should change how hard the human looks.
  • Why this one surfaced. Which policy triggered the hold, and what the risk classification was. The reviewer needs to know why this action is in front of them and the last forty weren't. Otherwise every hold looks equally arbitrary and gets the same reflexive approve.
  • What happens if they do nothing. The default on timeout. If the answer is "it goes through," you've built a system that fails toward the action, and a reviewer who steps out for lunch is now an approval. The default has to be deny.

None of that is a policy-engine feature. It's a rendering problem. It's what the reviewer sees in the half-second before they click.

The opposite failure is also rubber-stamping

Here's the trap on the other side. Once you accept that context matters, the instinct is to show more of it and hold more actions. Govern everything, attach three paragraphs to each hold, route it all to a human.

That's rubber-stamping too. Just from the other direction. Hold two hundred actions a day and the reviewer stops reading by the twentieth. Alert fatigue isn't a softer failure than the context-free button. It's the same failure, and it arrives faster, because the human feels busy the entire time they're not actually reviewing anything.

So the real target is narrow: a small number of high-signal holds, each carrying enough context to decide in a few seconds, defaulting to deny when ignored. Getting that number small is the policy engine's job, deciding which small fraction of actions are worth a human's attention. Making each of those decisions real is the UI's job. Both halves have to be good, and most tooling, ours included on plenty of days, over-invests in the first and under-invests in the second.

What this doesn't solve

"Enough context" isn't a fixed target. A wire-transfer reviewer and an infra-deploy reviewer need different things in front of them, and there's no universal template that serves both. And get it wrong in the generous direction and you hit a second problem: the payload you show the human to help them decide is sometimes the exact sensitive data you were trying to govern in the first place. The approval surface becomes its own data-handling question. There's no version of this where you show the reviewer nothing and still expect a real decision.

The easy sentence is "human in the loop." The hard question is what the human sees in the half-second before they click, and whether it's ever enough to make them click deny. If your approval button has never once been clicked deny in production, you didn't build oversight. You built a slower way to say yes.

Repo, if you want to see how we're currently getting this right and wrong: github.com/sidclawhq/platform

Top comments (0)