Stop writing prompts. Start writing contracts.
Prompt craft is a personal skill with no owner, no version, no review and no way to check whether it worked. A contract states what must be true when the work is done, which is the only artefact that survives the run that produced it.
There is a person on your team who gets noticeably better results out of agents than everyone else. They have a way of framing a task, a set of phrasings they reuse, an instinct for how much context to include. People ask them for help. Some of what they know has been pasted into a shared document.
That skill is real. It is also the least durable asset your organisation has, because none of it survives the person, the model version, or the week. Change the model and the phrasings that worked stop working. They leave, and the document is a list of incantations nobody can evaluate.
My position: prompt craft optimises the wrong end of the pipeline. It aims to make one generation come out well, and generation was never your constraint. What you need is an artefact that makes any generation’s result checkable, which is a contract: a stated set of conditions that must hold when the work is done.
The difference is not phrasing, it is direction
A prompt describes what to do. A contract describes what must be true afterwards.
That sounds like a small distinction and it changes everything downstream. A description of what to do can only be evaluated by comparing it to the output, which requires a human who understands both. A statement of what must be true afterwards can be evaluated against the result directly, by a person in eight seconds or by a check in eight milliseconds.
So the same effort, spent on the other side of the run, buys you something the prompt cannot: a verdict that does not depend on the person who wrote it being in the room.
It also buys durability. Prompts break when the model changes, because they are tuned to the behaviour of a particular system. Contracts do not, because they are statements about your domain. “The rate limit applies per client, not globally” is true regardless of who or what implements it, and it will still be true in two model generations.
A prompt
- Describes the work to be done
- Owned by whoever typed it
- No version, no review, no diff
- Evaluated by looking at the output
- Breaks when the model changes
- Improves generation, which is not your constraint
A contract
- States what must be true when work is done
- Attached to the work item, reviewed like code
- Versioned, argued about, diffable
- Evaluated against the result
- Survives model changes, because it is about your domain
- Improves verification, which is
What goes in one
A contract for a change has four parts, and the fourth is the one everyone forgets.
Preconditions: what the change may assume. Which services are available, what shape the input takes, what is already true of the data.
Postconditions: what must be observable afterwards. Not “add rate limiting” but the specific, checkable statements. Limits apply per API client. Exceeding a limit returns 429 with Retry-After. Internal service tokens are exempt. The limit is configurable without a deploy.
Invariants: what must remain true throughout. Existing clients under the limit see no behaviour change. No additional round trip on the hot path.
And the negative space: what must not change. This is the part that is almost never written and the part that catches the most expensive mistakes. Do not modify the auth middleware. Do not add a new dependency. Do not touch the export endpoint even though it shares the handler.
The negative space matters more with agents than it ever did with people, because a person infers the boundary of a task from context and social knowledge, and an agent infers it from what you said. Silent scope drift is not the agent misbehaving. It is the contract failing to state a boundary that a human colleague would have assumed.
Given a client that has made 100 requests this minute
When it calls GET /search
Then the response is 429
And the response carries a Retry-After header
Must not change:
- behaviour for clients under the limit
- the export endpoint, which shares this handler
- the auth middleware
May assume:
client identity is already resolved upstream
Why this is the higher-leverage investment
Controlled studies have found that human-refined specifications cut errors by up to 50 percent. That is a large effect for an intervention that involves no tooling and no model change, and it points at where the remaining human contribution actually sits.
The mechanism is not mysterious. Most agentic rework is not a case of the agent being incapable. It is the agent correctly building the wrong thing, because the request was underspecified and it resolved the ambiguity differently than you would have. Every ambiguity you remove before the run is a rework cycle you do not pay for after it.
And the rework cycle is expensive in exactly the place you cannot afford it. A second pass goes back through review, and review is the constrained stage. So a contract that prevents one rework cycle is worth considerably more than its own writing time, which is not true of a prompt that makes the first draft slightly nicer.
There is a second-order benefit that matters more over a year. Prompts accumulate as folklore. Contracts accumulate as a description of how your system is meant to behave, written incrementally by the people closest to each decision, in a form that can be checked. That is a knowledge base that builds itself out of work you were already doing.
Where this breaks down
Full specification is genuinely expensive, and often not worth it. Writing four clauses of negative space for a copy change is absurd. Contracts earn their cost on work with real blast radius, ambiguity or cross-team impact, and applying them uniformly would be a tax on the majority of changes that are small and obvious. I have not given you a good rule for where the line sits, because I do not have one that survives contact with a real backlog.
Over-specification destroys the thing you bought the agent for. If you specify tightly enough that there is exactly one implementation, you have written the code in prose, more slowly and with less precision. The strongest version of the prompt-craft position is that a good prompt leaves room for the system to find a better answer than you would have, and that room is real value. A contract that constrains the how rather than the what forfeits it.
Contracts rot, and they rot silently. A postcondition written eighteen months ago describes a system that has moved. Unlike a test, a written criterion does not fail when it becomes false. The only versions of this that hold up over time are the ones where the contract is executable, and getting there is a much larger commitment than writing better tickets.
Not everything is specifiable in advance. Exploratory work, performance investigation, anything where the goal is to find out what is true. Demanding postconditions there produces either fake ones or paralysis. I am describing a technique for well-understood change, and a lot of valuable engineering is not that.
And models are getting better at inferring intent. If a system reliably works out that internal tokens should be exempt because it can see the nightly sync and reason about it, the contract’s value falls. That is a plausible trajectory. My counter is that inference makes the answer more likely to be right and no more checkable, and checkability was the point. But if you believe inference will be near-perfect, most of this argument goes away.
The takeaway
Prompt craft is a real skill attached to an artefact with no owner, no version and no way to tell whether it worked. It improves the stage of your pipeline that stopped being scarce.
A contract states what must be true when the work is finished, including what must not change. It can be reviewed, argued about, checked against the result, and it stays true when the model underneath you is replaced. The same hour of thinking, spent on the other side of the run.
If you take one thing into next week: take the next non-trivial ticket you were about to hand to an agent and write the “must not change” list first. Three lines. It is the cheapest part of a contract and it catches the most expensive class of mistake.