<?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: Momcilo Savic</title>
    <description>The latest articles on DEV Community by Momcilo Savic (@momcilo_savic_f347191005c).</description>
    <link>https://dev.to/momcilo_savic_f347191005c</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%2F4096315%2F193b0aa5-a5cf-4be3-ab01-7ba6578681b3.png</url>
      <title>DEV Community: Momcilo Savic</title>
      <link>https://dev.to/momcilo_savic_f347191005c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/momcilo_savic_f347191005c"/>
    <language>en</language>
    <item>
      <title>AI Agent Code Review: 3 Patterns Where Cursor, Copilot, and Devin Silently Break Production</title>
      <dc:creator>Momcilo Savic</dc:creator>
      <pubDate>Thu, 27 Aug 2026 20:03:07 +0000</pubDate>
      <link>https://dev.to/momcilo_savic_f347191005c/ai-agent-code-review-3-patterns-where-cursor-copilot-and-devin-silently-break-production-2b1k</link>
      <guid>https://dev.to/momcilo_savic_f347191005c/ai-agent-code-review-3-patterns-where-cursor-copilot-and-devin-silently-break-production-2b1k</guid>
      <description>&lt;p&gt;AI-assisted refactors are fast, confident, and syntactically clean — which is exactly why an AI-generated code security check needs to look for something different than a traditional static analyzer does. A SAST tool asks "is this new code dangerous?" The failure mode that actually ships in agent-authored PRs is different: &lt;strong&gt;the danger was in the code that got deleted&lt;/strong&gt;, and nothing in a standard diff review, and nothing in CI, is set up to notice that.&lt;/p&gt;

&lt;p&gt;Below are three real patterns — reconstructed as clean, synthetic examples rather than screenshots of anyone's actual PR, but each one a faithful reproduction of something that has genuinely shipped in agent-generated pull requests. All three share the same signature: the diff looks like a &lt;em&gt;cleanup&lt;/em&gt;, the commit message is confident and plausible, no test touches the changed lines, and CI stays green.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this needs a different kind of pre-merge check for AI pull requests
&lt;/h2&gt;

&lt;p&gt;Human refactors and agent refactors fail differently. A human doing a "simplify this route file" pass usually has the mental model of the whole file loaded — they know &lt;em&gt;why&lt;/em&gt; &lt;code&gt;requireAuth&lt;/code&gt; is there even if they're moving it around. A coding agent operating on a local diff window is pattern-matching against the surrounding code and the instruction it was given ("clean this up," "make this more readable," "add a status filter"). It has no persistent belief about which lines are load-bearing for security and which are stylistic. When a security check happens to look like boilerplate next to the "real" logic, an agent optimizing for readability treats it exactly like boilerplate.&lt;/p&gt;

&lt;p&gt;That's the case for a pre-merge security check on AI pull requests that's structurally different from a generic linter: it needs to diff against &lt;em&gt;intent&lt;/em&gt;, not just syntax — specifically, it needs to notice when something that used to gate access to a route or a record is gone, even though nothing that remains is itself incorrect.&lt;/p&gt;

&lt;p&gt;Three concrete shapes this takes:&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 1: Auth regression from route consolidation
&lt;/h2&gt;

&lt;p&gt;The most common shape. An agent is asked to make a routes file more readable, or to merge two similar files, or to "group related routes." Somewhere in that pass, the middleware argument silently drops out of the call.&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%2F8gznwntef0hlkfg4arfi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8gznwntef0hlkfg4arfi.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 2: The "session covers it" IDOR
&lt;/h2&gt;

&lt;p&gt;A subtler variant, and the one most likely to survive review even from an attentive human, because it isn't a deletion of an entire auth check — it's a &lt;em&gt;narrowing&lt;/em&gt; of one that looks like a simplification.&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%2Fdbbwrls61c1at3hx1muz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdbbwrls61c1at3hx1muz.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 3: The query "simplification" that removes the index
&lt;/h2&gt;

