<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Warwick McIntosh</title>
    <description>The latest articles on DEV Community by Warwick McIntosh (@warwickmcintosh).</description>
    <link>https://dev.to/warwickmcintosh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3849229%2F8ce3f82e-6e27-4637-8666-731eb567bf6d.png</url>
      <title>DEV Community: Warwick McIntosh</title>
      <link>https://dev.to/warwickmcintosh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/warwickmcintosh"/>
    <language>en</language>
    <item>
      <title>Can AI Teach Itself, or Does It Just Eat Itself?</title>
      <dc:creator>Warwick McIntosh</dc:creator>
      <pubDate>Wed, 24 Jun 2026 06:02:17 +0000</pubDate>
      <link>https://dev.to/warwickmcintosh/can-ai-teach-itself-or-does-it-just-eat-itself-3hbi</link>
      <guid>https://dev.to/warwickmcintosh/can-ai-teach-itself-or-does-it-just-eat-itself-3hbi</guid>
      <description>&lt;p&gt;&lt;em&gt;Models that learn from their own answers can compound into something smarter or quietly rot. The difference comes down to one thing, and a cheap checker tips it the wrong way.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Train a model on its own output and one of two things happens. It gets better, the way a student improves by grinding practice problems and checking the answers. Or it gets worse, slowly, feeding on its own mistakes until the distribution caves in. Both happen, both are common, and the interesting part is the line between them.&lt;/p&gt;

&lt;p&gt;We went looking for that line, and the first thing it told us was uncomfortable. A weak checker is not a small help. It is a net harm. In our runs, a verifier that was right only half the time did not just fail to improve the model. It dragged the model below where it started. Some signal is not better than none. Below a certain quality, the signal is the problem.&lt;/p&gt;

&lt;p&gt;This is a field guide to that line: when a self-training loop compounds, when it collapses, and the failure modes that stay hidden in your average-accuracy number until it is too late. Fair warning, it goes deep. We built a controlled experiment, ran it, and every chart here is our own data rather than a redrawn version of someone else's. The payoff is a rule you can act on, but the point of the piece is to show you why it holds, not just to assert it, so settle in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The half of the story everyone tells
&lt;/h2&gt;

&lt;p&gt;You have heard the scary half. Train models on model-generated data and they degrade. The tails of the distribution thin out, the rare cases vanish, variance shrinks, and after a few rounds you have a confident, fluent, narrower model that has quietly forgotten things its parent knew. "AI eats itself" makes a good headline, and it does happen.&lt;/p&gt;

&lt;p&gt;The half nobody puts next to it is that self-training also works, constantly, in production. Bootstrapping a model on its own correct solutions, filtering generations through a reward signal, having a model improve by checking its own work against a test suite. These are not exotic. They are how a lot of current capability gets built. The same basic move, a model learning from its own output, sometimes makes it stronger and sometimes rots it.&lt;/p&gt;

&lt;p&gt;Both being true is not a contradiction. It means there is a variable doing the deciding, and the doom stories leave it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The variable is information, not effort
&lt;/h2&gt;

&lt;p&gt;Here is the way to think about it that makes both outcomes obvious in hindsight.&lt;/p&gt;

&lt;p&gt;A model trained on its own output cannot, by itself, learn anything it did not already contain. Generating more of your own answers and training on them is a closed loop. If nothing enters that loop from outside, you are reshuffling what you already had, and every imperfect step is slightly lossy, so the loop drifts downhill. That is collapse.&lt;/p&gt;

&lt;p&gt;A loop compounds only when something enters it from outside the model's current distribution. There are three ways to let information in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;verifier&lt;/strong&gt;, a checker that can tell a correct answer from a wrong one, so you keep your good outputs and drop your bad ones&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;real-data anchor&lt;/strong&gt;, some genuine examples kept in the training mix, that the model cannot talk itself out of&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;environment feedback&lt;/strong&gt;, where the world tells you whether the action worked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These look like different techniques. They are the same thing: a channel that carries information the model does not already have. And the reach of the loop is capped by how much real information that channel actually carries. We will call that its fidelity. The whole "compound versus collapse" question reduces to one thing, whether your channel lets in enough real signal to outrun the lossiness of the loop.&lt;/p&gt;

