A pattern shows up on almost every team I’ve worked with, regardless of how disciplined the process otherwise is: Dev, QA, and Product each walk away from the same requirement holding a slightly different picture of what’s being built. It rarely surfaces at the moment the requirement is written. It surfaces later, and by then it’s expensive — a bug report that turns out to be a misunderstanding, a scope argument in the middle of a sprint, a story that stalls because QA and Dev quietly disagreed about what “done” meant and neither noticed until the story was in review.

None of that is a carelessness problem. Everyone involved read the requirement, understood it, and acted on that understanding in good faith. The problem is upstream of any individual’s diligence: prose is not a precise medium, and a requirement written in prose leaves room for each reader to fill in the gaps with their own assumptions. Three people can read one paragraph, agree they understood it, and still be holding three different mental models — because the paragraph never forced any of them to state the model out loud.

Ambiguity is the default, not the exception

The instinct is to treat ambiguity as a failure of writing — as if a clearer paragraph would have prevented the divergence. Sometimes that’s true. But a lot of ambiguity survives even careful writing, because prose doesn’t have a fixed slot for the things that actually cause disagreement: the preconditions a scenario assumes, the exact action being taken, and the exact outcome that counts as correct. A sentence can gesture at all three without pinning any of them down, and a careful writer and a careless writer produce sentences that look almost identical on the page.

That’s the actual claim worth sitting with: ambiguity in a requirement isn’t the exception that slips through when someone’s rushed. It’s the default state of a paragraph, because nothing about paragraph form obligates the writer to be explicit about preconditions, action, and outcome as three separate, checkable things. Removing ambiguity requires a structure that makes leaving something implicit visibly incomplete — not just a writer who tries harder.

The tool isn’t the idea

The obvious reflex, once you frame it that way, is to reach for Gherkin — Given/When/Then, .feature files, Cucumber, Gauge, whatever a given team has already heard of. And that reflex usually derails the actual conversation, because it swaps a question about whether structure helps for an argument about which framework’s syntax is best, and those are very different conversations with very different stakes.

The idea worth separating out is narrower than any specific framework: a shared, structured way of expressing a requirement, precise enough that Dev, QA, and Product read it and independently arrive at the same understanding — for a front-end interaction and a back-end contract alike. Given/When/Then happens to be one well-worn implementation of that idea. It is not the only one, and a team that finds it clunky for how they actually write stories is free to define something narrower and purpose-built. What matters is the property the structure enforces, not the specific keywords it uses to enforce it.

What the structure actually buys

The value isn’t that Given/When/Then (or any equivalent) makes requirements nicer to read. It’s that it makes three specific things impossible to leave implicit:

  • Precondition — what state the world is in before anything happens. A prose requirement can skip this entirely and still read fine; a structured one has a slot for it that sits empty and visible if nobody fills it in.
  • Action — the one thing actually being tested or built, isolated from everything surrounding it. Prose habitually bundles several actions into one sentence; a structured format forces them apart.
  • Outcome — the specific, checkable thing that counts as correct. Not “it should work,” but the exact observable result that separates pass from fail.

None of that is Gherkin-specific. It’s what any sufficiently rigorous requirements notation has to capture, because those three things are exactly where Dev, QA, and Product’s mental models diverge in practice. Dev tends to fill in the precondition from what the code currently does. QA tends to fill in the outcome from what similar features have done before. Product tends to fill in the action from what the feature is supposed to accomplish, independent of implementation. Three reasonable defaults, three different requirements, one paragraph.

It doesn’t fix a bad requirement — it exposes one faster

Structure isn’t a substitute for a well-thought-out requirement. A story that’s genuinely underspecified will still be underspecified once it’s forced into Given/When/Then; the format just makes the gap visible immediately, in the empty slot, instead of three weeks later in a bug triage meeting. That’s a real cost worth naming: writing this way takes longer up front, and a team that adopts it without also agreeing to actually fill in every slot will just end up with more elaborately formatted ambiguity.

The trade only pays off if the added discipline happens before the story is estimated and picked up — not as a QA-only artifact bolted on after Dev has already started, and not as documentation nobody but the writer reads. If Product is the only one who ever produces the structured version and Dev never reads it before writing code, the format has changed nothing about where the three mental models diverge.

The test that actually matters

Whatever notation a team settles on — an existing BDD framework, a lighter internal convention, three fixed fields in a ticket template — the test for whether it’s working isn’t “does everyone use the format.” It’s whether Dev, QA, and Product can each read the same requirement on their own, before any conversation happens, and independently write down the same precondition, the same action, and the same outcome. If two of the three land in the same place and the third lands somewhere else, the requirement was ambiguous and the format caught it before a single line of code shipped. That’s the entire point — not tidier tickets, but disagreement surfacing on day one instead of in a bug report three sprints later.

The harder question a team has to answer honestly is whether the disagreements it’s currently having feel like a communication problem at all. Most of them don’t. They feel like a scope argument, or a QA nitpick, or a Dev misunderstanding — because by the time anyone notices, the original ambiguity is long gone, replaced by whatever each side decided to believe. A shared structured format doesn’t resolve that argument. It just moves it to before the work starts, where it’s an order of magnitude cheaper to have.

I ended up taking this argument far enough to build the tool it implies — a follow-up post covers lexicon, a markdown-native requirements format that compiles into Gherkin, Gauge, or a structured representation built for LLM consumption.