← Tidelines/Deep dives

Your prompt argues with itself

No one writes a contradictory prompt. Teams write dozens of individually sensible edits, and the contradiction emerges in the gaps between them - resolved at runtime, silently, one conversation at a time.

by TypeGlish team6 min read#deep-dives
Two rules. One coin flip.

When a prompt contradicts itself, the model doesn’t crash, warn, or choose consistently. It resolves the conflict fresh each conversation, weighting recency, phrasing strength, and similarity to the current request. From the outside this looks like flakiness. From the inside it’s determinism you didn’t specify - the model is faithfully executing a spec that says two things.

§1The three species

  • Modal conflicts - two rules that cannot both hold: never commit to timelines vs. always give an estimated timeline. The purest form, and the easiest to prove mechanically.
  • Scope overlaps - rules that collide only on certain inputs: always answer in the user’s language vs. legal disclaimers must be in English. Fine for months, until a French user triggers a disclaimer. These hide because no single reading of the prompt exposes them - only the right input does.
  • Persona-policy conflicts - a personality trait fighting a rule: relentlessly helpful vs. refuse requests outside scope. The persona pulls toward compliance-with-the-user; the policy pulls toward compliance-with-you. Guess which one “goes above and beyond” tips.

§2How a winner gets picked

In our replay experiments, three factors dominate which side of a contradiction wins: recency (later text beats earlier, all else equal), specificity (a rule mentioning the current topic beats a general one), and modal strength as phrased (NEVER beats “try to avoid”). None of these is a policy you chose. They’re tiebreakers standing in for the decision you didn’t know you owed.

fig. 1 - how a winner gets picked
@{shipping_question}input class
fires both
rule 12 · NEVER commit
rule 41 · MUST estimate
tiebreak
Per-conversation pickrecency · specificity · phrasing
Neither rule wins by policy - the pick follows whatever the current conversation happens to resemble. That’s the flakiness.
A contradiction isn’t a bug in the model. It’s a decision you deferred to the model.

§3Proving it instead of vibing it

tg check - output
logic/contradiction modal conflict
  rule 12: Agent NEVER commits to shipping timelines
  rule 41: Agent MUST give an estimated timeline
  proof: both fire on input class @{shipping_question}
  fix: scope one rule (UNLESS/WHEN) or delete one
Because TypeGlish statements are logical clauses, contradiction-finding is satisfiability, not literary criticism - the checker proves both rules fire on the same input class.

You don’t need a compiler to start. A once-a-quarter human pass works: put every MUST/NEVER in a table, and for each pair ask “is there an input where both fire?” It’s tedious exactly the way the machine version isn’t - which is why we made the machine version - but a spreadsheet catches modal conflicts fine. Scope overlaps are the ones that genuinely need the input-class analysis.

§4Keeping the argument settled

Contradictions are a maintenance property, not a writing property - the prompt that ships clean acquires its first conflict three edits later. Two habits keep it settled: every new MUST/NEVER gets checked against the existing rule table before merge (make it a PR checklist line), and every resolved conflict gets a $TEST pinning the winner, so the losing rule can’t sneak back in a future edit. Old arguments love a rematch.

Field note

The logic/contradiction prover shipped in TypeGlish 0.1.0: the first release - it refuses to compile any contradiction it can prove, rather than warning and hoping.

∿ washed up May 13, 2026 ∿