AI Safety · Human Oversight

The safety layer is you

We let AI agents write the code and quietly assumed the human approving the merge was the backstop. Someone finally measured that backstop. It caught a sabotaging agent 6% of the time. The catch rate turns out to be the smaller half of the problem.

June 2026 / Anuj Sadani | Tech / 12 min read

The backstop is you

We put agents in the loop to write the code and the tests. The safety argument for letting them do it was always the same one, usually unspoken: a human reviews the change and approves it before anything merges. The human is the control. Pull that assumption out and most of the case for handing production code to an agent gets a lot thinner.

So the control is worth pricing. How often does a competent developer, watching an agent work, actually catch that agent doing something it shouldn't? Until recently the honest answer was that nobody had measured it at scale. Now somebody has, in the closest thing to a realistic setting I've seen: real developers, real frontier models, real multi-hour sessions with a CI pipeline and merge requests.

The setup is deliberately mundane. Over 100 developers each spend five hours building a small e-commerce app in Python with one of four frontier coding agents, working through five CI-gated subtasks the way they'd work through tickets. The only thing they don't know is that the agent is carrying a second objective: quietly exfiltrate the app's user data to an outside address while completing every request it's given. The question is whether the human notices before the code ships.

The answer is the rest of this piece. It is not flattering to the assumption we've been building on.

A 6% catch rate, and why it's the ceiling

Across the sessions with no monitoring help, 94% of developers (83 of 88) shipped the sabotage. They merged code that was actively stealing user data, and they did it after reviewing and approving it. Six percent caught it.

It gets worse where it matters most. Against the strongest agents the catch rate rounds to nothing: Claude-Opus-4.6 succeeded around 95% of the time, GPT-5.4 around 94%, Gemini-3.1-Pro 100%. The one model that did worse, MiniMax-M2.7 at 82%, wasn't beaten by sharper humans. It leaked its own intent into messages the developer could see, and that's what got it caught. As models get better at staying quiet, that 82% drifts up toward the others. The competence of the agent and the detectability of its sabotage move in opposite directions.

Agent Got it shipped What the number means
Gemini-3.1-Pro 100% Took a direct sabotage instruction and was never caught, with or without task hints
Claude-Opus-4.6 ~95% Refused the direct prompt; complied once exfiltration was reframed as "data migration"
GPT-5.4 ~94% Same story: refused the direct ask, executed under the disguised framing
MiniMax-M2.7 82% "Lower" only because it leaked intent the developer could see, not because humans reviewed better
Pooled, no monitor 94% 83 of 88 sessions ended with working data-exfiltration code merged

Here's the part I'd attach an asterisk to before anyone files 94% under "developers are bad at this." These weren't random developers. 86% had security backgrounds and 70% had more than three years of experience, screened on questions about hallucinations and web vulnerabilities. This was close to a best-case audience for catching a problem like this.

And it was close to a best-case problem. One attack class, data exfiltration, with a clean reproducible signature. A five-hour window, not five months. Participants who didn't even know sabotage was on the table, so nobody walked in primed to look for it. Push any of those toward what production actually looks like, a noisier attack, a longer horizon, less security expertise, and the catch rate falls, it doesn't rise. So I read 6% as the ceiling on how often we catch this, not the floor. That reframes the whole conversation about whether human review is a sufficient control. It isn't.

It isn't carelessness

The easy explanation is that people were lazy. The data doesn't support it. In the condition where a monitor flagged the sabotage correctly and the developer still shipped it, the failures sort into three recurring shapes, and only one of them looks anything like inattention.

Three ways a developer ships it anyway
  • 1
    The review never happened (67%). The flag fired, the developer clicked through it, the code went in. "I was being very hands-off and letting Claude do everything for me even though I saw the alert." Attention was spent on getting CI green, and the alert read as one more permission dialog between them and a passing build. The failure happened before anyone looked at the code.
  • 2
    The cover story held (22%). Here the developer did look, read the agent's explanation, and judged the flagged code legitimate. One agent called a data-exfiltration function "real-time internal telemetry." Another defended an external URL as the clean way to separate internal services from outside endpoints. A developer who questioned it accepted the answer and moved on. Telling a real engineering rationale from a fluent fake is genuinely hard without context the reviewer often doesn't have.
  • 3
    The trust was already spent (11%). "My decision to allow was largely based on trust built from my daily experience with Claude Code." The developer didn't weigh the alert against the diff. They weighed it against months of the tool being helpful, and the tool won. No alert text overrides that in the moment.

The cleanest tell that this isn't a skill problem is in who caught it. Self-reported code-review confidence did not separate the developers who detected the sabotage from those who missed it. The thing that did separate them was lower baseline trust in AI coding agents going in. The people who caught it weren't more capable reviewers. They were more skeptical ones. That distinction runs through everything below.

A monitor helps, and still leaves the gap open

The obvious response is to put a second model on watch. Wire an LLM monitor into the tool calls, have it flag suspicious actions before they execute, and let it warn the developer. The study did exactly that, and it works, partway: sabotage success drops from 94% to 63%. That's a real reduction and I don't want to wave it off.

The arithmetic of the residual is the interesting part. The monitor caught 84% of the sabotage attempts, which is a respectable detector. But of the times it correctly flagged malicious code, developers approved it anyway in 56% of cases. So roughly half of all detected sabotage still shipped. The detector wasn't the bottleneck. The human reading its output was.

Where it leaks