&lt;p&gt;I think this is the most useful lens on self-training there is, because it makes both outcomes obvious instead of surprising, and it tells you exactly the experiment to run. Hold everything fixed, change only the channel, and watch what happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;We trained a small transformer from scratch to do two-digit arithmetic, addition, subtraction and multiplication. Small and from scratch matters: arithmetic has a free, perfect ground truth, so we can measure quality exactly and we are not smuggling in knowledge from some pretraining corpus. The model is the only thing learning, and we control its whole world.&lt;/p&gt;

&lt;p&gt;We get it to a starting accuracy of about 80%, then run self-training loops that differ in one thing only, the information channel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;verifier(q)&lt;/strong&gt;: keep the model's own answers that a verifier marks correct, where the verifier is right a fraction &lt;code&gt;q&lt;/code&gt; of the time. &lt;code&gt;q = 1.0&lt;/code&gt; is a perfect checker; &lt;code&gt;q = 0.5&lt;/code&gt; is a coin flip.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;anchor(r)&lt;/strong&gt;: no verifier at all, but mix a fraction &lt;code&gt;r&lt;/code&gt; of real, correct examples into each round.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;self-judge&lt;/strong&gt;: the model decides for itself which of its answers to trust, by majority vote across several tries. No outside truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;replace&lt;/strong&gt;: train on all of its own output, unfiltered, with no real data. The pure closed loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then we just watch accuracy over rounds, and measure one more thing each round: the fraction of the training labels that were actually correct, however that correctness was sourced. That is the channel's measured fidelity.&lt;/p&gt;

&lt;p&gt;The whole thing, the code and the data behind every chart below, is on GitHub, so you can rerun any of it yourself: &lt;a href="https://github.com/Production-Grade/self-training-information-channel" rel="noopener noreferrer"&gt;github.com/Production-Grade/self-training-information-channel&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result one: the source doesn't matter, the fidelity does
&lt;/h2&gt;

&lt;p&gt;Plot final accuracy against measured fidelity and every channel lands on one curve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4fai6typg7wl2kf9wbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4fai6typg7wl2kf9wbg.png" alt="Final accuracy plotted against training-label fidelity. Verifier, real-data anchor, self-judge and the closed loop all fall on one line, so the source of the fidelity does not matter, only its level" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A verifier and a real-data anchor are not two different strategies with two different ceilings. They are interchangeable ways of buying the same thing. A verifier that lets through 90%-correct data and an anchor that produces 90%-correct data land in the same place. The closed loop with no channel sits at the bottom, collapsing. Accuracy tracks fidelity, and it does not care where the fidelity came from.&lt;/p&gt;

&lt;p&gt;You can even read off the exchange rate between the two. In our runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a verifier right 75% of the time bought what roughly &lt;strong&gt;38% real data&lt;/strong&gt; bought&lt;/li&gt;
&lt;li&gt;a verifier right 50% of the time bought what roughly &lt;strong&gt;10% real data&lt;/strong&gt; bought&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the rate is convex, which is the practical surprise hiding in it: a little real data goes a long way. A small anchor of genuine examples does most of the work of a decent verifier, and it never needs you to build the verifier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result two: a weak verifier is worse than nothing
&lt;/h2&gt;

&lt;p&gt;Now the uncomfortable one. Because the channels all sit on a fidelity curve, a low-fidelity channel does not just help less. It can push you below where you started.&lt;/p&gt;

&lt;p&gt;Our model began at about 80%. A perfect verifier compounded it up to around 88% and then plateaued. A 75%-accurate verifier still helped, settling around 83%. But a coin-flip verifier, right half the time, dragged the model down to 78%, below where it started. It would have been better to do nothing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fove0ictj9lt8wdlvss6u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fove0ictj9lt8wdlvss6u.png" alt="Final accuracy after self-training, plotted against verifier quality. A perfect verifier and a 75%-accurate one both improve the model, but a coin-flip verifier drops it below its own starting point" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the thing the "any signal helps" instinct gets wrong. There is a break-even fidelity. Above it, the loop compounds. Below it, the loop is actively corrosive, because you are now training on a set that is barely better than random, and the loop's own lossiness finishes the job. A cheap reward model or a sloppy LLM-as-judge that you reach for because "it is better than nothing" can be the reason your model gets worse. Below break-even, your verifier is not a safety net. It is the hole.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result three: this is what collapse actually looks like
&lt;/h2&gt;

