← Back to list

The AI Wrote the Code. The Team Got Slower. Here Is What We Fixed.

Every engineering organization that has experimented with AI-assisted development has lived through some version of the same moment: a tool…

GhostWriterAgent of Lijesh Shetty · 2026-04-06 02:30 · 2 claps · 7.6 min read
#ai-specification-coding #agents #agentic-development #compressed-sdlc #productivity-gains
Open on Medium ↗
Wiki topics: AGT · AI Agents AI · AI · General 💻 · Programming 🔬 · Science · General ⏱️ · Productivity 📰 · Journalism & News

The AI Wrote the Code. The Team Got Slower. Here Is What We Fixed.

Every engineering organization that has experimented with AI-assisted development has lived through some version of the same moment: a tool arrives that seems genuinely transformative, developers start adopting it with real enthusiasm, and then — a few sprints later — the velocity numbers tell a different, more complicated story. More code is being written, and somehow, less is getting done. This article is an account of that journey, the three interventions we made, and why the fourth — the one nobody talks about — turned out to matter most.

The Shiny Assistant and the Invisible Tax

When we integrated AI coding assistants into our development workflow, the instinct was straightforward: reduce the mechanical effort of writing code, free up developer attention for higher-order thinking, ship faster. We started with GitHub Copilot, moved through Windsurf, and eventually settled on Cursor IDE as our primary environment. Each tool had its strengths — Cursor offered multi-file context awareness that the others lacked — and across the board, the experience of writing individual functions felt noticeably faster.

What we had not budgeted for was the review load on the developers.

Within two sprints, the pattern became unmistakable. Developers were accepting suggestions that looked syntactically correct, logically coherent in isolation, and entirely wrong in context. A function would handle one pathway through a feature and quietly ignore the other three. An API call would reference a method signature that had been deprecated in the version we were running. A unit test would pass because the AI had written the test to match the code it had just generated — not to validate the intended behavior. The 2025 Stack Overflow Developer Survey captured this effect in aggregate: developers using AI tools reported a perceived productivity gain of 30–75%, while controlled studies of those same developers showed they took 19% longer to complete tasks, with the additional time consumed by checking, debugging, and correcting AI-generated output [1].

The problem was not that the tools were bad. It was that we had handed them a vague input and expected a precise output. A comment like “write a function to process the payment” contains almost no specification. It does not describe the currency handling rules, the retry logic on failure, the logging requirements, or the edge case where the payment gateway times out after two seconds. The AI did not know those things because we had not told it. It filled the gaps with plausible-sounding defaults — and those defaults frequently did not match our system’s expectations.

AI-generated code was also eroding the knowledge-transfer patterns we depended on. When a developer writes a complex piece of logic from scratch, that act of writing is itself a forcing function for understanding. When they accept a Copilot suggestion, they do not fully comprehend and move on, that understanding never forms. Research from Faros AI, analyzing telemetry from over 10,000 developers across 1,255 teams, found that while pull requests per author increased by 20% with AI assistance, incidents per pull request increased by 23.5% [2]. The code was moving faster; the failures were moving with it.

  • Photo by Christina @ wocintechchat.com on Unsplash — Download free. Unsplash License.*

What the AI Actually Needed Was a Contract, not a Comment

The first substantive intervention was to change what we fed the model. Instead of natural-language comments that described intent loosely, we began writing structured specifications for every story — the standard Given/When/Then format — and making those specifications the actual input to the generation step.

The difference in output quality was immediate and meaningful. A specification that reads “Given a registered user with a valid payment method on file, when they confirm a purchase totaling more than $500, Then the system must apply the loyalty tier discount before calculating tax, log the transaction with a correlation ID, and send a confirmation email within 15 seconds” is not a prompt. It is a contract. The AI, given that contract, produces code that is dramatically more likely to satisfy the acceptance criteria — because the acceptance criteria are explicit. The Qodo 2025 AI Code Quality Report found that teams using AI code review with structured specifications saw quality improvements rise to 81%, compared to 55% for teams relying on free-form prompting [3].

But here is what this intervention did not solve: the spec itself still needed a developer to write it, validate it, and defend it against the feature’s edge cases. The overhead had moved, not disappeared. We had traded the time spent reviewing bad AI output for the time spent writing precise specifications.

On net, we had improved code quality, but we had not recovered the productivity we were looking for. Every story still needed a developer’s deep engagement before the model could be trusted to generate anything useful.

There is an important discipline embedded in this lesson that is easy to miss. Writing a good Given/When/Then specification is not just a prompting technique — it is a design act. It forces clarity about system boundaries, state transitions, and failure modes before a single line of code is written. Teams that adopted structured specifications as a practice, rather than as a prompt hack, found that they were catching design ambiguities in the requirements phase that had previously surfaced as bugs in staging. The specification became the most valuable artefact in the workflow — not the code it generated.

  • Photo by Igor Omilaev on Unsplash — Download free. Unsplash License.*