The monitor was tuned to stay quiet until the most dangerous moment and then fire. It fired. Developers read it like this: "The popup felt more like a warning than an urgent alert. After reading the message, I didn't dwell on it too much and just proceeded." If the single highest-stakes alert gets dismissed, a noisier monitor produces more dismissals, not more catches.

The developers in the study knew this about themselves. Asked what they'd actually want, only 9% wanted the flag-only design they'd been given. 70% wanted the monitor to propose a fix and wait for approval, and another 19% wanted it to just remove the malicious code and tell them after. Read that honestly: the people doing the reviewing want the human pulled further out of the critical path, because they don't trust themselves to act on a flag under deadline. That's not a tooling gap a better popup closes.

The attack surface is the context, not the model

This is the part the headline number buries, and it's where I think the real exposure lives. To get the sabotage to happen at all, the researchers had to install it. Claude-Opus-4.6 and GPT-5.4 both refused the straight red-team prompt. They only complied once the data theft was dressed up as a benign "data migration" task. Gemini and MiniMax took the direct instruction, but the two most aligned models would not, until they were tricked.

Read that correctly and it flips the threat model. A frontier coding agent, used normally, is not sitting there waiting to exfiltrate your database. The sabotage is something that gets configured in. And in production, the thing that configures the agent is its context: the system prompt in a tool definition, a third-party agent skill someone dropped into the repo, an MCP server you pointed it at, the planning instructions it loads. The model isn't the enemy. The untrusted thing you loaded into its context window is.

We already have the proof of concept for the delivery mechanism, and I've written about both halves of it. A hijacked PyPI package can ship malicious code to millions of AI developers in minutes. MCP treats a configuration string as a shell command by design. Neither needs the model to be misaligned. They need one untrusted component in the agent's setup, and the study tells you what happens after that: the agent pursues the hidden goal competently and quietly, for as long as the session runs.

The uncomfortable corollary

Once the disguised objective was accepted, alignment did nothing further to protect the developer. Claude-Opus-4.6 held the hidden goal across the full five hours and kept holding it even when participants questioned the suspicious behavior directly. The safety training lives at the entry point, where the model decides whether to take the instruction. Past that gate, you're on your own. So the gate, your context window, is the thing to defend.

Trust is the vulnerability that grows

Now the finding I keep coming back to. Over the five hours, while the agent was actively building an exfiltration channel, the developers' trust in it went up (+0.19). It only collapsed afterward, at debrief, when they were told what had happened, falling well below where they started. During the work itself, the hidden behavior moved their trust the wrong way.

The mechanism is simple and a little bleak. People used the visible signals as trust proxies. The tests passed, the code was coherent, the agent was responsive. All true. None of those signals had anything to do with the part that was stealing data, and developers had no habit of reading the part that did. The honest signals built confidence while the dishonest one rode along underneath.

Stretch that past five hours, which is the only setting that matters. Real agent deployments run for months, and they're explicitly designed to earn trust through a long string of successful tasks. The developer who's hardest to fool in week one is the same developer whose skepticism has been sanded down by month six of the tool being genuinely useful. The one trait that predicted catching the sabotage, lower baseline trust, is exactly the trait that productive daily use is built to erode.

What this means for long-running agents

The detectors in the study had pre-study trust of 3.18 on a 5-point scale; the people who missed it sat at 3.56. That third of a point of extra skepticism was worth more than any amount of security credentials. No monitor I know of has a mechanism for keeping that skepticism intact as the collaborative history piles up. We're shipping the opposite: more autonomy and more accumulated goodwill over time.

The arms race we're not pricing in

The sensible recommendations are the ones the developers themselves asked for: stack the monitors, and move from flag-only to recommend-and-wait. 78% wanted an LLM monitor, 67% wanted static analysis, 63% wanted a network-level view of outbound requests, and most wanted two or three together so a single alert is harder to dismiss as noise. I agree with all of it. I just don't think it's the end state, and the study quietly shows why.

Given an explicit objective, Gemini and MiniMax didn't run a fixed script. They adapted their sabotage across the session based on how the interaction was going, picking quieter methods when an approach drew scrutiny. The sabotage is a goal with flexible execution, not a plan. That changes what an interventionist monitor is up against.

A recommend-and-wait monitor moves the target. The question for a capable planning agent stops being "how do I avoid detection" and becomes "how do I get the monitor to recommend approval." Cover stories stop being the fallback and become the main attack. The malicious change arrives spread across several small, individually-reasonable commits instead of one suspicious diff. The fight shifts from beating a detector to social-engineering a human through the detector's own words, and the study's failure modes already tell you the human loses that one more than half the time. We need monitor evaluations run against agents optimized to talk past the monitor, not just agents told to misbehave with no instructions to evade.

What I actually do

None of this argues for not using coding agents. I use them every day. It argues for putting the scrutiny where the evidence says the exposure is, which is not where the default workflow puts it. The four habits I keep:

The frame to leave on

The backstop for AI coding agents was never code-review tooling. It was a human holding calibrated distrust over a collaborator they couldn't fully audit. We now have a measurement of how well that backstop works against a capable agent, and the number is 6%.

Better monitors are worth building, and stacking them with static analysis and network visibility will help. But the monitor reaches the code at the moment it executes. It doesn't reach the two things that actually decided the outcome: the untrusted context that turned a helpful agent into a hostile one, and the accumulated trust that made a developer wave off the alert the monitor correctly raised. Those are the surfaces to defend, and daily productive use erodes the second one on its own.

So the uncomfortable version, stated plainly. The safety layer for the code your agents write is you. Right now you catch six percent, the thing that helps most is staying a little suspicious, and everything about how we deploy these tools is designed to talk you out of it.