2026-09-10
The Method · Part 1 of 4
Requirements Are Engineering: Directing AI Without Losing the Fundamentals
The skill that separates useful AI work from confident guesswork is specifying what must be true. That is requirements engineering, not prompting magic.
The Method · Part 1 of 4 · ~5 min read · next: Part 2 — Architecture Before Code
The useful frame for "prompting" is not conversation craft. It is requirements engineering. When you ask a model to produce work, what you are really doing is specifying what must be true, what must not happen, and how you will know the result is correct. Done well, that is a professional skill. Done casually, it produces confident, plausible output that fails where it matters.
Why Casual Requests Fail
A model does not refuse an under-specified request; it satisfies it as written. That is what makes the failure mode so consistent: the output is not wrong, it is unconstrained. Two directions, and most bad AI work is one of them:
- Unconstrained — no rules were stated, so the draft invents its own conventions, and you discover them at review.
- Ungrounded — no context was given, so the draft is perfectly formatted for a system that does not exist.
Both are expensive for the same reason: ambiguity is not paid when you write the request, it is paid later — at review time, and at the moment of integration, which is the most expensive place to discover a misunderstanding. Generate ten drafts from a vague request and you get ten plausible answers, none of which you can accept without reading all of them.
What a Requirement Must Carry
Every useful request carries two kinds of constraint:
- Symbolic constraints — hard rules the output must obey. Never commit secrets. This function must not raise on empty input. Follow the existing module boundaries.
- Context — the facts a drafter needs. The service is in TypeScript; migrations live under
migrations/; errors are returned, not thrown.
And it carries a third thing teams most often skip: the check that will accept the work. A requirement you cannot test is a preference. Writing the acceptance check at the same time as the requirement is what turns "make it better" into something a person or a machine can actually satisfy — and that check is the gate the work will have to pass.
The difference is easiest to see side by side:
| Weak | Precise |
|---|---|
| "Write a backup script" | "A backup script that: (1) checks disk space first, (2) verifies the backup before deleting anything, (3) exits non-zero and alerts on any failure, (4) is safe to re-run" |
| "Improve this service" | "Refactor this service so calls to the customer API go through the existing client module, keep the public interface unchanged, and all existing tests still pass" |
| "Add validation" | "Reject payloads that are missing required fields or exceed 10 KB, returning the documented error shape" |
The pattern is identical each time: intent, constraints, and a testable definition of done. The precise version is longer to write and far cheaper to own.
What Changes When the Drafter Is a Machine
Three things shift, and each is worth adjusting for:
The spec is now written for a reader that will not ask. A colleague receiving an ambiguous request asks a question; a model proceeds. If the ambiguity matters, it has to be resolved in the request — or the model has to be asked to state its assumptions and questions before it writes anything. That single move ("list what you need to know and what you are assuming, then wait") prevents a large share of rework.
A precise spec pays twice. It directs the first attempt, and it defines the check that accepts the result. On a human team, requirements and testing are often separate people's work; with a fast drafter, they collapse into one artifact, which is a gain if you write it deliberately.
Speed makes the discipline easier to skip — and more valuable. A draft arrives in seconds, so the pressure to skip the specification is real. But the review capacity behind that draft has not changed. Requirements are how you spend a minute to avoid spending an hour of review on a misunderstanding.
Codify It Where It Lasts
A requirements discipline only pays off if it is not rebuilt in every session. Teams that do this well codify the durable parts in the repository:
- The rules that never change — the non-negotiable constraints on every change.
- The context — architecture, conventions, and state any contributor needs.
- The automation — the gates that verify the result regardless of who or what produced it.
Any assistant can read those; none of them owns them. A constraint that lives in a chat session is a constraint you will re-explain tomorrow, to the same model, in a slightly different way.
What It Buys You
- Fewer rework loops. The first draft is closer, because the request carried the constraints the reviewer would otherwise discover.
- Cheaper review. A reviewer checks the output against stated criteria instead of reconstructing the intent.
- Reusable knowledge. Constraints accumulated in the repository apply to every future change, by any contributor, human or AI.
- Defensible decisions. When the requirement is written down, "why is it like this?" has an answer that does not depend on who is still on the team.
The Orchestrator's Takeaway
Write the requirement — intent, constraints, and the check that accepts it — before asking for the work, and ask the drafter to surface its assumptions before it starts. Requirements reduce the search space; they do not remove the need for verification, and they are the cheapest place to prevent a whole class of rework.
Next in the Series
Requirements are the communication discipline. Part 2 designs the structure the work lands inside — architecture before code.
For the full method, see The DevOps Engineer's Guide to Effective AI Usage.