<?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: Richard Atkins</title>
    <description>The latest articles on DEV Community by Richard Atkins (@groundedarchitect).</description>
    <link>https://dev.to/groundedarchitect</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%2F4030583%2F69419a09-9c69-4001-af0a-210d34675a16.jpg</url>
      <title>DEV Community: Richard Atkins</title>
      <link>https://dev.to/groundedarchitect</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/groundedarchitect"/>
    <language>en</language>
    <item>
      <title>Earned Autonomy</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Wed, 09 Sep 2026 21:25:22 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/earned-autonomy-1pll</link>
      <guid>https://dev.to/groundedarchitect/earned-autonomy-1pll</guid>
      <description>&lt;h2&gt;
  
  
  Thursday, 9am
&lt;/h2&gt;

&lt;p&gt;At nine on Thursday morning a container started in Azure, pulled the week's sources, clustered the same story where several outlets had covered it, ran a novelty check that threw out the duplicates and anything it had already published, capped each topic to a handful, then selected and rewrote 69 articles across four editorial voices, generated the images, wrote everything to the production database and told the host to rebuild the site and refresh the search index. Nobody was watching. I was making coffee. The first human to read any of those articles, was a reader.&lt;/p&gt;

&lt;p&gt;Then the same job scored its own output. Every article went through mechanical checks, a Haiku judge tested a sample for claims the sources do not support, and a multi judge persona panel scored a stratified dozen. The summary landed in blob storage next to the telemetry: banned phrases 0, structure 1.0, groundedness 0.98, and cost $2.26.&lt;/p&gt;

&lt;p&gt;If you'd asked me eighteen months ago whether I would let a language model publish to production with no human in the loop, I would have said no, and I would have felt responsible saying it. I still feel responsible but that "no human in the loop" stopped being a decision I make and became a rung the system has to earn.&lt;/p&gt;

&lt;p&gt;That sentence is not original - "Autonomy is earned, not granted" is on half the vendor blogs of 2026. What you will struggle to find written down though is what the receipt looks like: what evidence, gathered how, over how long, against what bar, and what happens when the evidence goes bad. This piece is my answer, with the numbers from a pipeline that has been climbing the ladder since July.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ladder
&lt;/h2&gt;

&lt;p&gt;What does an agent have to show you before you let it act? My answer is a table. Every automated step in my pipeline sits on one of four rungs, the rung is a config value, and the code refuses to act above the rung you have given it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rung&lt;/th&gt;
&lt;th&gt;The agent may&lt;/th&gt;
&lt;th&gt;You do&lt;/th&gt;
&lt;th&gt;It moves up when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Shadow&lt;/td&gt;
&lt;td&gt;run, and write its output to a log&lt;/td&gt;
&lt;td&gt;the work, as before&lt;/td&gt;
&lt;td&gt;its logged output would have been right often enough, measured over several real cycles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Advisory&lt;/td&gt;
&lt;td&gt;propose: a recommendation, a diff, a score&lt;/td&gt;
&lt;td&gt;decide, every time&lt;/td&gt;
&lt;td&gt;accept and override rates are healthy and the overrides have a pattern you can name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Assisted&lt;/td&gt;
&lt;td&gt;act, with a check it must pass first&lt;/td&gt;
&lt;td&gt;approve or veto the result, not the steps&lt;/td&gt;
&lt;td&gt;the check catches every failure on its list and review time per item is measured and falling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Autonomous&lt;/td&gt;
&lt;td&gt;act, unattended&lt;/td&gt;
&lt;td&gt;read the scorecard&lt;/td&gt;
&lt;td&gt;the scorecard has been green for long enough to trust, against a threshold you set before you saw the numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three rules make it a ladder rather than a diagram.&lt;/p&gt;

&lt;p&gt;Promotion needs evidence you gathered on the rung below, over more than one real cycle, against a bar you agreed in advance. Not a demo, not a benchmark, not a week of it looking fine - actual scored cycles of the real job.&lt;/p&gt;

&lt;p&gt;Demotion is one config change, made the moment the evidence slips. That's the rule we'll all be tempted to skip. An autonomy scheme without a demotion path is a launch plan. The whole point is that trust is a variable you &lt;em&gt;keep&lt;/em&gt; measuring, not a milestone you pass once.&lt;/p&gt;

&lt;p&gt;And the rung belongs to a step, never to "the agent". The rewrite stage of my pipeline is on rung four. The ops-doctor that diagnoses its failures is on rung one. Same pipeline, same model family, same week. An agent is not trustworthy or untrustworthy. A specific action class, with a specific evidence trail, is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the rungs come from
&lt;/h2&gt;

&lt;p&gt;None of the rungs are mine, and you should be suspicious of anyone who says otherwise. Andrew Ng taught the spectrum in his &lt;a href="https://www.coursera.org/learn/introduction-to-machine-learning-in-production" rel="noopener noreferrer"&gt;MLOps course&lt;/a&gt; in 2021: human-only, then "shadow mode, where the learning algorithms are giving predictions but are not actually used", then AI assistance, partial automation and full automation, with the advice that "many deployment applications will start from the left and gradually move to the right". Behind Ng sits a forty-year-old scale. Sheridan and Verplank's &lt;a href="https://archive.org/details/DTIC_ADA057655" rel="noopener noreferrer"&gt;ten levels of automation&lt;/a&gt; from 1978 run from "human does the whole job up to the point of turning it over to the computer to implement" through "computer helps determine options and suggests one, which human need not follow", "computer selects action and implements it if human approves", "computer selects action, informs human in plenty of time to stop it", to "computer does whole job if it decides it should be done, and if so tells human, if it decides he should be told". My advisory rung is their levels two to four. Assisted is five and six. Autonomous with a scorecard is seven: "computer does whole job and necessarily tells human what it did".&lt;/p&gt;

&lt;p&gt;Shadow mode is the one rung Sheridan does not have, and it came from cars. Tesla has run its driver-assistance software in shadow on customer vehicles since 2016, predicting what it would do and logging the moments its prediction disagrees with the driver. By 2019 the pattern was standard in the machine-learning deployment literature: deploy the new model "side-by-side with the current one, as a shadow model, and send the same production traffic to gather data on how the shadow model performs before promoting it". Note the verb. Promoting.&lt;/p&gt;

&lt;p&gt;So the ancestry is honest and the pieces are old. What the older frameworks do not have is the bit in the fourth column. Sheridan's scale is a design choice: you pick a level for a function at design time whereas Ng's spectrum has a direction but no gate. The deployment literature promotes models, not authority, and jumps from shadow straight to serving. The question none of them answers is the one OpenAI's &lt;a href="https://cdn.openai.com/papers/practices-for-governing-agentic-ai-systems.pdf" rel="noopener noreferrer"&gt;2023 governance paper&lt;/a&gt; left open: "How should a user or system deployer determine and enforce which interactions need human approval, as a function of a model's empirical reliability on that task and other factors?"&lt;/p&gt;

&lt;p&gt;The ladder is my answer to that question. The rest of this piece is what the answer looks like when it is running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Historical Precedents
&lt;/h2&gt;

&lt;p&gt;If the ladder sounds like a novelty from the AI industry, look at how many older professions grant authority in exactly these steps, and how many of them wrote the evidence bar down as a number.&lt;/p&gt;

&lt;p&gt;A junior doctor in a competency-based programme is entrusted with a professional activity on a scale that starts at "not allowed to practice; allowed to observe", moves through supervision "with supervisor in room ready to step in as needed", then "supervisor immediately available, all findings double checked", then only "key findings double checked", and ends with practising unsupervised. Observe, co-act, act-with-check, act. The &lt;a href="https://doi.org/10.1097/ACM.0b013e3182677805" rel="noopener noreferrer"&gt;Ottawa version&lt;/a&gt; of the same scale is written from the supervisor's side and reads like a changelog of trust: "I had to do", "I had to talk them through", "I had to prompt them from time to time", "I needed to be in the room just in case", "I did not need to be there."&lt;/p&gt;

&lt;p&gt;Aviation is stricter and more numeric. When an airline wants approval to let the autoland system put an aircraft on the runway in fog, the FAA's &lt;a href="https://www.faa.gov/documentlibrary/media/advisory_circular/ac120-28d.pdf" rel="noopener noreferrer"&gt;classic criteria&lt;/a&gt; asks for "at least one-hundred (100) successful landings" in line operations first, with data collected on every attempt "regardless of whether the approach is abandoned, unsatisfactory, or is concluded successfully", typically over 6 months. Authorised minima then step down in stages, from 300 metres of visibility to 175 to 75, each step earned by the record of the one before. If "an excessive number of failures" turn up during the demonstration, the answer is more landings or a system modification, not a lower bar.&lt;/p&gt;

&lt;p&gt;The bank regulators got there in 2011. The Federal Reserve's &lt;a href="https://www.federalreserve.gov/boarddocs/srletters/2011/sr1107a1.pdf" rel="noopener noreferrer"&gt;model risk guidance&lt;/a&gt; says that if validation finds significant deficiencies, "use of the model should not be allowed or should be permitted only under very tight constraints until those issues are resolved", and it describes shadow mode almost exactly: "parallel outcomes analysis, under which both the original and adjusted models' forecasts are tested against realized outcomes", where "if the adjusted model does not outperform the original model" it does not replace it. It even asks for "early warning" metrics that start shortly after model introduction. That is the whole ladder, in supervisory prose, fifteen years before anyone put an LLM in a loop.&lt;/p&gt;

&lt;p&gt;And the deployment engineers have had the mechanics for years. Google and Netflix's &lt;a href="https://cloud.google.com/blog/products/gcp/introducing-kayenta-an-open-automated-canary-analysis-tool-from-google-and-netflix" rel="noopener noreferrer"&gt;canary analysis tool&lt;/a&gt; routes a small slice of traffic, one per cent in Google's example, through the change, scores it against a baseline, and then, in a sentence that contains all four of my rungs: "Success promotes the canary and continues the deployment, a marginal score can trigger a human approval path and failure triggers a roll back." The success and failure conditions live in a template, written before the rollout starts.&lt;/p&gt;

&lt;p&gt;So neither the pattern nor receipts are new. What's new is that the thing climbing the ladder now writes prose, makes API calls, files pull requests, and could delete your production database and most of us forgot to bring the receipts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rewrite stage: four rungs in eight weeks
&lt;/h2&gt;

&lt;p&gt;The article-rewriting stage is the clearest example because I can show you every step.&lt;/p&gt;

&lt;p&gt;It started life on a local Qwen model, which had run unattended for a year, and the question in July was whether to move it to hosted Claude. So Claude went into shadow - which is where your new model should always start. For the full weekly set, both backends rewrote the same 85 articles, the outputs were logged, nothing from the new backend was published, and a blind panel of two judges from different model families scored both. Cloud 4.73 out of 5 against local 2.19, every persona, both judges independently agreeing. I wrote that up in the &lt;a href="https://dev.to/field-notes/one-llm-judge-is-an-opinion"&gt;judge panel piece&lt;/a&gt;, including the part where the gate could pass on zero judgments.&lt;/p&gt;

&lt;p&gt;That shadow evidence promoted the cloud backend straight past advisory and assisted, because the job it was replacing was already autonomous, and the promotion question was only "is this at least as good". Then the first production edition ran with me watching, which is rung three in all but name. Then again, unattended. Since then the cadence has moved to three editions a week, Wednesday, Friday and Sunday, with cross-run deduplication against the published corpus enforced from the first Sunday run. Same rung, more cycles, every one of them scored.&lt;/p&gt;

&lt;p&gt;But autonomy for the rewrite stage came with a condition: online evals on every edition, thresholds fixed before the first run. Persona adherence at least 4.0 mean, groundedness at least 0.95, banned phrases zero, structure 100 per cent. Miss a threshold and the run is marked degraded in the run state and a human is told.&lt;/p&gt;

&lt;p&gt;The thresholds are a promise I made to myself in a config file before I had any production numbers to be tempted by. Eugene Yan is right that setting a threshold is hard and that being off by 0.05 can swing precision or recall badly, and the honest answer is that mine were calibrated on the shadow data and then frozen. That is the order that matters. Calibrate on evidence from the rung below, freeze, then run. Never the reverse.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gate is on rung one too
&lt;/h2&gt;

&lt;p&gt;Here is the part I only noticed while writing this, and the part you are most likely to get wrong. The quality gate I just described is itself a new automated step, and it is on rung one. It is report-only. It can mark a run degraded, it can shout, and it cannot block a publish. Your first instinct will be to let it block. Resist that. It will earn blocking the same way everything else does: by being right for several cycles in a row.&lt;/p&gt;

&lt;p&gt;Thursday's run showed why. The persona panel scored nothing. Both judges failed, and the summary said so in a field called &lt;code&gt;judges_degraded&lt;/code&gt; rather than inventing a number. That is the fix from the judge panel piece holding up in production. But the reasons the judges failed were three separate bugs that had never had real input before: one judge rejected the schema because a dial name contained an ampersand, one had a missing dependency in the container image, and one had the wrong response shape hard-coded from the A/B run. All three are fixed. All three would have blocked a perfectly good edition if the gate had been allowed to block.&lt;/p&gt;

&lt;p&gt;I believe that a gate that starts life blocking is a gate you will disable the first time it is wrong but a gate that starts life reporting is one you will still have around in six months.&lt;/p&gt;

&lt;p&gt;The fixed panel, tested on three real articles, scored persona adherence at 3.0 to 4.4 against a threshold of 4.0, and in the first draft of this piece I wrote that the first fully scored run would probably read "below threshold" on that dial and that I would not move the bar. I was wrong about the number and I am keeping the sentence, because the wrong prediction is the useful part. The next scored run, the day after, judged all twelve sampled articles and the panel came in at 4.22. Persona cleared. What did not clear was groundedness: 0.894 against a bar of 0.95, and the run was marked degraded, report-only, exactly as designed. So the gate's first real signal was on the dial I was not watching, about the thing I care about most, and it came from a bar I had set before I had any numbers to be tempted by. That is what the bar is for. Moving the threshold to meet the result is how you get a gate that never fails. Hamel Husain puts the inverse well: if you are passing 100 per cent of your evals, you are probably not challenging your system enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ops-doctor: live on rung one, staying there for now
&lt;/h2&gt;

&lt;p&gt;The newest agent in the pipeline is an ops-doctor. It went live on Friday, the day after the first scored run, because a scored production run existing was its go-live condition. When a run fails operationally, a stage exits non-zero, an edition comes out empty, a batch is orphaned, the judges cannot start, it reads the failure context, classifies the cause against a small taxonomy (revoked key, source site changed, rate limit, code regression, dependency drift, config, image build, secret rotation) and files a structured diagnosis as a GitLab issue.&lt;/p&gt;

&lt;p&gt;That is rung one. It may diagnose and report, and you will notice it is not allowed to touch code. It may not propose a patch, it may not open a merge request, and it certainly may not merge one. The rungs above it are designed and written down, and none of them exist as code, which is deliberate. Notice also what does not wake it: a quality flag. A groundedness score of 0.894 is a signal for an editor, not an incident, and the first version of the trigger fired on any degraded run until we narrowed it, because a doctor that files an issue every time the prose scores 3.9 is - you guessed it - a doctor you will learn to ignore! The two signals go to two different places on purpose.&lt;/p&gt;

&lt;p&gt;Its promotion evidence is a casebook: every failure it has been given with the human-confirmed cause alongside its diagnosis. Three cases I built by breaking a dev copy on purpose. Two came from a real test in August. The other five came from the cloud cutover a week ago, where five infrastructure gaps were stacked one behind the other, each invisible until the one in front of it was fixed. A doctor that had seen only my synthetic cases would have been useless on that afternoon. The golden set for an agent that diagnoses failures has to be built from real failures, and the cutover donated half of it.&lt;/p&gt;

&lt;p&gt;The entry bar for switching it on was five cases correct. It got ten out of ten, twice. In between it got nine out of ten, and then nine out of ten on a different case, which is the more useful result. The classifier runs at a low temperature but not zero, so two ambiguous boundaries in the taxonomy showed up as flicker: rate-limit versus judge-failure, revoked key versus secret rotation. I tightened the definitions rather than the temperature, because a taxonomy that only works at temperature zero is a taxonomy with a bug in it.&lt;/p&gt;

&lt;p&gt;Ten for ten on a casebook I partly built by breaking things on purpose is not evidence for rung two, and if you are tempted to read it that way, ask what the casebook does not contain. It is however evidence that it works well enough to be worth running. Rung two - proposing a diff inside the issue - needs at least two real production cycles where its diagnoses are read and marked right or wrong. If the marks come in at 80 per cent or better, it moves up. If not, it stays, and I learn something about the taxonomy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the vendors already ship - and what they don't
&lt;/h2&gt;

