<?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: Ricardas Kauneckas</title>
    <description>The latest articles on DEV Community by Ricardas Kauneckas (@ryckakas).</description>
    <link>https://dev.to/ryckakas</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%2F4122877%2Fd80d38f2-b4c0-4d93-b36c-951d085d1480.png</url>
      <title>DEV Community: Ricardas Kauneckas</title>
      <link>https://dev.to/ryckakas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ryckakas"/>
    <language>en</language>
    <item>
      <title>Stop Blaming AI for Bad Code: It’s a Scalpel, Not a Magic Wand</title>
      <dc:creator>Ricardas Kauneckas</dc:creator>
      <pubDate>Tue, 06 Oct 2026 13:15:51 +0000</pubDate>
      <link>https://dev.to/ryckakas/stop-blaming-ai-for-bad-code-its-a-scalpel-not-a-magic-wand-34o6</link>
      <guid>https://dev.to/ryckakas/stop-blaming-ai-for-bad-code-its-a-scalpel-not-a-magic-wand-34o6</guid>
      <description>

&lt;p&gt;Scroll through any developer platform right now, and you will immediately notice a massive trend: hating on AI.&lt;/p&gt;

&lt;p&gt;It has become so popular that I honestly cannot tell who is just chasing the current trend, and who is genuinely struggling to tame these tools. But the frustration usually stems from a fundamental misunderstanding of what AI actually is.&lt;/p&gt;

&lt;p&gt;If you hand a surgical scalpel to someone without surgical training, it does not magically make them a surgeon.&lt;/p&gt;

&lt;p&gt;The secret is not the scalpel itself. It is the hard-earned knowledge of how to wield it. AI in software development is exactly the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Letting the Scalpel Run Wild
&lt;/h2&gt;

&lt;p&gt;I will be controversial here: I don't think "one-shotting" huge features with AI is wrong. I also don't think trusting AI-written code is the root issue.&lt;/p&gt;

&lt;p&gt;The real mistake happens before a single prompt is ever written. It is a lack of proper setup.&lt;/p&gt;

&lt;p&gt;Most developers let AI agents run wild in massive, existing repositories heavily burdened with accumulated tech debt, anti-patterns, and smelly code. The AI agent scans the repo, assumes this bad code is the acceptable standard, and perfectly replicates your worst practices.&lt;/p&gt;

&lt;p&gt;Worse, some teams assume that because AI covers so much ground, they no longer need traditional code quality tools. This is how a tool becomes dangerous.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Building the Surgeon's Operating Room
&lt;/h2&gt;

&lt;p&gt;You cannot just write a &lt;code&gt;.cursorrules&lt;/code&gt; or &lt;code&gt;agents.md&lt;/code&gt; file, ask the AI to "be a good developer," and expect 100% compliance. You have to remove the implicitness. You must frame the AI into conventions that are strictly enforced by tools.&lt;/p&gt;

&lt;p&gt;To actually harness AI-driven development, you need an environment built on hard guardrails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write Real Tests, Not Echoes:&lt;/strong&gt; Stop letting AI generate tests just to satisfy existing code. Build real business logic and conformance tests that actively fail when an agent strays outside a domain or breaks a class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build Regression Fixtures:&lt;/strong&gt; Record fixtures that allow you to run the new feature code against the previous version. You need an automated way to compare and catch unexpected regressions immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gate Everything in CI:&lt;/strong&gt; Pull requests generated by AI need strict automated gates. If it doesn't pass the pipeline, it doesn't get merged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demand Visual Evidence:&lt;/strong&gt; Let agents run E2E testing using browser tools. Have them capture and provide actual visual evidence on the PR showing that the feature works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to hold the AI's hand. The goal is to build an infrastructure that maximizes your absolute confidence in the code sitting in that PR.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. From Token Furnace to Reliable Worker
&lt;/h2&gt;

&lt;p&gt;I currently run a fully autonomous AI factory. My experience has been extremely positive, but getting here wasn't magic.&lt;/p&gt;

&lt;p&gt;Initially, I had built a "token furnace", which was basically a system that just burned through API calls without delivering reliable value. It only became a reliable worker when I stopped focusing on the AI and started focusing entirely on the infrastructure. I worked on the environment until it was so fine-tuned that I actually trusted leaving it running alone.&lt;/p&gt;

