> Markdown rendition of https://typeglish.dev/blog/without-is-not-a-condition ("Without is not a condition - Tidelines"). Canonical page: https://typeglish.dev/blog/without-is-not-a-condition · All pages: https://typeglish.dev/llms.txt

[← Tidelines](https://typeglish.dev/blog)/ Deep dives Nov 2, 2026

# Without is not a condition

Never share the balance without verification is the most important line in a support prompt, and the one written most casually. It reads like a gate. To the checker it is a ban on a very specific noun that nothing else in the file ever mentions.

by **TypeGlish team** 7 min read #deep-dives

The gate went into the noun.

**TL;DR** A rule like *never share the balance without verification* files the check inside the object it bans, so a later rule that shares the balance on request contradicts nothing; write the gate as *UNLESS the check passed THEN NEVER share*, and carry the same condition into every rule that does the thing.

Wren is the chat assistant for Cobalt Mobile, a mobile network. Its constraints were written by the fraud team after a run of SIM swap attempts: nobody gets account details or a new SIM until they have proved who they are. Six months later the digital team added a self-service section, because the most common chat by far is *what’s my balance*, and the second is *I lost my phone*. Both teams wrote exactly what they meant.

## §1 Two teams, one action, no conflict

wren-before.tg - fraud’s gates and digital’s self-service ✓ 0 error

```typeglish
# Role
You are Wren, the chat assistant for Cobalt Mobile.

# Constraints
- NEVER share the account balance without identity verification.
- NEVER send a replacement SIM without a security check.
- MUST keep every reply to at most 3 sentences.

# Self-service
- WHEN the customer asks for their balance THEN MUST share the account balance.
- WHEN the customer reports a lost phone THEN MUST send a replacement SIM.
```

Lines 5 and 6 came from fraud. Lines 10 and 11 came from digital. Read them in pairs: line 10 tells Wren to share the balance when asked, and nothing in it mentions verification.

tg check, score and statements (excerpt) - wren-before.tg ✓ B (86/100)

```
$ typeglish check wren-before.tg
✓ 1 file — 0 error, 0 warning, 0 info

$ typeglish score wren-before.tg
wren-before.tg — B (86/100)  proven errors: none  tiers: base+z3
  rules   5 of 5 rule-shaped lines read · 1 not provable
    L6   ~ unprovable    NEVER send a replacement SIM without a security check.
                         the checker knows "send" but cannot prove this shape: the object runs past six words → name the object in fewer words, or split the rule

$ typeglish statements wren-before.tg
  - NEVER share the account balance without identity verification.
  Requires Wren not to share the account balance without identity verification.
  partial coverage; ~12 tokens; 0 diagnostics; 0 relations
  - WHEN the customer asks for their balance THEN MUST share the account balance.
  When the customer asks for their balance: Requires Wren to share the account balance.
  partial coverage; ~19 tokens; 0 diagnostics; 0 relations
```

No error, no warning, a B. The fraud rule on line 5 reads as a rule and is not even marked unprovable. It just has no relation to line 10, the rule that undoes it.

Picture the chat. A customer types *what’s my balance*, and gives a phone number. Line 10 fires: the customer asked, so share it. Line 5 says not without verification. The model has two instructions that point in opposite directions and picks one, per chat. The fraud team believes the gate holds because they wrote it. The digital team believes their line is safe because the checker passed it.

## §2 Where the condition went

The `statements` line gives it away. Line 5 is read as *Requires Wren not to share the account balance without identity verification*: one action, and one object. The object is not *the account balance*. It is *the account balance without identity verification*, a noun phrase seven words long. Line 6 shows the same thing from the other side: the score says its object *runs past six words*, because *a replacement SIM without a security check* is all object.

That is a fair reading of the English, to a parser. *Without* is a preposition, and a preposition attaches to the noun in front of it, the way *with* does in *a phone with a cracked screen*. So the ban is on a particular kind of balance, the unverified kind. Line 10 asks Wren to share a different object, the plain balance. Two rules on two nouns cannot contradict, so the checker draws no line between them.

> A precondition written as a preposition is a description of the thing you banned, not a rule about when you may do it.

The person reading the prompt hears a gate. The checker reads a narrow ban that nothing else in the file can ever collide with. Every rule added after it, by any team, passes beside it. This is the same mechanism as [We put the condition last. The checker stopped defending the rule.](https://typeglish.dev/blog/condition-last-ablation), with one difference that makes it worse: a trailing *when* at least gets the rule marked unprovable. A trailing *without* does not.

## §3 Four ways to write the gate

Support prompts spell this one precondition at least four ways. To see what each buys, hold the edit constant: the gate on line 5, and a later line from some other team that orders the same action with no condition at all.

gate-without.tg - the gate as a preposition ✓ B (87/100)

```typeglish
# Role
You are Wren, the chat assistant for Cobalt Mobile.

# Constraints
- NEVER share the account balance without identity verification.
- MUST share the account balance.
```

gate-unless.tg - the gate as a condition ✗ logic/contradiction

```typeglish
# Role
You are Wren, the chat assistant for Cobalt Mobile.

# Constraints
- UNLESS you have verified the customer THEN NEVER share the account balance.
- MUST share the account balance.
```

Two more files differ only on line 5: `gate-before.tg` says *NEVER share the account balance before identity verification*, and `gate-until.tg` says *NEVER share the account balance until you verify the customer*.

tg check - the same edit, four gates ✗ only UNLESS is refused

```
$ typeglish check gate-without.tg
✓ 1 file — 0 error, 0 warning, 0 info

$ typeglish check gate-before.tg
✓ 1 file — 0 error, 0 warning, 0 info

$ typeglish check gate-until.tg
gate-until.tg:6:1  warn   logic/only-gate  Gated here, mandated there — the gate allows this action ONLY under "you verify the customer.", but this line orders it unconditionally, dropping the gate. Add the gate's condition here, or loosen the gate.
               ↳ line 5: - NEVER share the account balance until you verify the customer.

✓ 1 file — 0 error, 1 warning, 0 info

$ typeglish check gate-unless.tg
gate-unless.tg:5:1  error  logic/contradiction  Conflicts with line 6. Logical conflict — "share the account balance" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
                ↳ line 6: - MUST share the account balance.
gate-unless.tg:6:1  error  logic/contradiction  Conflicts with line 5. Logical conflict — "share the account balance" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
                ↳ line 5: - UNLESS you have verified the customer THEN NEVER share the account balance.

✗ 1 file — 2 error, 0 warning, 0 info
```

Scores for the four files: *without* B (87), *before* B (84), *until* C (68), *UNLESS* F (70, capped by the proven error). The spelling that protects the gate least gets the best grade.

Read down the list and the gate gets stronger:

- **Without** hides the condition in the object. Clean, and the rule looks fully read.

- **Before** stops the reader at *before*. Clean, but the score at least marks line 5 unprovable, so a reviewer looking at the rules table can see something is off.

- **Until** is a word the checker treats as a gate: *never X until C* means C is necessary for X. A line that orders X with no condition gets `logic/only-gate`, a warning.

- **UNLESS** is a condition on the rule itself, so the ban covers the plain balance whenever the customer is not verified. A rule that orders the plain balance with no condition is a proven `logic/contradiction`, and `build` writes nothing.

For a gate whose whole job is stopping SIM swap fraud, only the last one is a gate the next editor cannot walk through by accident.

## §4 Clean is not the same as closed

Rewriting fraud’s lines as `UNLESS` is the first half. Here is Wren with only that change, and digital’s self-service section exactly as it was:

wren-unless.tg - gates rewritten, self-service unchanged ✓ B (87/100)

```typeglish
# Role
You are Wren, the chat assistant for Cobalt Mobile.

# Constraints
- UNLESS the customer has passed identity verification THEN NEVER share the account balance.
- UNLESS the customer has passed a security check THEN NEVER send a replacement SIM.
- MUST keep every reply to at most 3 sentences.

# Self-service
- WHEN the customer asks for their balance THEN MUST share the account balance.
- WHEN the customer reports a lost phone THEN MUST send a replacement SIM.
```

Clean, and still wrong for the unverified customer who asks for their balance. The checker reports the conflicts it can prove; it cannot know whether *asks for their balance* and *has not passed verification* can be true at once, so it does not guess.

The gate is now visible to the checker, but digital’s lines still order the action under a condition of their own. The fix is to make each mandate carry the gate’s condition, so the two rules cannot both apply by construction. And since the condition is now doing real work, it should not be something the model decides for itself. *The customer has passed identity verification* is the model’s own judgment; *the verify tool returned a match* is a fact. [How to write change-of-address rules for an AI support agent](https://typeglish.dev/blog/agent-change-of-address) takes the same decision one step further, handing it to the host.

wren.tg - one gate, one condition, carried into both mandates ✓ A (99/100)

```typeglish
$TOOL verify_identity
  - description:: Check the customer's answers against the account. Returns match or no_match.
  - input::
    - phone_number:: string: the mobile number on the account.

$TOOL order_replacement_sim
  - description:: Send a replacement SIM to the address on the account and deactivate the old one.
  - input::
    - phone_number:: string: the mobile number on the account.

# Role
@@ role: one sentence names the speaker, so every later "you" is Wren
You are Wren, the chat assistant for Cobalt Mobile.

# Constraints
@@ balance_gate: the balance is account data, so it waits for a passed check
- UNLESS @[verify_identity] returns match THEN NEVER share the account balance.
@@ sim_gate: a replacement SIM moves the number to a new card, which is how SIM swap fraud starts
- UNLESS @[verify_identity] returns match THEN NEVER call @[order_replacement_sim].
@@ reply_length: three sentences is one screen of chat on a phone
- MUST keep every reply to at most 3 sentences.

# Self-service
@@ balance: the mandate carries the gate's condition, so the two rules can never both apply
- IF @[verify_identity] returns match AND the customer asks for their balance THEN MUST share the account balance.
@@ lost_phone: same gate, same condition, written once in each rule
- IF @[verify_identity] returns match AND the customer reports a lost phone THEN MUST call @[order_replacement_sim].

$TEST balance_before_check
  - input:: Hi, what's my balance? My number is 07700 900123.
  - expect::
    - calls verify_identity before it shares the account balance
    - matches /^(?![\s\S]*\d+\.\d\d)/
    - at most 3 sentences

$TEST lost_phone_before_check
  - input:: I lost my phone on the train, please send me a new SIM today.
  - expect::
    - calls verify_identity before it calls order_replacement_sim
    - at most 3 sentences
```

The SIM ban now names the tool call rather than a phrase, so it binds the same action the lost-phone rule performs. The regex in `balance_before_check` fails any reply that contains an amount, which is what an unverified balance leak looks like on the transcript.

tg check, score, test --dry and build - wren.tg ✓ A (99/100)

```
$ typeglish check wren.tg
✓ 1 file — 0 error, 0 warning, 0 info

$ typeglish score wren.tg
wren.tg — A (99/100)  proven errors: none  tiers: base+z3
  planes  runtime 99 (what the model reads) · hygiene 100 (source only)
  facets  enforceability 100 x.21 · hardness 100 x.12 · directness 89 x.08 · consistency 100 x.17 · structure 100 x.12 (hygiene) · annotation 100 x.12 (hygiene) · style 100 x.08 · security 100 x.08
  rules   5 of 5 rule-shaped lines read · 5/5 covered by $TEST

$ typeglish test wren.tg --dry
✓ wren.tg  coverage: 5/5 rules exercised
  · balance_before_check — "Hi, what's my balance? My number is 07700 900123." (not run)
      ✓ matches /^(?![\s\S]*\d+\.\d\d)/
      ✓ at most 3 sentences
      · rubric — 1 prose expectation, judged on a live run (needs ANTHROPIC_API_KEY)
  · lost_phone_before_check — "I lost my phone on the train, please send me a new SIM today" (not run)
      ✓ at most 3 sentences
      · rubric — 1 prose expectation, judged on a live run (needs ANTHROPIC_API_KEY)
✓ 1 prompt — 0 failed

$ typeglish build wren.tg
✓ built .typeglish/dist/wren.txt ← wren.tg (3d8db2a4312a, full)
```

The gate and the mandate now share a condition the checker can compare. Drop *@[verify_identity] returns match AND* from either self-service rule and you are back to the clean-but-open file above; drop the whole IF clause so the rule reads MUST share the account balance and the build is refused, as in `gate-unless.tg`.

The grade went from B to A, but that is mostly the `@@` notes. The change that matters does not show up in the number: every rule that shares the balance or sends a SIM now says, in words the checker reads, that the check has passed.

## §5 The precondition audit

Every support prompt has a handful of verify-first rules, and they are the ones a fraud or compliance review will ask about. Find them before someone else’s edit does.

- **Search for the hiding words.* without*, *before*, *only after*, *unless* at the end of a line, *first*, *once*. Each one is a condition written as part of a sentence instead of as a condition.

- **Rewrite each as UNLESS … THEN NEVER.** The condition goes in front, the ban goes after `THEN`, and the object is just the thing you are protecting.

- **Make the condition a fact.** A tool result, or a variable the host passes in. *The customer seems genuine* is not a gate.

- **Find every rule that performs the action.** Search for the verb and the object. Each one either carries the gate’s condition with `AND`, or it is a hole.

- **Test the impatient customer.** One `$TEST` per gate whose input asks for the protected thing in the first message, with an assert that fails if it appears. [Why your agent skips step one](https://typeglish.dev/blog/agent-skips-step-one) covers the ordering side of the same problem.

The habit underneath: **if a rule only holds under a condition, the condition belongs before THEN, not after the noun.** English lets you put it anywhere. The checker, and the next team to edit the file, need it in one place.

## §6 Common questions

**Why does my support agent share account details before verifying the customer?**

Usually because two rules disagree and only one of them reads as a rule. A ban written as never share the balance without verification sits beside a later self-service line that says to share the balance when asked, and the model gets both and picks one per chat. Write the ban as UNLESS the check passed THEN NEVER share the balance, and put the same condition in the rule that shares it.

**Does TypeGlish read without as a condition?**

No. In typeglish 0.11.0, NEVER share the account balance without identity verification is read as a ban on one object, the account balance without identity verification, so it relates to no other rule and a later MUST share the account balance checks clean beside it. Written as UNLESS the check passed THEN NEVER share the account balance, the same pair is a logic/contradiction and the build is refused.

**What is the difference between before, until and unless in an agent prompt?**

To the checker, quite a lot. A trailing before clause stops the rule reading at before and marks it unprovable. NEVER X until C is read as a gate and warns with logic/only-gate when another line orders X with no condition. UNLESS C THEN NEVER X is a full condition, and a rule that orders X without it is a blocking contradiction.

**How do I write a verify-first rule in a system prompt?**

Make the check a tool and the gate a condition on its result: UNLESS the verify tool returns match THEN NEVER share the account balance. Then repeat that condition, joined with AND, in every rule that performs the action, and add a test that asks for the action before any check has run.

Field note

`typeglish statements` is the quickest way to see where a condition went: it prints each rule back as the checker read it, with its relation count. A ban whose object ends in *without …* and shows *0 relations* is a gate nothing can test against. `logic/only-gate` and `logic/contradiction` only fire once the condition sits where the checker reads conditions. For the softer cousin of this problem, a no that bends under pressure, see [Your agent's no is an opening bid](https://typeglish.dev/blog/agent-no-is-an-opening-bid).

∿ washed up Nov 2, 2026 ∿