&lt;p&gt;Not every dangerous agent refactor is a security regression — some are latent production incidents. This one shows up when a new requirement (an admin filter, a search field, a sort option) gets bolted onto an existing, indexed query in the least structurally invasive way an agent can find.&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%2Fl6dp9oow0461avng3a8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl6dp9oow0461avng3a8y.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;where: { customerId }&lt;/code&gt; was doing real work — it was the difference between a database using an index to return 20 rows and a database returning every row in the table so the application can filter them in JavaScript. The "after" version is not wrong, and at low data volumes it's not even slow. It's a regression that's invisible in development, invisible in a code review that isn't thinking about table size, and invisible in CI unless your test fixtures happen to contain enough rows to make the difference measurable — which they almost never do. It becomes visible in production, usually as a latency spike or a timeout, usually weeks after merge, usually with no obvious connection back to "that readability refactor from last sprint."&lt;/p&gt;

&lt;h2&gt;
  
  
  Vibe coding security risks are a systemic property, not a tool defect
&lt;/h2&gt;

&lt;p&gt;It's tempting to read these three examples and look for the culprit in a specific tool's system prompt or training data. That's the wrong frame. Cursor, Copilot, Devin, and every other agent in this category are optimizing for the instruction they were given plus the surrounding code's style — that's the job. The risk isn't that any one of these tools is careless; it's structural to what "vibe coding" — accepting agent-generated diffs on the strength of them looking right and running correctly — actually is. A diff that compiles, passes existing tests, and reads as cleaner than what it replaced will clear almost every review process teams have today, because those processes were built around the assumption that a human wrote the change and therefore had some model of what mattered in it.&lt;/p&gt;

&lt;p&gt;The volume problem compounds this: teams merging agent-authored PRs faster than a human reviewer can build the old kind of mental model are, by construction, the teams least equipped to catch a pattern that requires exactly that mental model to notice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a pre-merge check for this actually needs to look at
&lt;/h2&gt;

&lt;p&gt;Given the shape of all three patterns above, a useful check has to do two things a standard linter doesn't:&lt;/p&gt;

&lt;p&gt;It needs the &lt;strong&gt;removed&lt;/strong&gt; side of the diff, not just the added side — every one of these three examples is a deletion (or a narrowing) that reads as safe specifically because the remaining code is syntactically fine.&lt;/p&gt;

&lt;p&gt;It needs enough context to distinguish &lt;em&gt;this specific pattern&lt;/em&gt; — authorization and query-shape changes — from the much larger and noisier space of "any diff at all," so it doesn't become another alert people learn to dismiss.&lt;/p&gt;

&lt;p&gt;That's the specific, narrow thing we built &lt;strong&gt;Agent Code Merge Gate&lt;/strong&gt; to do: a free GitHub Action that reviews a PR's diff for exactly these two failure modes — authorization regressions and query/index risk — and posts one non-blocking PR comment with an executive summary. Three lines of YAML, no dashboard required to see results, nothing installed beyond the workflow step itself.&lt;/p&gt;

&lt;p&gt;It won't catch everything an agent can get wrong — input validation dropped silently is a related pattern it doesn't check yet, and it's worth naming that limitation plainly rather than implying broader coverage than exists. But for the two specific patterns above, where regressions are consistently invisible to both CI and a normal-speed review pass, it's a check purpose-built for the failure mode agentic coding actually produces, not a generic scan repurposed to sound relevant to it.&lt;/p&gt;

&lt;p&gt;If you're merging Cursor, Copilot, or Devin-authored PRs faster than your reviewers can build a mental model of each one — which describes most teams adopting these tools right now — this is worth the three lines of YAML: &lt;strong&gt;&lt;a href="https://github.com/marketplace/actions/avalonlabs-agent-code-merge-gate" rel="noopener noreferrer"&gt;Install Agent Code Merge Gate on GitHub Marketplace&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>github</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Bug Class AI Coding Agents Keep Introducing (and How We Started Catching It in CI)</title>
      <dc:creator>Momcilo Savic</dc:creator>
      <pubDate>Wed, 26 Aug 2026 20:57:02 +0000</pubDate>
      <link>https://dev.to/momcilo_savic_f347191005c/the-bug-class-ai-coding-agents-keep-introducing-and-how-we-started-catching-it-in-ci-1np7</link>
      <guid>https://dev.to/momcilo_savic_f347191005c/the-bug-class-ai-coding-agents-keep-introducing-and-how-we-started-catching-it-in-ci-1np7</guid>
      <description>&lt;h2&gt;
  
  
  The pattern
