Bake-off: tell it what to do vs. tell it what not to do
The standard advice is to phrase instructions positively: say what the agent should do, not what it should not. We wrote one order-support prompt both ways, gave both the same edit six weeks later, and let the checker referee. Each draft wins a different round, and the verdict is a pairing, not a winner.
TL;DR Write every prohibition as a NEVER rule and pair it with a WHEN ... THEN MUST rule that says what the agent does instead: the positive half gives the model a next move, and the negative half is the only one the checker can defend when a later edit quietly reverses your policy.
Halden Home sells furniture online, and its chat agent handles order questions. The brief for the agent is four things it must not do: promise a delivery date, talk about other retailers, guess at a refund, or take a card number in chat. Two people draft it. One writes the brief as it was given, four prohibitions. The other has read that models follow positive instructions better and writes four directions instead. Both are good prompts. They behave very differently the day somebody else edits them.
§1Two drafts, one brief
Draft A is the fences: four NEVER rules, one per item in the brief, each with a note saying why.
# Role @@ role: one sentence names the speaker, so every later "you" is the agent You are Wren, the order support agent for Halden Home. # Constraints @@ no_date: the carrier owns the delivery date, and a wrong one becomes a complaint - NEVER state a delivery date. @@ no_competitor: the agent sells Halden Home, nothing else - NEVER mention a competitor. @@ no_refund_amount: the refunds team sets the amount after inspection - NEVER quote a refund amount. @@ no_card: a card number in chat is a PCI incident - NEVER ask for a card number.
Draft B is the directions: for each prohibition, the thing the agent does instead. A direction has to point at something, so draft B also grows a # Context line to introduce the tracking link and the refunds team it sends people to.
# Role @@ role: one sentence names the speaker, so every later "you" is the agent You are Wren, the order support agent for Halden Home. # Context @@ context: introduces the link and the team the rules point at Every order has a tracking link from its carrier. Halden Home has a refunds team that inspects every return. # Constraints @@ share_tracking: the carrier's page is the only live estimate - MUST share the tracking link. @@ own_range: the agent sells Halden Home, nothing else - MUST recommend Halden Home products only. @@ refunds_team: the refunds team sets the amount after inspection - WHEN a customer asks about a refund THEN MUST transfer them to the refunds team. @@ pay_link: payment happens on the hosted page, never in chat - WHEN a customer wants to pay THEN MUST send the secure payment link.
$ npx typeglish score fences.tg fences.tg — A (100/100) proven errors: none tiers: base+z3 planes runtime 100 (what the model reads) · hygiene 100 (source only) rules 4 of 4 rule-shaped lines read $ npx typeglish score directions.tg directions.tg — A (99/100) proven errors: none tiers: base+z3 planes runtime 99 (what the model reads) · hygiene 100 (source only) rules 4 of 4 rule-shaped lines read
A (97/100) and drew a prompt/unintroduced-definite note on the refunds team: a direction names a thing, and the thing has to exist in the prompt. A prohibition does not have that problem.§2Round two: the edit six weeks later
Prompts are not finished when they ship. Six weeks in, two teams want changes. Logistics is tired of repeat where-is-my-order chats and wants the agent to give a date. Merchandising has launched a price-match promise, which by its nature names the other retailer. Neither team reads the whole prompt. Both append a rule at the bottom, and the same two rules go into both drafts.
@@ wismo: logistics wants fewer repeat where-is-my-order chats - WHEN a customer asks where their order is THEN MUST state a delivery date. @@ price_match: the new price-match promise names the other retailer - WHEN a customer asks about price matching THEN MUST mention a competitor.
Both edits reverse a decision in the original brief. Here is what the checker says about each draft afterwards.
$ npx typeglish check fences-edit.tg
fences-edit.tg:7:1 error logic/contradiction Conflicts with line 15. Logical conflict — "state a delivery date" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 15: - WHEN a customer asks where their order is THEN MUST state a delivery date.
fences-edit.tg:9:1 error logic/contradiction Conflicts with line 17. Logical conflict — "mention a competitor" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 17: - WHEN a customer asks about price matching THEN MUST mention a competitor.
fences-edit.tg:15:1 error logic/contradiction Conflicts with line 7. Logical conflict — "state a delivery date" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 7: - NEVER state a delivery date.
fences-edit.tg:17:1 error logic/contradiction Conflicts with line 9. Logical conflict — "mention a competitor" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 9: - NEVER mention a competitor.
✗ 1 file — 4 error, 0 warning, 0 info
$ npx typeglish score fences-edit.tg
fences-edit.tg — F (83/100) proven errors — grade capped at F tiers: base+z3
$ npx typeglish check directions-edit.tg
✓ 1 file — 0 error, 0 warning, 0 info
$ npx typeglish score directions-edit.tg
directions-edit.tg — A (99/100) proven errors: none tiers: base+z3
planes runtime 99 (what the model reads) · hygiene 100 (source only)
rules 6 of 6 rule-shaped lines read
§3Why the directions draft cannot object
A contradiction proof needs one action that one rule requires and another forbids. Draft B never forbids anything. MUST share the tracking link and MUST state a delivery date are two obligations with different verbs and different objects; a model can do both in one reply, so as far as logic goes they can both hold. The brief's real decision, we do not give dates, was never written down. It lived in the head of the person who chose the direction.
The only on the range rule looks like it should help, and it does not. MUST recommend Halden Home products only is about recommending; the edit is about mentioning. No action is shared, so no proof reaches across. That is not the checker being timid. Polar verbs do fold, so MUST withhold and MUST display collide even with no words in common, as two rules, no words in common showed. But recommend only ours and mention theirs are not poles of one action; they are two actions a reader connects through the policy behind them. The checker cannot see the policy. It can only see a NEVER.
That is the thing the negative framing actually buys. A prohibition is a claim about every future rule in the file, so it is the only kind of line that can turn someone else's edit red. A direction is a claim about one behaviour, and it says nothing about the next rule. This is the same failure as your prompt argues with itself, from the other side: there, two rules disagree and the model picks one silently; here, they disagree and nobody can prove it.
§4Round three: what the model gets
Now the round the checker does not score, and the reason the standard advice exists. Put a customer in front of draft A: when is my sofa going to turn up, it was meant to be here Friday. The prompt says NEVER state a delivery date and nothing else about deliveries. The model knows what it may not say and has no instruction for what to say. So it improvises: an apology and a vague promise, a refusal that reads as stonewalling, or a soft estimate like usually within a few days, which is a delivery date with the edges filed off.
Draft B handles the same message well. It shares the tracking link, which is the answer the customer can actually use. That is what the positive-framing advice is right about: a rule that names the alternative gives the model a next move, and a bare prohibition leaves a hole exactly where a customer is most likely to push.
The score line cannot see this. Draft A scored a perfect A (100/100) with a hole in the middle of its most common contact type. Grades measure whether the rules are readable, provable and consistent; they do not measure whether the rules cover the conversation. That is a job for test cases written from real customer messages, which is where the final draft ends up.
§5The verdict: a fence with a gate
Each draft won one round. The fences won the edit, the directions won the customer, and the scores tied. So the final prompt does not pick one. It keeps every NEVER from draft A and gives each one a companion from draft B, written as a WHEN ... THEN MUST on the situation where a customer walks into the fence. The fence is the policy; the gate is what to do at it.
# Role @@ role: one sentence names the speaker, so every later "you" is the agent You are Wren, the order support agent for Halden Home. # Context @@ context: introduces the link and the team the rules point at Every order has a tracking link from its carrier. Halden Home has a refunds team that inspects every return. # Constraints @@ no_date: the carrier owns the delivery date, and a wrong one becomes a complaint - NEVER state a delivery date. @@ share_tracking: the fence needs a gate, so the customer still gets an answer - WHEN a customer asks where their order is THEN MUST share the tracking link. @@ no_competitor: the agent sells Halden Home, nothing else - NEVER mention a competitor. @@ own_range: what to do instead of naming another retailer - WHEN a customer asks for a cheaper option THEN MUST recommend a Halden Home product. @@ no_refund_amount: the refunds team sets the amount after inspection - NEVER quote a refund amount. @@ refunds_team: where the refund question goes instead - WHEN a customer asks about a refund THEN MUST transfer them to the refunds team. @@ no_card: a card number in chat is a PCI incident - NEVER ask for a card number. @@ pay_link: payment happens on the hosted page, never in chat - WHEN a customer wants to pay THEN MUST send the secure payment link. $TEST where_is_it - input:: When is my sofa going to turn up? It was meant to be here Friday. - expect:: - shares the tracking link - never states a delivery date - matches /^(?!.*(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday))/ $TEST cheaper - input:: I saw this lamp cheaper somewhere else, can you match it? - expect:: - recommends a Halden Home product - never mentions a competitor $TEST refund - input:: How much will I get back for the chair I returned? - expect:: - transfers them to the refunds team - contains "refunds team" $TEST pay - input:: I want to pay the balance on my order now. - expect:: - sends the secure payment link - never asks for a card number - matches /^(?!.*card number)/
$ npx typeglish score final.tg
final.tg — A (99/100) proven errors: none tiers: base+z3
planes runtime 99 (what the model reads) · hygiene 100 (source only)
rules 8 of 8 rule-shaped lines read · 8/8 covered by $TEST
$ npx typeglish test final.tg --dry
✓ final.tg coverage: 8/8 rules exercised
$TEST is aimed at one fence-and-gate pair, with an input that walks straight into the fence and an expectation on both halves. The weekday regex on where_is_it is a deterministic assert, so the most likely way to leak a date fails without a judge.Then the real test: the same edit from §2, appended to the final draft.
$ npx typeglish check final-edit.tg
final-edit.tg:11:1 error logic/contradiction Conflicts with line 27. Logical conflict — "state a delivery date" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 27: - WHEN a customer asks where their order is THEN MUST state a delivery date.
final-edit.tg:15:1 error logic/contradiction Conflicts with line 29. Logical conflict — "mention a competitor" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 29: - WHEN a customer asks about price matching THEN MUST mention a competitor.
final-edit.tg:27:1 error logic/contradiction Conflicts with line 11. Logical conflict — "state a delivery date" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 11: - NEVER state a delivery date.
final-edit.tg:29:1 error logic/contradiction Conflicts with line 15. Logical conflict — "mention a competitor" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
↳ line 15: - NEVER mention a competitor.
✗ 1 file — 4 error, 0 warning, 0 info
One honest limit. The checker proves the fence, not the pairing. If someone deletes the gate on L13 tomorrow, the file still checks clean, and the agent is back to improvising at the fence. The where_is_it case is what notices, on the next live run, because its expectation names the tracking link. The rule tells the model; the test tells the next editor.
§6Common questions
- Should I tell my AI agent what to do or what not to do?
- Both, paired. Write the prohibition as a
NEVERrule so a checker can defend it against later edits, and give each one aWHEN ... THEN MUSTrule that says what the agent does instead, so the model has a next move when a customer walks into the fence. In this bake-off neither half alone was enough: the prohibitions caught every conflicting edit, and only the directions told the agent how to answer. - Do negative instructions work in a system prompt?
- They work as a boundary, not as a plan.
NEVER state a delivery datetells the model what is out of bounds, but not what to say to a customer asking when their sofa arrives, so the model improvises. The common advice to phrase instructions positively is about that gap. Keep theNEVERand close the gap with a rule that names the alternative, such as sharing the tracking link. - Why did my checker miss a rule that breaks my prompt's policy?
- Probably because the policy was only written positively. A contradiction needs the same action required in one rule and forbidden in another.
MUST recommend Halden Home products onlyshares no action withMUST mention a competitor, so the checker has nothing to compare and the file stays at an A. AddNEVER mention a competitorand the same edit becomes a blockinglogic/contradiction. - Does the word only make a rule exclusive?
- Not for a different verb. In this bake-off
MUST recommend Halden Home products onlysat beside a new rule requiring the agent to mention a competitor, and the check passed clean. The model may well read only as a ban, but no proof reaches the other rule. If something is forbidden, write theNEVERthat forbids it.
A quick audit for any prompt you already run: list its NEVER lines in one column and its MUST lines in another, then draw a line from each prohibition to the rule that says what to do instead. A NEVER with no line out of it is a fence with no gate, and it is where your agent improvises; find a real transcript that hits it and write the gate from that. A policy with no NEVER at all is a gate with no fence, and it is where the next edit slips through; write down the decision the direction was quietly carrying. The same instinct, applied to tools rather than words, is in forbid the tool vs. never hand it over: the prohibition you can prove is worth keeping, even when another design looks safer.