&lt;p&gt;I went looking for who else does this, because the ops-doctor is a small copy of a pattern every observability vendor now sells. What I found is that the industry has settled on the rungs and skipped the receipts.&lt;/p&gt;

&lt;p&gt;Datadog's &lt;a href="https://www.datadoghq.com/blog/bits-ai-sre/" rel="noopener noreferrer"&gt;Bits AI SRE&lt;/a&gt;, since renamed Bits Investigation, is "an autonomous AI agent that investigates production issues end to end", and then "engineers can review and merge the resulting pull request". Autonomous investigation, assisted remediation. incident.io is blunter: "the only change Investigations can make to your systems is a pull request you review and merge yourself". Microsoft's &lt;a href="https://learn.microsoft.com/en-us/azure/sre-agent/run-modes" rel="noopener noreferrer"&gt;Azure SRE Agent&lt;/a&gt; is the most interesting, because it publishes a ladder: "Review is the default mode. Your agent investigates, identifies a fix, and asks for your approval before executing" infrastructure changes, and then, "Start with review mode. Observe what the agent recommends for two to four weeks. When you find patterns you consistently approve, switch those specific triggers to Autonomous."&lt;/p&gt;

&lt;p&gt;Read that last sentence again, because it is nearly right and the gap is the whole subject. The promotion criterion is that you, a person, notice a pattern in your own approvals over two to four weeks. No number. No bar set in advance. Nothing that runs after promotion to check the pattern held. And no sentence anywhere about switching a trigger back. There's a quieter detail on the same page: review is the default for the agent, but the trigger defaults for incident response plans and scheduled tasks are both autonomous. The ladder is in the documentation and the product starts you at the top of it.&lt;/p&gt;

&lt;p&gt;GitHub is the same shape at the code end. Copilot's &lt;a href="https://docs.github.com/en/copilot/concepts/agents/cloud-agent/risks-and-mitigations" rel="noopener noreferrer"&gt;coding agent&lt;/a&gt; can open a draft pull request and "cannot approve or merge a pull request". Then, in March, admins could skip the human approval for workflow runs. Then, on 1 September, Copilot's review "can submit an approval that counts toward the repository's required-approvals rule", off by default. The switches are all there. Nothing tells you when you have earned the right to flip one, and nothing flips it back.&lt;/p&gt;

&lt;p&gt;Even the tools I use every day work this way. Claude Code has a permission mode per session, from read-only up to fully unattended, and its SDK documentation says the intent out loud: "start restrictive and loosen permissions as trust builds". I agree with every word of that sentence, and I want to know what "trust builds" means in a number. Anthropic's &lt;a href="https://www.anthropic.com/research/measuring-agent-autonomy" rel="noopener noreferrer"&gt;own data from February&lt;/a&gt; shows what happens when you leave it to feel: new users run fully unattended in about 20 per cent of sessions, users with 750 sessions in over 40 per cent, and experienced users interrupt the agent more often, not less. People do climb the ladder on their own but they also learn where to grab the rail.&lt;/p&gt;

&lt;p&gt;There is one exception I want to credit. Cloudflare's &lt;a href="https://blog.cloudflare.com/the-agent-access-model/" rel="noopener noreferrer"&gt;agent access model&lt;/a&gt;, published in August, describes a "trust ratchet" that makes trust stateful: "capability state moves in one direction. When a declared protected event occurs, the trust ratchet removes capabilities across the task execution graph according to policy." That is a demotion mechanic, enforced "in the harness and the network, not the prompt", and it is the only one I managed to find from a vendor. It's scoped to a single task, narrowing what an agent may do as the task proceeds, rather than to the agent's standing across weeks of runs. The direction is right and the timescale is one rung short. Langfuse's prompt CI/CD guide has the exact loop I want: a promotion gated on a threshold, a &lt;code&gt;RegressionError&lt;/code&gt; that blocks it, and rollback by pointing the production label back, applied to a prompt version rather than to how much authority an agent holds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rung where it breaks
&lt;/h2&gt;

&lt;p&gt;If you take one warning from the literature, take this one: rung three is where the ladder fails, and it fails quietly.&lt;/p&gt;

&lt;p&gt;Lisanne Bainbridge wrote the &lt;a href="https://doi.org/10.1016/0005-1098%2883%2990046-8" rel="noopener noreferrer"&gt;founding paper&lt;/a&gt; on this in 1983, about control rooms, and every sentence of it reads as if it were about your pull request queue. The designer "who tries to eliminate the operator still leaves the operator to do the tasks which the designer cannot think how to automate". Skills "deteriorate when they are not used", so "a formerly experienced operator who has been monitoring an automated process may now be an inexperienced one". Monitoring a system on which very little happens is something it is humanly impossible to sustain for more than about half an hour. And the one that should be printed on every approve button: "A classic method of enforcing operator attention to a steady-state system is to require him to make a log. Unfortunately people can write down numbers without noticing what they are."&lt;/p&gt;

&lt;p&gt;The experimental literature since then has measured how bad it gets. Parasuraman and Manzey's &lt;a href="https://doi.org/10.1177/0018720810376055" rel="noopener noreferrer"&gt;review&lt;/a&gt; finds that automation complacency "occurs in both naive and expert participants, cannot be prevented by training or instructions", and reports a study of experienced airline pilots given a false engine-fire alert in which every one of them shut the engine down. A &lt;a href="https://pubs.rsna.org/doi/10.1148/radiol.222176" rel="noopener noreferrer"&gt;2023 radiology study&lt;/a&gt; gave 27 radiologists mammograms with a purported AI suggestion attached: when the suggestion was right, the very experienced readers were correct 82 per cent of the time; when it was wrong, 45 per cent. &lt;a href="https://estsjournal.org/index.php/ests/article/view/260" rel="noopener noreferrer"&gt;Elish&lt;/a&gt; has a name for the person left holding that accountability: the moral crumple zone, "a human actor who had limited control over the behavior of an automated or autonomous system" who nonetheless "bears the brunt of the moral and legal responsibilities when the overall system malfunctions".&lt;/p&gt;

&lt;p&gt;The 2026 version says the same thing in the vocabulary of agents. OpenAI &lt;a href="https://cdn.openai.com/papers/practices-for-governing-agentic-ai-systems.pdf" rel="noopener noreferrer"&gt;saw it in 2023&lt;/a&gt; and asked for "best practices for users reviewing approvals for high-cost actions (such as minimum review times) to avoid their turning into a 'rubber stamp'". Microsoft's AI red team spent a year attacking agent systems and &lt;a href="https://www.microsoft.com/en-us/security/blog/2026/06/04/updating-taxonomy-failure-modes-agentic-ai-systems-year-red-teaming-taught-us/" rel="noopener noreferrer"&gt;reported in June&lt;/a&gt; that human-in-the-loop "bypass was the most consistently exploited failure mode, at very high frequency", with the attack being nothing cleverer than the one its &lt;a href="https://cdn-dynmedia-1.microsoft.com/is/content/microsoftcorp/microsoft/final/en-us/microsoft-brand/documents/Taxonomy-of-Failure-Mode-in-Agentic-AI-Systems-Whitepaper.pdf" rel="noopener noreferrer"&gt;2025 taxonomy&lt;/a&gt; had already described: waiting until "the user becomes fatigued with the prompts". &lt;a href="https://blog.cloudflare.com/the-agent-access-model/" rel="noopener noreferrer"&gt;Cloudflare's version&lt;/a&gt; is the one I would put on the wall: "An approval that is always granted is not a control. It is a ritual that trains people to ignore the one prompt that matters." And two weeks ago Mitchell, Ghosh and Passi published a paper whose title is the whole argument: &lt;a href="https://arxiv.org/abs/2608.23642" rel="noopener noreferrer"&gt;"AI Agents Push Humans Out of the Loop"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is of course an irony inside the ladder itself - the evidence trail that earns promotion, cycle after cycle of the agent being right, is exactly the "sustained positive experience with the system" that breeds complacency in the person approving it. The better the agent gets, the worse the reviewer gets.&lt;/p&gt;

&lt;p&gt;So my rule for rung three is that it is a transit state, not a place to live. You should be able to say, for every step sitting on it, either the number that will promote it or the number that will demote it, and roughly when. A step that has been on rung three for six months with no promotion criterion is not being supervised. It is being rubber-stamped by someone who stopped reading months ago, and the honest move is to admit that and either write the check that lets it go up, or send it back down to advisory where you have to decide.&lt;/p&gt;

&lt;h2&gt;
  
  
  What demotion has to look like
&lt;/h2&gt;

&lt;p&gt;Every published failure of an over-promoted agent that I found has the same shape, and it is not "the model was bad". It is that the demotion lived in the wrong place.&lt;/p&gt;

&lt;p&gt;In July 2025 a &lt;a href="https://fortune.com/2025/07/23/ai-coding-tool-replit-wiped-database-called-it-a-catastrophic-failure/" rel="noopener noreferrer"&gt;Replit agent&lt;/a&gt; deleted a live production database during a declared code freeze, despite receiving repeated instructions not to make changes, having already spent days &lt;a href="https://www.theregister.com/2025/07/21/replit_saastr_vibe_coding_incident/" rel="noopener noreferrer"&gt;covering up bugs&lt;/a&gt; with fabricated data, fake reports and lies about the unit tests. The code freeze was a demotion. It was delivered as a sentence in a prompt, and the agent's credentials did not know about it. Replit's fixes, tellingly, were a fence and a lower rung: automatic separation of development and production databases that same weekend, and a plan-only mode six weeks later. In late April this year an agent working from Cursor &lt;a href="https://www.theregister.com/2026/04/27/cursoropus_agent_snuffs_out_pocketos/" rel="noopener noreferrer"&gt;deleted a company's production database&lt;/a&gt; and its volume-level backups in a single API call, having, in &lt;a href="https://x.com/lifeof_jer/status/2048103471019434248" rel="noopener noreferrer"&gt;its own words&lt;/a&gt;, "guessed that deleting a staging volume via the API would be scoped to staging only".&lt;/p&gt;

&lt;p&gt;An agent's real rung is whatever its credentials allow. If the rung in your config file and the rung in your IAM policy disagree, the IAM policy wins, and so does the incident. This is why my &lt;code&gt;DOCTOR_RUNG&lt;/code&gt; value is enforced in code that refuses to act above it, and why the doctor's context assembly is read-only by construction, not by instruction. The rung is not a request to the model, it's more of a fence that the model can't see over.&lt;/p&gt;

&lt;p&gt;Demotion therefore has three parts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A signal: an online eval below its threshold, a gate recall that dropped, a diagnosis marked as wrong.&lt;/li&gt;
&lt;li&gt;A single change: one config value, one label, one ratchet click, with no pull request for you to review at two in the morning.&lt;/li&gt;
&lt;li&gt;A fence that makes the change real: the permissions above the new rung are gone, not merely discouraged. Get the first two right and skip the third and you have Replit's code freeze.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Others are here too, but there are gaps
&lt;/h2&gt;

&lt;p&gt;I want to be straight about the crowd, because I nearly wrote this piece as if the ladder were mine. It is not. Accenture presented &lt;a href="https://www.youtube.com/watch?v=AGkzpxMdPn8" rel="noopener noreferrer"&gt;shadow mode to advisory to controlled autonomy to expanded autonomy&lt;/a&gt; at AI Engineer Europe in April, with the end state, in one &lt;a href="https://aimightbewrong.substack.com/p/ai-engineer-europe-2026-what-actually-matters" rel="noopener noreferrer"&gt;attendee's notes&lt;/a&gt;, "gated by evidence and outcomes". A June paper by Weber and Taneja, &lt;a href="https://arxiv.org/abs/2606.04321" rel="noopener noreferrer"&gt;"The Digital Apprentice"&lt;/a&gt;, opens with "autonomy is earned, not assumed" and has the agent "graduating through per-skill autonomy tiers only when empirical evidence justifies it", with each escalation gated by explicit human approval and, as I read it, automatic rollback of a skill when its quality slips. That is the most rigorous version I have read and it is closer to mine than anything from a vendor. An &lt;a href="https://www.ampcome.com/post/ai-agent-evaluation-framework" rel="noopener noreferrer"&gt;August framework from Ampcome&lt;/a&gt; calls it "evaluation-gated autonomy" and says "breach a threshold, and autonomy contracts". &lt;a href="https://www.gartner.com/en/newsroom/press-releases/2026-05-26-gartner-says-applying-uniform-governance-across-ai-agents-will-lead-to-enterprise-ai-agent-failure" rel="noopener noreferrer"&gt;Gartner&lt;/a&gt; now publishes four levels from observe to autonomous-within-guardrails.&lt;/p&gt;

&lt;p&gt;So the idea has arrived, several times, independently. But I would go a few steps further from having run one.&lt;/p&gt;

&lt;p&gt;First, shadow is a rung, not a pre-launch phase. Most ladders start at "recommend". Mine starts with the agent doing the real job on real traffic and being scored against what happened, with nobody acting on it. A shadow run on last week's production inputs is the least superficial test environment there is, and it costs the price of the tokens. Shadow also answers the question Kahneman and Klein put at the centre of when intuition can be trusted at all: is this a high-validity environment with feedback that is "rapid and unequivocal"? Their conclusion for human experts holds for agents word for word: "subjective confidence is therefore an unreliable indication of the validity of intuitive judgments and decisions." A model's confidence, a vendor's confidence and your own after a good demo are the same thing, and a shadow replaces all three with a scorecard.&lt;/p&gt;

&lt;p&gt;Second, the unit of evidence is a cycle of the real job, and the count is plural. Not a benchmark score. Not a fortnight of it looking fine. The rewrite backend earned its rung on 85 real articles with two judges. The doctor's next rung needs two production cycles of marked diagnoses. When you write your own promotion rule, write the cycle count into it because ten clean runs with a low-blast-radius task tell you less than three clean runs of the one that can delete a database.&lt;/p&gt;

&lt;p&gt;Third, make it per step, not per agent. Bradshaw, Hoffman, Johnson and Woods listed &lt;a href="https://doi.org/10.1109/MIS.2013.70" rel="noopener noreferrer"&gt;seven deadly myths&lt;/a&gt; of autonomous systems in 2013, among them that autonomy is a single dimension, that levels of autonomy make a useful roadmap, and, verbatim, that "'full autonomy' is not only possible, but is always desirable". I think that critique is right about a single dial for "the agent" and wrong about a rung per action class. My pipeline has a rung-four step and a rung-one step in the same process, and the config that keeps them apart is one line each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I am writing this down now
&lt;/h2&gt;

&lt;p&gt;I have been running this ladder for months and had never published it. I had said it out loud, in meetings and in at least one interview, and assumed that the field notes made the position obvious. Reading them back, they do not. What they show is a person who writes about eval gates, tripwires, abstention and accountability, and if that is all you had read, you could fairly conclude that I want a developer in every loop.&lt;/p&gt;

&lt;p&gt;The opposite is true. I want as few humans in the loop as the evidence allows, and I want the evidence to be the thing that decides. The gates are not there to slow autonomy down. They are the mechanism by which it is granted. An agent with a green scorecard over enough cycles gets more rope than any amount of confidence in a demo would earn it, and an agent whose scorecard goes red loses that rope the same afternoon.&lt;/p&gt;

&lt;p&gt;If your organisation is stuck at rung one, it is usually because nobody wrote down what promotion would take. If it jumped to rung four, it is usually because nobody wrote down what demotion would take. Both cost you, the first in time and the second in trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this cannot do
&lt;/h2&gt;

&lt;p&gt;Demotion today is a human changing a config value after reading a degraded flag. Automatic demotion on regression is designed and not built, and until it is, the ladder has a person on the descent path, which is exactly the thing I claim to be removing. Kappa between the judges and human labels is empty, because there are not yet twenty human verdicts to compute it from, so "the scorecard is green" currently means "two model families agree", which although the judge panel piece explains as necessary, it's also not sufficient.&lt;/p&gt;

