All articles

The requirement was unclear. The code is done anyway.

Coding agents don't eliminate unclear requirements. They eliminate the friction that used to make ambiguity visible.

A ticket with one gapped line flows via a direct arrow into an immaculate code panel with a checkmark — the same gap hidden inside one terracotta line of finished codeA ticket with one gapped line flows via a direct arrow into an immaculate code panel with a checkmark — the same gap hidden inside one terracotta line of finished code

Coding agents don't eliminate unclear requirements. They eliminate the friction that used to make ambiguity visible.

"The case should be closed automatically." At first glance, that's a manageable requirement: check a few conditions, change the status, trigger follow-up processes. But when exactly is a case closed? As soon as all internal steps are done, or only once an external system has confirmed? What happens if that confirmation never arrives, arrives late, or contradicts a message that has already been processed? And may a closed case be reopened later?

A coding agent can find plausible answers to all of these questions and write them straight into the code. It can model states, define timeouts, handle error cases and add matching tests. A short while later, a coherent implementation exists – even though the decisive questions were never answered by the business.

Unclear requirements have always existed. What's new is that they barely hold up implementation anymore. In complex software systems, the ambiguity rarely sits in complicated sentences but in small words like "automatically", "valid", "cancelled" or "closed". Behind them hide states, deadlines, permissions and follow-up processes. Whoever interprets them differently doesn't just change an edge case — they change the behavior of the entire system.

Where ambiguity used to become visible

The classic path of a requirement was long. It travelled from the business department through business analysis and product owners into refinement and finally to development. This chain was slow, expensive and full of translation losses. Every handover could distort meaning – but it also offered the chance to discover a contradiction.

Somebody asked what "closed" actually means. Somebody else noticed that two rules don't fit together, or that no decision exists for an outage. That happened neither reliably nor particularly elegantly, but often early enough to still halt the implementation. The many handovers were therefore not just organizational ballast. They created friction, and at that friction, ambiguity could become visible.

Exactly this friction comes under pressure once a coding agent dramatically shortens the distance from a fuzzy sentence to a working artifact. The existing organization doesn't disappear, but a ticket becomes an instruction; a short while later, implementation, tests and documentation sit in the pull request. The code looks clean, the pipeline is green and the result looks finished. That easily creates the impression that the requirement must have been just as clear as its implementation.

But the unresolved question hasn't disappeared. It simply no longer gets an opportunity to interrupt the process. The translation loss now concentrates at the point where a ticket becomes an executable instruction.

A green build answers no business question

Of course an agent can ask clarifying questions. It gets dangerous where it finds enough context to build something consistent without asking. For automatic closing, it could for instance check whether all known sub-steps are done, change the status after a defined timeout, and then start the intended follow-up processes. Technically, that can be a clean solution.

What remains open is who decided that a missing sub-step may count as done after that timeout. Equally unresolved is how a late event is handled, whether the status may be reset, and whether follow-up processes that have already started must then be compensated. At the latest when two systems report different states, a plausible implementation is no longer enough. Then it takes a conscious decision about which behavior is intended and which system is authoritative.

In complex systems, it's therefore not enough for the result to be correct. It must also be traceable by which rule, with which data state and under whose responsibility it came about. An agent, however, can pour its assumptions into code and then write tests that confirm exactly those assumptions. The green pipeline then shows that code and tests fit each other. Whether both rest on the right business decision is something it cannot answer.

That's exactly why plausible assumptions are so hard to discover. Faulty code stands out; a wrong business assumption can be completely green. It may only show itself in production, when an event arrives in an unexpected order or a follow-up process can no longer be undone.

More text is not yet a specification

The obvious reaction is that developers simply need to write better prompts. That falls short, because no prompt trick decides under which conditions a case is closed in business terms.

What matters instead is keeping three different kinds of gaps apart. Sometimes context is merely missing that can be filled in from code, documentation or examples. Sometimes an existing rule is ambiguous and needs to be clarified. And sometimes the necessary decision has genuinely not been made yet. Then it takes someone who is authorized to make it and who answers for the consequences. More text only helps if it contains missing context or a decision that has already been made.

That is exactly where the lasting value of requirements engineering lies: making implicit knowledge visible, breaking terms apart, finding contradictions, and naming boundaries and exceptions. This work doesn't simply migrate from the product owner to the developer. It moves closer to the code – and with that, it must become clearer who may make a decision, what it rests on, and how its effect is verified.

Business, product and technical leadership therefore can't rely on a long process chain eventually discovering the open questions. Whoever copies a ticket unchanged into an agent hasn't meaningfully shortened the chain. They've merely automated its last misunderstanding.

Clarify first, then accelerate

A good specification doesn't prescribe every class and every method to the agent. It marks out the space in which technical freedom is allowed. For automatic closing, the relevant states and events must therefore be known first. Just as necessary is clarity about which system and which point in time are authoritative, how contradictory data is handled, which rule must never be violated, and who answers for the business decision. Only then can you also determine how to tell, in production, that the implementation actually holds.

The first output of a coding agent should therefore often not be code yet. More useful at first is an overview of the assumptions it would have to make for the implementation: What can be derived from the existing system? Where do rules contradict each other? Which gap requires a decision? And which wrong assumption would be expensive or hard to reverse? Used this way, the agent isn't just an executing tool but also an instrument for making ambiguity visible before it solidifies in the implementation.

This is not additional ceremony. For me, this is where the actual work of a software studio begins: connecting intent, architecture and implementation in a way that keeps speed from becoming an end in itself. Understand first, then decide, then build – and afterwards verify in the running system that the decision holds.

Coding agents thus don't just change how fast software comes into being. Above all, they change the moment at which a business decision must become visible. That doesn't take longer prompts, but people who can break a seemingly simple term down into states, rules, permissions, exceptions and evidence — without delegating the responsibility for the result to their wording.

In complex systems, that was always part of good engineering work. What's new is only the price of leaving it out: What nobody decides doesn't stay open. It lands in the code as an assumption. Someone still has to answer for it.