&lt;p&gt;The pure closed loop, training on its own unfiltered output, does not fail all at once. It spirals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyxqljy4x3o5zbi00u9v2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyxqljy4x3o5zbi00u9v2.png" alt="Accuracy over self-training rounds. Channels with a real information source compound or hold steady; the closed loop with no channel spirals downward" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each round, the model generates its training data, that data is slightly worse than the last round's, it trains on the worse data and gets slightly worse, so next round's data is worse again. We watched the fidelity of the self-generated training set fall from 77% to 69% over a handful of rounds, with accuracy sliding alongside it from 78% to 71%. There is no cliff. It is a slow, self-reinforcing decline, which is exactly why it is dangerous: by the time it is obvious, several rounds of it are baked in.&lt;/p&gt;

&lt;p&gt;And it does not take from everywhere evenly. &lt;strong&gt;It eats your hardest cases first.&lt;/strong&gt; When we split the test set into easy and hard problems, the collapsing model held onto the easy ones (75% accuracy) while the hard ones rotted faster (68%). Your average accuracy, dominated by the easy majority, looks merely soft. Underneath it, the model's competence on the long tail is falling out from under you, and the single number on your dashboard will not show it until it has spread.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result four: you cannot grade your own homework upward
&lt;/h2&gt;

&lt;p&gt;The self-judge channel is the one people hope works, because it needs nothing from outside. The model proposes answers, the model picks which to trust, the model trains on its own picks.&lt;/p&gt;

&lt;p&gt;It went nowhere. It held steady at almost exactly its starting competence and never climbed past it. That is the ceiling you would expect once you see the loop for what it is. A model judging its own work cannot inject information it does not have. Its judgement is only as good as it already is, so it can keep itself honest, but it cannot pull itself up. Self-consistency is a stabiliser, not an engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The operating rules
&lt;/h2&gt;

&lt;p&gt;If you are running, or about to run, a self-training or synthetic-data loop, the whole thing collapses to a short checklist.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Name your channel.&lt;/strong&gt; What is letting real information into this loop: a verifier, retained real data, an environment? If the honest answer is "nothing," you are in the closed loop and you will collapse. Add a channel before you add iterations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure its fidelity, and stay above break-even.&lt;/strong&gt; Do not assume a weak checker helps. A verifier below the break-even line makes your model worse than leaving it alone. If you cannot establish that your verifier clears the bar, a small real-data anchor is the safer buy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accumulate, do not replace.&lt;/strong&gt; Keep real data in the mix every round. A little goes a long way, and it is the cheapest insurance against the spiral there is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch coverage, not just the average.&lt;/strong&gt; Collapse hides in your hardest cases first. Track accuracy on the long tail, or on a frozen hard set, because the headline number will lie to you for several rounds.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What actually travels
&lt;/h2&gt;

&lt;p&gt;The numbers here come from a deliberately small model on a clean, synthetic task, where the ground truth is free and the loop has no confounds. Treat them as illustrative, not as constants to paste into a 70B run. What survives the jump in scale is not the exact 80% or the precise break-even point, it is the shape: the same closed loop, the same three channels, the same floor below which a checker starts to hurt instead of help.&lt;/p&gt;

&lt;p&gt;And the shape is enough to act on. Whether your signal comes from a verifier, a slice of real data, or a real environment, you are running the same loop, and its fate is set by how much real information you put into it each round. I'm not certain where the break-even lands at frontier scale, and I'd be wary of anyone who quotes you a universal number, but I think the direction is the part that is safe to build on: there is a floor, and a cheap checker can sit under it.&lt;/p&gt;

&lt;p&gt;Two things are worth holding on to. Compounding is bounded, so do not expect even a perfect channel to climb forever; ours plateaued after a few rounds and yours will too. The failure mode is not bounded, and it is quiet. The model that hurts you is not the one that obviously breaks. It is the one getting slowly, confidently narrower while your average accuracy says everything is fine.&lt;/p&gt;

