<?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: Ian Smith</title>
    <description>The latest articles on DEV Community by Ian Smith (@ian_smith_4fb32f6c3156124).</description>
    <link>https://dev.to/ian_smith_4fb32f6c3156124</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%2F2425123%2F4c7cf3a8-374b-4004-b315-1607e915c5a5.jpg</url>
      <title>DEV Community: Ian Smith</title>
      <link>https://dev.to/ian_smith_4fb32f6c3156124</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ian_smith_4fb32f6c3156124"/>
    <language>en</language>
    <item>
      <title>Prevention, Not Recovery: What I learned building a tool to restrain AI coding agents</title>
      <dc:creator>Ian Smith</dc:creator>
      <pubDate>Mon, 27 Jul 2026 16:25:19 +0000</pubDate>
      <link>https://dev.to/ian_smith_4fb32f6c3156124/prevention-not-recovery-what-i-learned-building-a-tool-to-restrain-ai-coding-agents-4i1e</link>
      <guid>https://dev.to/ian_smith_4fb32f6c3156124/prevention-not-recovery-what-i-learned-building-a-tool-to-restrain-ai-coding-agents-4i1e</guid>
      <description>&lt;p&gt;Got AI-generated bugs? Slop in your diffs? You are not alone.&lt;br&gt;
&lt;a href="https://github.com/iansmith/slopstop" rel="noopener noreferrer"&gt;slopstop&lt;/a&gt; is a Claude Code plugin that&lt;br&gt;
replaces the prompt-and-hope loop with a prevention-oriented one. Work starts from a ticket — scoped and test-anchored —&lt;br&gt;
before any implementation exists. It does not merge until several independent&lt;br&gt;
passes have tried to find slop in it. The bet: prevention is cheaper than&lt;br&gt;
recovery.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problem with reviewing slop out
&lt;/h2&gt;

&lt;p&gt;Most of the tooling around AI-written code is recovery tooling. It looks at a diff&lt;br&gt;
that already exists and hunts for what is wrong with it. That is useful, and&lt;br&gt;
slopstop uses these types of tools, but in conjunction with various other&lt;br&gt;
analysis and adversarial agents. By the time slopstop invokes a code-review&lt;br&gt;
tool, we should have prevented the really expensive mistakes like adding&lt;br&gt;
new abstractions, out-of-scope implementations, or vacuous testing.&lt;br&gt;
The review tools can, and are, victimized by code-writing agents because the&lt;br&gt;
agent leaves a working program (with tests?) but the shape is the one the&lt;br&gt;
agent chose. Put another way: Have you ever seen a code review agent say, "Throw&lt;br&gt;
this whole thing away and do something simpler"?&lt;/p&gt;

&lt;p&gt;Tests that pass are the interesting case. The common, sad failure mode of&lt;br&gt;
AI-generated tests is that they are reverse-engineered from the implementation:&lt;br&gt;
the agent reads the code it just wrote and writes assertions describing it. Those&lt;br&gt;
tests pin the current behaviour, bugs included, and pass vacuously forever. A&lt;br&gt;
review pass will not catch that. The tests are green. The diff is clean. The code&lt;br&gt;
is wrong.&lt;/p&gt;
&lt;h2&gt;
  
  
  What slopstop does instead
&lt;/h2&gt;

&lt;p&gt;The effort moves earlier — before the implementation exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Failing tests for what the ticket requires.&lt;/strong&gt; &lt;code&gt;/slopstop:plan&lt;/code&gt; writes the tests&lt;br&gt;
first, from the ticket's stated behaviour rather than from any code. They have to&lt;br&gt;
be red, and red for the right reason, before implementation starts. Every work&lt;br&gt;
item in the plan is anchored to a named test turning green. slopstop commits&lt;br&gt;
the state with the red tests and no implementation before work on the&lt;br&gt;
implementation begins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A written Definition of Done and scope boundary.&lt;/strong&gt; Also drafted up front, in&lt;br&gt;
plain language, on the ticket. You can see it is working when Claude stops&lt;br&gt;
and asks &lt;em&gt;"would you like me to spin out a new ticket for this out-of-scope&lt;br&gt;
task?"&lt;/em&gt; instead of quietly widening the diff. The definition of done section of&lt;br&gt;
a slopstop ticket is the only way a ticket's implementation can be merged: "Are&lt;br&gt;
all the definition of done conditions met?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A simplify pass before the commit exists.&lt;/strong&gt; &lt;code&gt;/slopstop:pr&lt;/code&gt; runs a simplify pass&lt;br&gt;
over the uncommitted changes — over-engineering, dead code, needless abstraction —&lt;br&gt;
while removing them is still free. We use &lt;a href="https://code.claude.com/docs/en/code-review#review-a-diff-locally" rel="noopener noreferrer"&gt;Claude's own simplify&lt;br&gt;
pass&lt;/a&gt; for this&lt;br&gt;
(a cleanup-only review that applies its fixes without hunting for bugs), so this&lt;br&gt;
is a "review type" pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A complexity gate that catches what simplification misses.&lt;/strong&gt; slopstop computes&lt;br&gt;
cyclomatic complexity for every function in the diff, using&lt;br&gt;
&lt;a href="http://www.lizard.ws" rel="noopener noreferrer"&gt;lizard&lt;/a&gt; — and installs it for you if it isn't already&lt;br&gt;
there. It warns above 10 and fails above 15. This catches a specific AI failure&lt;br&gt;
mode: instead of factoring a problem into small pieces, the agent stuffs&lt;br&gt;
everything into one function with a dozen branches. A human reviewer might wave&lt;br&gt;
that through because the tests pass. The complexity gate will not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A review pass that checks itself.&lt;/strong&gt; There is an automated code review that is&lt;br&gt;
performed on every ticket's implementation. slopstop will verify each finding&lt;br&gt;
reported by the code review, and sorts what can be verified into should-fix /&lt;br&gt;
could-fix / skip. Findings that do not hold up against the code are refuted in&lt;br&gt;
writing rather than dutifully applied.&lt;/p&gt;
&lt;h2&gt;
  
  
  It scales past one ticket