&lt;/h2&gt;

&lt;p&gt;AI coding agents are good at producing a diff that &lt;em&gt;works&lt;/em&gt; in the&lt;br&gt;
narrowest sense — the function still returns what the test expects. What&lt;br&gt;
they're not reliably good at is preserving properties nobody wrote a test&lt;br&gt;
for in the first place.&lt;/p&gt;

&lt;p&gt;The two we kept running into: an authorization check quietly dropped&lt;br&gt;
during an agent-driven refactor (nothing failed, because no test covered&lt;br&gt;
&lt;em&gt;who&lt;/em&gt; was allowed to call the route — only that the route worked), and a&lt;br&gt;
rewritten query that behaved fine against a small dev dataset and&lt;br&gt;
full-table-scanned the moment it hit production data. Neither shows up in&lt;br&gt;
CI as it exists today. Both show up in code review only if the reviewer&lt;br&gt;
happens to look at exactly the right five lines out of a few hundred.&lt;/p&gt;
&lt;h2&gt;
  
  
  What we built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/avalonlabs-platform/agent-code-merge-gate" rel="noopener noreferrer"&gt;Agent Code Merge Gate&lt;/a&gt;&lt;br&gt;
is a free GitHub Action, now &lt;a href="https://github.com/marketplace/actions/avalonlabs-agent-code-merge-gate" rel="noopener noreferrer"&gt;live on the GitHub Marketplace&lt;/a&gt;,&lt;br&gt;
that runs on every pull request and scans the diff specifically for those&lt;br&gt;
two regression classes. It runs an offline heuristic pass (fast, no&lt;br&gt;
external call) plus one AI-backed pass for a short Executive Summary, and&lt;br&gt;
posts a single comment back to the PR that updates on every push rather&lt;br&gt;
than piling up duplicates.&lt;/p&gt;

&lt;p&gt;Deliberately narrow scope — it's not trying to be a general linter. It&lt;br&gt;
covers the two failure modes we found ourselves manually re-checking for&lt;br&gt;
once AI-generated PRs became the majority of our merge volume.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wiring it into CI
&lt;/h2&gt;

&lt;p&gt;Three lines in a workflow file:&lt;/p&gt;

&lt;p&gt;​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Agent Code Merge Gate&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;avalonlabs-platform/agent-code-merge-gate@v1.0.0&lt;/span&gt;
&lt;span class="s"&gt;​```&lt;/span&gt;
&lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="nv"&gt;endraw %&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;


&lt;span class="s"&gt;No signup and no config needed for the default behavior. Two inputs worth&lt;/span&gt;
&lt;span class="na"&gt;knowing about&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="nv"&gt;raw %&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="na"&gt;`fail-on-critical&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="s"&gt;` turns a CRITICAL finding into an&lt;/span&gt;
&lt;span class="s"&gt;actual failed check instead of just a comment, and `comment-on-pr&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="s"&gt;`&lt;/span&gt;
&lt;span class="s"&gt;if you'd rather build your own notification from the raw `status` output.&lt;/span&gt;

&lt;span class="c1"&gt;## What's next&lt;/span&gt;

&lt;span class="s"&gt;Right now it's diff-scoped — it sees what changed in this PR, not the&lt;/span&gt;
&lt;span class="s"&gt;whole repo's history of how that code got there, which limits how much&lt;/span&gt;
&lt;span class="s"&gt;context it can reason about. Whole-repo context is the obvious next step,&lt;/span&gt;
&lt;span class="s"&gt;and it's also where this stops being a free CI script and starts being a&lt;/span&gt;
&lt;span class="s"&gt;product decision — worth its own post once it's built rather than&lt;/span&gt;
&lt;span class="s"&gt;speculated about here.&lt;/span&gt;

&lt;span class="s"&gt;If you've hit a different bug pattern that seems to show up&lt;/span&gt;
&lt;span class="s"&gt;disproportionately in AI-generated PRs, I'd genuinely like to hear about&lt;/span&gt;
&lt;span class="s"&gt;it — that's exactly the kind of thing worth building detection for next.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>javascript</category>
      <category>github</category>
    </item>
  </channel>
</rss>
