30% of Your AI Coding Time Is Wasted on Fixing the AI
Last month I hit a new personal record for time wasted on AI-generated code. The task was straightforward - refactor our UserProfileCard.tsx component to use our new design system tokens. It was a mechanical change, replacing old hard-coded hex values and font sizes with new CSS variables. The perfect job for a coding agent. I fed it the component, the new token documentation, and told it to have at it.
Ten minutes later, it came back with a pull request that touched a dozen files. It had correctly propagated the changes through several parent components and storybook files. It looked… perfect. A little too perfect, honestly. But the code was clean, the logic was simple replacement, and I was busy. So I did what we all do: I skimmed it, saw it looked plausible, and merged it.
Two days later, our lead designer sends me a Slack message with a screenshot. “Hey, the hover state on the secondary buttons in the user profile is broken. It’s not changing color.” I look at the screenshot. He’s right. I dive back into the code. After an hour of digging, I find the problem. In one of the 12 files it changed, in a deeply nested CSS module, the agent had hallucinated a token name. It wrote --color-button-secondary-hover when the correct token was --color-button-secondary-active. A one-word difference. An easy mistake for a language model to make, and an absolute nightmare for a human to find. The two hours I spent debugging and fixing its “ten-minute” job was a stark reminder of a new, infuriating tax on our productivity.
The Blind Rework Tax
Let that sink in. A significant chunk of time spent “accelerating development” with AI is actually just cleaning up after it. It’s a hidden cost, a productivity tax we’re all paying. We’re not building new features; we’re just getting paid to be the world’s most expensive linters.
And I’m definitely not alone here. I saw a post on Reddit’s r/aipromptprogramming that just laid it bare. The title was “Blind coding.” and the top comment, with over 70 replies, stated that “30% of AI centric coding involves fixing the minute details of what the AI produced.” A third of our time. Gone. Just vanished into the ether of fixing plausible but wrong code.
It’s a low-grade fever burning through the industry. Over on r/cursor, a user laments, “I spend more time telling Cursor to fix its own mistakes than I do writing code myself,” a sentiment that kicked off a thread of over 60 comments in agreement. It’s the same story on Hacker News, where a developer named kemotep just bluntly states that for many tasks, “Debugging what they output makes them a significant speed down.” A speed down. We are adopting tools that, without the right process, literally make us slower.
Why This Is Our New Normal
The root of this problem isn’t that the AIs are “dumb” or that the models aren’t powerful enough. It’s far more fundamental. The problem isn’t that the AI is a bad coder. It’s that the AI is a pathologically brilliant liar.
An AI coding agent has one goal: complete the text. Its entire existence is about generating a sequence of tokens that looks like a statistically probable answer to your request. It has no internal model of “working software.” It has no understanding of “correctness.” It doesn’t know what a compiler is, what a test runner does, or what a broken hover state feels like to a user. Its only metric for success is generating something that looks like code a human might write in a similar situation.
It’s a machine built to create plausible-looking artifacts. And it is spectacularly good at it. The problem is, “plausible” and “correct” are two very different things. My agent didn’t fail because it was bad at refactoring; it failed because its job was to produce text, not to produce a working button. And until we change the definition of “done,” we will be stuck in this loop forever.
Why Prompting Won’t Fix It
I know what the prompt engineering gurus are screaming right now. “Julian, you just needed a better prompt! You should have told it, ‘Refactor the component, AND you MUST verify that all interactive states work as defined in the design spec.’”
Let’s be honest with ourselves. This is a trap. We are trying to solve a systemic, architectural problem with a conversational patch. It’s like trying to enforce a building’s fire code by shouting “don’t forget the sprinklers!” at the construction workers from the street. You might get a sprinkler in that one room, that one time, but you haven’t fixed the process. You haven’t made the system itself more reliable.
Trying to guarantee correctness by asking an agent to check its own work is asking the fox to audit the henhouse. The agent can generate tests, sure. But it can just as easily generate tests that pass against its own broken code. It’s just more text generation. You’re fighting gravity. You can win for a moment with a heroic, perfectly crafted prompt, but the agent’s innate tendency to just produce plausible output - not verified output - will always win in the end. A prompt is not an enforceable contract.
Tired: “Prompting the AI to write tests for its own code.” Wired: “Requiring the AI to pass tests enforced by an external system.”
The Fix
The solution to the blind rework tax is embarrassingly simple, and frankly, a little boring. It’s not a better model. It’s not a secret prompting framework. It’s not a fancier IDE.
The fix is non-negotiable, external verification.
That’s it. You need a system - an unblinking, unemotional referee that sits outside the conversational loop with the agent - that defines what “done” actually means. A system that doesn’t care how elegant the code looks. It cares about one thing and one thing only: is there objective, verifiable proof that the software does what it is supposed to do? The agent’s job isn’t finished when it types the last line of code. Its job is finished when the external system says it is.
What This Looks Like in Practice
This is the entire philosophy we’re building on at Ceetrix. We are building the external referee that makes any agent a reliable engineering partner instead of a plausible-code generator.
Let’s replay my disastrous button refactor from last month, but this time inside Ceetrix. The task to refactor UserProfileCard.tsx would be created from a design document using our Spec Chain Enforcement. This creates an unbreakable link between the code to be written and the requirements it must satisfy.
That task would then be analyzed. Because it involves a UI component, Ceetrix would automatically create a mandatory ui-component Test Task Type. This isn’t a suggestion; it is a requirement for completion. The required_tests for this component, which include checks for default, hover, and active states, are now part of the agent’s job description.
The agent would go off and generate its “perfect” code with the hallucinated CSS variable. It would then submit its work. But it wouldn’t come to me. It would first have to pass through our Gate System (G0-G12). Gate G10 would automatically run the required UI component tests. The hover state test would fail. Hard.
The gate would slam shut. The work would be rejected. The agent (or me, if I were doing it manually) would be blocked from marking the task as complete. Instead of a Slack message from my designer two days later, I would get an instant, automated notification that the agent’s submission failed verification.
To get past the gate, the agent would have to fix its own mistake and resubmit. This time, the tests would pass. It would then have to provide Task Completion Evidence, including the files_changed and a rationale for why the work is now correct. Only then would the gate open. Only then is the work actually “done.” The two-hour, human-powered debugging scavenger hunt is replaced by a five-minute, automated rejection loop that the agent has to solve itself. It stops being my problem.
Have your say: What’s the most subtle, time-wasting bug an AI has ever slipped past you? I want to hear the war stories of plausible but broken code. And when you’re ready to stop paying the rework tax, try Ceetrix.
