> Markdown rendition of https://typeglish.dev/blog/usually-rules-rewrite ("Rewrite: the rules that say usually - Tidelines"). Canonical page: https://typeglish.dev/blog/usually-rules-rewrite · All pages: https://typeglish.dev/llms.txt

[← Tidelines](https://typeglish.dev/blog)/ Best practices Aug 14, 2026

# Rewrite: the rules that say usually

Five of six rules in a billing agent prompt open with usually, typically or rarely, because that is how the policy was actually described to you. The file checks perfectly clean, and one of those words in front of a number is enough to take the number out of the solver.

by **TypeGlish team** 8 min read #best-practices

Most occasions. Which ones?

**TL;DR** A six-rule agent prompt written in frequency adverbs (`usually`, `typically`, `rarely`, `generally`, `occasionally`) checks at `0 error, 0 warning, 0 info` and scores C (66/100) with **enforceability 28**, and the adverb in front of a bound removes that bound from the proofs: `You MUST keep every response to at most 4 sentences` beside `at least 6 sentences` is 2 blocking `logic/numeric` errors, while `Generally keep every response to at most 4 sentences` beside the same line is clean. Rewriting each adverb into a guarded rule or an honest `MAY` gives B (83/100) with enforceability 94.

Nobody sets out to write a vague prompt. The vagueness arrives in the handover, because it is how the policy was described: *we usually escalate those, we rarely send them to retention, we generally keep it short.* That is an accurate description of what the floor does, and writing it down faithfully feels like the responsible move. It is also the single most common thing in an agent prompt that no review catches, because there is nothing obviously wrong with any individual line.

## §1 Before: six rules and a perfect tick

Dax handles billing for a broadband ISP. Six rules, one hard, five described the way the team lead described them.

dax.tg - before ✓ 0 findings

```typeglish
# Role
You are Dax, the billing support agent for Northwind Broadband.

# Constraints
- You MUST ask for an account number before you discuss an account.
- Usually escalate a billing dispute to a human agent.
- Typically offer a goodwill credit when a customer reports a second outage.
- Rarely transfer a caller to a retention specialist.
- Generally keep every response to at most 4 sentences.
- Occasionally mention that an online billing portal exists.
```

Every rule is a real policy. Nothing is misspelled, nothing is hedged with *try to*, and there is not a contradiction in the file.

tg check dax.tg, then tg score dax.tg - output ✗ C (66/100)

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

$ typeglish score dax.tg
dax.tg — C (66/100)  proven errors: none  tiers: base+z3
  planes  runtime 72 (what the model reads) · hygiene 50 (source only)
  facets  enforceability 28 x.21 · hardness 57 x.12 · directness 89 x.08 · consistency 100 x.17 ·
          structure 100 x.12 (hygiene) · annotation 0 x.12 (hygiene) · style 100 x.08 · security 100 x.08
  lever   enforceability 28/100 (up to +15 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.
```

Zero findings and enforceability 28. The score is the only part of the toolchain with anything to say, and the lever line says it in one sentence.

Twenty-eight out of a hundred, with a clean bill of health above it. That gap is the whole subject of this post, and it is not a bug in the checker. It is the checker being precise about what it can and cannot prove, and a frequency adverb is a genuinely well-formed thing to write.

## §2 What *usually* actually is

It is easy to file `usually` under hedging, alongside *try to* and *where possible*. It is not the same thing. A frequency adverb is a **quantity claim over occasions**, and the words form a square of opposition exactly the way *all*, *some* and *no* do over a set:

- `ALWAYS` and `NEVER` are the corners: every occasion, no occasion.

- `usually`, `mostly`, `generally`, `typically` claim **most** occasions.

- `sometimes`, `occasionally`, `at times` claim **some** occasions.

- `rarely`, `seldom` claim **few** occasions, which is most-not, and still some.

Because they are quantities, they conflict with each other, and the checker proves it. Put two of them on one action and the file stops building.

most occasions vs. few occasions ✗ 2 errors

```typeglish
# Role
You are Dax, the billing support agent for Northwind Broadband.

# Constraints
- Usually escalate a billing dispute to a human agent.
- Rarely escalate a billing dispute to a human agent.
```

Two rules a reviewer would skim past, three months apart, in a file of forty.

tg check - output

```
f1.tg:5:1  error  logic/contradiction  Frequency conflict — "escalate a billing dispute to a
  human agent" is required on most occasions but required on few occasions. The occasions
  cannot both hold. (conflicts with line 5)
f1.tg:6:1  error  logic/contradiction  Frequency conflict — "escalate a billing dispute to a
  human agent" is required on most occasions but required on few occasions. The occasions
  cannot both hold. (conflicts with line 4)

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

*Required on most occasions but required on few occasions.* The proof is about the quantities, not the wording.

The corners work too. `ALWAYS` beside `sometimes` is not a contradiction, it is a subsumption, and the checker separates the two cases:

every occasion vs. some occasions ✗ 3 errors

```typeglish
# Role
You are Dax, the billing support agent for Northwind Broadband.

# Constraints
- ALWAYS apologize for an outage.
- Sometimes apologize for an outage.
```

Three blocking errors: `logic/quantifier-strength` on both lines, and `logic/force-subsumption` on the weaker one. The message is worth quoting: *a model may read the weaker as "not always".*

So the frequency square is fully wired, and every corner of it conflicts with `NEVER` for the same action. This matters because it sets up the exact boundary of what the clean tick in §1 was worth. Those six rules are all about *different* actions. Nothing collided, so nothing was proven, and a file where nothing collides is not a file that has been checked.

## §3 The word that takes the number out of the solver

Here is the part that is genuinely surprising, and the reason this is a rewrite post rather than a style note. Two files, differing by one word on one line.

the bound under MUST ✗ 2 errors

```typeglish
# Role
You are Dax, the billing support agent for Northwind Broadband.

# Constraints
- You MUST keep every response to at most 4 sentences.
- You MUST write at least 6 sentences in every response.
```

`logic/numeric`, twice, blocking: *"at most 4 sentences" and "at least 6 sentences" can't both hold.*

the same two bounds, one word changed ✓ 0 findings

```typeglish
# Role
You are Dax, the billing support agent for Northwind Broadband.

# Constraints
- Generally keep every response to at most 4 sentences.
- You MUST write at least 6 sentences in every response.
```

`0 error, 0 warning, 0 info`. Four is still less than six. Nothing is checking.

The bound is still in the file. A person reading it still sees *at most 4 sentences* and understands the intent perfectly. It simply no longer occupies the slot the solver reasons about, because the rule carrying it does not obligate anything. It is the same behaviour across the whole family:

the same pair, one leading word at a time - output

```
each file: <this line> + "You MUST write at least 6 sentences in every response."

You MUST keep every response to at most 4 sentences.     2 error, 0 warning, 0 info
Generally keep every response to at most 4 sentences.    0 error, 0 warning, 0 info
Usually keep every response to at most 4 sentences.      0 error, 0 warning, 0 info
Typically keep every response to at most 4 sentences.    0 error, 0 warning, 0 info
Mostly keep every response to at most 4 sentences.       0 error, 0 warning, 0 info
Rarely write more than 4 sentences.                      0 error, 0 warning, 0 info
You SHOULD keep every response to at most 4 sentences.   0 error, 0 warning, 0 info
```

Seven files, one changed line each. `SHOULD` is in the list because this is not really about adverbs: it is about force, and a rule that does not obligate does not put its number anywhere a proof can reach. [Softening a rule stops it being graded](https://typeglish.dev/blog/deontic-force-ablation) for the same reason.

> A number under a soft rule is documentation. It looks exactly like a constraint until something needs to contradict it.

That last row is the one to take to a review. The prompt in §1 has a four-sentence cap in it, and if somebody adds a length rule next quarter, there is no version of that edit that fails. Not in CI, not under `--strict`, not on the day it ships.

## §4 After: the same six rules, decided

The rewrite is not a matter of swapping every adverb for `MUST`. That would be a lie in the other direction, and it would make the agent rigid in exactly the places the team deliberately left room. The move is to ask, per rule, what the adverb was standing in for. In practice it is always one of two things.

dax.tg - after ✓ B (83/100)

```typeglish
# Role
You are Dax, the billing support agent for Northwind Broadband.

# Constraints
- You MUST ask for an account number before you discuss an account.
- WHEN a caller disputes a charge twice THEN you MUST escalate to a human agent.
- WHEN a caller reports a second outage in one month THEN you MUST offer a goodwill credit.
- UNLESS a caller asks to cancel THEN you MUST NOT transfer a caller to a retention specialist.
- You MUST keep every response to at most 4 sentences.
- You MAY mention that an online billing portal exists.
```

Six rules in, six rules out. Three became guarded, one became hard, one became an explicit permission, and one never moved.

- ***Usually* and *typically* meant "there is a condition and I did not write it down".** The two escalation rules became guards. *WHEN a caller disputes a charge twice THEN you MUST escalate* says the same thing the team lead meant, with the occasion named. Both required a decision nobody had made: *twice*, and *a second outage in one month*.

- ***Rarely* was a prohibition with an exception.* Rarely transfer a caller to a retention specialist* became *UNLESS a caller asks to cancel THEN you MUST NOT transfer*. Written that way it is obvious that *rarely* was never a frequency at all, it was a policy about who asks.

- ***Generally* was just a flinch.** Nobody actually wanted a soft cap on length. It became `MUST`, which puts the 4 back in the solver.

- ***Occasionally* genuinely meant "up to you".** That is what `MAY` is for. It stays soft on purpose, and the file stays clean, because `MAY` is an honest permission rather than an obligation nobody intends to enforce.

tg score, before vs. after - output ✓ C to B

```
before                                        after
C (66/100)                                    B (83/100)
runtime 72 · hygiene 50                       runtime 95 · hygiene 50
enforceability 28                             enforceability 94
hardness 57                                   hardness 83
directness 89                                 directness 91
consistency 100                               consistency 100
0 error, 0 warning, 0 info                    0 error, 0 warning, 0 info
```

Enforceability 28 to 94 with no rule deleted. Both files check identically clean, which is the point: the tick was never the measurement.

## §5 What the rewrite actually bought

The honest accounting, because a 28-point score jump is the least interesting thing here.

- **The next edit is proven.** Add *You MUST write at least 6 sentences in every response* to the before file and it is `0 error, 0 warning, 0 info`. Add it to the after file and it is 2 blocking `logic/numeric` errors. Same edit, same repo, two different futures.

- **Five deferred decisions got made.* Twice*, *a second outage in one month*, *unless a caller asks to cancel*. None of those numbers existed before the rewrite, and the model was picking them per conversation. This is the real cost of the adverb: not that it is vague, but that it silently delegates a policy decision to inference.

- **Nothing became stricter than intended.** The one rule that was genuinely optional stayed optional, as `MAY`. If your rewrite cannot produce at least one `MAY`, you have probably hardened something the team meant to leave open.

- **The check output did not change.** Clean before, clean after. Any process that gates on the exit code alone would have seen nothing happen, which is why the score, and specifically the enforceability facet, is the number to put in CI with `--min`.

One limit worth stating plainly. Enforceability 94 is not a claim that the agent obeys these rules. It is a claim that the rules are the kind of thing that can be checked, tested and contradicted. A rule the compiler can defend is still a rule a model can fumble, and pinning the behaviour needs a `$TEST`. What the rewrite removes is the category of failure where nobody ever wrote down what was supposed to happen.

## §6 Common questions

**Is it bad to write usually or typically in an agent system prompt?**

It is worse than it looks, because nothing warns you. A six-rule billing prompt with `usually`, `typically`, `rarely`, `generally` and `occasionally` on five of its rules checks at `0 error, 0 warning, 0 info` and builds, and the only sign of trouble is the score: C (66/100) with enforceability 28 out of 100, and a lever line telling you to write rules as MUST or NEVER with concrete bounds. A frequency adverb is not a hedge the checker frowns at. It is a quantity claim over occasions, and on its own it is perfectly well formed. What it costs you is that you never decided which occasions, so the model decides per conversation.

**Does the TypeGlish checker prove anything about usually and rarely?**

Yes, on the on-or-off axis. Frequency words form a square of opposition over occasions: `usually`, `mostly`, `generally` and `typically` claim most occasions, `sometimes` and `occasionally` claim some, `rarely` and `seldom` claim few, and `ALWAYS` and `NEVER` are the all and none corners. `Usually escalate a billing dispute` beside `Rarely escalate a billing dispute` is 2 blocking `logic/contradiction` errors reading *Frequency conflict, required on most occasions but required on few occasions*. `ALWAYS apologize` beside `Sometimes apologize` is 3 blocking errors, two `logic/quantifier-strength` and one `logic/force-subsumption`. Every corner of the square conflicts with `NEVER` for the same action.

**Why did my agent prompt stop catching a contradiction after I softened a rule?**

Because a number only enters the solver when the rule that carries it obligates. Compare two files that differ by one word. `You MUST keep every response to at most 4 sentences` beside `You MUST write at least 6 sentences in every response` is 2 blocking `logic/numeric` errors, *at most 4 sentences and at least 6 sentences can't both hold*. Change the first word to `Generally`, `Usually`, `Typically`, `Mostly` or `Rarely` and the identical pair of bounds checks at `0 error, 0 warning, 0 info`. `SHOULD` does the same thing. The bound is still readable by a person and no longer reachable by a proof.

**How do I rewrite a usually rule without making the agent rigid?**

Ask what the word was standing in for, and write that instead. `Usually` almost always means one of two things. If it means most occasions because there is an exception, the exception is a condition, so write a guarded rule: `WHEN a caller disputes a charge twice THEN you MUST escalate to a human agent`. If it means the agent may choose, say so with `MAY`, which is honest and stays clean. Rewriting six rules that way in a billing prompt moved it from C (66/100) with enforceability 28 to B (83/100) with enforceability 94, with no rule deleted and no rule made stricter than it was meant to be.

Field note

The pattern behind this one shows up everywhere once you have seen it: **a defect that is invisible to the check and visible to the score.** The before file has no finding to fix, so no diagnostic, no CI failure, no line for a reviewer to comment on. It has a number, 28, and a lever line naming the cause in one sentence. That is a different kind of feedback and it wants a different habit, which is a floor rather than a green tick: `typeglish score dax.tg --min B` exits non-zero on the before file and passes on the after. The same asymmetry runs through [a QA scorecard pasted into a prompt](https://typeglish.dev/blog/teardown-qa-scorecard), where the checker is quietest about exactly the rows that are not instructions. Silence from a checker is a statement about its reach, never a verdict on your prompt.

∿ washed up Aug 14, 2026 ∿