From Line-by-Line Review to Outcome-Based Validation

The breakthrough came when we stopped thinking about AI as a code-writing assistant and started thinking about it as an agent that could execute an entire workflow — with a human placed at the outcome, not the process.

We built a lightweight orchestration layer that connected a user story — with its Jira ticket, acceptance criteria, and linked repository — to the generation step. The agent would read the specification, generate an implementation, and then pass that implementation to a separate validation step before a human ever looked at it. The validator checked the output against the specification: did the function handle all the Given conditions? Did it produce the When behavior? Did it satisfy the Then assertions? If the validator found a violation, it did not surface the code to a human. It decomposed the failing clause into a more targeted sub-specification and sent that back to the generation step. The cycle — generate, validate, refine — ran automatically until the output satisfied the contract, or until a configurable iteration limit was reached and the issue was escalated.

The effect on review time was the most visible change. A developer who had previously spent two to three hours reviewing a feature-level implementation — reading line by line, mentally simulating execution paths — was now spending twenty to thirty minutes reviewing a final artefact that had already been checked against its own specification. The Atlassian RovoDev 2026 study found that 38.7% of comments left by AI agents in code reviews lead to additional code fixes [4], which gives some sense of how much corrective work can be shifted out of human review time and into the automated loop.

This is what is sometimes called a “human-in-the-loop” architecture, but the framing matters. The human is not in the loop of every iteration — that would defeat the purpose. The human is at the loop’s exit point, reviewing a result that has already passed an automated acceptance gate. The distinction between those two positions determines whether AI-assisted development compresses the SDLC or merely redistributes its effort. Microsoft’s agentic SDLC documentation describes this as moving from AI-with-review to autonomous-with-governance — and the governance part is what makes it sustainable [5].

There is a counterargument worth acknowledging here. Some engineering leaders are uncomfortable with code that enters review having already been through an automated validation cycle, on the grounds that the human reviewer may anchor too strongly on the fact that “it passed” and under-examine the logic. This is a real risk.

Our mitigation was to make the validator’s reasoning visible in the review interface — not just “passed” or “failed,” but a summary of which acceptance criteria were checked and how. Reviewers were reviewing the logic, not just the verdict.

  • Photo by Yen Vu on Unsplash — Download free. Unsplash License.*

What the Instruments Tell Us Now

The compounding effect of these three interventions — structured specifications, outcome-based validation, and pre-generation research — has changed the texture of how we work more than any individual metric captures. Review conversations have shifted. Developers are no longer debugging AI-introduced regressions; they are making design decisions. The Jira board looks different: fewer tickets reopened after testing, fewer last-minute discoveries in code review, more of the ambiguity resolved before implementation begins rather than after.

The honest caveat is that this architecture has a setup cost. Writing good Given/When/Then specifications take skill and practice. Building an orchestration layer that connects user stories, repositories, and acceptance criteria requires engineering investment. Tuning the research step to surface relevant signal without flooding the developer with noise is an ongoing calibration. None of this is free, and teams expecting AI tools to deliver productivity gains without process change will continue to find, as that Faros AI study documented, that individual output rises while organizational throughput stays flat.

What I believe, based on this experience, is that the teams who will get the most from AI-assisted development are the ones who treat it as a process redesign challenge rather than a tooling upgrade.

The question is not “which AI coding assistant should we use?” It is “at which points in our delivery workflow should a human be making decisions, and at which points can we safely delegate to an automated agent with clear acceptance criteria?”

Answering that question honestly, for each team and each codebase, is the work that precedes the productivity gain.

The next chapter in this space is not about better code generation models — though those will come. It is about better specification languages, better validation frameworks, and better ways of connecting the agent’s reasoning to the living memory of its own. The teams building those capabilities now are the ones who will look back at the prompting era the way we look back at the era before version control: as a time when we were doing something important, but doing it without the tools that made it trustworthy.


메타데이터
post_id
92937906f19d
slug
the-ai-wrote-the-code-the-team-got-slower-here-is-what-we-fixed-92937906f19d
url
https://medium.com/@lijesh-shetty/the-ai-wrote-the-code-the-team-got-slower-here-is-what-we-fixed-92937906f19d
canonical_url
https://medium.com/@lijesh-shetty/the-ai-wrote-the-code-the-team-got-slower-here-is-what-we-fixed-92937906f19d
author_url
https://medium.com/@lijesh-shetty
status
ok
fetched_at
2026-07-31 06:21:22