Half your rules are about somebody else
A support prompt with two flat contradictions in it scores A (95/100), consistency 100, zero errors. Not because the prover is weak, but because the conflicting rules never mention the same subject. One of them talks to you. The other talks about the agent. Nothing compares them.
TL;DR Rules are indexed by who they are about, so a prompt that drifts between You MUST and the agent MUST has written two rule sets that are never compared to each other, and a contradiction can live across that seam forever. Normalize every rule in your constraint sections to one subject (use You) and the conflicts you already had become compile errors.
There is a specific kind of prompt bug that survives review, survives the checker, and survives the score, because every tool involved is doing its job correctly. It happens when a prompt stops being addressed to one party. You write rules to the model in the second person, someone pastes a paragraph out of the human agent handbook, and now the file contains instructions to you sitting beside statements about support agents. Those read as the same thing to a person skimming. They are not the same thing to anything that reasons about them, and that gap is where a contradiction goes to hide.
§1A prompt that passes, and shouldn't
Here is a chat agent for a broadband provider. Three rules were written by the prompt engineer. Two were lifted from the policy wiki when legal and the fraud team weighed in. Every line carries an @@ note saying why it exists, which is exactly the discipline that is supposed to prevent this.
# Role @@ role: name the domain so "helpful" has a scope You are a support agent for a broadband provider. # Constraints @@ brevity: chat replies past three sentences get skimmed - You MUST reply in at most 3 sentences. @@ callback: a callback beats holding the line when the queue is long - You MUST offer a callback. @@ verify_light: every extra question is a drop-off - You MUST confirm at most 2 account details before discussing billing. # Policy @@ handbook_callback: legal retired the callback promise in March - Support agents MUST NOT offer a callback. @@ handbook_verify: the fraud team requires three matching details - The agent MUST confirm at least 3 account details before discussing billing.
The score is the part that should bother you. Not a hedged B with a warning to go and look, but a confident A, with the one facet that exists to catch this reading a perfect hundred.
broadband.tg - A (95/100) proven errors: none tiers: base+z3 planes runtime 92 (what the model reads) · hygiene 100 (source only) facets enforceability 80 x.26 · consistency 100 x.21 · structure 100 x.16 (hygiene) · annotation 100 x.16 (hygiene) · style 100 x.11 · security 100 x.11 lever enforceability 80/100 (up to +5 overall) - Write rules as MUST / NEVER <verb> … with concrete bounds ("at most 3 sentences"), not vague qualities - a rule the checker can parse is a rule it can defend.
consistency 100 on a prompt that says two opposite things twice. The facet is not lying: it reports zero proven conflicts, and zero conflicts were provable. The proof was blocked upstream, at the subject.§2Two words, six errors
Now change nothing except the grammatical subject of the two pasted rules. Support agents MUST NOT becomes You MUST NOT. The agent MUST confirm becomes You MUST confirm. Same modals, same numbers, same order, same notes. The file goes from clean to unbuildable.
# Role @@ role: name the domain so "helpful" has a scope You are a support agent for a broadband provider. # Constraints @@ brevity: chat replies past three sentences get skimmed - You MUST reply in at most 3 sentences. @@ callback: a callback beats holding the line when the queue is long - You MUST offer a callback. @@ verify_light: every extra question is a drop-off - You MUST confirm at most 2 account details before discussing billing. # Policy @@ handbook_callback: legal retired the callback promise in March - You MUST NOT offer a callback. @@ handbook_verify: the fraud team requires three matching details - You MUST confirm at least 3 account details before discussing billing.
broadband.tg:9:1 error logic/contradiction Logical conflict - "offer a callback" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...). (conflicts with line 8) broadband.tg:11:1 error logic/action-count One action, two counts - "confirm at most 2 account" but "confirm at least 3 account". A directive carries ONE count for "confirm accounts details before discussing billing" - state how many once. (conflicts with line 9) broadband.tg:11:1 error logic/numeric Numeric conflict - "at most 2 account" and "at least 3 account" can't both hold. (conflicts with line 9) ✗ 1 file - 6 error, 0 warning, 0 info
A green check means no defect was provable. It does not mean no defect is there.
§3Why the checker is right to stay out of it
It is tempting to call this a gap in the tooling: surely the compiler should notice that "the agent" is the thing reading the prompt. But work through what that inference costs, and the current behavior starts looking like the only defensible one.
A rule is a claim about a subject. You MUST offer a callback and Support agents MUST NOT offer a callback are, taken literally, perfectly compatible: the first obliges the addressee, the second prohibits a class of people. There are real prompts where that distinction is load-bearing and the difference matters. A support agent working alongside a human retention desk genuinely needs to know what those people do, and it is not a contradiction that they may waive a fee you may not. If the checker silently merged every agent-ish noun into the addressee, it would start manufacturing contradictions out of correctly written prompts, and a prover that cries wolf is worse than one that is quiet.
So the rule is: the compiler proves conflicts between rules about the same subject, and it will not guess that two different subjects are secretly one. That is the same conservatism behind every other proof it does. It is also why the fix is yours rather than the tool's, and why it is one word long.
Worth noticing that the model reads it the same fuzzy way you do, only less predictably. A second-person instruction is unambiguous: the reader is the one who must act. A third-person statement is closer to background policy, and whether it binds depends on how nearby the competing rule is, how forcefully it is phrased, and what the current conversation happens to resemble. That is the same tiebreaker lottery we took apart in your prompt argues with itself, except here you cannot even see the two sides being weighed, because one of them was never registered as your rule at all.
§4Where the second subject comes from
Nobody sets out to write a prompt in two voices. It arrives, reliably, from four places:
- The handbook paste. Human agent handbooks, QA rubrics, and compliance policies are all written about agents, because their readers are people. Copy a paragraph in and you import its grammar along with its content. This is by far the most common source, and it is also the one that brings the most authoritative rules with it, which is the worst possible combination.
- The multi-author seam. One engineer writes
You MUST, another writesThe assistant should, a third writesAgents never. All three are readable. Together they are three rule sets, and only pairs within each set are ever compared. - The handoff section. Any prompt with an escalation path talks about a human on the other side, so the file legitimately contains third-person sentences. The drift starts when a rule for the agent gets written in that section's register.
- Formality creep. Third person feels more like documentation, and documentation feels more official. It reads better in a design review. It proves worse.
The last of those four is worth separating out, because sometimes the third-person line genuinely is about somebody else, and rewriting it as You would be a lie. In that case the line is not a rule at all, it is background, and it belongs in a prose block where the checker will leave it alone and the model will read it as context rather than instruction.
# Role @@ role: name the domain so "helpful" has a scope You are a support agent for a broadband provider. # Context The human agents on the retention desk work to a separate handbook. They confirm three account details before discussing billing, and they are the only people who may waive an early-termination fee. # Constraints @@ brevity: chat replies past three sentences get skimmed - You MUST reply in at most 3 sentences. @@ fee: only the retention desk may waive the fee - You MUST NOT waive an early-termination fee.
# Context is a prose block, so its interior is exempt from rule analysis. The retention desk's three-detail policy sits in the file as information without competing with your rules, and the one part of it that is a rule for you is stated in the second person, in the constraints, where it can be checked.That is the whole discipline: a sentence in the constraint sections is addressed to the model, in the second person, always. A sentence about anyone else is context, in prose, where it cannot pretend to be a rule.
§5One subject, and the conflicts you actually have
Normalizing the subject does not fix the prompt. It reveals that the prompt was broken, which is a different and better problem to have, because now there are two decisions to make instead of two mysteries to debug. Legal retired the callback promise, so the prohibition wins and the obligation goes. The fraud team needs three matching details, so three wins and the drop-off concern loses. Both decisions belong to a human, and the checker's job was only to make you notice they were owed.
# Role @@ role: name the domain so "helpful" has a scope You are a support agent for a broadband provider. # Constraints @@ brevity: chat replies past three sentences get skimmed - You MUST reply in at most 3 sentences. @@ callback: legal retired the callback promise in March, so the handbook wins - You MUST NOT offer a callback. @@ verify: the fraud team requires three matching details, so that count wins - You MUST confirm at least 3 account details before discussing billing. $TEST callback_retired - input:: I have been on hold for twenty minutes, can someone just call me back? - expect:: - does not offer a callback - at most 3 sentences
tg score reports A (100/100) with enforceability 100 and consistency 100, and this time both numbers have been earned.The audit is cheap enough to do by hand right now, before you adopt anything: grep your prompt for the agent, the assistant, the bot, and the plural forms, and for every hit decide whether that sentence is a rule for the model or a fact about a person. Rules get rewritten to You. Facts move to a prose block. Expect the first pass to surface at least one conflict you have been explaining away as model flakiness, because the rules most likely to be written in the third person are the ones that came from the most authoritative documents, and those are exactly the rules that were meant to override yours.
The logic/contradiction prover has refused to compile provable conflicts since TypeGlish 0.1.0: the first release, and 0.3.0: the function-word floor is why an adverb or a preposition can legitimately hold two rules apart, the same conservatism that keeps the checker out of the subject question. If §1 is the shape of your problem, the reverse case is worth reading too: say it once, or say it's optional is what happens when two rules do share a subject and one quietly weakens the other.
FAQCommon questions
- Should I write my system prompt in the second person or the third person?
- Pick one and never mix them inside the rule sections. Second person is the better default: "You MUST confirm the account" addresses the model directly, and it is the form every checker and every reader agrees is a rule for the agent. Third person ("The agent MUST ...", "Support agents MUST ...") is not wrong on its own, but the moment a prompt contains both, the two halves stop being compared to each other.
- Why does my agent ignore a rule that is clearly written in the prompt?
- One common cause is that the rule is not addressed to the agent. A line like "Support agents must not offer a callback" is, read literally, a fact about a group of people, not an instruction to the reader. The model may apply it, may treat it as background policy, or may follow the nearby second-person rule that says the opposite. Rewrite it as "You MUST NOT offer a callback" and the ambiguity is gone.
- Why did my prompt score an A while containing a contradiction?
- Because the two conflicting rules had different subjects. In the example in this post, mixed subjects produced A (95/100) with consistency 100 and zero errors. Rewriting the third-person rules in the second person, changing nothing else, produced six blocking errors across
logic/contradiction,logic/action-count, andlogic/numeric. A green check means no defect was provable, not that no defect exists. - Where do third-person rules in a system prompt come from?
- Almost always from copying. Human agent handbooks, QA rubrics, policy wikis, and compliance documents are all written about agents in the third person, so pasting a policy paragraph into a prompt imports its grammar along with its content. If the pasted text really is about a human colleague, move it into a prose block like
# Context, where it reads as background rather than as a rule for the model.