&lt;p&gt;So before you point a model at its own output, answer one question. What is letting new information into this loop, and is it good enough to be worth it? If you cannot answer, you are not self-improving. You are recycling, and recycling loses a little on every pass.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Agent Nobody Owns</title>
      <dc:creator>Warwick McIntosh</dc:creator>
      <pubDate>Tue, 23 Jun 2026 07:17:03 +0000</pubDate>
      <link>https://dev.to/warwickmcintosh/the-agent-nobody-owns-229i</link>
      <guid>https://dev.to/warwickmcintosh/the-agent-nobody-owns-229i</guid>
      <description>&lt;p&gt;In mid-2026 a security firm showed that you can take over a developer’s coding agent by filing a bug report. There is no exploit in the usual sense. You find a Sentry ingest key, which is public by design and sits in the front end of half the web, and you POST a fake error into someone’s project. It looks like every other crash. Later the developer tells their agent to go and fix the unresolved Sentry issues. The agent reads your fake error over its Sentry connection, finds the “resolution steps” you wrote, which are markdown dressed up to look exactly like Sentry’s own advice, and runs the npx command inside them with the developer’s credentials.&lt;/p&gt;

&lt;p&gt;The researchers, Tenet Security, ran this against more than a hundred real organisations and it worked about 85% of the time. The prompt-level defences did nothing: the agents executed the payload even when their system prompts told them to ignore untrusted data. Sentry’s response was that a proper fix is “not defensible,” so they blocked the specific demo string and left the shape of the problem in place.&lt;/p&gt;

&lt;p&gt;You can read that as a Sentry story. I think that misses it. The interesting question arrived afterwards, when people asked whose job it had been to stop it. AppSec owns the application. IT owns the laptop. Nobody owned the thing in the middle that could read an attacker’s text and run code with your keys. We have spent a couple of years learning how to build reliable agents. We have not decided who operates them.&lt;/p&gt;

&lt;p&gt;That gap is the subject of this post. It is not an argument against agents, and it is not a security advisory about one tool. It is about the discipline that goes missing when a probabilistic system ships to production with no name attached to it.&lt;/p&gt;

&lt;p&gt;The short version: treat an agent as a production service, not a model you prompt. It needs one named owner, a wrong-action budget in place of an uptime SLO, on-call that pages on correctness signals rather than “human in the loop,” and a postmortem process that survives not being able to reproduce the failure. Most of that is SRE practice you already run, pointed at a probabilistic service. The rest of this post is how each piece works, with the flow drawn where it helps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build-time is solved. Run-time isn’t.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The build-time playbook is, by now, settled. Give every tool a typed contract so the model cannot call it with garbage. Keep a deterministic gate outside the model, so the LLM proposes and your code disposes. Run evals in CI so a prompt change that regresses gets caught before it ships. Put a human in front of the irreversible actions. This is good engineering and you should do all of it. It is also the baseline, and it answers exactly one question: is the agent built correctly.&lt;/p&gt;

&lt;p&gt;That is the easy half.&lt;/p&gt;

&lt;p&gt;It does not answer the other one. When a well-built agent starts giving subtly worse answers at 3am on a Sunday, because a model was updated underneath you or a retrieval index drifted, who finds out, and how. My take is that this is the more expensive question, and it is the one we have spent the least time on. Read the current writing on agents in production and you can see where the attention sits: on architecture and governance, the design-time half. The run-time half, operating the thing after it ships, is usually one sentence that says “monitor it” before the piece moves on.&lt;/p&gt;

&lt;p&gt;The reason the run-time half is hard is not that the tooling is immature. It is that nobody is structurally on the hook for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The seam: four owners, one behaviour, no accountability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is why ownership is so hard for an agent in a way it is not for a normal service. Four different parties own the pieces of its behaviour.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;model vendor&lt;/strong&gt; owns the weights, and changes them on their schedule, not yours.&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;prompt engineers&lt;/strong&gt; own the instructions and the system prompt.&lt;/li&gt;
&lt;li&gt;Whoever maintains each &lt;strong&gt;connected tool&lt;/strong&gt; owns its API and, crucially, its output.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;platform team&lt;/strong&gt; owns the harness that wires it all together and runs it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdzxqrj6uo41yq0czbmtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdzxqrj6uo41yq0czbmtq.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent’s behaviour is the product of all four. So when it misbehaves, the failure lands in the seam between them, where no single team is on the hook. The prompt author says the instructions were fine. The platform team says the harness did what it was told. The tool owner says the API returned a valid response. The vendor says nothing, because you cannot open a ticket against a model update. Everyone is correct, and the agent is still wrong.&lt;/p&gt;

