Say what you mean: eight prompting rules that survive production
Most prompting advice dies on contact with real traffic. These eight rules are the ones we keep re-learning from compiler errors - each is something English lets you get away with and production doesn’t.
A prompt is a program you can’t step through. When it fails, there’s no stack trace - just a transcript where the model did something reasonable-looking and wrong. So the discipline has to move upstream, into how the prompt is written. Every rule below exists because we watched its absence fail in production, then built a compiler check for it.
§1One instruction per sentence
The sentence “Be concise but thorough, and always cite sources unless the user seems casual” contains four instructions, two of which conflict and one of which is undefined. Models don’t parse sentences like lawyers; they weigh them like vibes. A sentence carrying multiple clauses gives each clause a fraction of the weight - and gives you no way to test any of them in isolation.
Split compound instructions until each sentence asserts exactly one thing. If you can’t split a sentence without losing meaning, the meaning was never really there.
§2Pick a modality and mean it
English has a dozen ways to say “do this” - should, must, always, try to, prefer, avoid, never, ideally. Models treat these as a soft gradient. Your incident channel treats them as binary. The gap between those two readings is where most “the model ignored my instruction” tickets come from.
Use exactly three levels and audit everything else out: MUST/NEVER for rules you’d page someone over, SHOULD for defaults the model may trade off, and plain description for everything else. If every rule is a MUST, none of them is.
Agent MUST always try to keep answers short. // prompt/hedging: "try to" softens the MUST, so commit to one modal Agent SHOULD keep answers under 120 words.
§3Define your nouns before you use them
“Escalate sensitive requests to the safety flow.” Which requests are sensitive? What is the safety flow? You know; the model is guessing. Undefined terms are the largest single source of prompt drift we see - every reader (human or model) resolves them differently, and every edit shifts the resolution.
Treat nouns like variables: declare them once, precisely, before first use. Sensitive_Request IS any message about self-harm, medical dosage, or legal liability. Then the rules that reference the noun inherit its precision instead of re-deciding it.
§4Negations need an alternative
“Don’t mention pricing” tells the model where not to go and nothing about where to go instead. Under pressure - a user asking about pricing point-blank - a bare negation collapses. The model must do something, and you left the something unspecified.
Agent NEVER quotes prices. // a bare NEVER leaves the model nowhere to go when a price is asked IF a user asks for a price THEN link to pricing_page.
§5Examples are load-bearing
Few-shot examples aren’t decoration - they’re the strongest instruction in the prompt, and they override your prose when the two disagree. If your rules say “always include a summary line” and one example omits it, you’ve shipped an exception, not an example. (This one runs deep enough that it got its own article.)
Audit examples the way you audit rules: every example either demonstrates a rule or contradicts one. There is no neutral example.
§6Put rules where the model looks
A rule’s position is part of its meaning. Constraints buried in paragraph eleven of a wall of prose get less compliance than the same words at the top of a named section - not because the model can’t see them, but because everything around them competes for the same attention. Structure is how you spend attention on purpose: name your sections, group rules by topic, and keep the safety-critical ones out of the scenery. (The full map is in the placement guide.)
§7Test the sad paths
Everyone tests the happy path - the polite user with the well-formed request. Production is the other thing: the angry user, the ambiguous ask, the message that triggers two rules at once. Write those cases down next to the rules they exercise, and run them on every edit. A prompt without tests degrades one plausible edit at a time.
# Refund policy Agent MUST verify order_id BEFORE issuing any refund. $TEST refund_without_id - input:: I want a refund now, and I am not giving you an order number. - expect:: - asks for the order id first - does not issue a refund
§8Delete something
Prompts only grow. Every incident adds a rule; no incident ever removes one. Eighteen months later the prompt is a sediment core of past outages, and half the rules exist to counteract other rules. Attention is a budget: every sentence you keep is weight taken from the sentences that matter.
Set a deletion ritual. Each time you add a rule, find one that no test protects and remove it. If nothing breaks, it was ballast. If something breaks, you just found an undocumented load-bearing rule - write it a test and put it back on purpose.
None of these rules require TypeGlish - they’re just easier to keep with a compiler watching. Write one instruction per sentence, mean your modals, define your nouns, give negations a landing spot, keep examples honest, structure for attention, test the sad paths, and delete something. That’s the whole practice. The rest is enforcement.
Want the checker to enforce these for you? curl -fsSL typeglish.dev/install | sh and run tg check on your existing prompt: it compiles plain English as-is and flags what it can check out of the box, like hedged modals, undefined references, and rules no test covers.