&lt;p&gt;My biggest takeaway? &lt;strong&gt;Make everything bounded.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Stop the Snake from Eating Its Own Tail
&lt;/h3&gt;

&lt;p&gt;In my case, the issue usually isn't that reviewing agents hallucinate or fight over trivial syntax. More often than not, I find their actual code review findings to be completely valid. For my factory, the real killer has been &lt;strong&gt;documentation rot and context bloat&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To keep agents aligned, you have to provide enough context and compound findings from previous sessions. But this documentation quickly bloats and rots. References get scattered across the repository, and soon, a perfectly capable agent that would have otherwise executed flawlessly gets misguided because an outdated file gave it conflicting instructions.&lt;/p&gt;

&lt;p&gt;When my agents start spinning in circles or blocking PRs, it is rarely because the AI failed at reasoning. It is almost always a context problem.&lt;/p&gt;

&lt;p&gt;This is why you must remain in control. Human-in-the-loop (HITL) is an absolutely normal and necessary part of autonomous development. If an agent gets stuck in a loop because it is battling stale docs, you need infrastructure that automatically parks the PR. The agents do the heavy lifting, but a human must step in to clean up the context and act as the circuit breaker.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Architect and the Executor
&lt;/h2&gt;

&lt;p&gt;Using AI correctly means the AI works for you, not the other way around. The same rule applies to the development process. The human is supposed to make the decisions, the AI is supposed to execute them, and the infrastructure is supposed to validate that execution and ensure quality.&lt;/p&gt;

&lt;p&gt;If an AI makes a rogue decision that negatively impacts your codebase, only the human is to blame. You cannot blame the tool just because you are not using it correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The problem with AI in software development isn’t the AI. The problem is expecting a scalpel to perform the surgery on its own in a dirty operating room.&lt;/p&gt;

&lt;p&gt;Stop blaming the tool. Start building the infrastructure, write tests that actually challenge the code, and bound your agents so they work for you, not against each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Over to you:&lt;/strong&gt; Have you tried automating any part of your PR review process? What guardrails have actually worked for your team? Let me know in the comments!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Clean code didn't get less important in the AI age — it got more important</title>
      <dc:creator>Ricardas Kauneckas</dc:creator>
      <pubDate>Sun, 13 Sep 2026 08:02:21 +0000</pubDate>
      <link>https://dev.to/ryckakas/clean-code-didnt-get-less-important-in-the-ai-age-it-got-more-important-513c</link>
      <guid>https://dev.to/ryckakas/clean-code-didnt-get-less-important-in-the-ai-age-it-got-more-important-513c</guid>
      <description>&lt;p&gt;Most of the code in my day to day now flows through an agent before it lands in&lt;br&gt;
a diff. You'd think that makes clean code less relevant: nobody's staring at&lt;br&gt;
this line by line anymore. It's the opposite. The less humans read and write&lt;br&gt;
code by hand, the more the shape of the codebase does the work a reviewer used&lt;br&gt;
to do in their head.&lt;/p&gt;

&lt;p&gt;Two ideas explain why, and they lead to a concrete practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guidelines vs. guardrails
&lt;/h2&gt;

&lt;p&gt;When you brief an agent (a CLAUDE.md, an AGENTS.md, a comment in the PR&lt;br&gt;
description) you're writing guidelines. Implicit rules you hope it sticks to.&lt;br&gt;
Keep functions small. No god classes. Extract instead of nesting. They work,&lt;br&gt;
right up until the context fills up, the task gets gnarly, or the model just&lt;br&gt;
decides a fourth level of nesting is fine today. Nothing enforces them. They're&lt;br&gt;
a &lt;em&gt;request&lt;/em&gt;, not a &lt;em&gt;constraint&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guardrails&lt;/strong&gt; are the other half. Explicit rules a tool enforces, with an exit&lt;br&gt;
code that fails the build. A linter, a type checker, a complexity gate in CI.&lt;br&gt;
The agent doesn't need to remember the rule or agree with it. The pipeline&lt;br&gt;
rejects the output and it gets fixed before anything ships.&lt;/p&gt;

&lt;p&gt;Both mattered before LLMs wrote code too. But guidelines used to be backstopped&lt;br&gt;
by a human reviewer who'd actually read the diff and push back. That backstop&lt;br&gt;
is thinner now. Review is faster, diffs are bigger, and the reviewer is often&lt;br&gt;
skimming code they didn't write and won't internalize the way the author would&lt;br&gt;
have. Guardrails pick up that slack. If a rule actually matters, it belongs in&lt;br&gt;
something that fails the build, not only in a paragraph the agent is&lt;br&gt;
statistically likely to follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's still for humans too
&lt;/h2&gt;