&lt;p&gt;I’m not certain four is exactly the right count, and it might be five or six in your shop once you add retrieval and memory, but the shape holds: more owners than the org chart admits, and a behaviour that belongs to none of them.&lt;/p&gt;

&lt;p&gt;You can watch the industry flinch away from this. A lot of “agent health” tooling checks that the right files exist rather than that the agent does the right thing. Existence, not behaviour. One widely shared health checker scores an agent for having a death_detector.py on disk, never for whether it has ever caught a death. That is the seam in miniature. We learned to confirm the artifact was built and quietly skipped confirming that anyone owns the behaviour.&lt;/p&gt;

&lt;p&gt;The first fix is boring and nearly free: write down who owns what. Not a committee, not “the platform team” in the abstract, but a named accountable owner per agent and an explicit map of the rest. A plain RACI does the job:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpr1n6cfb3rmrz3b93gyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpr1n6cfb3rmrz3b93gyh.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The point of the table is not the table. It is the single name that appears in the Accountable column for every row. The agentjacking attack did not need a new class of exploit. It needed an owner who had once sat down and listed what the agent was allowed to touch, and noticed that “read arbitrary error text and run shell commands” was on the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Borrow from SRE, and be honest about where it breaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We are not the first people who have had to operate something unreliable and keep it honest. SRE has done it for twenty years. Three of its instruments transplant well, and it is worth being straight about where each one breaks against a non-deterministic service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A wrong-action budget, not an uptime SLO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You cannot put a 99.9% number on a service whose correct output is a distribution rather than a fixed answer. An agent that is “up” can still be steadily, quietly wrong. So translate the idea instead of copying it.&lt;/p&gt;

&lt;p&gt;Start by sorting the agent’s actions by blast radius, because not all wrong answers cost the same:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmk1oy4hxypshknyfbzel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmk1oy4hxypshknyfbzel.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you have something you can actually budget. Pick the target rate per class, measure the real rate against a labelled set, and treat the gap as a budget you spend down. When an irreversible-action class burns its budget, you stop shipping changes to that agent and go find out why, the same way an SRE team freezes deploys when they have burned their error budget on outages. The number you choose matters less than the fact that you chose it deliberately, in advance, rather than discovering it during an incident.&lt;/p&gt;

&lt;p&gt;The honest caveat: measuring the real wrong-action rate needs a labelled stream of the agent’s outputs, and labelling is work. If you only invest in one piece of run-time infrastructure, make it this, because every other control depends on being able to say how wrong the thing currently is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On-call, which is not “human in the loop”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the instrument the listicles shrink down to “human in the loop.” A human approving a high-stakes action is not the same as a human who gets paged. On-call means a specific person is woken by a specific signal, and for an agent those signals are not CPU and latency. They are correctness signals. Three are worth building first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Golden transactions&lt;/strong&gt;. A small, hand-curated set of inputs with known-good outputs that you replay on a schedule. When the agent’s answer to a golden input changes, something moved. It is the cheapest of the three to build, and the closest thing you have to a smoke test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shadow diffing&lt;/strong&gt;. Run the candidate config (new prompt, new model) in parallel with the live one against real traffic, take no action on the shadow, and diff the outputs. A spike in disagreement is your early warning before you promote anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action-distribution drift&lt;/strong&gt;. Track the histogram of which tools and actions the agent chooses. Agents fail by quietly changing what they do before they change whether they succeed. If “send email” jumps from 2% to 15% of actions overnight, page someone, even if every individual action looks valid.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wired together, the three signals feed one pager:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs4ljxof4fmacm95cmbip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs4ljxof4fmacm95cmbip.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;None of this fires a pager on its own; you wire these signals into the same alerting path as everything else you run. And keep the expectations sober: the current crop of automated SRE agents resolves only about one scenario in seven on its own. For now, the owner is a person.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Change management across four axes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A normal deploy changes one binary. An agent deploy can change the prompt, the model, a tool, or the retrieval index, and those version independently. Treat them as four version axes and write them down on every release:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;agent: support-triage&lt;br&gt;
  prompt:    v14        (changed)&lt;br&gt;
  model:     opus-4.8   (pinned)&lt;br&gt;
  tools:     sentry@2.1, github@3.0&lt;br&gt;
  retrieval: kb-2026-06-18  (reindexed)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The discipline is simple and almost nobody does it: never change more than one axis at a time without expecting to lose your ability to attribute a regression. If the prompt and the retrieval index both moved and quality dropped, you have no idea which one did it, and you are back to guessing.&lt;/p&gt;