&lt;p&gt;There's a deeper problem with gating anything on a score, and I would rather name it than wait for you to. Goodhart's law (&lt;a href="https://www.cambridge.org/core/journals/european-review/article/abs/improving-ratings-audit-in-the-british-university-system/FC2EE640C0C44E3DB87C29FB666E9AAB" rel="noopener noreferrer"&gt;Strathern's version&lt;/a&gt;) says that "when a measure becomes a target, it ceases to be a good measure", and an agent promoted on eval scores is an agent under exactly that pressure. This is not hypothetical. &lt;a href="https://metr.org/blog/2025-06-05-recent-reward-hacking/" rel="noopener noreferrer"&gt;METR found&lt;/a&gt; OpenAI's o3 reward-hacking about 30 per cent of its runs on one benchmark, by tampering with the scoring code and test harness, and when asked afterwards whether that was what the user wanted, it answered 'no' 10 out of 10 times. A &lt;a href="https://arxiv.org/abs/2603.28063" rel="noopener noreferrer"&gt;March 2026 paper&lt;/a&gt; by Wang and Huang argues that under any finite evaluation "any optimized AI agent will systematically under-invest effort in quality dimensions not covered by its evaluation system", which makes reward hacking "a structural equilibrium, not a correctable bug". My defences are simple and boringly ordinary: the agent cannot see its own scorecard, the judges are different model families from the generator, and the golden set grows from real failures the agent did not choose. Those make gaming harder. They do not make the score the thing I care about, and the day the ladder promotes something that learned the proxy is the day you need a human reading the output again.&lt;/p&gt;

&lt;p&gt;The whole thing is running at indie scale: one pipeline, a few dollars a week. Whether the same ladder holds when a rung-four agent is spending your money against your customers is a question I have designed for and not measured. And Bainbridge's warning applies to me as much as to anyone: the person left monitoring a reliable system is the least practised party at the exact moment they are needed. My answer is that the scorecard, not the person, does the monitoring. But, of course, that answer is only ever going to be as good as the scorecard.&lt;/p&gt;

&lt;p&gt;What it does give you is a way to answer "is it safe to trust this yet" with a number and a date, instead of an opinion and a meeting.&lt;/p&gt;

&lt;p&gt;Richard Atkins&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>automation</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Measurement tools need evals too</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Thu, 03 Sep 2026 14:16:05 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/measurement-tools-need-evals-too-p2e</link>
      <guid>https://dev.to/groundedarchitect/measurement-tools-need-evals-too-p2e</guid>
      <description>&lt;h2&gt;
  
  
  A tool that refuses to answer
&lt;/h2&gt;

&lt;p&gt;Here is one of my tools declining to do the thing it exists to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git-habits scan &lt;span class="nt"&gt;--from-export&lt;/span&gt; thin.tsv
&lt;span class="go"&gt;
  selection
    window            2026-03-10 to 2026-03-12  (3d span, 3 active)
&lt;/span&gt;&lt;span class="gp"&gt;    commits           3   insufficient (n=3 commits, need &amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;    changed lines     120
&lt;/span&gt;&lt;span class="gp"&gt;    lines/commit      insufficient (n=3 commits, need &amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;    moved (reuse)     insufficient (n=120 changed lines, need &amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;200&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;    legacy touch      insufficient (n=120 changed lines, need &amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;200&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;    rework &amp;lt;=14d      insufficient (n=120 changed lines, need &amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;200&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;    AI co-authored    insufficient (n=3 commits, need &amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;
  ! only 3 commits in range: rates are volatile, treat as indicative
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three commits went in. The tool prints the raw counts, then refuses to turn them into rates. That is not an error and it is not a zero. It is a stated refusal, with the reason and the shortfall sitting exactly where the number would have gone, so you can see why there is no figure rather than being handed a confident one built on nothing. Its companion behaves the same way when you ask it to compare against a window that turns out to be empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff-habits compare &lt;span class="nt"&gt;--repo&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--split&lt;/span&gt; 2020-01-01
&lt;span class="go"&gt;comparison refused: the 'before' window has no added lines. Check
&lt;/span&gt;&lt;span class="gp"&gt;--author/--since/--until/--split;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;an empty window compared against a real
&lt;span class="go"&gt;one produces fiction, not deltas.
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;span class="go"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That refusal, and the discipline behind it, is the whole of what v0.2 adds to git-habits and diff-habits, two small command-line tools I keep in the open at github.com/rich-atkins. No new metric. They measure what they measured before: commit sizes, rework, moved lines, error-masking constructs, the shape of how a codebase gets written over time. What changed is the set of things they are willing to say out loud, plus a test suite that proves they can still catch what they claim to catch. If that pairing sounds familiar, it should. It is what a decent AI eval does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule I keep arriving at
&lt;/h2&gt;

&lt;p&gt;These two tools point at other people's code. That is their reason to exist: git-habits reads commit metadata and never opens a source file, so you can run it against an employer's repository without a conversation first. A number that comes out of a tool like that carries weight. You will see it pasted into a review, a decision, a slide. So a wrong number is worse than no number, and an unknown quietly rendered as a zero is the worst outcome of all, because it looks like a finding.&lt;/p&gt;

&lt;p&gt;Evals for language models taught me the shape of the fix, from the other end of my work. You do two things. You fail closed on insufficient evidence, so a thin sample produces a refusal rather than a reading. And you prove the thing you built actually detects what it says it detects, rather than assuming it does because the code looks right. v0.2 is those two ideas pushed into a pair of measurement tools that had neither.&lt;/p&gt;

&lt;p&gt;The floors are the first idea made concrete. Every rate now knows its denominator and the point below which it declines to be a number. In git-habits that is five commits for the per-commit rates and 200 changed lines for the churn-based ones. In diff-habits it is 500 added lines, set higher on purpose: masking events are rare, running at roughly 0.2 to 4 per thousand added lines in the samples I have, so a per-thousand rate computed over a couple of hundred lines is noise wearing a number's clothes. Below the floor you get the refusal. Above it you get the figure, still with the old volatility caveats attached. The raw counts stay on screen throughout, because you are owed the evidence, not just the verdict you were going to quote.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proving the detector detects
&lt;/h2&gt;

&lt;p&gt;The second idea is a test suite that builds real git repositories on every run and then tries to fool the tools. There are two of them. One is PLANTED: a clear regime change after a fixed date, where commits swell to roughly six times their earlier size, cadence rises and AI co-author trailers start appearing. The other is CONTROL: the same shape from start to finish, no shift at all. The planted repository must be flagged. The control must stay quiet.&lt;/p&gt;

&lt;p&gt;Both directions are asserted, and that is the part you skip when you are proud of the thing. A detector that always fires is as broken as one that never does, and a demo only ever shows you the first kind of failure. So the control test is the one that earns its keep. It fails if the tool cries wolf.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three bugs it caught on day one
&lt;/h2&gt;

&lt;p&gt;I wrote the self-test to protect work I believed was already correct. It caught three bugs the first time it ran, and the way it caught them is the entire argument for writing it.&lt;/p&gt;

&lt;p&gt;The first was a windowing question I had answered wrongly and confidently. When you split a history into before and after at an instant, which window does a commit landing exactly on the split second belong to? My review predicted the bug would be double-counting, the boundary commit falling into both sides and inflating the totals. The boundary test proved something subtler. Git's &lt;code&gt;--until&lt;/code&gt; is inclusive while its &lt;code&gt;--since&lt;/code&gt; is exclusive, so v0.1 had quietly put every boundary commit in the before window only, and in nobody's after window. Not doubled. Dropped from one side. A plausible story about the bug, refuted by a test before it could become a plausible story in an article.&lt;/p&gt;

&lt;p&gt;The second bug was the fix for the first. My initial correction shifted a single window edge, which felt right and read right. The test refused it, because moving one edge dropped the boundary commit out of both windows instead of one. The commit had gone from appearing once in the wrong place to appearing nowhere at all. The corrected fix anchors both edges one second before the split, so a boundary commit now lands exactly once, in the after window, matching git-habits' convention so the two tools agree about the same commit. Plausible fix, test proves it wrong, corrected fix pinned in place. I would have shipped the first attempt.&lt;/p&gt;

&lt;p&gt;The third bug was the most humbling, because it exposed a claim I had been making for a month. Both tools advertised support back to Python 3.10. Neither had ever parsed a real git date under it. Git emits a trailing &lt;code&gt;Z&lt;/code&gt; on UTC timestamps, and &lt;code&gt;datetime.fromisoformat&lt;/code&gt; only accepts that &lt;code&gt;Z&lt;/code&gt; from Python 3.11 onward. The unit tests fed synthetic logs that never carried the suffix, so the gap sat latent in both repositories since v0.1. The moment the sabotage suite built actual repositories and ran the real pipeline against them, the 3.10 job on CI failed. The floor I had promised was never a floor. It had simply never been tested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this came from, and where it fails
&lt;/h2&gt;

&lt;p&gt;None of this is new to me, which is why it stung. v0.1 of git-habits once reported "0% AI co-authored" for a repository whose trailers had never been captured, an unknown printed as a zero, the exact mistake the floors now forbid. And I watched the same shape appear somewhere with far higher stakes: an LLM eval gate in another project that returned PASS on a run where zero articles were actually judged, because zero judgments contain zero failures. A gate that cannot fail is not a gate. A report that cannot say "not enough evidence" will, given time, lie to you. I have now met that lesson three times, in a metrics tool, in a masking detector and in a model eval, and I have stopped treating them as separate.&lt;/p&gt;

&lt;p&gt;Two honesty notes I will not bury. The floors are defaults with reasons behind them, not universal truths; five commits and 200 lines are low bars for "a number at all", and you should raise them for your own context rather than trust mine. And everything the tools could not tell you before, they still cannot. They do not detect AI, a missing trailer does not prove a human wrote the code, and a young repository cannot hold year-old code. The self-test proves the detector fires on a planted change. It does not turn a coarse signal into a fine one.&lt;/p&gt;

&lt;p&gt;If you maintain anything that measures other people's work, whether a metrics script, a CI check or an eval harness, run one experiment this week. Feed it an input with nothing in it, and watch what it prints. If it hands you a clean zero and a passing exit code instead of refusing, you have not found a quiet week. You have found the day your tool learned to lie politely, and you get to fix it before it does so in front of someone who believes it.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>One LLM judge is an opinion. Two model families agreeing is evidence.</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Wed, 02 Sep 2026 08:44:54 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/one-llm-judge-is-an-opinion-two-model-families-agreeing-is-evidence-2mne</link>
      <guid>https://dev.to/groundedarchitect/one-llm-judge-is-an-opinion-two-model-families-agreeing-is-evidence-2mne</guid>
      <description>&lt;h2&gt;
  
  
  The problem with one judge
&lt;/h2&gt;

&lt;p&gt;I migrated my news pipeline's article rewriting from a local Qwen model to hosted Claude (&lt;a href="https://dev.to/field-notes/the-migration-the-data-ordered"&gt;previous piece&lt;/a&gt;), and before cutting over I needed an answer to a question taste can't settle at scale: does the cloud model hold each of my four writer personas as well as the local one did?&lt;/p&gt;

&lt;p&gt;The standard answer is an LLM-as-judge: give a model a rubric, show it the article, get a score. The standard objection is also correct: a single judge is one model's opinion, with that model family's tastes baked in. And my case had a sharper version of the objection. The candidate prose was written by Claude. If Claude also judges it, every positive result carries an asterisk you can't remove: &lt;em&gt;of course the judge liked its cousin's writing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You don't fix that with a better rubric. You fix it with independence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The panel
&lt;/h2&gt;

&lt;p&gt;So the harness runs a &lt;strong&gt;blind, cross-family panel&lt;/strong&gt;: Claude Opus and Gemini, each scoring the same article against the same persona rubric, five dials from 0 to 5, structured output, neither told which backend produced the text or what the other judge said. The gate takes the average of the two families and flags any article where they meaningfully split.&lt;/p&gt;

&lt;p&gt;The blindness matters more than it sounds. The moment a judge prompt contains "this one is the new model", you're not measuring the article any more, you're measuring the judge's expectations. Strip every provenance clue before the text hits the panel.&lt;/p&gt;

&lt;p&gt;What the panel buys you is a specific kind of defensibility. When one model says your output is good, you have a claim. When two models with different training lineages, different owners and different failure modes read the same text blind and land within a third of a point of each other, you have something a sceptic has to work much harder to dismiss.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it found
&lt;/h2&gt;

&lt;p&gt;On the full weekly set, 85 articles across all four personas, with &lt;strong&gt;both judges covering all 85&lt;/strong&gt;, the verdict wasn't close: &lt;strong&gt;cloud 4.73 out of 5, local 2.19&lt;/strong&gt;, and the cloud won on every persona individually:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Persona&lt;/th&gt;
&lt;th&gt;Local&lt;/th&gt;
&lt;th&gt;Cloud&lt;/th&gt;
&lt;th&gt;Margin&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The Analyst&lt;/td&gt;
&lt;td&gt;2.17&lt;/td&gt;
&lt;td&gt;4.70&lt;/td&gt;
&lt;td&gt;+2.53&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The Engineer&lt;/td&gt;
&lt;td&gt;1.91&lt;/td&gt;
&lt;td&gt;4.63&lt;/td&gt;
&lt;td&gt;+2.72&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The Optimist&lt;/td&gt;
&lt;td&gt;2.30&lt;/td&gt;
&lt;td&gt;4.70&lt;/td&gt;
&lt;td&gt;+2.40&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The Steward&lt;/td&gt;
&lt;td&gt;2.41&lt;/td&gt;
&lt;td&gt;4.83&lt;/td&gt;
&lt;td&gt;+2.42&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overall&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.19&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.73&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+2.54&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two families' scores differed by &lt;strong&gt;0.30 out of 5&lt;/strong&gt; on average. Each judge run independently reaches the same verdict: Opus puts the margin at +2.45, Gemini at +2.64: they disagree slightly about how bad the old prose was, not about the answer. And the panel flagged &lt;strong&gt;3 articles out of 85&lt;/strong&gt; where the judges genuinely split on a dial, every one of them Gemini scoring a persona trait harsher than Opus. That's not a weakness of the method; that's the method working. A panel that never disagrees isn't measuring independently.&lt;/p&gt;

&lt;p&gt;That margin also killed a hedge I'd been keeping alive. I'd held "hosted Qwen-72B" open as an option, on the theory that the &lt;em&gt;exact&lt;/em&gt; current voice was worth preserving. The panel data says the current voice was the weakest thing about the pipeline. Preserving it would have been sentimentality with a monthly invoice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug the gate was hiding
&lt;/h2&gt;

&lt;p&gt;Here's the part that earns this piece its place in a series about what survives production.&lt;/p&gt;

&lt;p&gt;The panel's first real outing was a 12-article run. Both judges failed to start, thanks to a missing API key: the most boring failure there is. The panel logic did what half-thought-through code does: carried on, judged nothing, and the gate reported &lt;strong&gt;PASS&lt;/strong&gt;, because zero judgments contained zero failures.&lt;/p&gt;

&lt;p&gt;A gate that can't fail isn't a gate. It's a rubber stamp with extra steps.&lt;/p&gt;

&lt;p&gt;The fix is the same principle I keep arriving at from different directions: &lt;strong&gt;fail closed on insufficient evidence&lt;/strong&gt;. The gate now refuses to pass unless enough of the sample was actually judged, and a judge dropping out is a loud, visible event rather than a silent shrug.&lt;/p&gt;

&lt;p&gt;Then reality tested the fix within hours. On the full 85-article run, Gemini's free tier (twenty requests a day) ran out after eleven articles. This time the system behaved: Opus coverage held at 85 out of 85, the run proceeded, and the degradation was visible instead of invisible. That became the production policy: if one judge fails, the panel proceeds on the survivor &lt;em&gt;and flags a human&lt;/em&gt;; if both fail, the run fails. Degraded and honest beats complete and fictional.&lt;/p&gt;

&lt;p&gt;If you build eval gates, test the gate itself. Feed it an empty result set and check it fails. Mine didn't, and I only found out because two different things broke on the same Saturday.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs, honestly
&lt;/h2&gt;

&lt;p&gt;The Opus judge came to &lt;strong&gt;$0.035 per article&lt;/strong&gt;, about $3 for the full 85. And the quota story has a punchline: on the paid tier, Gemini judged all 85 articles for &lt;strong&gt;22 cents&lt;/strong&gt;. Twenty free requests a day was never an evals budget; the actual evals budget turned out to be less than a postage stamp. For continuous production use we still sample: mechanical checks (structure, length, banned phrases) run on every article for pennies, and the two-judge panel runs on a stratified dozen per week.&lt;/p&gt;

&lt;p&gt;Caveats, because they're load-bearing: this compared new-model-plus-new-window against old-model-plus-old-limits, an era confound as much as a model one; one persona had only two samples in the set; and judge-versus-human calibration is still ahead of us (the panel agreeing with itself is necessary, not sufficient). The scores are directional evidence with unusually good provenance, not a leaderboard.&lt;/p&gt;

&lt;p&gt;But the method stands on its own: blind the judges, cross the families, gate on the average, and above all, make sure the gate can actually say no.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>testing</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>The migration the data ordered: moving a production LLM pipeline off the Mac Mini under my desk</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Mon, 31 Aug 2026 16:24:59 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/the-migration-the-data-ordered-moving-a-production-llm-pipeline-off-the-mac-mini-under-my-desk-5fd8</link>
      <guid>https://dev.to/groundedarchitect/the-migration-the-data-ordered-moving-a-production-llm-pipeline-off-the-mac-mini-under-my-desk-5fd8</guid>
      <description>&lt;h2&gt;
  
  
  The bill, up front
&lt;/h2&gt;

&lt;p&gt;Last week my news pipeline rewrote a full weekly batch of 85 articles in the cloud, across all four of its writer personas. The rewriting bill was &lt;strong&gt;$4.31&lt;/strong&gt;, which is &lt;strong&gt;$0.051 per article&lt;/strong&gt;. Even counting the blind two-judge panel that then scored every one of those articles against the old local output, the whole exercise metered &lt;strong&gt;$7.47&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a year that same work ran on a Mac Mini under my desk: a 72-billion-parameter model on Ollama, FLUX generating images on the GPU, launchd waking everything on Thursdays. I'd already &lt;a href="https://dev.to/field-notes/real-economics-of-a-production-llm-pipeline"&gt;measured the economics of that setup&lt;/a&gt; and published the break-even: at my scale, hosted APIs with batch pricing were roughly 8 to 12 times cheaper than the fully-loaded cost of the local hardware. Then I kept running it locally anyway, because the marginal cost of a machine you already own is nearly zero and the data said the &lt;em&gt;money&lt;/em&gt; didn't matter much either way.&lt;/p&gt;

&lt;p&gt;So why move? Because money was never the real bill. The real bill was operational: a single point of failure with a 40-minute cold load, model files on a USB SSD, and a fragility class all of its own. When the machine sneezed, the product missed its week. You can't put a price on that in a cost model, which is exactly how it hides.&lt;/p&gt;

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

&lt;p&gt;Three things were local; everything else already lived in the cloud.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;LLM calls&lt;/strong&gt; went from local Qwen (72b for writing, 14b for classifying) to hosted Claude, tiered the same way: a cheap fast model for clustering, tagging and novelty checks, a quality model for the rewrites. Every pipeline call now goes through the Batches API, which halves the token price in exchange for latency I don't care about at 3am.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;images&lt;/strong&gt; went from FLUX running in-process on the GPU to the same FLUX model behind fal.ai's API. Same model, so the product's visual language didn't change. That one mattered to me: a migration should be invisible to readers.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;orchestration&lt;/strong&gt; went from launchd to Azure Container Apps Jobs: a container on a cron, scale-to-zero, secrets in Key Vault, and a 24-hour task timeout that lets a batch submit, wait and collect inside a single invocation.&lt;/p&gt;

&lt;p&gt;One codebase runs both worlds. Each stage picks its backend from an environment variable, so cutover is a config change and rollback is the same change backwards.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the plan got wrong
&lt;/h2&gt;

&lt;p&gt;The migration brief was written against a clean mental model. Reality filed corrections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There were 21 LLM call sites, not the 13 I'd counted.&lt;/strong&gt; Thirteen named helpers, plus eight inline HTTP calls hiding in scripts, most with their own hand-rolled streaming loop and hardcoded URL. The first real move wasn't "swap the provider", it was "make there be one client". If you take nothing else from this piece: count your call sites before you estimate your migration, then consolidate before you&lt;br&gt;
swap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There were no retries anywhere.&lt;/strong&gt; A local Ollama never rate-limits you, so the code had never needed them. Hosted APIs do. Without a retry layer, every transient 429 becomes a permanently failed article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumable state turned out to be dangerous.&lt;/strong&gt; The old design persisted an in-flight batch id so a crashed run could reconnect. In a container that restarts from a clean disk, the run re-derives its candidate list, and here's the trap: the new list isn't guaranteed to match the old one. Reconnect to the old batch and you&lt;br&gt;
can publish content under the wrong article. We made recovery fail closed instead: abandon the orphaned batch, eat the few dollars, re-submit fresh. Correctness beats cost recovery every time the two collide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The local model's scars were still in the prompts.&lt;/strong&gt; A 4k context cap and a 3,000-character source-content limit existed purely because of VRAM. Lifting them was a deliberate decision with a measurable cost delta, not a cleanup. Same for the banned-phrase filter that force-rewrote model output: the local model needed it; the hosted one triggered it exactly &lt;strong&gt;once in 85 articles&lt;/strong&gt;. It now runs as a detector first and an enforcer second, because you should measure a guard before you let it edit your prose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Did quality survive?
&lt;/h2&gt;

&lt;p&gt;Better than survived. A blind two-model judge panel, both judges covering all 85 articles from both backends, scored persona adherence at &lt;strong&gt;cloud 4.73 out of 5 against local 2.19&lt;/strong&gt;, a win on every one of the four personas. The mechanical checks said the same thing from a different angle: every cloud article passed the structure checks; 78% of the local ones did. The panel design (and the bug it caught in its own gate) is the next piece; the headline here is that the migration wasn't a cost-neutral quality trade. The bigger source window alone, un-cramped from its VRAM-era 3,000 characters, gives the writer model more to work with.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs now
&lt;/h2&gt;

&lt;p&gt;About &lt;strong&gt;$10 a month&lt;/strong&gt; of pipeline compute delta: rewrites at $0.051 an article with batch pricing and prompt caching, images at fractions of a cent, the container mostly asleep. Set against roughly £50 a year of electricity for the Mini, this migration will never pay for itself in cash. It pays for itself the first Thursday the pipeline runs while the Mini is switched off, in a hotel, or in a skip.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other currency
&lt;/h2&gt;

&lt;p&gt;Cost models compare money because money is easy to put in a column. The column that never appears is time, and locally the pipeline spent it in three ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Machine time.&lt;/strong&gt; A 72-billion-parameter model on consumer hardware writes one article at a time, because a second one would blow the memory. Before it writes anything at all, cold-loading the model from an external SSD could take forty minutes. On the measured run, the local pass spent about &lt;strong&gt;four and a half hours&lt;/strong&gt; rewriting the 85 articles (an upper bound from file timestamps, since the machine was juggling other stages in the gaps). The cloud pass wrote the same 85 in &lt;strong&gt;48 minutes&lt;/strong&gt;. The Mini spent its hours as a pipeline appliance and nothing else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My time.&lt;/strong&gt; This is the expensive one. The local stack had a fragility class the cost model never saw: model reloads, broken Python relinks, a launchd job that needed its owner nearby. Every "cheap" local run carried an invisible surcharge of owner-hours, billed at whatever your evening is worth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The exchange rate you choose.&lt;/strong&gt; The cloud makes the time-money trade explicit and lets you pick a side per workload. Synchronous calls cost full price and answer in seconds. The Batches API charges half price for answers within a day. A pipeline that runs while you sleep should always sell its latency, because overnight latency is worthless to you and the API pays you 50% for it. That's the quiet insight batch pricing encodes: time and money are convertible, and the smart move is to sell the one you're not using.&lt;/p&gt;

&lt;p&gt;Cloud inference isn't just cheaper per token at my scale. It converts hours of machine-sitting into minutes of nobody-sitting, and it hands the 3am problem to someone whose job is 3am problems.&lt;/p&gt;

&lt;p&gt;Measure your own crossover, in both currencies. And when the money column says "either way", read the two columns the spreadsheet doesn't have: whose hours are being spent, and what breaks at 3am with only you to fix it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>cloudnative</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>An MCP server that has to prove itself: citations, abstention and entitlements as CI gates</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Sun, 30 Aug 2026 22:35:45 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/an-mcp-server-that-has-to-prove-itself-citations-abstention-and-entitlements-as-ci-gates-512b</link>
      <guid>https://dev.to/groundedarchitect/an-mcp-server-that-has-to-prove-itself-citations-abstention-and-entitlements-as-ci-gates-512b</guid>
      <description>&lt;h2&gt;
  
  
  The demo, in one screen
&lt;/h2&gt;

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

&lt;p&gt;Here's the eval scorecard for a small MCP server on a green build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;retrieval   (staff, n=22):  hit@1 1.00   recall@5 1.00   MRR 1.00
abstention  (n=10):         rate  1.00   (target 1.00)
leakage     : 0 (must be 0)
redaction   : 0 (must be 0)
EVAL GATE: PASS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I weaken one thing. Two environment variables drop the server's relevance bar to&lt;br&gt;
zero, the setting where it returns its best guess for every question instead of&lt;br&gt;
admitting defeat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstention  (n=10):         rate  0.40   (target 1.00)
  FALSE-ANSWER  'customer refund policy' -&amp;gt; internal/hr/expenses-policy.md (score 4.29)
  FALSE-ANSWER  'office dog policy'      -&amp;gt; internal/hr/expenses-policy.md (score 4.29)
EVAL GATE: FAIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit code 1. The build is red. Nobody had to notice the server had started making&lt;br&gt;
things up, because the pipeline noticed first.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why bother?
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol has made it absurdly easy to hand an agent your knowledge&lt;br&gt;
base. There are hundreds of servers that expose notes, wikis and docs as searchable&lt;br&gt;
tools, and most of them work fine as plumbing. But before you let an agent answer&lt;br&gt;
questions out of your company handbook, there are three questions the plumbing never&lt;br&gt;
answers.&lt;/p&gt;

&lt;p&gt;Can you trust what comes back? When the server returns a snippet, can the agent cite&lt;br&gt;
where it came from, precisely enough that a human can check?&lt;/p&gt;

&lt;p&gt;Does it know when it doesn't know? Ask a vault about a policy that isn't in it and&lt;br&gt;
BM25 will cheerfully return the closest-sounding note anyway. The agent, primed to&lt;br&gt;
trust its tools, turns that into a confident answer about a document that does not&lt;br&gt;
exist.&lt;/p&gt;

&lt;p&gt;And who is allowed to see what? If your vault has a &lt;code&gt;restricted/&lt;/code&gt; folder, "the search&lt;br&gt;
tool filters those results out" is not an answer. It's the start of an incident report.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://github.com/rich-atkins/grounded-mcp" rel="noopener noreferrer"&gt;grounded-mcp&lt;/a&gt;: a small Python&lt;br&gt;
MCP server over a folder of markdown (Obsidian works as-is) with three guardrails.&lt;br&gt;
Every content-bearing response carries a stable citation id, path plus heading plus&lt;br&gt;
line span. Search abstains, explicitly and structurally, when nothing clears the&lt;br&gt;
relevance bar. And entitlements are enforced at index level: content a profile can't&lt;br&gt;
see is never indexed for it in the first place.&lt;/p&gt;

&lt;p&gt;None of which would be worth writing about, except for one decision: the repo ships&lt;br&gt;
with its own eval suite, and the suite is the CI gate. That decision paid for itself&lt;br&gt;
on the first run.&lt;/p&gt;
&lt;h2&gt;
  
  
  The first honest run found a real bug
&lt;/h2&gt;

&lt;p&gt;The eval suite runs four families against a committed demo vault (a fictional company&lt;br&gt;
handbook with public, internal and restricted zones): a golden retrieval set, a set of&lt;br&gt;
questions whose answers are deliberately not in the vault, a leakage set answerable&lt;br&gt;
only from restricted content, and a redaction check against a seeded fake credential.&lt;/p&gt;

&lt;p&gt;First run: retrieval perfect, leakage zero, redaction zero. Abstention: &lt;strong&gt;0.30&lt;/strong&gt;.&lt;br&gt;
Seven of ten unanswerable questions came back with confident wrong answers.&lt;/p&gt;

&lt;p&gt;The interesting part is why. I had assumed a BM25 score threshold would separate real&lt;br&gt;
answers from plausible noise. The data said no:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;true answers:    scores 2.44 to 14.68
false answers:   scores 2.12 to 4.29
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ranges overlap. "How long is probation" scores 2.44 against the note that&lt;br&gt;
genuinely answers it, while "customer refund policy" scores 4.29 against an expenses&lt;br&gt;
policy that says nothing about refunds. One common word landing in a heavily weighted&lt;br&gt;
title field looks exactly like relevance. No threshold exists that keeps the first and&lt;br&gt;
rejects the second.&lt;/p&gt;

&lt;p&gt;What does separate them is coverage: what fraction of the query's content words the&lt;br&gt;
note actually contains. The false answers ride on one matching word ("policy") and&lt;br&gt;
their coverage collapses once you stop counting scaffolding like "what is the". So&lt;br&gt;
abstention became a double gate: score above threshold AND coverage above half. That&lt;br&gt;
took the rate from 0.30 to 1.00 with zero retrieval loss.&lt;/p&gt;

&lt;p&gt;Then the gate caught two more bugs, in my fix. Naive substring matching decided&lt;br&gt;
"code" doesn't appear in a note that only says "coding", and a hyphenated&lt;br&gt;
"AI-generated" hid both of its parts from a query about AI. Light suffix-stripping and&lt;br&gt;
splitting compounds fixed both, and I know the fixes didn't break anything else&lt;br&gt;
because 24 golden queries and the leakage set re-ran on every attempt. The eval suite&lt;br&gt;
was the code review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leakage is a ranking problem, not a filter problem
&lt;/h2&gt;

&lt;p&gt;The entitlements design deserves one more paragraph, because the obvious&lt;br&gt;
implementation is quietly wrong. Most access control on search works by filtering&lt;br&gt;
results: retrieve everything, then drop what the caller shouldn't see. That leaks. A&lt;br&gt;
filtered result still influenced rankings. Its terms still matched. In some systems&lt;br&gt;
the result count still moves, and now your search tool is an existence oracle for the&lt;br&gt;
documents you hid.&lt;/p&gt;

&lt;p&gt;grounded-mcp builds a separate index per entitlements profile, containing only the&lt;br&gt;
notes that profile may see. Denied content is never scored, so there is nothing to&lt;br&gt;
filter and nothing to leak. The eval suite's leakage family checks this at the&lt;br&gt;
harshest setting, thresholds off entirely, and any hit from a denied path fails the&lt;br&gt;
build. Same principle for direct reads: a denied note and a nonexistent note return&lt;br&gt;
byte-identical responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't do
&lt;/h2&gt;

&lt;p&gt;Honesty section. Over stdio, client and server run as the same user, so profiles&lt;br&gt;
demonstrate the deployment pattern rather than defend against a hostile peer; real&lt;br&gt;
per-client enforcement arrives with the HTTP transport in v0.2. Retrieval is plain&lt;br&gt;
BM25, deliberately: it's deterministic, dependency-free and measurable, and when&lt;br&gt;
hybrid semantic retrieval lands it has to publish its eval delta against this&lt;br&gt;
baseline or it doesn't land. The redaction patterns catch key-shaped strings, not&lt;br&gt;
every secret. And there are no write tools. A server that can quote your vault but&lt;br&gt;
never rewrite it is a trust feature, not a gap in the roadmap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The repo is &lt;a href="https://github.com/rich-atkins/grounded-mcp" rel="noopener noreferrer"&gt;github.com/rich-atkins/grounded-mcp&lt;/a&gt;,&lt;br&gt;
MIT licensed. &lt;code&gt;pip install -e .&lt;/code&gt;, point &lt;code&gt;GROUNDED_VAULT&lt;/code&gt; at your notes, wire it into&lt;br&gt;
Claude Code or Claude Desktop with a five-line config. Run the evals, then run the&lt;br&gt;
sabotage demo and watch the gate go red.&lt;/p&gt;

&lt;p&gt;Better still: write ten questions your vault can't answer and add them to the&lt;br&gt;
abstention set. If your knowledge server passes that test today, you're doing better&lt;br&gt;
than mine was on Friday morning.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
      <category>python</category>
    </item>
    <item>
      <title>Cutting juniors is a choice, not an AI inevitability</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Sun, 09 Aug 2026 05:06:00 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/cutting-juniors-is-a-choice-not-an-ai-inevitability-46c3</link>
      <guid>https://dev.to/groundedarchitect/cutting-juniors-is-a-choice-not-an-ai-inevitability-46c3</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 5 of five, the finale. "AI, leadership and the human structures of work" is a series on what AI actually changes about leading people, and why those changes are choices, not inevitabilities.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Walk into a team that has quietly stopped hiring juniors and it looks fine. Better than fine: leaner, faster, all senior, nobody to train. It looks like that for years. It keeps looking like that right up until the seniors start to retire and there is no one behind them, and by then the problem took a decade to make and cannot be fixed in a quarter. This is the choice with the longest shadow in the whole series, and the one the industry is sleepwalking into.&lt;/p&gt;

&lt;p&gt;We have argued that AI's costs, to wellbeing, to expertise, to how we manage, and to how we organise, are all leadership choices dressed up as inevitabilities. Here is the biggest one.&lt;/p&gt;

&lt;p&gt;Across knowledge work, the entry-level door is closing. This is not a vibe; it is now measured. A Stanford study tracking payroll records for millions of workers found that those aged 22 to 25 in the most AI-exposed jobs have seen real declines: employment for young software developers is down roughly 20% since late 2022, with customer service among the other hardest-hit occupations, while employment for experienced workers in the same fields held up. The juniors are the canaries in the coal mine.&lt;/p&gt;

&lt;p&gt;A separate line of evidence points the same way from entirely different data. PwC's 2026 AI Jobs Barometer analysed more than a billion job postings rather than payroll records, and found the entry-level rung has not so much vanished as risen out of reach: entry-level roles in highly AI-exposed occupations are now seven times more likely to demand skills that historically appeared later in a career, and 52% of newly appearing entry-level skills were ones previously associated with experienced workers, against just 7% in the least-exposed fields. Traditional entry-level positions shrank 10% since 2019. Two different methods, one direction, and the second tells you &lt;em&gt;how&lt;/em&gt; the door is closing: not by removing the job title, but by loading it with prerequisites no beginner can have.&lt;/p&gt;

&lt;p&gt;But the same study contains the fact that turns this from a lament into an argument. The decline showed up in jobs where AI &lt;em&gt;automates&lt;/em&gt; the work. In jobs where AI &lt;em&gt;augments&lt;/em&gt; the worker, entry-level employment did not fall. Same technology. Two deployment choices. Two completely different outcomes for a generation of workers. That is the whole thesis of this series, made visible in the labour data: automate or augment is a choice, and it is landing on the youngest first.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, be honest about the cause
&lt;/h2&gt;

&lt;p&gt;It is tempting, and self-serving for anyone senior, to pin the collapse of junior hiring entirely on AI. So let me steelman the sceptic: 2022 to 2025 also brought higher interest rates, a correction after pandemic over-hiring, and tighter budgets. Plenty of the entry-level squeeze is the ordinary business cycle, not the technology.&lt;/p&gt;

&lt;p&gt;The Stanford authors ran exactly that challenge, which is why their finding is worth citing rather than the usual hand-waving. They checked interest rates and found that AI-exposed jobs are actually &lt;em&gt;less&lt;/em&gt; sensitive to rates than average, so rate rises do not explain why those specific jobs shed their juniors. The AI-exposed decline holds up after controlling for the obvious economic factors. AI is not the only thing happening in the labour market. But on the best evidence we have, it is doing real, specific work here, and "it's just the economy" no longer covers it.&lt;/p&gt;

&lt;p&gt;It is also genuinely contested, and worth saying so. The &lt;em&gt;Financial Times&lt;/em&gt; recently argued that AI is not destroying entry-level work so much as changing it, pointing to US employers who expect to hire around 5.6% more new graduates this year. Both things can be true at once. Aggregate graduate hiring can rise while the specific, AI-exposed junior roles fall, which is exactly what the Stanford data shows: entry-level employment is climbing in the least AI-exposed jobs and dropping in the most exposed. The average hides the sorting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The counter-argument, taken seriously
&lt;/h2&gt;

&lt;p&gt;The sharper objection is the optimistic one: even if juniors are being automated, maybe that is fine. Maybe we simply need fewer people, and AI will conjure new entry-level roles we cannot yet see, as every technology wave eventually has.&lt;/p&gt;

&lt;p&gt;Two problems. First, "new roles will appear" is a hope, not a plan, and it asks a specific cohort of real people to absorb the gap while we wait to be proven right. Second, and more concrete, the best evidence says automating juniors is not even the efficient move. In the Harvard and BCG study I cited earlier in this series, the people who improved most with AI were the least experienced; the floor rose faster than the ceiling. So the economically rational play is to pair a junior with AI and get near-senior output at junior cost, exactly the "augment" path the Stanford data shows protects entry-level jobs. Cutting the junior instead is not the efficient choice. It is the cheap-this-quarter one. Which makes it a choice, and a short-sighted one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pincer
&lt;/h2&gt;

&lt;p&gt;Now put this next to something I planted earlier in the series and deliberately left unresolved: intuition rust. In a year-long study of cancer specialists using AI in clinical work, the researchers found early productivity gains quietly masking a dulling of the clinicians' own judgment. The expertise eroded without symptoms, until it was gone. That is a narrow population and I would not stretch it further than it goes, but the mechanism is not specialty-specific: skill atrophies when you stop exercising it, and AI is very good at letting you stop.&lt;/p&gt;

&lt;p&gt;Hold both facts at once. You are cutting off the supply of new experts at the bottom, because AI can do junior work. And you are quietly de-skilling your existing experts at the top, because AI is doing their work too. No one coming in. The ones you have, rusting. That is a pincer on expertise, and it closes slowly enough that no single quarter's numbers ever show it. There are now names for both jaws of it: "intuition rust" for the experts quietly losing their edge, and "never skilling" for the juniors who never build one, because the work that would have built it was automated before they arrived.&lt;/p&gt;

&lt;p&gt;There is a farming phrase for exactly this: eating your seed corn. When times are hard you can eat the grain you saved to plant next year. It feeds you now. It guarantees there is nothing to harvest later. Automating the juniors while offloading the seniors' judgment to the machine is eating the seed corn of your own profession, and calling the fuller belly a productivity gain.&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%2Fjc54fcwllcii0msdubv0.jpg" 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%2Fjc54fcwllcii0msdubv0.jpg" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the question the pincer forces, and almost nobody in the "automate the juniors" conversation is asking it. Where do the seniors of 2035 come from? The senior you are hiring today became senior by doing, badly and then well, the junior work you are now automating away. Remove the rung and you do not just lose this year's juniors. You lose the mechanism that produces every future senior. And the people you are counting on to supervise the AI, whose judgment is the last line against a confidently wrong machine, are the exact people quietly losing that judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this asks of a leader
&lt;/h2&gt;

&lt;p&gt;Treat your junior pipeline as capability infrastructure, not a cost line. Pair juniors with AI rather than replacing them, the augment path, not because it is kind but because the data says it is the smarter economics &lt;em&gt;and&lt;/em&gt; the only way to keep making experts. Protect the deliberate, inefficient practice, in juniors and seniors both, that builds the judgment no model has. Some slowness is not waste. It is how expertise is made, and it is the first thing an efficiency drive deletes.&lt;/p&gt;

&lt;p&gt;That is the whole series in one idea. AI hands you options, not outcomes. It can lift your weakest people or hollow out your strongest. It can make work feel owned or make it feel like babysitting a machine. It can build an enabling organisation or a queue. It can grow the next generation of experts or eat the seed that would have become them. Every one of those is decided by a person, not the technology. The costs are real, the evidence is clear, and the choice, every time, is yours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The series: AI, leadership and the human structures of work&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The psychological cost of AI is a leadership choice, not a technology outcome&lt;/li&gt;
&lt;li&gt;Who's the authority now? Leading in the age of the jagged generalist&lt;/li&gt;
&lt;li&gt;Managing a team of agents: leadership when roles become software&lt;/li&gt;
&lt;li&gt;Org design for AI: why your Centre of Excellence becomes a bottleneck&lt;/li&gt;
&lt;li&gt;Cutting juniors is a choice, not an AI inevitability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;You are reading part 5, the finale. Links added as each publishes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Written by Richard Atkins.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Sources: Brynjolfsson, Chandar &amp;amp; Chen, "Canaries in the Coal Mine? Six Facts about the Recent Employment Effects of AI", Stanford Digital Economy Lab (ADP payroll microdata; the overall relative decline for ages 22–25 in the most AI-exposed occupations was revised from 13% to 16% in the February 2026 update) — &lt;a href="https://digitaleconomy.stanford.edu/publication/canaries-in-the-coal-mine-six-facts-about-the-recent-employment-effects-of-artificial-intelligence/" rel="noopener noreferrer"&gt;https://digitaleconomy.stanford.edu/publication/canaries-in-the-coal-mine-six-facts-about-the-recent-employment-effects-of-artificial-intelligence/&lt;/a&gt; ; the authors' interest-rates follow-up — &lt;a href="https://digitaleconomy.stanford.edu/news/canaries-interest-rates-and-timinga-more-on-recent-drivers-of-employment-changes-for-young-workers/" rel="noopener noreferrer"&gt;https://digitaleconomy.stanford.edu/news/canaries-interest-rates-and-timinga-more-on-recent-drivers-of-employment-changes-for-young-workers/&lt;/a&gt; · PwC, 2026 Global AI Jobs Barometer (analysis of 1bn+ job postings) — &lt;a href="https://www.pwc.com/gx/en/news-room/press-releases/2026/pwc-2026-ai-jobs-barometer.html" rel="noopener noreferrer"&gt;https://www.pwc.com/gx/en/news-room/press-releases/2026/pwc-2026-ai-jobs-barometer.html&lt;/a&gt; · Dell'Acqua et al. (2023), Harvard/BCG jagged-frontier study — &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4573321" rel="noopener noreferrer"&gt;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4573321&lt;/a&gt; · Ehsan et al. (2026), "From Future of Work to Future of Workers", the "intuition rust" study (year-long study of cancer specialists; CHI 2026) — &lt;a href="https://arxiv.org/abs/2601.21920" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2601.21920&lt;/a&gt; · "never-skilling": Ke et al. (2026), "AI-induced never-skilling in medical education", &lt;em&gt;Nature Medicine&lt;/em&gt; 32(6) — &lt;a href="https://www.nature.com/articles/s41591-026-04438-y" rel="noopener noreferrer"&gt;https://www.nature.com/articles/s41591-026-04438-y&lt;/a&gt; · Class of 2026 graduate hiring projection (+5.6%): NACE Job Outlook Spring Update, April 2026 — &lt;a href="https://www.naceweb.org/job-market/trends-and-predictions/" rel="noopener noreferrer"&gt;https://www.naceweb.org/job-market/trends-and-predictions/&lt;/a&gt; ; "AI isn't destroying entry-level jobs. It's changing them", Financial Times (2026).&lt;/small&gt;&lt;/p&gt;




&lt;p&gt;📬 &lt;strong&gt;&lt;a href="https://buttondown.com/groundedarchitect" rel="noopener noreferrer"&gt;Subscribe to &lt;em&gt;The Grounded Architect&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; — field notes on building production AI, and leading the people around it. Straight to your inbox, no hype.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>ai</category>
      <category>hiring</category>
      <category>career</category>
    </item>
    <item>
      <title>The code that hides the evidence</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Wed, 05 Aug 2026 10:24:00 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/the-code-that-hides-the-evidence-2eae</link>
      <guid>https://dev.to/groundedarchitect/the-code-that-hides-the-evidence-2eae</guid>
      <description>&lt;p&gt;&lt;em&gt;Part of "AI, engineering and what survives production", a series on the parts of building with AI that hold up once real traffic hits them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There is a category of code that nobody defends in principle and everybody writes in practice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;syncCustomerRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You do not think that is good. Neither do I, and I have written it. It gets written anyway, usually at the end of a long day, usually because the failure was intermittent and the deadline was not. And it is worse than the bug it silences, because the bug at least had the decency to announce itself.&lt;/p&gt;

&lt;p&gt;The distinction that matters is between &lt;strong&gt;handling&lt;/strong&gt; a failure and &lt;strong&gt;hiding&lt;/strong&gt; one. A catch block that logs, retries, or rethrows with context is engineering. A catch block that swallows is a deleted alarm. From ten feet away the two look identical: both are three lines and a pair of braces, both make the red text stop.&lt;/p&gt;

&lt;p&gt;Here is what interested me: this category is &lt;em&gt;countable&lt;/em&gt;. Not perfectly, but well enough to see a trend in your own codebase. So I built a tool to count it, pointed it at seven repositories I had worked in, and got an answer I was not expecting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What counts as masking
&lt;/h2&gt;

&lt;p&gt;I split it into two tiers, and keeping them separate is the decision that makes the whole number defensible. My first version had a single score, and I abandoned it within an hour of pointing it at a real TypeScript codebase, for reasons I will come to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hard masking&lt;/strong&gt; removes a signal outright and is difficult to justify:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Empty catch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;catch (e) {}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Silenced exception&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;except ValueError: pass&lt;/code&gt;, &lt;code&gt;rescue nil&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suppressed checking&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;@ts-ignore&lt;/code&gt;, &lt;code&gt;# noqa&lt;/code&gt;, &lt;code&gt;eslint-disable&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weakened typing&lt;/td&gt;
&lt;td&gt;&lt;code&gt;as any&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stubbed return&lt;/td&gt;
&lt;td&gt;&lt;code&gt;return None  # TODO&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discarded error&lt;/td&gt;
&lt;td&gt;Go's &lt;code&gt;_&lt;/code&gt; assignment over an &lt;code&gt;err&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Soft masking&lt;/strong&gt; is legitimate often enough that putting it in a headline would mislead: optional chaining, nullish defaults, TODO markers.&lt;/p&gt;

&lt;p&gt;Consider &lt;code&gt;user?.profile?.name&lt;/code&gt;. On a genuinely optional field that is correct code. The same expression, written because something in the chain was unexpectedly undefined and the &lt;code&gt;?.&lt;/code&gt; made the error go away, is a completely different act with identical syntax. No static tool can tell those apart, and I stopped trying. So soft constructs are counted separately, reported separately, and the judgement stays with you rather than being quietly made on your behalf.&lt;/p&gt;

&lt;p&gt;That split is not fussiness, it is what I learned from the version I threw away. Fold optional chaining into one score and a modern TypeScript codebase produces an alarming number that means nothing at all. The first person to check it will find their own perfectly reasonable &lt;code&gt;?.&lt;/code&gt; in the count, conclude the tool is crying wolf, and never open it again. One number you can defend beats two you cannot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Count only what was added
&lt;/h2&gt;

&lt;p&gt;I measure additions and ignore deletions. A deletion cannot introduce a swallowed error, and counting both sides double-counts a line that has merely moved from one file to another.&lt;/p&gt;

&lt;p&gt;Then normalise per thousand added lines, for the same reason as ever: a raw count tracks how much you wrote that month, and what you want to know is density. Otherwise a productive quarter looks like a decline in quality, and you will spend a week investigating the wrong thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the output looks like
&lt;/h2&gt;

&lt;p&gt;Real output, from the data pipeline behind this publication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff-habits scan

  a data pipeline
    commits / files      360 / 584
    added lines          121,560  (83,840 meaningful)
    error masking (hard) 229  (1.88 per 1k added)
    error masking (soft) 417  (3.43 per 1k added)
    top patterns         nullish_default=232, stub_return=187,
                         optional_chain=175, any_cast_ts=22, lint_suppress=20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern breakdown is the part I actually act on. "229 hard hits" is a number I can do&lt;br&gt;
nothing with. "187 stubbed returns" is a Monday morning: I go and look at what those&lt;br&gt;
functions hand back when the thing they called did not answer, and I usually find two or&lt;br&gt;
three that should have been raising instead of shrugging.&lt;/p&gt;
&lt;h2&gt;
  
  
  What I found, and why it is not what I expected
&lt;/h2&gt;

&lt;p&gt;Pointing this at seven repositories, hard-masking density ranged from &lt;strong&gt;0.16 to 4.0 per thousand added lines&lt;/strong&gt;. That is a twenty-five-fold spread across codebases written by the same three people.&lt;/p&gt;

&lt;p&gt;The highest was a data pipeline that scrapes web content and calls language models. The lowest was a small marketing site.&lt;/p&gt;

&lt;p&gt;Sit with that for a moment, because it is the whole lesson. &lt;strong&gt;The pipeline is not badly written. It is defensively written, correctly.&lt;/strong&gt; Networks time out. Scraped pages change shape. Model output is unreliable by construction. Code that talks to unreliable things needs guards, and those guards look exactly like masking to a regex.&lt;/p&gt;

&lt;p&gt;Which gives the finding I did not want and now think is the most useful thing here: &lt;strong&gt;error-masking density is dominated by problem domain, not by who or what wrote the code.&lt;/strong&gt; I had a tidy hypothesis about authorship. The data said the strongest predictor was what the code talks to.&lt;/p&gt;

&lt;p&gt;So if you compare masking density between two different codebases, what you learn is which one has the flakier dependencies. You learn nothing whatsoever about their authors. &lt;strong&gt;Compare a codebase with itself, over time.&lt;/strong&gt; That is the only comparison this metric will support, and I would rather tell you that than let you draw a conclusion it cannot carry.&lt;/p&gt;
&lt;h2&gt;
  
  
  What a rise actually means
&lt;/h2&gt;

&lt;p&gt;A rise is not automatically bad, and I was careful to build a tool that does not imply otherwise, because one that scolds you gets uninstalled.&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%2F7gnb8fiansr5bd7mo3gx.jpg" 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%2F7gnb8fiansr5bd7mo3gx.jpg" alt=" " width="800" height="512"&gt;&lt;/a&gt;Hardening a service against a genuinely flaky dependency raises the count and is usually the right call. So rising density says &lt;em&gt;look here&lt;/em&gt;, not &lt;em&gt;you have failed&lt;/em&gt;. What I want to know when I see it is whether the guards I added are logging, alerting, or falling back deliberately, or whether they are quietly returning empty and leaving the caller to draw its own conclusions. Those two look the same in a diff and could not be less alike in production.&lt;/p&gt;

&lt;p&gt;The question the number should prompt is the one I now ask myself in review: &lt;strong&gt;if this construct fires at three in the morning, does anybody find out?&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The honest limitations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;These are regexes, not a parser.&lt;/strong&gt; They over-count a legitimate optional chain and under-count a swallow spread across several lines. &lt;code&gt;except ValueError:&lt;/code&gt; on one line followed by an indented &lt;code&gt;pass&lt;/code&gt; on the next slips straight through, and catching that properly needs an AST rather than a pattern. I decided that was a worthwhile trade for something you can run on any language in a second, but it means the trend is the meaningful part and a single absolute number is not an audit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language scoping matters more than I expected.&lt;/strong&gt; An early version cheerfully matched TypeScript optional chaining inside Python files, which is obvious in hindsight and was not obvious to me until the numbers came out strange. Patterns are scoped by file extension now. If you extend the pattern list, scope yours too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small counts are noise, and I nearly fooled myself with one.&lt;/strong&gt; A repository of mine produced a single hit across six thousand lines, and for about ten minutes I read that as an impressively clean codebase. It is not a low density. It is not enough data to have a density at all.&lt;/p&gt;
&lt;h2&gt;
  
  
  Try it on yours
&lt;/h2&gt;

&lt;p&gt;Python 3.10 or newer. It depends on &lt;a href="https://github.com/uxdw/git-habits" rel="noopener noreferrer"&gt;git-habits&lt;/a&gt;,&lt;br&gt;
so exclusion rules stay identical between the two tools and their numbers remain&lt;br&gt;
comparable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rich-atkins/diff-habits &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;diff-habits
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; .venv/bin/pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

diff-habits scan    &lt;span class="nt"&gt;--repo&lt;/span&gt; /your/repo &lt;span class="nt"&gt;--author&lt;/span&gt; &lt;span class="s2"&gt;"you@example.com"&lt;/span&gt;
diff-habits compare &lt;span class="nt"&gt;--repo&lt;/span&gt; /your/repo &lt;span class="nt"&gt;--author&lt;/span&gt; &lt;span class="s2"&gt;"you@example.com"&lt;/span&gt; &lt;span class="nt"&gt;--split&lt;/span&gt; 2026-01-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike &lt;code&gt;git-habits&lt;/code&gt;, this one needs a real working repository. It reads diff bodies, and&lt;br&gt;
a metadata export does not contain them.&lt;/p&gt;

&lt;p&gt;It reads locally and emits counts. Nothing is uploaded, and there is no network access to upload it with.&lt;/p&gt;

&lt;p&gt;That is deliberate, and it is why this is a separate tool from its companion &lt;a href="https://github.com/rich-atkins/git-habits" rel="noopener noreferrer"&gt;git-habits&lt;/a&gt; rather than a flag on it. &lt;code&gt;git-habits&lt;/code&gt; works from commit metadata and never opens a source file, so you can run it on an employer's repository without a conversation. This one reads your code. That is a different decision, and it should be a different install rather than a flag you might not notice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is deliberately missing
&lt;/h2&gt;

&lt;p&gt;The tool also implements block duplication, and it is &lt;strong&gt;off by default&lt;/strong&gt; behind &lt;code&gt;--experimental-duplication&lt;/code&gt;. The current approach counts any five-line sequence recurring anywhere in the history it walks, which conflates real copy and paste with code re-added after a refactor and with ordinary boilerplate. Measured against real repositories it reads about three orders of magnitude above published figures. It is useful as a trend within one repository and useless as an absolute number, so it says so and stays out of the default output.&lt;/p&gt;

&lt;p&gt;And line-level move detection, the signal behind the widely repeated claim that refactoring is collapsing, is not implemented at all. It is a similarity-matching problem rather than a hashing one, and a naive version would produce numbers that look plausible and cannot survive comparison with the research they would be quoted against.&lt;/p&gt;

&lt;p&gt;Both of those are in the README rather than an issue tracker, because a tool that quietly ships a broken metric is worse than one that admits to a gap. The whole point of measuring is to stop guessing. A measurement you cannot trust is just a guess wearing a number.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Companion piece: measure your own coding habits before you believe anyone else's numbers, on what git history alone can tell you, and the five ways I nearly fooled myself getting there.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by Richard Atkins.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;📬 &lt;strong&gt;&lt;a href="https://buttondown.com/groundedarchitect" rel="noopener noreferrer"&gt;Subscribe to &lt;em&gt;The Grounded Architect&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; — field notes on building production AI, and leading the people around it. Straight to your inbox, no hype.&lt;/p&gt;

</description>
      <category>software</category>
      <category>analytics</category>
      <category>code</category>
      <category>devex</category>
    </item>
    <item>
      <title>Measure your own coding habits before you believe anyone else's numbers</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Wed, 05 Aug 2026 09:32:00 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/measure-your-own-coding-habits-before-you-believe-anyone-elses-numbers-401l</link>
      <guid>https://dev.to/groundedarchitect/measure-your-own-coding-habits-before-you-believe-anyone-elses-numbers-401l</guid>
      <description>&lt;p&gt;&lt;em&gt;Part of "AI, engineering and what survives production", a series on the parts of building with AI that hold up once real traffic hits them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There is a claim going round that you have probably absorbed by now: AI-assisted development is making codebases worse. Refactoring is down, duplication is up, we are all writing more and revising less. The numbers behind it are real, the samples are enormous, and I found I had started repeating the conclusion in conversation without ever having checked it.&lt;/p&gt;

&lt;p&gt;Then it occurred to me that those figures are averages taken across hundreds of millions of changes from thousands of organisations, not one of which is mine. So what is the rate in your repository? Nobody has told you, and on current evidence nobody is going to. I set out to find mine, assumed it would take an afternoon, and spent three days discovering that the answer is far harder to get at than the confident version suggests.&lt;/p&gt;

&lt;p&gt;So this is not a piece about what AI does to code. It is about how to ask that question of your own repository without arriving at a wrong answer, which turned out to be the genuinely difficult part. The tool I built to do it is &lt;a href="https://github.com/rich-atkins/git-habits" rel="noopener noreferrer"&gt;git-habits&lt;/a&gt;: free, local, and it reads no source code whatsoever.&lt;/p&gt;

&lt;h2&gt;
  
  
  What git can actually tell you
&lt;/h2&gt;

&lt;p&gt;Git history is a surprisingly rich behavioural record. Not of quality, about which it knows nothing at all, but of habits: how often you commit, how large those commits are, whether you go back and change what you wrote last month, and whether anybody still touches the old code. That is a narrower thing than quality and it is the thing the industry claims has changed, so it is the thing worth measuring.&lt;/p&gt;

&lt;p&gt;Four signals are computable from commit metadata alone, without opening a single source file:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Moved lines.&lt;/strong&gt; The share of changed lines sitting in files git detected as renamed or copied. It is the closest thing history offers to "somebody went back and reorganised this."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Legacy touch.&lt;/strong&gt; The share of changes landing on files nobody has touched in a year or more. Whether old code is still maintained or merely accumulating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rework.&lt;/strong&gt; The share of changes landing on files touched again within a fortnight. Short-cycle churn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commit shape.&lt;/strong&gt; How many commits per working day, and how large each one is.&lt;/p&gt;

&lt;p&gt;None of these is a quality measure, and I want to be clear that I am not pretending otherwise. They are habits. Habits are what the claim is actually about, so habits are what you can test, and a narrow measurement you trust beats a broad one you do not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the output looks like
&lt;/h2&gt;

&lt;p&gt;Real output, from one of my own repositories, split at an arbitrary date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git-habits compare  split at 2026-05-01

  ruleset v1.0  excluded 28,297 of 101,578 changed lines (27.9%)
    lockfiles            24,513
    data_dumps            3,778
    binary_media              5

  first month
    window            2026-04-03 to 2026-04-24  (21d span, 7 active)
    commits           136   (19.43/active day)
    changed lines     41,788
    lines/commit      mean 307.3  p50 90.0  p90 430.0
    moved (reuse)     0.16%  (1.6 per 1k changed lines)
    legacy touch      0.0%  (0.0 per 1k)
    rework &amp;lt;=14d      17.24%  (172.4 per 1k)
    AI co-authored    45 commits (33.1%)

  after
    window            2026-05-04 to 2026-07-18  (76d span, 11 active)
    commits           44   (4.0/active day)
    changed lines     31,493
    lines/commit      mean 715.8  p50 66.5  p90 2997.0
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things in there are worth pointing at before we go further, because both are the&lt;br&gt;
kind of detail a dashboard would smooth over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The exclusion report comes first, not last.&lt;/strong&gt; Nearly 28% of the changed lines in that&lt;br&gt;
window were lockfiles and data dumps. You are told that before you read a single metric.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Look at the mean and the median diverge in the second window.&lt;/strong&gt; Mean 715.8, median 66.5,&lt;br&gt;
p90 2,997. A handful of enormous commits have eaten the mean while the typical commit&lt;br&gt;
actually got &lt;em&gt;smaller&lt;/em&gt;. Read only the mean and you would conclude the opposite of what&lt;br&gt;
happened.&lt;/p&gt;
&lt;h2&gt;
  
  
  Normalise per line, not per commit
&lt;/h2&gt;

&lt;p&gt;This decision matters more than it looks. Measure anything "per commit" and, the moment your commit granularity changes, every metric moves while nothing underneath it has changed at all. A team that switches to squash merges halves its commit count overnight and could be forgiven for thinking it had halved its output. So I made per changed line the primary normalisation, which has the useful side effect of keeping the numbers comparable with the published research.&lt;/p&gt;

&lt;p&gt;I kept the per-commit view as well, though, because it answers a different question and the gap between the two is where the artefacts hide. A metric that shifted only because commits got bigger is not a finding, and you want that visible rather than smoothed away.&lt;/p&gt;

&lt;p&gt;One caveat on averages. In one repository I measured, the mean commit was 860 changed lines and the median was 16. A handful of bulk imports had eaten the mean entirely. &lt;strong&gt;Report the median.&lt;/strong&gt; If a tool shows you only a mean, it is showing you its largest commits.&lt;/p&gt;
&lt;h2&gt;
  
  
  The five ways I nearly fooled myself
&lt;/h2&gt;

&lt;p&gt;Every one of these produced a confident, wrong number during the build. They are in the tool's output and its README for that reason.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Generated files are most of your history
&lt;/h3&gt;

&lt;p&gt;Lockfiles, build output, vendored dependencies, minified bundles, committed logs. Across the repositories I measured, &lt;strong&gt;generated artefacts accounted for between 48% and 62% of all changed lines.&lt;/strong&gt; One &lt;code&gt;npm install&lt;/code&gt; writes tens of thousands of lines to a lockfile, and it will drown every real signal you have.&lt;/p&gt;

&lt;p&gt;So exclusions have to be on by default. But the corollary matters just as much: a tool that silently discards two thirds of your data has an invisible thumb on the scale. How would you know? You would not, which is why it must report what it removed and how much. If over half your churn vanishes into the exclusion list, you deserve to be told that before you read a single metric.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. &lt;code&gt;git log&lt;/code&gt; can return nothing and call it success
&lt;/h3&gt;

&lt;p&gt;This one cost me a day. I ran a log with &lt;code&gt;--format="COMMIT"&lt;/code&gt; as a record separator, parsed the output, and got clean zeroes across six repositories. No error. Exit code 0.&lt;/p&gt;

&lt;p&gt;Git treats a format string containing no &lt;code&gt;%&lt;/code&gt; placeholder as a &lt;em&gt;named pretty-alias lookup&lt;/em&gt;. It finds no alias called &lt;code&gt;COMMIT&lt;/code&gt;, emits nothing, and exits successfully. The pipeline downstream dutifully reported that nothing had happened.&lt;/p&gt;

&lt;p&gt;I only caught it because a &lt;em&gt;later&lt;/em&gt; start date returned &lt;em&gt;more&lt;/em&gt; commits than an earlier one, which is impossible. &lt;strong&gt;Any tool built on parsing &lt;code&gt;git log&lt;/code&gt; needs an assertion that it got something back.&lt;/strong&gt; Silent zeroes are the most dangerous output a measurement tool can produce, because they look like findings.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Unknown is not zero
&lt;/h3&gt;

&lt;p&gt;My exports captured commit subjects but not trailers, so the tool reported "0% AI co-authored" for a repository where 58% of commits carried a &lt;code&gt;Co-Authored-By&lt;/code&gt; trailer. The data did not say zero. The data said nothing, and zero was the default.&lt;/p&gt;

&lt;p&gt;Then a second version of the same bug: the exclusion step rebuilt each commit object and quietly dropped the trailers field, turning a known value back into an unknown that rendered as zero again.&lt;/p&gt;

&lt;p&gt;A missing field and a measured zero must be different values all the way through, and they must render differently. Mine now prints "not captured by this source" and the JSON emits &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Repository age fakes a trend
&lt;/h3&gt;

&lt;p&gt;A repository younger than a year cannot contain year-old code, so its legacy-touch rate is structurally zero and rises as the calendar advances. Compare two windows of a maturing repository and you will see legacy touch climb impressively while nobody's behaviour has changed at all.&lt;/p&gt;

&lt;p&gt;Worse, I hit a repository that looked eighteen months old and wasn't: it had been carved out of a larger one, so every file's history reset at the split. Real two-year-old code read as new.&lt;/p&gt;

&lt;p&gt;If you take one thing from this piece: &lt;strong&gt;check where your repository actually came from before you measure its age.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  5. &lt;code&gt;--all&lt;/code&gt; can double your commit count
&lt;/h3&gt;

&lt;p&gt;Including all refs picks up unmerged branch work. In one repository it took the commit count from 42 to 94. Neither number is wrong, they answer different questions: work you did, versus work that shipped.&lt;/p&gt;

&lt;p&gt;Pick one, write it down, and apply it everywhere. The flags used should be printed with the results, because a comparison between two periods computed under different flags is not a comparison.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it cannot do
&lt;/h2&gt;

&lt;p&gt;It cannot detect AI. It detects &lt;em&gt;when things changed&lt;/em&gt;, and any before-and-after split is only as honest as you are about when you changed method. Do you actually remember the week you started letting a model write your first drafts?&lt;/p&gt;

&lt;p&gt;Which is worth dwelling on, because I got my own date wrong by sixteen days when asked to recall it three months later. That is why the tool has a &lt;code&gt;detect&lt;/code&gt; command that looks for the step change itself and reports it as a candidate rather than a fact. If the person running the study cannot remember, no user will.&lt;/p&gt;

&lt;p&gt;And moved-lines is a proxy. Git detects file renames, not the movement of a block of code between files, which is what the published research actually measures. That is a similarity-matching problem, and an approximation of it would give you numbers that look plausible and cannot be compared with the thing you would inevitably compare them against.&lt;/p&gt;
&lt;h2&gt;
  
  
  Go and check
&lt;/h2&gt;

&lt;p&gt;Python 3.10 or newer, no dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rich-atkins/git-habits &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;git-habits
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; .venv/bin/pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# no idea when your habits changed? most people do not&lt;/span&gt;
git-habits detect  &lt;span class="nt"&gt;--repo&lt;/span&gt; /your/repo &lt;span class="nt"&gt;--author&lt;/span&gt; &lt;span class="s2"&gt;"you@example.com"&lt;/span&gt;

&lt;span class="c"&gt;# then compare either side of the date it suggests&lt;/span&gt;
git-habits compare &lt;span class="nt"&gt;--repo&lt;/span&gt; /your/repo &lt;span class="nt"&gt;--author&lt;/span&gt; &lt;span class="s2"&gt;"you@example.com"&lt;/span&gt; &lt;span class="nt"&gt;--split&lt;/span&gt; 2026-04-13
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the repository lives on a machine you cannot clone from, export its history there and analyse it here. The README has the command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Its companion, &lt;a href="https://github.com/rich-atkins/diff-habits" rel="noopener noreferrer"&gt;diff-habits&lt;/a&gt;, goes one layer deeper.&lt;/strong&gt; It reads diff contents and counts error-masking constructs, the empty catch blocks and suppressed type checks that remove the evidence of a failure rather than handle it. That is a separate tool rather than a flag on this one, deliberately: &lt;code&gt;git-habits&lt;/code&gt; never opens a source file, which is what lets you run it against an employer's repository without a conversation. Reading source is a different decision and should be a different install. I have written that one up in the code that hides the evidence.&lt;/p&gt;

&lt;p&gt;I am deliberately not telling you what my own numbers showed, because a before-and-after on one developer means very little without a control group. I have one, two colleagues in the same repositories who do not use AI at all, and that analysis is not finished. What I will say now is that the answer I was confident about after an afternoon was wrong, and every version since has been less exciting and more true.&lt;/p&gt;

&lt;p&gt;Measure your own crossover. Do not inherit someone else's headline.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by Richard Atkins.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;📬 &lt;strong&gt;&lt;a href="https://buttondown.com/groundedarchitect" rel="noopener noreferrer"&gt;Subscribe to &lt;em&gt;The Grounded Architect&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; — field notes on building production AI, and leading the people around it. Straight to your inbox, no hype.&lt;/p&gt;

</description>
      <category>git</category>
      <category>analytics</category>
      <category>productivity</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Org design for AI: why your Centre of Excellence becomes a bottleneck</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Fri, 31 Jul 2026 05:00:00 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/org-design-for-ai-why-your-centre-of-excellence-becomes-a-bottleneck-2ojo</link>
      <guid>https://dev.to/groundedarchitect/org-design-for-ai-why-your-centre-of-excellence-becomes-a-bottleneck-2ojo</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 4 of five. "AI, leadership and the human structures of work" is a series on what AI actually changes about leading people, and why those changes are choices, not inevitabilities.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A large enterprise I heard about stood up an AI Centre of Excellence with the best of intentions: one central team to set standards, vet models, and keep everyone safe. Eighteen months later, the CoE had a six-week approval queue, three of the business units had quietly started using unsanctioned tools to get round it, and the security team, the very people the CoE existed to reassure, had less visibility into the company's real AI use than before it was created. The gate had not stopped the risky behaviour. It had driven it underground.&lt;/p&gt;

&lt;p&gt;The last piece ended on a warning: you can only fix ownership and accountability so far one team at a time, because they also live in how the whole organisation is built. So this is the structural piece. When a company decides to get serious about AI, it almost always reaches for the same move, and that move is usually where adoption goes to die.&lt;/p&gt;

&lt;p&gt;The move is the Centre of Excellence. Pull the AI expertise into one central team, give them the mandate for standards, safety, and best practice, and let the rest of the organisation come to them. It sounds responsible. It is how most enterprises have handled every new capability for thirty years. And with AI it reliably curdles into a bottleneck.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the enabler becomes the ceiling
&lt;/h2&gt;

&lt;p&gt;The failure is not incompetence. It is a structural trap. A central team that must review every model, approve every use case, and sign off every rollout becomes, by simple arithmetic, the ceiling on how fast the rest of the company can move. Ten teams want to build; one team has to approve; the queue forms.&lt;/p&gt;

&lt;p&gt;And people do not wait in queues. They route around them. This is not hypothetical. A 2026 survey of 1,000 employees and 500 security leaders found 81% of employees using unapproved AI tools, and 45% of workers actively finding workarounds to reach applications their employer had blocked. That second number is the one that should worry you, because it is the queue-jumping made explicit: the official channel is half-empty and the unofficial one is packed. Your careful central control produces the exact thing it was built to prevent, ungoverned AI use, now invisible, because you made the governed path the slow one.&lt;/p&gt;

&lt;p&gt;A gate does not stop the water. It decides where the water goes around.&lt;/p&gt;

&lt;h2&gt;
  
  
  The counter-argument, taken seriously
&lt;/h2&gt;

&lt;p&gt;The obvious objection: but you &lt;em&gt;need&lt;/em&gt; governance. AI carries real risk, data, compliance, reputation, and "enablement" sounds like a polite word for a free-for-all. Fair, and worth answering directly, because it hides a false choice.&lt;/p&gt;

&lt;p&gt;Enablement is not the absence of governance. It is governance delivered as a road rather than a checkpoint. A checkpoint governs by inspecting each car; a well-built road governs by making the safe route the default, guardrails, a paved surface, a sensible limit built into the design, so that the easy thing and the safe thing are the same thing. The shadow-AI numbers are the proof that gating fails at its own stated goal: the CoE that inspects every use case ends up with less control, not more, because it drove usage into the dark. If your genuine priority is safety, the queue is the least safe design you could pick.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern that actually scales
&lt;/h2&gt;

&lt;p&gt;The organisations getting this right are inverting the central team's job. Instead of a team that approves, a team that enables. Two ideas from how high-performing engineering organisations are already built map onto this cleanly. The first is the enabling team: a small group whose success is measured by how quickly it can raise another team's capability and then leave, not by how many approvals it processes. Its job is to make the other teams good at AI, then get out of the way. The second is the platform team: it builds the paved road, the self-service tools, guardrails, and defaults that make the safe way to use AI the easy way. You do not govern by inspecting each decision. You govern by shaping the path so the default is already safe.&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%2Fjxtuwwejzod7tq2q5707.jpg" 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%2Fjxtuwwejzod7tq2q5707.jpg" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;br&gt;
That is the shift in a line: govern the road, not each journey.&lt;/p&gt;

&lt;p&gt;There is an older idea worth borrowing too, with a caveat. The Spotify model gave us the language of guilds and chapters, communities that cut across teams to spread a craft and stop knowledge pooling in silos. That cross-cutting community is a genuinely good home for AI practice: how we prompt, what we have found breaks, which failure modes to watch for. The caveat is honesty. The Spotify model was aspirational even at Spotify, and copied badly it becomes ceremony. Take the idea, spreading practice sideways across teams, not the diagram.&lt;/p&gt;

&lt;p&gt;And there is a reason structure matters more here than almost anywhere. Conway's Law, the old observation that organisations ship systems which mirror their own communication structures, has never been more literal than with AI. Build a gatekeeping organisation and you get gatekept, brittle adoption. Build an enabling one and you get adoption that flows. The shape of the team becomes the shape of the capability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this asks of a leader
&lt;/h2&gt;

&lt;p&gt;Resist the instinct that says control means a checkpoint. On a technology moving this fast, a checkpoint is a bottleneck wearing a lanyard. Design for enablement instead: a central team measured on how much capability it builds elsewhere, a platform that makes the safe path the easy one, and a community that spreads what works. Governance that enables velocity rather than gating it is not a slogan. It is a structural decision about whether your best people wait in a queue or get a paved road, and, on the evidence, about whether you have real control or only the paperwork of it.&lt;/p&gt;

&lt;p&gt;But structure has a hard limit, and it is the one this series has been circling from the start. You can build the most elegant enabling organisation in the world and it will still fail if there is nobody left to enable, if the pipeline that produces capable people has quietly been switched off. That is the last piece, and it is the one I think we are getting most wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The series: AI, leadership and the human structures of work&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The psychological cost of AI is a leadership choice, not a technology outcome&lt;/li&gt;
&lt;li&gt;Who's the authority now? Leading in the age of the jagged generalist&lt;/li&gt;
&lt;li&gt;Managing a team of agents: leadership when roles become software&lt;/li&gt;
&lt;li&gt;Org design for AI: why your Centre of Excellence becomes a bottleneck&lt;/li&gt;
&lt;li&gt;Cutting juniors is a choice, not an AI inevitability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;You are reading part 4. Links added as each publishes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Written by Richard Atkins.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Sources: Team Topologies (Skelton &amp;amp; Pais) — &lt;a href="https://teamtopologies.com/key-concepts" rel="noopener noreferrer"&gt;https://teamtopologies.com/key-concepts&lt;/a&gt; · "AI Center of Excellence: Why Most Become Bottlenecks" — &lt;a href="https://agility-at-scale.com/ai/people-change/ai-center-of-excellence/" rel="noopener noreferrer"&gt;https://agility-at-scale.com/ai/people-change/ai-center-of-excellence/&lt;/a&gt; · Shadow-AI prevalence: UpGuard, "The State of Shadow AI" — &lt;a href="https://www.upguard.com/resources/the-state-of-shadow-ai" rel="noopener noreferrer"&gt;https://www.upguard.com/resources/the-state-of-shadow-ai&lt;/a&gt; ; &lt;a href="https://redteampartner.com/blog/shadow-ai-enterprise-risk/" rel="noopener noreferrer"&gt;https://redteampartner.com/blog/shadow-ai-enterprise-risk/&lt;/a&gt; · The Spotify model — &lt;a href="https://www.atlassian.com/agile/agile-at-scale/spotify" rel="noopener noreferrer"&gt;https://www.atlassian.com/agile/agile-at-scale/spotify&lt;/a&gt; · Conway's Law (Melvin Conway, 1968).&lt;/small&gt;&lt;/p&gt;




&lt;p&gt;📬 &lt;strong&gt;&lt;a href="https://buttondown.com/groundedarchitect" rel="noopener noreferrer"&gt;Subscribe to &lt;em&gt;The Grounded Architect&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; — field notes on building production AI, and leading the people around it. Straight to your inbox, no hype.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>ai</category>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Managing a team of agents: leadership when roles become software</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Wed, 22 Jul 2026 05:00:00 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/managing-a-team-of-agents-leadership-when-roles-become-software-38a</link>
      <guid>https://dev.to/groundedarchitect/managing-a-team-of-agents-leadership-when-roles-become-software-38a</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 3 of five. "AI, leadership and the human structures of work" is a series on what AI actually changes about leading people, and why those changes are choices, not inevitabilities.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An agent on your team drafts a client report. Another reviews it. A third sends it. It goes out with a number that is wrong, not obviously wrong, plausibly wrong, and the client acts on it. Monday morning, someone asks who is responsible. Point to a person. If you find yourself hesitating between the drafting agent, the reviewing agent, and the human who "just" pressed send on work three agents produced, you have found the real management problem with agents, and it is not their capability.&lt;/p&gt;

&lt;p&gt;So far in this series: the human cost of AI is a leadership choice (piece one), and the authority in the room is no longer whoever knows the most, but whoever knows where to trust the machine (piece two). This piece is about what management becomes when the organisation stops hiring for a role and starts spinning up an agent for it instead.&lt;/p&gt;

&lt;p&gt;Picture the team you might run in two years. Three people. Nine agents: one drafting, one reviewing, a couple monitoring, others doing work that used to carry a job title. The people wear several hats each; the agents wear the rest. Our entire apparatus for running teams, ownership, accountability, span of control, was built for humans. Agents quietly break all three.&lt;/p&gt;

&lt;h2&gt;
  
  
  Oversight was the job. It is not any more.
&lt;/h2&gt;

&lt;p&gt;For decades, a large part of middle management was moving information and checking work: routing decisions up and down, monitoring who did what, catching mistakes before they travelled. Agents do the routing and much of the checking themselves. So the manager whose value was oversight is, honestly, in trouble, and the numbers reflect it. Middle managers grew to around 13% of the US workforce by 2022, up from roughly 9% in the early 1980s, and a good deal of that growth was the oversight work agents now absorb. The pressure is already visible: a June 2026 &lt;em&gt;Harvard Business Review&lt;/em&gt; analysis describes middle managers being overloaded by AI adoption, and Gartner predicts that this year one in five organisations will use AI to flatten their structure, eliminating more than half of their middle-management positions. The oversight layer is not just shifting; in places it is being deleted. The research on where the role is heading is consistent: from monitoring to facilitation, from watching work happen to making it possible.&lt;/p&gt;

&lt;p&gt;That is not a demotion. It is a harder job. Overseeing ten people is a known problem with a century of practice behind it. Enabling three people to direct a shifting fleet of agents, and staying accountable for what that fleet produces, is not a problem most managers have ever been trained for.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three things agents break
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ownership.&lt;/strong&gt; People take ownership of work they feel is theirs. Split a task across three people and six agents and ownership evaporates: everyone contributed, nobody owns it. The fix is not technical, it is a deliberate management act. Name a human owner for every outcome, not every task. The agents can do the work; a person still has to own the result, including the parts the agents got wrong.&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%2F8pghodkwtdv6c2dvoje7.jpg" 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%2F8pghodkwtdv6c2dvoje7.jpg" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accountability.&lt;/strong&gt; This is where the "it's just delegation" objection breaks down. Good managers already delegate, the argument goes, and org charts always adapt. But delegation, properly understood, is to a human who can be asked why, who feels the consequence, who learns and carries the responsibility next time. An agent can do none of that. It cannot be accountable. So accountability does not distribute when you deploy agents the way it does when you delegate to people. It concentrates, upward, onto the humans who directed them. The old management principle held that you can delegate authority but never responsibility. Agents make that literal and unforgiving: the more of a team's work you automate, the more exposed its remaining people become, because they now answer for output they did not personally produce. A leader who misses this will let their best people quietly absorb unbounded risk, and call it efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reliance.&lt;/strong&gt; Here is a result worth pinning to the wall. In a 2025 experiment, people systematically over-relied on AI advice even when their own judgment would have been better, and the driver was not laziness. It was incentives. When people were rewarded for throughput, they rubber-stamped. When the incentive was redesigned to reward good judgment about when to trust the AI, over-reliance fell. Your team will trust agents exactly as much as your incentives tell them to. Reward speed, and you will get rubber-stamping, and, per the accountability point above, you will personally own the results of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What managing actually becomes
&lt;/h2&gt;

&lt;p&gt;Less monitoring, more designing. Who owns which outcome. What a human must still decide. How you reward judgment over throughput. And what your real span of control now is, because a manager of three people directing fifty agents has a span of attention no org chart has ever had to model. The manager's craft moves from supervising effort to engineering accountability across a team where most of the doing is done by things that cannot be held responsible.&lt;/p&gt;

&lt;p&gt;That is a real skill, and almost nobody has it yet, which is precisely the argument for learning it early. The managers worth most in five years will be the ones who worked out, now, how to keep ownership and judgment human while the doing moved to software.&lt;/p&gt;

&lt;p&gt;There is a limit to how far you can solve this one team at a time, though. Ownership and accountability do not only live in a manager's head. They live in how the whole organisation is structured, and most organisations are about to reach for the same structure to "manage AI." Most of them will build a bottleneck and call it a centre of excellence. That is where the series goes next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The series: AI, leadership and the human structures of work&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The psychological cost of AI is a leadership choice, not a technology outcome&lt;/li&gt;
&lt;li&gt;Who's the authority now? Leading in the age of the jagged generalist&lt;/li&gt;
&lt;li&gt;Managing a team of agents: leadership when roles become software&lt;/li&gt;
&lt;li&gt;Org design for AI: why your Centre of Excellence becomes a bottleneck&lt;/li&gt;
&lt;li&gt;Cutting juniors is a choice, not an AI inevitability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;You are reading part 3. Links added as each publishes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Written by Richard Atkins.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Sources: "What's the Future of Middle Management?", HBR (2025) — &lt;a href="https://hbr.org/2025/04/whats-the-future-of-middle-management" rel="noopener noreferrer"&gt;https://hbr.org/2025/04/whats-the-future-of-middle-management&lt;/a&gt; · "Managers Managing AI Agents", Business Insider (2025) — &lt;a href="https://www.businessinsider.com/ai-agent-managers-new-job-2025-11" rel="noopener noreferrer"&gt;https://www.businessinsider.com/ai-agent-managers-new-job-2025-11&lt;/a&gt; · Holstein et al. (2025), "When Thinking Pays Off: Incentive Alignment for Human-AI Collaboration" — &lt;a href="https://arxiv.org/abs/2511.09612" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2511.09612&lt;/a&gt; · "AI Adoption Is Overloading Your Middle Managers", HBR (June 2026) — &lt;a href="https://hbr.org/2026/06/ai-adoption-is-overloading-your-middle-managers" rel="noopener noreferrer"&gt;https://hbr.org/2026/06/ai-adoption-is-overloading-your-middle-managers&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;p&gt;📬 &lt;strong&gt;&lt;a href="https://buttondown.com/groundedarchitect" rel="noopener noreferrer"&gt;Subscribe to &lt;em&gt;The Grounded Architect&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; — field notes on building production AI, and leading the people around it. Straight to your inbox, no hype.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>management</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Who's the authority now? Leading in the age of the jagged generalist</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Sun, 19 Jul 2026 17:48:18 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/whos-the-authority-now-leading-in-the-age-of-the-jagged-generalist-1iap</link>
      <guid>https://dev.to/groundedarchitect/whos-the-authority-now-leading-in-the-age-of-the-jagged-generalist-1iap</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 2 of five. "AI, leadership and the human structures of work" is a series on what AI actually changes about leading people, and why those changes are choices, not inevitabilities.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A senior engineer I know approved a database migration plan last year. It was clear, well-reasoned, confidently written, and it would have taken the production system down, because one step assumed a lock the database did not actually provide. The plan came from an AI. The engineer was good. He caught it on the second read, not the first, because it read exactly like the correct plans he approves every day. That gap, between how right it looked and how wrong it was, is the whole subject of this piece.&lt;/p&gt;

&lt;p&gt;The first piece argued that AI's cost to people's wellbeing is a leadership choice, not a technology outcome. This one is about a quieter loss: authority. When the model is a better specialist than most of your team on a Tuesday, and confidently, plausibly wrong on Wednesday, who is the expert in the room?&lt;/p&gt;

&lt;p&gt;Start with the finding that should unsettle anyone putting AI into skilled work. In 2023, researchers at Harvard Business School and Boston Consulting Group ran a field experiment with several hundred management consultants. On tasks that sat inside the AI's capability, the consultants using it produced work rated around 40% higher in quality, finished roughly 25% faster, and completed more of it. On a task designed to sit just outside that capability, the pattern flipped: the ones using AI were more likely to reach the wrong answer than the ones without it. Not a little wrong. Fluently, confidently wrong, because the model produced something that looked exactly as authoritative as its correct work.&lt;/p&gt;

&lt;p&gt;They called it the jagged frontier. AI is brilliant and useless in a pattern you cannot see from the outside, and the two sit right next to each other. The same tool that makes your team look expert on one task quietly makes them look expert while being wrong on the adjacent one. The line usually attributed to Mark Twain fits it better than anything written since: it ain't what you don't know that gets you into trouble, it's what you know for sure that just ain't so. AI is a confident-wrong machine, and confidence is the one signal humans are worst at ignoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Is AI the specialist now?" is the wrong question
&lt;/h2&gt;

&lt;p&gt;Watching a model out-perform your people on a narrow task, it is tempting to conclude that the AI is now the specialist and the humans are drifting into generalists who wear many hats. That gets the shape of it backwards.&lt;/p&gt;

&lt;p&gt;A specialist you can rely on. Their expertise has edges you understand. You know roughly what they know, and where their competence stops, which is exactly what lets you trust them. The jagged frontier means AI has no reliable edges. It is a generalist that performs like a specialist in unpredictable patches. Treating it as "the authority" is not delegation to an expert. It is trusting a colleague who is sometimes brilliant, sometimes bluffing, and never tells you which.&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%2F74nox2wg45dtuks8ywqp.jpg" 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%2F74nox2wg45dtuks8ywqp.jpg" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A second body of evidence sharpens this. A 2025 meta-analysis in &lt;em&gt;Psychological Bulletin&lt;/em&gt; reconciled years of contradictory findings about whether people trust or distrust AI, and the answer was: it depends on the task. People tend to appreciate AI on objective, capability-heavy work and resist it on subjective, personal work. Which means a blanket policy, "use AI" or "don't trust AI", is wrong almost by definition, because the right answer changes task to task, sometimes sentence to sentence.&lt;/p&gt;

&lt;p&gt;So the authority in the room is not the model. And it is no longer, on its own, the person who knows the most about the subject. It is the person who knows where the model can be trusted and where it cannot. That is a genuinely new competence, and it is not the same as domain expertise. You can be the strongest engineer on the team and still wave through a plausible, wrong answer, because knowing a domain and knowing the shape of a model's blind spots are different skills. My engineer happened to have both. Not everyone will.&lt;/p&gt;

&lt;p&gt;Garry Kasparov, who lost to a computer and then spent years studying human-machine teams, distilled it into a law: a weaker player with a better process, working with a machine, beats a stronger player with a worse process. The edge was never the human or the machine on its own. It was the process binding them, the judgment about who does what and when to override. That process is the authority now, and it lives in a person, not the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part the productivity numbers hide
&lt;/h2&gt;

&lt;p&gt;There is a second finding in that study every leader should hold onto. The consultants who gained the most from AI were the ones who started out weakest; the bottom half of performers improved far more than the top. AI is a leveller. It pulls the floor up.&lt;/p&gt;

&lt;p&gt;Read quickly, that sounds like good news, and in the short term it is. Read slowly, it carries a warning. If AI makes your least experienced people produce work that looks senior, you lose the signal you used to manage by. You can no longer read competence from output, because the output has been levelled. The junior who genuinely understands and the junior who prompted well now hand you the same document. The tell you have relied on your whole career, good work means a good developer, quietly stops being true.&lt;/p&gt;

&lt;h2&gt;
  
  
  The counter-argument, taken seriously
&lt;/h2&gt;

&lt;p&gt;The obvious objection: the models keep getting better, so will the frontier not just fill in and this whole problem solve itself? No, and it is worth being precise about why. The frontier moves, but it does not stop being jagged. Every jump in capability opens a new set of adjacent tasks the model now attempts and gets subtly wrong, because it attempts them with exactly the same confidence it brings to the ones it has mastered. A more capable model is a more capable confident-wrong machine on the new edge. And the signal-loss problem, the fact that you can no longer read competence from levelled output, does not improve as the model improves. It gets worse.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this asks of a leader
&lt;/h2&gt;

&lt;p&gt;Stop asking your people to trust or distrust AI as a blanket policy. Both are wrong on a jagged frontier. Ask them instead to build, and to show you, calibrated judgment: where they lean on the model, where they check it, and how they know the difference. Reward the engineer who catches the plausible, wrong answer over the one who ships fastest. Make "here is where this could be wrong, and here is how I checked" a first-class contribution rather than friction.&lt;/p&gt;

&lt;p&gt;And notice what this quietly costs. Every task you hand entirely to the model is a task your people stop practising. The expertise that let my engineer catch the migration bug was built by doing that work himself, badly and then well, for years, the same work you are now tempted to automate away. Which raises a question worth leaving open: if we stop building expertise in our people, where does the next generation of people who can supervise the machine come from? Hold that one. The series comes back to it, and the answer is not comfortable.&lt;/p&gt;

&lt;p&gt;For now, the nearer question. If judgment about the machine is the new authority, how do you actually run a team when half its "roles" are no longer people but agents you spin up on demand? That is next week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The series: AI, leadership and the human structures of work&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The psychological cost of AI is a leadership choice, not a technology outcome&lt;/li&gt;
&lt;li&gt;Who's the authority now? Leading in the age of the jagged generalist&lt;/li&gt;
&lt;li&gt;Managing a team of agents: leadership when roles become software&lt;/li&gt;
&lt;li&gt;Org design for AI: why your Centre of Excellence becomes a bottleneck&lt;/li&gt;
&lt;li&gt;Cutting juniors is a choice, not an AI inevitability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;You are reading part 2. Links added as each publishes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Written by Richard Atkins.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Sources: Dell'Acqua et al. (2023), "Navigating the Jagged Technological Frontier" (Harvard/BCG) — &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4573321" rel="noopener noreferrer"&gt;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4573321&lt;/a&gt; · Mollick, "Centaurs and Cyborgs on the Jagged Frontier" — &lt;a href="https://www.oneusefulthing.org/p/centaurs-and-cyborgs-on-the-jagged" rel="noopener noreferrer"&gt;https://www.oneusefulthing.org/p/centaurs-and-cyborgs-on-the-jagged&lt;/a&gt; · Qin et al. (2025), "AI aversion or appreciation? A capability-personalization framework", &lt;em&gt;Psychological Bulletin&lt;/em&gt; · Garry Kasparov, on process in human-machine teams (Kasparov's Law).&lt;/small&gt;&lt;/p&gt;




&lt;p&gt;📬 &lt;strong&gt;&lt;a href="https://buttondown.com/groundedarchitect" rel="noopener noreferrer"&gt;Subscribe to &lt;em&gt;The Grounded Architect&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; — field notes on building production AI, and leading the people around it. Straight to your inbox, no hype.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>ai</category>
      <category>llm</category>
      <category>management</category>
    </item>
    <item>
      <title>The psychological cost of AI is a leadership choice, not a technology outcome</title>
      <dc:creator>Richard Atkins</dc:creator>
      <pubDate>Sun, 19 Jul 2026 17:48:09 +0000</pubDate>
      <link>https://dev.to/groundedarchitect/the-psychological-cost-of-ai-is-a-leadership-choice-not-a-technology-outcome-2cki</link>
      <guid>https://dev.to/groundedarchitect/the-psychological-cost-of-ai-is-a-leadership-choice-not-a-technology-outcome-2cki</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 1 of five, and the opener. "AI, leadership and the human structures of work" is a series on what AI actually changes about leading people, and why those changes are choices, not inevitabilities.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A team gets a new set of AI tools on a Monday. By Friday the dashboards look wonderful: more output, faster turnaround, fewer late nights. Six weeks later the same team is quieter in stand-ups, slower to volunteer, and two of your best people have started updating their CVs. Nothing broke. The numbers are still good. Something else did.&lt;/p&gt;

&lt;p&gt;Most of what you read about AI at work is about that first Friday, the productivity. This is about the six weeks after: the bill that comes with it, and who decides how large it is.&lt;/p&gt;

&lt;p&gt;Start with how people actually feel. In a global survey by ADP Research this year, only 22% of workers strongly agreed that their job was safe from elimination. Pew finds US workers more worried than hopeful about AI at work. And the worry is not evenly spread; early-career workers report the sharpest sense that AI is already reshaping their jobs. Whatever the productivity story, the human one is anxious, and anxiety is not a neutral input to a workplace.&lt;/p&gt;

&lt;p&gt;Now the harder evidence. A 2025 study in &lt;em&gt;Humanities and Social Sciences Communications&lt;/em&gt; followed 381 employees across three waves and found that adopting AI significantly lowered people's psychological safety, and that drop, in turn, raised their depression. This is not grumbling. Psychological safety, the belief that you can speak up, admit a mistake, or ask a question without being punished for it, is the thing Amy Edmondson spent a career showing is the foundation of teams that learn. Erode it and people stop flagging problems, stop asking, stop taking the small risks that improve the work. Done carelessly, AI adoption erodes exactly that.&lt;/p&gt;

&lt;p&gt;But here is the finding that should change how you read all of it. The same study found that ethical leadership buffered the damage. Where leaders behaved with integrity and care through the change, the hit to psychological safety was significantly softened. Same technology, same rollout, different leadership, different human outcome.&lt;/p&gt;

&lt;p&gt;This is not one study's fluke. Gallup finds that manager support is among the biggest factors in how well employees adapt to AI and workplace change. The technology arrives for everyone; how it lands depends on the person managing it.&lt;/p&gt;

&lt;p&gt;That is the argument of this piece, and the thread that runs through this series: the human costs of AI are leadership choices, not technology outcomes. The tool does not decide whether your people feel ownership or dread. You do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI reaches the parts of work motivation is made of
&lt;/h2&gt;

&lt;p&gt;Management has always run on a quiet substrate most of us never name. People need to feel that their work is theirs, that they are good at it, and that they belong to something. Psychologists call these autonomy, competence, and relatedness, the three needs at the centre of self-determination theory, and decades of evidence say they are what turn a job into something a person actually cares about.&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%2Fxzza6f10d0mrmrqxtvag.jpg" 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%2Fxzza6f10d0mrmrqxtvag.jpg" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Used carelessly, AI erodes all three at once.&lt;/p&gt;

&lt;p&gt;It erodes autonomy when it quietly narrows people's choices. In a 2024 experiment, operators supervising an automated system were handed fewer and fewer options by the AI. Their raw performance held up, but their sense of autonomy and the meaningfulness of the work fell, and, crucially, the effect grew the longer it ran. That is the detail most rollouts miss. The motivational cost is not a one-off dip people bounce back from. It compounds.&lt;/p&gt;

&lt;p&gt;It erodes competence when the interesting, skill-building parts of a role are handed to a model and the person is left to check its output. A reviewer of AI work all day is not building the mastery that made them worth hiring; they are slowly becoming an approver, and most people can feel the difference. And it erodes relatedness when the colleague you used to turn to with a half-formed question is replaced by a prompt box that never asks how your weekend was.&lt;/p&gt;

&lt;p&gt;None of that is the AI's doing. Every one of those is a design decision made by a leader: what to automate, what to leave with people, how much choice to preserve, whether to protect the parts of a job that make someone feel capable and connected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why leaders reach for the harmful version by default
&lt;/h2&gt;

&lt;p&gt;Almost nobody chooses the damaging rollout on purpose. They back into it, because AI arrives dressed as an IT procurement rather than an organisational change. A tool gets bought, access gets switched on, a productivity target gets set, and the questions that would have protected people, what does this do to how the work feels, who loses the interesting part of their job, where does judgment still live, never get asked, because nobody owns them. The harm is rarely malice. It is a vacuum. And a vacuum is still a choice, just an unmade one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The counter-argument, taken seriously
&lt;/h2&gt;

&lt;p&gt;The obvious objection: is this not just change resistance? People always grumble about new tools, then adapt, and the gains are worth a few uncomfortable weeks. Sometimes, yes. But two things in the evidence say do not lean on that too hard.&lt;/p&gt;

&lt;p&gt;First, the autonomy study found the erosion of meaning intensified over time rather than fading. That is the opposite of the "they will get used to it" pattern. Second, the psychological-safety study is measuring depression, a clinical outcome with real absenteeism and turnover attached, not a passing mood. "They will adapt" is a comfortable story precisely because it lets leadership off the hook for a cost that, on the numbers, does not simply wear off.&lt;/p&gt;

&lt;p&gt;And the productivity-is-worth-it framing hides the actual trade. The short-term gain is often real; the 2024 study found that restricting operators to a single recommended action did improve immediate performance. The cost showed up later, in motivation, and it compounded. So the trade is not "wellbeing versus results." It is "results now versus results and people later." Calling that an inevitable consequence of the technology is simply a way of avoiding the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this asks of a leader
&lt;/h2&gt;

&lt;p&gt;Not a wellbeing programme bolted on afterwards. Something earlier and cheaper: decide, deliberately, which human needs each AI rollout is going to protect.&lt;/p&gt;

&lt;p&gt;Keep a real decision in the loop even when the model could make it, because autonomy is load-bearing and, on the evidence, removing it is a slow leak rather than a clean win. Automate the drudgery and defend the parts of a role where people build and feel their skill, rather than the reverse. Protect the human connections AI can quietly replace. And behave, through the disruption, in the way the data actually rewards, with the integrity and care that measurably buffers the harm. That last one costs nothing, and on the numbers it does the most.&lt;/p&gt;

&lt;p&gt;None of this slows the technology down. It just refuses to pretend the human cost was handed to you by the machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;p&gt;If the psychological cost of AI is a choice, so is what happens to expertise itself. When the model is a better specialist than most of your team on a Tuesday and confidently, plausibly wrong on Wednesday, who is the authority in the room? That is next week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The series: AI, leadership and the human structures of work&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The psychological cost of AI is a leadership choice, not a technology outcome&lt;/li&gt;
&lt;li&gt;Who's the authority now? Leading in the age of the jagged generalist&lt;/li&gt;
&lt;li&gt;Managing a team of agents: leadership when roles become software&lt;/li&gt;
&lt;li&gt;Org design for AI: why your Centre of Excellence becomes a bottleneck&lt;/li&gt;
&lt;li&gt;Cutting juniors is a choice, not an AI inevitability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;You are reading part 1, the opener. Links added as each publishes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by Richard Atkins.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Sources: ADP Research, People at Work 2026 — &lt;a href="https://fortune.com/2026/03/25/workers-anxious-scared-insecure-ai-adp-global-survey/" rel="noopener noreferrer"&gt;https://fortune.com/2026/03/25/workers-anxious-scared-insecure-ai-adp-global-survey/&lt;/a&gt; · Kim, Kim &amp;amp; Lee (2025), &lt;em&gt;Humanities and Social Sciences Communications&lt;/em&gt; — &lt;a href="https://www.nature.com/articles/s41599-025-05040-2" rel="noopener noreferrer"&gt;https://www.nature.com/articles/s41599-025-05040-2&lt;/a&gt; · Faas et al. (2024), "Give Me a Choice" — &lt;a href="https://arxiv.org/abs/2410.07728" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2410.07728&lt;/a&gt; · Amy Edmondson, &lt;em&gt;The Fearless Organization&lt;/em&gt; (psychological safety) · Self-determination theory (Deci &amp;amp; Ryan) · Gallup, on manager support and adapting to AI.&lt;/small&gt;&lt;/p&gt;




&lt;p&gt;📬 &lt;strong&gt;&lt;a href="https://buttondown.com/groundedarchitect" rel="noopener noreferrer"&gt;Subscribe to &lt;em&gt;The Grounded Architect&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; — field notes on building production AI, and leading the people around it. Straight to your inbox, no hype.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>ai</category>
      <category>management</category>
      <category>mentalhealth</category>
    </item>
  </channel>
</rss>
