Ask an agent to “add a discount code field to checkout” and you will get one. It will work. It may also apply the discount after tax, stack with an existing promotion, and survive a refund — because none of those were mentioned, and an unmentioned rule is not a rule the agent can see.
Two kinds of sentence do different jobs
Almost every requirement people write is an instruction: do this thing. Almost every requirement people actually mean also contains a constraint: and this other thing must still be true afterwards.
Humans fill in constraints from context. Someone who has worked on the checkout for a year knows the discount applies pre-tax, because they remember the argument about it. The agent has no memory of that argument, and the code may not express it clearly enough to infer.
- An instruction is satisfied once. “Add the field.”
- A constraint has to hold forever. “Discounts always apply before tax.”
- A non-goal stops a reasonable generalisation. “Do not build a general promotions engine.”
Write only the first and you are relying on the agent to reconstruct the other two. Sometimes it does. The times it does not are the ones that cost a day.
The same request, written twice
Nothing about the second version is longer-winded for its own sake — every added line closes a gap that would otherwise be filled by a guess.
Instruction only
- Add a discount code field to checkout.
Constraint, non-goal, and evidence
- Change: accept a discount code at checkout and show the reduced total before payment.
- Must stay true: discounts apply before tax; one code per order; a refund returns the amount actually charged, not the pre-discount total.
- Do not: build code generation, expiry rules, or per-user limits. One hard-coded test code is enough for now.
- Done when: an order with a code and an order without one both produce a correct receipt and a correct refund.
The second version is not a specification. It is four lines, and three of them are about what must not move. That ratio is the whole technique.
You should not be inventing constraints per task
Here is the part that decides whether this technique is cheap or exhausting. If every request means sitting down to work out what must stay true, you are not writing requirements — you are making product decisions under time pressure, one ticket at a time, which is the worst possible moment to make them.
The constraints already exist somewhere. The invariants and non-goals come from the plan's dependency list and MVP boundary. What this change specifically touches comes from a dependency check — the full version of that review, with the touchpoint inventory and the stop conditions, is its own note and worth doing before anything large.
So the writing is a lookup, not an invention. And when the lookup fails — when you genuinely cannot say what must stay true — that is information. It means the decision was never made, and an agent is about to make it for you by accident.
If you are discovering a constraint while writing the task, you are not documenting a decision. You are making one, late.
Name the finish line, or the work expands
“Works correctly” is not checkable. Neither is “handles edge cases.” Both read like standards and function as blanks the agent gets to fill in.
What works is naming the specific thing you will look at afterwards: a state that must exist, a number that must match, a flow that must complete end to end. It has to be something you could be shown and could disagree with.
With an agent this matters more than it does with a person, and for an unobvious reason: an agent has no sense of proportion about effort. Left without a finish line it keeps going — more abstraction, more configuration, more defensive branches for cases that will never occur — and every one of those additions looks like diligence in the diff. A named stop point ends the task at the right size, the same way a build plan carries a stop rule so polish cannot postpone the next decision.
What to keep, and what to throw away
Requests written this way produce something reusable, which is the part most people miss. Sort the lines when the task is done.
| Line | Afterwards |
|---|---|
| The change | Throw away — it happened |
| What must stay true | Keep, in the repo context file |
| What not to do | Keep if it is durable, drop if it was about timing |
| How you will know | Keep as a test if it is worth re-checking |
Do that a few times and the durable half accumulates into the product context an agent reads at the start of every session — built out of decisions you were making anyway rather than as a separate documentation project.
The instruction is the errand. The constraint is the product. Only one of them is worth writing down twice.
Reader response
Was this field note useful?
Decisions before code
Want the constraints written down before the build?
Apply for a Clarity SprintField notes by email
Thanks, you're on the list. ✓
Email signup did not go through. Please try again.
A short note when there is something worth sharing. No spam.