&lt;p&gt;The usual case for low complexity is human: less to hold in your head, fewer&lt;br&gt;
ways to misread a branch, easier to test. All of that applies to an agent just&lt;br&gt;
as much. A function with a cognitive complexity of 70 is exactly as easy to&lt;br&gt;
introduce a bug into whether the thing writing it has a brain or a context&lt;br&gt;
window. Deep nesting burns tokens and attention the same way it burns a&lt;br&gt;
reviewer's patience, and the failure mode is the same: an edge case gets missed&lt;br&gt;
because the shape of the code hid it.&lt;/p&gt;

&lt;p&gt;The part that's easy to miss is that a codebase also acts as reference material&lt;br&gt;
for the next session. An agent asked to add a feature doesn't invent a style&lt;br&gt;
from nothing, it pattern matches on what's already there, because that's the&lt;br&gt;
most relevant context it has. A clean, consistent codebase means new code tends&lt;br&gt;
to follow the same clean patterns. A messy one means the agent's best available&lt;br&gt;
example of "how we do things here" is the mess, and it faithfully extends it.&lt;br&gt;
Good code compounds into more good code. Bad code compounds into more bad code,&lt;br&gt;
just faster than it used to, because now there's an eager pair of hands copying&lt;br&gt;
whatever pattern is nearest.&lt;/p&gt;

&lt;p&gt;That's the actual argument for guardrails over guidelines: a linter that fails&lt;br&gt;
the build doesn't let the mess get far enough to become a template.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tools, not just one kind
&lt;/h2&gt;

&lt;p&gt;None of this is language specific, or even complexity specific. It applies to&lt;br&gt;
every category of quality tool: formatters, type checkers, static analysis,&lt;br&gt;
security scanners, complexity gates. The common thread is enforced, not&lt;br&gt;
requested.&lt;/p&gt;

&lt;p&gt;For cognitive and cyclomatic complexity there's &lt;a href="https://github.com/uudashr/gocognit" rel="noopener noreferrer"&gt;&lt;code&gt;gocognit&lt;/code&gt;&lt;/a&gt;&lt;br&gt;
for Go and the &lt;a href="https://github.com/SonarSource/eslint-plugin-sonarjs" rel="noopener noreferrer"&gt;&lt;code&gt;sonarjs&lt;/code&gt;&lt;/a&gt;&lt;br&gt;
ESLint rules for JS/TS, and for PHP I maintain a small one myself - &lt;a href="https://github.com/ryckakas/bonsai-lint" rel="noopener noreferrer"&gt;bonsai-lint&lt;/a&gt;: a single&lt;br&gt;
static binary written in Rust with no PHP runtime or Composer entry that scans large codebases&lt;br&gt;
in a couple of seconds and supports baselining, so a legacy project can gate on&lt;br&gt;
new violations without fixing everything that predates the tool.&lt;/p&gt;

&lt;p&gt;For static analysis there's &lt;a href="https://phpstan.org/" rel="noopener noreferrer"&gt;PHPStan&lt;/a&gt; for PHP and&lt;br&gt;
&lt;a href="https://mypy-lang.org/" rel="noopener noreferrer"&gt;mypy&lt;/a&gt; for Python. For formatting,&lt;br&gt;
&lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt; and &lt;code&gt;gofmt&lt;/code&gt; are the cheapest guardrail there&lt;br&gt;
is, with zero excuse not to run one. For security, &lt;a href="https://semgrep.dev/" rel="noopener noreferrer"&gt;Semgrep&lt;/a&gt;&lt;br&gt;
covers the same principle at higher stakes.&lt;/p&gt;

&lt;p&gt;If you're running agents against a codebase day to day, worth asking: what&lt;br&gt;
guardrails are actually catching things for you, versus what's still living as&lt;br&gt;
a hopeful paragraph in a prompt file?&lt;/p&gt;

&lt;p&gt;LINKS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ryckakas/bonsai-lint" rel="noopener noreferrer"&gt;https://github.com/ryckakas/bonsai-lint&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cleancode</category>
      <category>softwaredevelopment</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