&lt;/h2&gt;

&lt;p&gt;Preventing slop does not mean working alone. &lt;code&gt;/slopstop:design&lt;/code&gt; interviews you&lt;br&gt;
about an idea, or just some random thoughts, until things are sufficiently clear&lt;br&gt;
about what you want and how you want it done that we can write a Product&lt;br&gt;
Requirements Document and a Charter for the idea you sent into &lt;code&gt;/slopstop:design&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/slopstop:tickets&lt;/code&gt; cuts a ticket tree from it and hands the tree to an&lt;br&gt;
adversary that tries to break it. The adversary checks every ticket created&lt;br&gt;
against the PRD and Charter generated by &lt;code&gt;/slopstop:design&lt;/code&gt; and if it finds&lt;br&gt;
anything that doesn't match up, it rejects the ticket tree with a reason.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/slopstop:run&lt;/code&gt; drives parallel headless agents,&lt;br&gt;
one per ticket, each isolated in its own git worktree, across multiple model&lt;br&gt;
tiers — where every tier's work is checked by the tier above it. Weaker models&lt;br&gt;
cost less but trigger more rounds of correction — the usual money-for-time trade.&lt;/p&gt;

&lt;p&gt;The guarantees that hold for one ticket hold for the fleet: frozen tests with&lt;br&gt;
tamper checks, independent handoff verification before any branch is integrated,&lt;br&gt;
and a human gate at every stage boundary.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it looks like when it catches something
&lt;/h2&gt;

&lt;p&gt;Claims about adversarial verification are cheap, so there is a&lt;br&gt;
&lt;a href="https://iansmith.github.io/slopstop/walkthrough/index.html" rel="noopener noreferrer"&gt;transcript&lt;/a&gt;. One&lt;br&gt;
real run: a five-sentence feature description turned into seven merged PRs by a&lt;br&gt;
fleet of deliberately underpowered agents, read in time order, quoting the&lt;br&gt;
transcript at every point where the process caught something.&lt;/p&gt;

&lt;p&gt;Among the catches: a design interview that finds a contradiction between two of the&lt;br&gt;
human answers seventy seconds apart. An adversary that rejects a ticket tree because&lt;br&gt;
the lock it specified would not actually have locked — and proves it with a&lt;br&gt;
forty-trial experiment. An implementing agent that reported success, exited&lt;br&gt;
cleanly with a green tree, and had done nothing at all. And a final adversary that&lt;br&gt;
re-ran the suite, confirmed the code was correct, and then found that the&lt;br&gt;
orchestrator's own report had fabricated a violation against one of its own&lt;br&gt;
agents — followed by a public retraction on the ticket.&lt;/p&gt;

&lt;p&gt;That last one is the one to sit with. The process caught its own supervisor lying.&lt;/p&gt;
&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The walkthrough shows numerous examples of slopstop catching code errors, catching&lt;br&gt;
ticket problems, and most importantly, &lt;em&gt;human design errors&lt;/em&gt;. It is worth reading&lt;br&gt;
in full.&lt;/p&gt;

&lt;p&gt;Install slopstop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin marketplace add iansmith/slopstop
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;slopstop@slopstop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start from a ticket:&lt;br&gt;
&lt;a href="https://github.com/iansmith/slopstop/blob/master/WORKFLOW.md" rel="noopener noreferrer"&gt;&lt;code&gt;/slopstop:start &amp;lt;ticket&amp;gt;&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/iansmith/slopstop" rel="noopener noreferrer"&gt;github.com/iansmith/slopstop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Questions about the approach or the adversary catches? I'm in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>testing</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