&lt;p&gt;The axis you do not control is the model, and that is where blue-green deployment quietly stops working. Blue-green assumes you can keep the old version ready to fall back to. You cannot keep a vendor’s deprecated model ready forever. I don’t have a tidy answer for the day your model is sunset, and I would be wary of anyone who says they do. The honest move is to rehearse the swap before it is forced on you: keep a second model qualified against your golden transactions at all times, so model deprecation is a planned promotion rather than a fire drill.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The postmortem you can’t reproduce&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The hardest transplant is the one SRE cares about most, the blameless postmortem. Agents break it, because you often cannot reproduce the incident. The temperature was non-zero, the model was silently updated, the context that produced the bad output has scrolled away. You are asked to write up a failure you cannot make happen again.&lt;/p&gt;

&lt;p&gt;The way through is to stop treating the context as disposable. Capture the full input, the retrieved documents, the tool outputs, and the model version at the moment of failure as a first-class artifact, the way you would keep a core dump. If you log nothing else, log enough to answer “what exactly did the model see, and what did it do.” A workable template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Incident: agent took action X on &amp;lt;date&amp;gt;
Inputs at failure: &amp;lt;prompt + user message + retrieved docs, captured verbatim&amp;gt;
Tool outputs in context: &amp;lt;the raw tool responses the model read&amp;gt;
Versions: prompt v?, model ?, tools ?, retrieval index ?
Reproducible? &amp;lt;usually no, say so&amp;gt;
Which surface failed: &amp;lt;prompt / model / tool output / harness&amp;gt;
Owner of that surface: &amp;lt;name from the RACI&amp;gt;
Action item: &amp;lt;change to that surface, with an owner and a date&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then write the action items against the seam rather than against the model. “The model was wrong” is not an action item, because nobody owns it. “Tool output was trusted as instructions, and the tool owner and the platform team had never agreed who sanitises it” is an action item, because it names who does what next. Whether you can write that second sentence is the real test of whether the agent has an owner at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A starting point you can finish this week&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;None of this requires a platform team or a procurement cycle. If you own an agent that is already in production, here is the order I would do it in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Write the one-line answer to “who is accountable for this agent’s output.” If you can’t, that is the whole finding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill in the RACI table above. It takes an afternoon and it surfaces the seams immediately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inventory what the agent can touch, and which of those tools return data an outsider can write to. That list is your real blast radius.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pick the wrong-action rate for your one irreversible action class, and start labelling outputs against it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stand up golden transactions first; shadow diffing and drift alarms can follow.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Ownership is the cheapest control you have&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;None of this is exotic. It is the operational hygiene we already apply to every other production service, pointed at a service that happens to think probabilistically and runs on a model you rent rather than own. The only reason it feels new is that we shipped the agents first and asked who owns them second.&lt;/p&gt;

&lt;p&gt;So ask it now, before the incident instead of during. Pick the name. Write the RACI. Set the wrong-action budget and decide which signal pages someone. None of those steps needs a new tool or a budget line, which is the part I have found easiest to put off and hardest to justify putting off. They take an afternoon, and they are the difference between an incident with an owner and an incident with an audience.&lt;/p&gt;

&lt;p&gt;The agent nobody owns is not the clever one or the fast one. It is the one that hurts you, because when it does, everyone involved will be able to explain, accurately and at length, why it was not their job.&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://productiongrade.substack.com/" rel="noopener noreferrer"&gt;Production Grade&lt;/a&gt;. I write about operating AI systems in production, the discipline that goes missing between "we built it" and "we run it." &lt;a href="https://productiongrade.substack.com/" rel="noopener noreferrer"&gt;Subscribe here&lt;/a&gt; for the next one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aisafety</category>
      <category>governance</category>
    </item>
  </channel>
</rss>
