{"slug": "agents-don-t-fail-at-writing-code-they-fail-at-everything-around-it", "title": "Agents don't fail at writing code — they fail at everything around it", "summary": "After six months of running Claude Code agents against a large codebase, a developer found that the agents were competent at writing code but failed at surrounding process tasks such as deciding whether to build something, reusing existing code, and verifying fixes. The developer solved these issues by codifying explicit process rules, including requiring proof of verification and sweeping for systemic bugs, rather than relying on better prompting.", "body_md": "I've spent about six months running Claude Code agents against a codebase big enough to\n\nhurt — several hundred open issues, agents committing daily, a CI pipeline that fails loudly\n\nwhen they get it wrong.\n\nHere's the thing nobody told me going in: the agents were fine at writing code. Genuinely\n\nfine. Give one a well-scoped function and it comes back with something reasonable.\n\nWhat they were bad at was everything *around* writing code. Deciding whether the thing\n\nshould be built at all. Noticing that the helper they were about to write already existed\n\nsixty lines up. Checking whether the fix worked before announcing that it did. Those aren't\n\ncoding failures — they're process failures, and no amount of better prompting fixed them,\n\nbecause the problem was never the prompt.\n\nWhat fixed them was writing the process down.\n\nAn agent needs to format a duration. It writes `formatDuration()`\n\n. Your codebase already has\n\n`humanizeElapsed()`\n\nin a utils file it never opened.\n\nThis is the most expensive failure mode I hit, because nothing about it looks like a\n\nfailure. The code works. Tests pass. Review approves it. You only find out six months later\n\nwhen you change how durations are displayed and catch three of the four places.\n\nAgents are strongly biased toward writing new code rather than finding existing code,\n\nbecause writing is what they're rewarded for and searching is expensive. The counter-pressure\n\nhas to be explicit: **before you write a helper, prove the concept doesn't already exist.**\n\nNot \"check quickly\" — prove it, with a search you can cite.\n\nThe same discipline kills the \"v2\" reflex, where an agent that finds a function it doesn't\n\nfully understand writes `processDataV2()`\n\nnext to it and leaves both in the tree forever.\n\nAsk an agent whether the fix works and it will tell you the fix works. It is not lying. It\n\nhas genuinely reasoned its way to a confident answer, and reasoning feels like verification\n\nfrom the inside.\n\nThe rule that fixed this is blunt: **you may not say \"done\", \"fixed\", or \"passing\" without\npasting the command output that proves it.** Not a description of the output. The output.\n\nThe interesting part is how often an agent following that rule catches itself. It goes to\n\nrun the test so it can quote the result, the test fails, and the claim never gets made. The\n\nverification step isn't a check on the answer — it's what produces the answer.\n\nAn agent fixes a null-check bug in `UserService`\n\n. The same bug is in eleven other services,\n\nbecause they were all written from the same template by the same agent three weeks earlier.\n\nAgents fix what you point at. They don't generalise from one instance to a class of\n\ninstances unless you ask, and the whole reason the bug is interesting is that it's probably\n\nsystemic. So after every fix: **sweep the adjacent files for the same defect, and file what\nyou find.** File it even if you can't fix it now — an unfixed bug you've recorded is a\n\nAn agent hits a failing test and immediately proposes a fix. Then another. Then another. Each\n\none is plausible, none of them work, and forty minutes later the file has accumulated three\n\nspeculative changes and the original bug is still there — now harder to see.\n\nWhat's missing is the step where you find out *why* it fails before deciding what to change.\n\nRead the actual error. Reproduce it in isolation. Form one hypothesis, test that hypothesis,\n\nand only then edit. And when three attempts have failed, stop — a fourth attempt is not a\n\nstrategy, it's a slot machine. Escalate with what you learned.\n\nThe obvious place for rules like these is your project instructions, and I started there. It\n\ndoesn't scale.\n\nEverything in `CLAUDE.md`\n\nis in context permanently, competing with the actual task for\n\nattention. A twelve-line debugging protocol is exactly right when a test is failing and pure\n\nnoise the other 95% of the time. Push enough process in there and the important rules get\n\ndiluted by the situational ones.\n\nSkills load on trigger. The debugging discipline shows up when something breaks and stays out\n\nof the way otherwise. That's the whole difference, and it turns out to matter a lot.\n\nThe second reason is portability. Process discipline isn't project-specific — the \"second\n\nhelper\" problem is the same in every codebase I've worked in. Keeping it in one project's\n\ninstructions means re-deriving it in the next project. Packaged as a plugin, it moves.\n\nI've extracted the general, project-agnostic half of what accumulated and published it as a\n\nClaude Code plugin marketplace:\n\n```\n/plugin marketplace add mrveiss/Claude-Dev-Skills\n/plugin install claude-dev-skills@claude-dev-skills\n```\n\nEight skills:\n\n`process`\n\n`canonical-coding`\n\n`commit`\n\n`review-lenses`\n\n`gap-audit`\n\n`web-audit`\n\n`ui-design`\n\n`memory-cleanup`\n\nApache-2.0, and two of them consolidate ideas from other skill authors — notably Jesse\n\nVincent's [Superpowers](https://github.com/obra/superpowers) suite, which is worth reading on\n\nits own.\n\nThey came out of building [AutoBot-AI](https://github.com/mrveiss/AutoBot-AI). The\n\nproject-specific ones — the issue-to-merge loop, full-stack debugging, the codebase audits —\n\nlive in [their own marketplace](https://github.com/mrveiss/AutoBot-AI-Claude-dev-skills),\n\nbecause they hardcode that platform's branch names and paths and are no use anywhere else.\n\nThis is the half that travels.\n\nProcess discipline has a real cost. Every one of these rules makes the agent slower, and some\n\nof them make it slower in ways that feel pointless in the moment — proving a helper doesn't\n\nexist takes longer than writing the helper, almost every time.\n\nThe trade only pays off over a codebase's lifetime, which means it's genuinely the wrong call\n\nfor a prototype you'll throw away in a week. If you're spiking something, skip all of this\n\nand let the agent write.\n\nWhere it pays is the second year, when you're the one maintaining what the agents built.\n\nIf you try the set, I'd like to know where it's wrong: does `process`\n\nroute the way you\n\nactually work, or does it fire when you don't want it? Is `canonical-coding`\n\ntoo strict for a\n\ncodebase that legitimately carries parallel implementations? And what's missing?", "url": "https://wpnews.pro/news/agents-don-t-fail-at-writing-code-they-fail-at-everything-around-it", "canonical_source": "https://dev.to/mrveiss/agents-dont-fail-at-writing-code-they-fail-at-everything-around-it-46ah", "published_at": "2026-08-25 13:00:02+00:00", "updated_at": "2026-08-25 13:15:12.375131+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models", "ai-products"], "entities": ["Claude Code"], "alternates": {"html": "https://wpnews.pro/news/agents-don-t-fail-at-writing-code-they-fail-at-everything-around-it", "markdown": "https://wpnews.pro/news/agents-don-t-fail-at-writing-code-they-fail-at-everything-around-it.md", "text": "https://wpnews.pro/news/agents-don-t-fail-at-writing-code-they-fail-at-everything-around-it.txt", "jsonld": "https://wpnews.pro/news/agents-don-t-fail-at-writing-code-they-fail-at-everything-around-it.jsonld"}}