Somebody on your team has a very good prompt. It took a fortnight of iteration, it produces the right shape of migration every time, and it lives in a text file next to their downloads folder.
That prompt is doing genuine engineering work. It encodes conventions, forbidden patterns, the shape of the output you want. It is a specification. It is just stored somewhere no specification should ever be stored.
The case for turning anything you can specify into a specification rather than a request leaves one question open, and it is the one that decides whether any of it holds next month: where does the specification live? This is about the first place people try to put one, and why it leaks.
What a prompt actually is
Split any working prompt in two and the halves behave very differently.
# the durable half: true on Monday, true in March, true for everyone
Use constructor injection. No field injection.
Never widen a public method's visibility to make a test pass.
Every new endpoint gets a contract test before the implementation.
# the volatile half: true for this task only
Migrate OrderService to the new pricing interface. Keep the existing
rounding behaviour, there is a test for it.
The volatile half belongs in a prompt. That is exactly what a prompt is for: the part that genuinely differs each time you sit down.
The durable half does not, and putting it there is what causes the trouble. It gets retyped from memory, so it drifts. It is invisible, so a reviewer cannot tell whether it was applied. It is unversioned, so nobody can see when it changed or why. And it is personal, so the colleague sitting next to you is solving the same problem with a slightly different set of rules.
The tell
You do not need a framework to spot this. Ask one question about any instruction you are about to type:
Would I type this again tomorrow, on a different task?
Yes means it is a rule and it belongs somewhere a machine can read. No means it is context for today and the prompt is the right home.
The mistake is not writing prompts. It is that the two halves get typed into the same box, so the durable half inherits the lifespan of the volatile half, which is one conversation.
Moving one rule out
Take the rule that annoys you most because you keep repeating it. Write it down somewhere the assistant reads by default, and put the reason next to it.
## Dependency injection
Constructor injection only. No field injection, including in tests.
Why: field injection hides a missing dependency until runtime, and the
failure surfaces in a component that did nothing wrong. A constructor
that cannot be satisfied fails at startup, next to the cause.
The reason is not decoration. A rule without one gets deleted by the next person who finds it inconvenient, and an assistant given a rule without a reason applies it literally in situations where the reason clearly does not hold.
Now the same instruction is versioned, reviewable, and identical for everyone. When it stops being right, someone changes it in a pull request rather than quietly typing something different.
What does not move
Plenty of what you type is genuinely single-use, and dragging it into a shared file makes that file worse. A context file crammed with task-specific detail is noise, and noise gets skimmed by people and diluted for the model.
| stays in the prompt | moves out |
|---|---|
| which file, which function, this week’s constraint | conventions that hold across tasks |
| what you are trying to achieve right now | what is forbidden and why |
| a paste of the failing output | the shape of output you always want |
| your judgment about this specific tradeoff | how to resolve a class of tradeoff |
The line is durability, not importance. An urgent one-off instruction is still a one-off.
Where this part stops
Moving the durable half into a shared file is one step up the list. It is still a document that a model reads and a person can ignore, which is why the next parts keep climbing: a rule you can execute beats a rule you can read, and a rule that refuses beats both.
The point is not to reach the top of the list for everything. It is to stop leaving rules at the bottom of it by default.
If your team’s real conventions live in half a dozen private prompt files, that’s the work I do.