BlogEngineering

ENGINEERING

Approval is a boundary, not a checkbox

A checkbox records that someone consented. A boundary is a limit the system cannot cross whatever was clicked. Most tools ship one and describe the other.

SAGARISEngineering9 min
Approval is a boundary, not a checkbox

Every AI product now ships an approval screen. A modal, a summary of what the agent proposes to do, a button. You read it, you click, the thing happens. The screen is the whole reassurance: a human was in the loop.

Ask a different question about that screen and it stops being reassuring. Not "what happens when I click yes", which is obvious, but "what happens to this action if the screen is never rendered". If the answer is that the action proceeds anyway, or that it cannot arrive by any other route so the question is silly, you are looking at a checkbox and not a boundary, and the difference is the whole subject of this piece.

A checkbox records that a human consented. A boundary is a limit the system cannot cross regardless of what anyone consented to. They are both useful. They are not substitutes, and the failure mode is always the same direction: a checkbox is shipped, a boundary is described.

The strongest boundary is one nobody can approve past

The clearest example we have is the surface external AI assistants see when they connect to us over MCP.

The obvious way to make that surface read-only is a list. Enumerate the safe tools, do not add the dangerous ones, and put an approval prompt in front of anything that writes. That is a checkbox: it works exactly as long as everybody who edits the list remembers what the list is for.

The tool surface is instead computed. It takes the public API operation census, filters it to a single read-only HTTP method, and builds tools from what survives. The consequence is stated in the file's own header: a mutating operation can never appear as a tool, whatever gets added to the census. Nobody has to remember. There is no approval flow for a write over MCP because there is no write tool to approve, and a new one cannot be introduced by anyone editing the wrong file.

The Brain view tools are held by a different mechanism with the same shape: they are bound to a closed union by an exhaustive mapping, so adding a read view fails the build until somebody deliberately describes it, and removing one fails the build until somebody deliberately drops it. Exposure becomes a compile-time decision rather than a default.

Now the crack, because a boundary claim is worth nothing unless you publish where it stops being structural. That operation census is a hand-typed array. The test that guards it binds the specification document to the array in both directions, which is real, and it never reads the route files from disk, which means the last link in an otherwise derived chain is typed by a person. The filter is structural. The population it filters is not. That is the honest bound, and it tells you exactly which edit could still hurt us.

The floor that does not ask who approved

The second shape is a limit that survives the most permissive setting the product offers.

Our auto-execution policy takes an action and an autonomy level and returns one of three verdicts: auto, approval required, or blocked, each with a reason and, where a human is needed, who has to sign off. The levels run from manual, where nothing runs unattended, up to autonomous.

At every level, including autonomous, one rule holds: a critical action that is irreversible and has an external side effect can never auto-execute. It is not a policy the operator configures. It is a branch in the function, and turning autonomy all the way up does not reach it.

Underneath that sits a smaller guard that I find more instructive. Before any level logic runs at all, the policy checks that the action's metadata is coherent: a risk tier it recognises, and reversible and external-side-effect flags that are actually booleans. Anything else is blocked outright as malformed. That is a boundary against a category of failure a checkbox cannot see, because a hallucinated or smuggled action with undefined risk fields looks perfectly approvable on a screen. It has a name, it has parameters, and a tired reviewer would click yes.

What an approval actually proves, measured

There is a mechanism above the policy that we built specifically because approvals are weak evidence.

The earned-autonomy ladder computes what autonomy level a track record deserves, rather than accepting the one an operator picked. It reads two independent signals, and a rung requires both: how often a human approved what the agent proposed, and how often an executed action landed a good outcome. The reason for the second is written into the field comment. Without an outcome bar, a record of fifty approvals and one execution would clear the top rung. That would be autonomy earned on approvals rather than on results, which is a precise description of what rubber-stamping looks like in a database.

The ladder is not generally available yet, and it is worth being exact about what that means. Turning it on is tighten-only: the earned level is clamped to the operator's static ceiling, so enabling it can only make a workspace more restrictive. Raising a workspace above its static level needs a second global switch and that specific workspace on an allowlist, deliberately split so one environment variable cannot flip everyone into raise mode. Any error reading the track record fails closed to manual. And neither mode touches the floor, because the resolved level is only ever handed to the same policy function that enforces it.

Two honest labels. The ladder is built but not generally available yet. And the level the policy consumes today is the static one an operator set.

Where a checkbox is the right instrument

None of this is an argument against approval screens. It is an argument about what they are for.

A checkbox belongs where the decision is genuinely a judgement the system cannot make: the human is adding information, not permission. Whether this email should go to this person this week is that kind of decision. Our grounded runtime plans every tool call with a status attached, and any tool that mutates a CRM, sends outreach or books time comes back marked as requiring approval, with a reason, which the assistant then says out loud rather than quietly holding. We publish the same thing as a product boundary: SAGARIS does not send outreach without explicit human approval, and does not write back to your CRM unless write-back is enabled. That write-back path is built but not generally available, and runs as a dry run.

A checkbox stops being the right instrument the moment the volume rises. A person approving one send is supervising. A person approving four hundred is producing a log file. Anything that survives at that volume has to be a limit rather than a decision, which is why the irreversible-and-external case is a floor and not a prompt.

The failure mode this is all aimed at

The dangerous configuration is not a missing approval screen. It is a present one, on a path that was never gated underneath.

It happens three ways. The gate lives in the interface, so an action arriving through an API call, a webhook or a scheduled job never meets it. The gate consults a flag that nothing in the deployed configuration ever sets. Or the approval is recorded after the side effect, which makes it an audit entry wearing a control's clothes.

The cure is architectural, and our outbound gate is the version of it we can point at. It is an in-code choke point that every outbound path consults, and the header says plainly why it exists: the infrastructure-level scheduler pause is invisible to application code and covers only one of many send paths. Anything absent, empty or malformed keeps the gate shut. It is deployed closed, opening it is a deliberate per-environment act, and a contract test pins that closed default across the deploy surfaces so the code and the configuration cannot drift apart.

So the question to put to any system that acts on your behalf is not whether a human approves the action. Everyone will say yes to that, and they will be telling the truth about the screen. Ask what the system refuses to do when nobody is watching, and then ask which line of code refuses it. If the answer to the second question is a screen, you have consent without a constraint, and the two only look alike until the day something arrives by a route the screen does not cover.

SAGARIS

Written by the SAGARIS team.

See the engine run on your pipeline.

Thirty minutes, your own data, no setup.

Book a demo

Get the next one in your inbox.

SAGARIS opens fully in October 2026. Join the waitlist and we will be in touch before launch.

We use these details to contact you about SAGARIS. See our privacy policy.

Book a demo