Your AI Coding Tool Has a Requirements Problem, Not a Code Problem
The AI coding debate on X keeps arguing about output quality. Communications of the ACM just pointed at the real problem: most teams never defined what they wanted clearly enough for a human developer, let alone an AI agent.
There is a recurring argument on X that goes roughly like this: someone posts a screenshot of spectacularly wrong AI-generated code, the replies split between "AI is still not ready" and "you just need a better prompt," and nothing gets resolved. Both sides are missing the point that a recent Communications of the ACM piece put plainly — the failure usually happens before the first prompt is written.
The argument is about requirements engineering. Specifically: that teams are expecting AI coding tools to compensate for the chronic under-specification that plagued software projects long before anyone heard of Copilot. That bet is not paying off.
The Actual Problem Is Upstream
Here is the uncomfortable truth most AI coding discourse ignores: ambiguous requirements don't become clear because an LLM is involved. They become more expensive.
When a developer receives a vague ticket, they ask clarifying questions. They use judgment accumulated over years of similar work. They make reasonable assumptions, flag risks, and sometimes push back. An AI coding agent does none of that by default. It executes against whatever context it receives. If the context is thin, it fills the gaps with statistically plausible code — which often looks correct and is structurally wrong.
This is not a model quality problem. GPT-4o, Claude 3.7, and Gemini 1.5 Pro are all good enough to write solid code when the problem is properly defined. The bottleneck is upstream. Teams that feed AI tools the same five-sentence tickets they used to feed junior developers are getting the same class of failures — just faster, at higher volume, and with less visibility because the code looks cleaner.
The ACM piece frames this correctly: requirements engineering discipline, applied to how you work with AI coding tools, is the determinant of whether those tools produce value or produce a technical debt backlog nobody wants to own.
What Requirements Engineering Actually Means Here
Requirements engineering has a formal academic definition. For this conversation, the relevant parts are practical: being explicit about what the system must do, what constraints apply, what success looks like, and where the boundaries are.
Most engineering teams do this adequately for major features. They do it poorly for the routine 80% of work — bug fixes, smaller feature additions, refactors, API integrations. That routine 80% is exactly where AI coding tools get used most heavily.
The gap looks like this:
- Vague constraint — "make the checkout flow faster"
- Explicit constraint — "reduce checkout page load time from 3.2s to under 1.5s on 3G connections, without changing the payment provider integration, measured via Lighthouse on the staging environment"
A developer might implicitly understand the second version is what's meant. An AI agent will optimize against the first — possibly by removing features, adding aggressive prefetching that breaks mobile sessions, or rewriting a component that was not supposed to be touched.
The problem compounds with AI because the tools are fast enough to produce a seemingly complete implementation before anyone notices the framing was wrong. A developer writing by hand runs into the ambiguity during construction. An AI agent produces a finished artifact that has to be reverse-engineered and argued about.
How This Maps to What We See in Practice
We have written before about technical debt in AI coding — specifically about pattern duplication and architectural drift that emerges when AI tools optimize locally without awareness of global structure. The root cause is almost always under-specification. The model is not told what the architecture is, what patterns are already in use, which modules should not be touched. It fills those gaps with whatever is most statistically coherent for the task.
Similarly, in our work on the discovery phase, we have seen how AI-assisted requirements gathering with tools like Fireflies.ai and Otter.ai changes what gets captured from stakeholder conversations — and therefore what downstream development actually works from. When the capture is better, the outputs improve. Not because the model changed. Because the context did.
The pattern is consistent: input quality drives output quality more than model capability does, past a certain competence floor that current models cleared at least two years ago.
What X Gets Wrong About This
The X discourse on AI coding tools tends to collapse into two failure modes.
Failure mode one: blaming the model. "Cursor hallucinated a database schema." "Copilot introduced a race condition." These are real observations. They are also incomplete diagnoses. The relevant question is what the model was given to work with. A schema hallucination often traces back to no schema being provided in context. A race condition often traces back to no concurrency constraints being specified.
Failure mode two: blaming the prompt. "You just need to write better prompts." This is directionally correct but misses the structural point. Prompt engineering is not a substitute for requirements engineering. A better prompt is a better-specified task. The discipline of getting there — stakeholder alignment, constraint documentation, acceptance criteria — is requirements engineering. Calling it "prompt craft" makes it sound like a personal skill when it is actually a team process.
The ACM framing is useful here because it connects the current AI tooling moment to decades of software engineering research on what actually causes projects to fail. The answer is consistently requirements — ambiguous, incomplete, or unstable requirements. AI coding tools do not change that finding. They expose it faster.
A Practical Approach: Requirements Before Prompts
The teams getting consistent value from AI coding tools are doing something that looks obvious in retrospect: they specify before they prompt.
That means treating the AI context window like a contract, not a conversation. Before any agent starts writing code, the relevant context should include:
Define the Scope Explicitly
What files, modules, or services are in scope? What is explicitly out of scope? This sounds basic. Most tickets do not include it. Without it, an AI agent may refactor adjacent code that was not meant to be touched, introducing changes nobody reviewed and nobody asked for.
State the Constraints
Performance targets, security requirements, compatibility constraints, third-party API limitations, data handling rules. These are the things a senior developer knows implicitly. The AI does not. Write them down.
Specify the Acceptance Criteria
What does done look like? Not "the feature works" — what does working mean, measurably? Which tests should pass? Which edge cases need to be handled? Which should return errors rather than silent failures?
Reference the Existing Architecture
If there are patterns in the codebase that should be followed — service layer conventions, error handling approaches, testing frameworks — say so explicitly and provide examples. AI tools that have access to relevant existing code produce work that fits the codebase. AI tools working from a blank context produce work that fits the training data, which is a different thing.
Make Assumptions Explicit
Every task has embedded assumptions. State them. "Assume the user is authenticated at this point." "Assume the upstream API is reliable — no retry logic needed." "Assume UTF-8 encoding throughout." When assumptions are unstated, the model makes them, and they may not match the actual system.
This is not a checklist to mechanically fill out for every ticket. It is a thinking process. For small, well-understood tasks, it takes two minutes. For complex features, it takes a structured session — the same session you would run before assigning the work to a developer.
The Security Angle Is Underrated
There is a secondary consequence of under-specified AI prompts that does not get enough attention: security surface expansion.
We have covered this in detail in our AI-augmented development security analysis. AI tools that are not given explicit security constraints will not infer them. They will produce code that works in the happy path and may be vulnerable in others. SQL injection risks, improper input validation, missing authentication checks on generated endpoints — these are not exotic edge cases. They are consistent findings when AI-generated code is audited without the corresponding security requirements having been specified upfront.
More code shipped per sprint means more attack surface per sprint, unless the requirements explicitly constrain how that code handles untrusted input, authentication state, and data exposure.
The fix is the same: requirements engineering. Security constraints belong in the specification, not as an afterthought in code review. When an AI agent is told "this endpoint handles unauthenticated requests and must validate all input against this schema before processing," it produces very different code than when it is told "build an endpoint that accepts product IDs."
The Organizational Gap
The reason this problem persists is organizational, not technical. Requirements engineering is work that happens before visible output is produced. In the current AI tooling hype cycle, the visible output — code — appears faster than ever. That creates pressure to compress or skip the upstream work because it feels like the bottleneck.
It is not the bottleneck. The rework cycle when AI-generated code misses the mark is the bottleneck. It is less visible because it shows up in code review cycles, in QA failures, in post-merge refactors, in the gradual accumulation of structural debt that makes future AI-assisted work slower, not faster.
The teams that feel like AI tools are not delivering value despite high adoption rates are often the teams that optimized for prompts-per-day without fixing the upstream specification problem. Tracking adoption does not tell you whether what ships is correct. As we have noted in our AI-human collaboration audit work, the metric that matters is the quality of what moves from first prompt to final commit — not the speed of generation in isolation.
Getting Engineering Leads to Care About This
If you are trying to make this argument internally, the framing that tends to land is cost of rework.
AI tools increase throughput. Throughput without quality gates increases the volume of code that needs to be fixed. If your code review process is already a bottleneck — and in most teams it is — increasing AI output without improving specification quality makes the bottleneck worse, not better. Senior engineering time that was previously spent writing code gets consumed by reviewing AI-generated code that misses the requirements because the requirements were never clearly stated.
The investment in requirements engineering is an investment in making the throughput increase actually useful. An hour spent specifying a task clearly before handing it to an AI coding agent typically saves two to four hours of rework. That ratio holds in human development too. AI just makes the stakes higher by compressing the time between specification and delivery of wrong output.
What Changes and What Doesn't
The ACM piece is doing something valuable: connecting current AI tooling practice to the body of knowledge that software engineering spent fifty years building. That knowledge did not become irrelevant because models got good at code completion. It became more relevant.
The fundamental insight of requirements engineering — that the cost of fixing a defect grows exponentially the later it is caught in the development cycle — applies directly to AI-assisted development. A misunderstood requirement that surfaces in production is expensive regardless of whether a human or an AI wrote the implementation. The difference is that AI can produce a plausible-looking wrong implementation faster and at larger scale.
The tools change. The underlying engineering problems don't.
What this means practically for teams in 2025 and beyond:
- Invest in structured context creation — treat prompts and agent context as first-class engineering artifacts, not throwaway text
- Apply requirements review gates before AI agents start generating, not just after they finish
- Audit AI output against stated requirements, not just against "does it seem right"
- Train product and engineering to specify together — AI coding tools make cross-functional alignment more valuable, not less
- Measure rework rates, not just generation rates — the signal you want is how often AI-generated output requires substantive revision before merge
The X discourse will keep arguing about model quality. That is a fine thing to track. But teams that are serious about getting value from AI coding tools should spend proportionally more time on the upstream problem that CACM just accurately named.
Requirements engineering was the discipline that separated software projects that shipped from software projects that spiraled. That has not changed. It just moves faster now.