Agents don't fail at writing code — they fail at everything around it 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. I've spent about six months running Claude Code agents against a codebase big enough to hurt — several hundred open issues, agents committing daily, a CI pipeline that fails loudly when they get it wrong. Here's the thing nobody told me going in: the agents were fine at writing code. Genuinely fine. Give one a well-scoped function and it comes back with something reasonable. What they were bad at was everything around writing code. Deciding whether the thing should be built at all. Noticing that the helper they were about to write already existed sixty lines up. Checking whether the fix worked before announcing that it did. Those aren't coding failures — they're process failures, and no amount of better prompting fixed them, because the problem was never the prompt. What fixed them was writing the process down. An agent needs to format a duration. It writes formatDuration . Your codebase already has humanizeElapsed in a utils file it never opened. This is the most expensive failure mode I hit, because nothing about it looks like a failure. The code works. Tests pass. Review approves it. You only find out six months later when you change how durations are displayed and catch three of the four places. Agents are strongly biased toward writing new code rather than finding existing code, because writing is what they're rewarded for and searching is expensive. The counter-pressure has to be explicit: before you write a helper, prove the concept doesn't already exist. Not "check quickly" — prove it, with a search you can cite. The same discipline kills the "v2" reflex, where an agent that finds a function it doesn't fully understand writes processDataV2 next to it and leaves both in the tree forever. Ask an agent whether the fix works and it will tell you the fix works. It is not lying. It has genuinely reasoned its way to a confident answer, and reasoning feels like verification from the inside. The rule that fixed this is blunt: you may not say "done", "fixed", or "passing" without pasting the command output that proves it. Not a description of the output. The output. The interesting part is how often an agent following that rule catches itself. It goes to run the test so it can quote the result, the test fails, and the claim never gets made. The verification step isn't a check on the answer — it's what produces the answer. An agent fixes a null-check bug in UserService . The same bug is in eleven other services, because they were all written from the same template by the same agent three weeks earlier. Agents fix what you point at. They don't generalise from one instance to a class of instances unless you ask, and the whole reason the bug is interesting is that it's probably systemic. So after every fix: sweep the adjacent files for the same defect, and file what you find. File it even if you can't fix it now — an unfixed bug you've recorded is a An agent hits a failing test and immediately proposes a fix. Then another. Then another. Each one is plausible, none of them work, and forty minutes later the file has accumulated three speculative changes and the original bug is still there — now harder to see. What's missing is the step where you find out why it fails before deciding what to change. Read the actual error. Reproduce it in isolation. Form one hypothesis, test that hypothesis, and only then edit. And when three attempts have failed, stop — a fourth attempt is not a strategy, it's a slot machine. Escalate with what you learned. The obvious place for rules like these is your project instructions, and I started there. It doesn't scale. Everything in CLAUDE.md is in context permanently, competing with the actual task for attention. A twelve-line debugging protocol is exactly right when a test is failing and pure noise the other 95% of the time. Push enough process in there and the important rules get diluted by the situational ones. Skills load on trigger. The debugging discipline shows up when something breaks and stays out of the way otherwise. That's the whole difference, and it turns out to matter a lot. The second reason is portability. Process discipline isn't project-specific — the "second helper" problem is the same in every codebase I've worked in. Keeping it in one project's instructions means re-deriving it in the next project. Packaged as a plugin, it moves. I've extracted the general, project-agnostic half of what accumulated and published it as a Claude Code plugin marketplace: /plugin marketplace add mrveiss/Claude-Dev-Skills /plugin install claude-dev-skills@claude-dev-skills Eight skills: process canonical-coding commit review-lenses gap-audit web-audit ui-design memory-cleanup Apache-2.0, and two of them consolidate ideas from other skill authors — notably Jesse Vincent's Superpowers https://github.com/obra/superpowers suite, which is worth reading on its own. They came out of building AutoBot-AI https://github.com/mrveiss/AutoBot-AI . The project-specific ones — the issue-to-merge loop, full-stack debugging, the codebase audits — live in their own marketplace https://github.com/mrveiss/AutoBot-AI-Claude-dev-skills , because they hardcode that platform's branch names and paths and are no use anywhere else. This is the half that travels. Process discipline has a real cost. Every one of these rules makes the agent slower, and some of them make it slower in ways that feel pointless in the moment — proving a helper doesn't exist takes longer than writing the helper, almost every time. The trade only pays off over a codebase's lifetime, which means it's genuinely the wrong call for a prototype you'll throw away in a week. If you're spiking something, skip all of this and let the agent write. Where it pays is the second year, when you're the one maintaining what the agents built. If you try the set, I'd like to know where it's wrong: does process route the way you actually work, or does it fire when you don't want it? Is canonical-coding too strict for a codebase that legitimately carries parallel implementations? And what's missing?