There is a version of the agentic coding demo that always gets applause. One agent takes a task, writes the code, runs the tests, reviews the diff, and merges it. No handoffs, no waiting, no human in the way. It looks like the future because it is fast and it is whole.

It is also the moment a control that has protected software for decades quietly gets deleted. The agent that produced the work is the same agent that approved it. That is not automation. That is grading your own homework, at machine speed, with nobody else in the room.

The principle being violated has a name, and separation of duties for AI agents is worth taking as seriously as we take it for people.

The oldest control in software

Separation of duties is not a security fad. It is the reason the person who writes a check is not the person who signs it, the reason the developer who writes code is not usually the one who approves the pull request, the reason deploys often need a second pair of eyes. The four eyes principle exists because a single actor, however competent, has a blind spot exactly where they are most confident: in their own work.

The point was never that the producer is untrustworthy. A great engineer still gets their own pull request reviewed. The point is that independent verification catches a class of error that self-review structurally cannot, and that accountability needs to rest with someone other than the person who did the thing. Remove the second actor and you do not just lose a checkpoint. You lose the independence that made the checkpoint mean anything.

Why self-approval fails harder for an agent

You might reasonably ask whether a capable model reviewing its own output is good enough. It is not, and the reasons get worse, not better, as the model gets more capable.

The first problem is shared context. When the same agent, in the same session, with the same understanding of the task, both writes and reviews, the review inherits every assumption the writing made. If the agent misread the requirement, it misread it for both jobs. The review is not a second opinion. It is the same opinion, asked twice.

The second problem is self-assessment bias, which language models exhibit in a specific and dangerous way: a model that is confidently wrong tends to be just as confident when it grades its own answer. The failure and the evaluation of the failure are correlated, because they come from the same place. Self-approval risk is highest precisely on the errors you most need to catch, the ones the model does not know it made.

The third problem is that approval is not really a technical act. It is an accountability act. When something ships and breaks, "the agent that wrote it also approved it" is not an answer anyone can stand behind. There is no independent judgment to point to, because there was none.

What separation actually looks like for agents

Keeping the producer and the approver separate does not mean putting a human in front of every keystroke. It means the thing that approves is genuinely independent of the thing that produced, and has authority the producer does not.

Independence can come in a few forms, and the strong designs use more than one. Deterministic checks are the cheapest and most trustworthy layer, because a test suite or a static analysis does not share the model's blind spots at all. An independent reviewer, a different agent or at least a fresh context with a different job, catches more than a self-review, though it is not a cure, as we will get to. And for the decisions that carry real consequence, the approver is a human, because accountability cannot be delegated to the same system that is asking for approval.

The other half of separation is that the approval has to be real, not a formality the producer can wave through. An approval step that the producing agent can satisfy on its own, or that a human clicks without seeing anything, is separation on the org chart only. This is the same argument as what "a human approved this" should actually mean: the gate has to bind, or it is decoration.

Where the human belongs

Not every step needs a second actor, and pretending otherwise trains everyone to rubber-stamp. The judgment worth reserving is about which actions are consequential enough that an independent, accountable approval is non-negotiable: code entering the product, anything touching production, changes that are hard to reverse. Those are the ones where a producer approving its own work is not a shortcut but a liability. Deciding where that line sits is its own discipline, covered in which decisions must stay human.

The honest limitation

Separation of duties is a control, not a guarantee, and it costs something. It adds a step, and therefore latency, and if you gate the wrong things it adds friction that trains people to stop looking. An independent AI reviewer is better than self-review but it is not a human and it does not fully escape correlated error: two models trained on similar data can share a blind spot, so a second agent reduces the risk rather than removing it. And a human approver only helps if the approval is real, which means the interface has to make seeing easier than clicking.

None of that argues for collapsing the roles. It argues for spending the separation where it matters and making it genuine where you spend it. The failure mode of skipping it is not slowness. It is a confident, well-formatted, self-approved change that no independent party ever actually judged, shipped under the comfortable illusion that it was reviewed.

This is a line we drew deliberately in how Loopsfinity is built: the agent that produces a change is never the actor that approves it, and the approval of what enters the product stays with an accountable human. Not because the agent is careless, but because "it reviewed itself" has never been a sentence you want to say after an incident, and building the separation in from the start is a great deal cheaper than wishing you had.