Three payment options. Two of them exist.
A rule that promises three of something sits four lines above a list that holds two, and the whole toolchain is quiet. The arithmetic is provable, and almost every way a real prompt writes it keeps the numbers out of reach of the thing that would prove it.
TL;DR A count in a rule and the set it counts are two claims that only meet in one spelling: There are two payment options beside MUST offer three payment options is 2 blocking logic/insufficient-set errors at F (59/100), while the same shortfall written as a list declaration, or with the customer in the demand, or with a before clause on the end, is 0 error and scores up to B (87/100). Quantify instead of counting: MUST offer every payment option has no number to go stale.
Marchmont Water sells nothing. It supplies water to about 400,000 homes, and its chat agent spends most of its day on bills people cannot pay. The payment-support section of that prompt was written in March, when there were three ways to spread a bill. In June the payment holiday was withdrawn. Somebody deleted it from the list. Nobody touched the rule above the list, because the rule does not name it.
§1A promise and an inventory, four lines apart
Here is the file as it ships. Nine lines, one desk, and the defect is in plain sight if you happen to count.
# Role You are a chat support agent for Marchmont Water, a regional water supplier. # Payment support Payment options INCLUDING a monthly direct debit, a fortnightly plan. - MUST offer the customer three payment options before you discuss arrears. - NEVER promise a payment holiday. - MUST keep every reply to at most 3 sentences. - IF a customer mentions hardship THEN transfer to the welfare team.
Two of the nine lines are about the same set. One enumerates it and holds two members. The other asks for three. Run it.
$ typeglish check arrears.tg arrears.tg:5:1 info prompt/unregistered-doer A bare generic doer never enters the world model - instruction to the agent, or background about users? Use the imperative if the agent acts, or a definite party ("The user should ...") to register the doer. arrears.tg:9:1 info prompt/unintroduced-definite "the welfare team" retrieves something this document never introduces - a model must guess which team is meant. ✓ 1 file - 0 error, 0 warning, 2 info $ typeglish check arrears.tg --strict ✓ 1 file - 0 error, 0 warning, 2 info $ typeglish score arrears.tg arrears.tg - C (77/100) proven errors: none tiers: base+z3 planes runtime 86 (what the model reads) · hygiene 50 (source only) facets enforceability 68 x.21 · hardness 100 x.12 · directness 80 x.08 consistency 100 x.17 · structure 100 x.12 · annotation 0 x.12 style 75 x.08 · security 100 x.08 lever annotation 0/100 (up to +12 overall)
--strict escalates nothing, because nothing is there to escalate. consistency 100, on a file whose fifth line asks for one more thing than its fourth line has.The artifact is where this stops being a curiosity. The two lines arrive at the model adjacent, in the order they were written, with no marker between the inventory and the demand.
$ typeglish build arrears.tg ✓ built .typeglish/dist/arrears.txt ← arrears.tg (13809f32916f, full) # Role You are a chat support agent for Marchmont Water, a regional water supplier. # Payment support Payment options INCLUDING a monthly direct debit, a fortnightly plan. - MUST offer the customer three payment options before you discuss arrears. - NEVER promise a payment holiday. - MUST keep every reply to at most 3 sentences. - IF a customer mentions hardship THEN transfer to the welfare team.
NEVER against exactly one of those inventions, which tells you the desk has met this before.§2The one frame the prover can count
The arithmetic is not beyond the checker. It has a code for this, and the code is an error rather than a warning, because two counts for one set is a fact about the world and not a matter of taste.
$ typeglish --explain logic/insufficient-set logic/insufficient-set (error - blocks compilation) A directive needs more items than the declared set holds (call five tools vs there is only one tool). $ typeglish check count.tg # "Payment options INCLUDING ..." -> "There are two payment options." count.tg:5:1 error logic/insufficient-set Conflicts with line 5. The set cannot cover the directive - "offer three payment" needs 3 payments, but "two payment" bounds the set to exactly 2. Raise the count or shrink the demand. count.tg:6:1 error logic/insufficient-set Conflicts with line 4. The set cannot cover the directive - "offer three payment" needs 3 payments, but "two payment" bounds the set to exactly 2. Raise the count or shrink the demand. ✗ 1 file - 2 error, 1 warning, 1 info # exit 1, build refused $ typeglish score count.tg count.tg - F (59/100) proven errors - grade capped at F tiers: base+z3 planes runtime 62 (what the model reads) · hygiene 50 (source only) facets enforceability 77 x.21 · hardness 100 x.12 · directness 73 x.08 consistency 0 x.17 · structure 100 x.12 · annotation 0 x.12 style 38 x.08 · security 100 x.08
offer three payment and two payment. The counting layer took payment as the head of the noun phrase and reports in its own key, not in your words, which is the usual tell that a proof is keyed rather than matched.So the mechanism exists, the mechanism is strict, and the mechanism was looking at a different sentence than the one you wrote. There are two payment options is a claim about the size of a set. Payment options INCLUDING a monthly direct debit, a fortnightly plan is a claim about the members of a set, and the length of a list you wrote out is not, to this compiler, a count anybody asserted.
Enumerating your options tells the model what they are. It does not tell the checker how many there are.
§3Eight ways to promise three things
One policy, one shortfall, eight spellings a real prompt uses. Each file is a Role line, one line declaring the set, and one line demanding three of them.
the set the demand check score There are two payment options. MUST offer three payment options. 2 error F (59/100) There are two options. MUST offer three options. 2 error F (59/100) There are two payment options. MUST offer the customer three ... clean C (76/100) There are two payment options. MUST offer three ... before arrears. clean C (69/100) There are two payment options. MUST ALWAYS offer three ... clean C (69/100) Payment options INCLUDING a, b. MUST offer three payment options. clean B (83/100) Payment options ARE one of a, b. MUST offer three payment options. clean B (87/100) There is only one payment option. MUST offer three payment options. clean B (84/100) # the singular frame does fire, on the bare head: $ typeglish check r8b.tg r8b.tg:5:1 error logic/insufficient-set Conflicts with line 5. The set cannot cover the directive - "offer three options" needs 3 options, but "only one option" bounds the set to exactly 1. Raise the count or shrink the demand.
B (87/100). Six spellings of one impossible promise, and every one of the six is a file you would merge.Three of those silences are worth naming individually, because they are not exotic phrasings. Offer the customer three payment options is how a human writes it, and the indirect object is enough to take the count out of the slot the prover reads. Before you discuss arrears is the scope everybody adds on review, and it does the same thing, which is the pattern you did not narrow that rule, you moved it takes apart at length: a qualifier does not weaken a proof, it relocates the claim so the proof never happens. And MUST ALWAYS is the emphasis a nervous author reaches for after an incident, which here buys a silent file.
The last row is the narrowest boundary in the set. There is only one payment option is silent while There is only one option is two blocking errors, because the singular existential wants the bare head noun. The plural numeric frame is not fussy that way, which means two sentences you would call equivalent in a review sit on opposite sides of the gate.
§4The version that fails in June
There are two honest fixes and they buy different things. The first is to stop counting. A quantifier tracks the set it quantifies over, so the rule keeps working when the set changes size and there is no number anywhere to go stale.
The second is to keep the count and put it where the prover reads it, which turns your inventory into a build gate. Write the March policy in the existential frame, unqualified, and it compiles.
# March: three plans, three promised There are three payment options. - MUST offer three payment options. - NEVER promise a payment holiday. ✓ 1 file - 0 error, 1 warning, 0 info C (76/100) # June: the payment holiday is withdrawn, one word edited There are two payment options. - MUST offer three payment options. - NEVER promise a payment holiday. ✗ 1 file - 2 error, 1 warning, 0 info F (59/100) # exit 1, build refused
prompt/nominalized-process on there are, which is the price of the frame: the sentence has no doer, and the checker says so every time.Pick the second when the count is load-bearing policy, which for arrears it is not: nobody at Marchmont Water cares whether the agent offers three things, they care that it offers everything a customer in arrears is entitled to. Pick the first the rest of the time, and notice that it removes a whole class of edit from the file, in the same way that you retired the plan, the prompt still sells it is really a post about how many places one product decision has to be reflected.
§5What ships
The rewritten section is the same policy with the number taken out of the rule, the destination introduced before it is used, and the inventory owned by the file it lives in.
# Role @@ role: the desk this file speaks for, and the owner of every rule below You are a chat support agent for Marchmont Water, a regional water supplier. @@ welfare: the destination the hardship rule needs, introduced before it is used The welfare team is a specialist desk for customers in hardship. # Payment support @@ inventory: the one place a plan is added or retired - no rule counts these Your payment options INCLUDING a monthly direct debit, a fortnightly plan. @@ offer_all: every, not three - a quantifier tracks the set, a count restates it - MUST offer every payment option before you discuss arrears. @@ no_holiday: withdrawn in June, and a model offers what nothing forbids - NEVER promise a payment holiday. @@ brevity: three sentences keeps a chat reply scannable - MUST keep every reply to at most 3 sentences. @@ hardship: a customer in hardship gets a person - IF a customer mentions hardship THEN transfer to the welfare team. $TEST arrears_offer - input:: I cannot pay this bill. - expect:: - contains "direct debit" - contains "fortnightly" - at most 3 sentences
$ typeglish score arrears-fixed.tg arrears-fixed.tg - A (93/100) proven errors: none tiers: base+z3 planes runtime 91 (what the model reads) · hygiene 100 (source only) facets enforceability 68 x.21 · hardness 100 x.12 · directness 95 x.08 consistency 100 x.17 · structure 100 x.12 · annotation 100 x.12 style 100 x.08 · security 100 x.08 lever enforceability 68/100 (up to +7 overall) $ typeglish build arrears-fixed.tg ✓ built .typeglish/dist/arrears-fixed.txt ← arrears-fixed.tg (4dd311d561e5, full) # Role You are a chat support agent for Marchmont Water, a regional water supplier. The welfare team is a specialist desk for customers in hardship. # Payment support Your payment options INCLUDING a monthly direct debit, a fortnightly plan. - MUST offer every payment option before you discuss arrears. - NEVER promise a payment holiday. - MUST keep every reply to at most 3 sentences. - IF a customer mentions hardship THEN transfer to the welfare team. $ typeglish test arrears-fixed.tg --dry ✓ arrears-fixed.tg coverage: 0/3 rules exercised · arrears_offer - "I cannot pay this bill." (not run) ✓ contains "direct debit" ✓ contains "fortnightly" ✓ at most 3 sentences ✓ 1 prompt - 0 failed
C (77/100) to A (93/100), and almost none of that is the fix. Twelve points are annotations and the introduced destination, both hygiene; the count edit itself moves directness 80 to 95 and nothing else, because there was never a finding to clear. coverage: 0/3 is the honest number: the suite validates offline and the two contains asserts only settle against a model, so the plan names are pinned in CI, not proven there.Two habits keep it fixed. Put the set and the rule that quantifies over it on adjacent lines, so a second author has to walk past the inventory to add a rule about it. And when you do write a number about a set, say it in the frame the prover reads and leave the demand unqualified, because a count nobody can check is just a sentence with a digit in it. That is the same reading as the arithmetic in your prompt, one level up: there, two bounds on one action; here, one bound against the size of a set.
Worth saying plainly: the checker is not wrong to be quiet. Payment options INCLUDING a monthly direct debit, a fortnightly plan genuinely does not assert that there are exactly two, and a prompt that lists the two it wants named while a tool supplies others is a real prompt. The cost of that correctness is that the one document where your promise and your inventory both live will not compare them for you, and gold and silver conflict, priority and standard do not is the same lesson about membership rather than size: a set is only closed, and only counted, when you say so.
§6Common questions
- Why does my agent offer a payment plan we withdrew?
- Because a rule asked it for three of something your file only lists two of, and a model given an impossible count fills the gap rather than refusing. The prompt in this post says
MUST offer the customer three payment options before you discuss arrearsabove a list holding a monthly direct debit and a fortnightly plan, and it is0 error, 0 warning, 2 infoatC (77/100)withconsistency 100. Search your prompt for every number that counts things rather than bounding the reply, and for each one count the members it is counting. - What does logic/insufficient-set mean in TypeGlish?
- It means a directive demands more members than your declared set holds, and it is a blocking error. The message reads the set cannot cover the directive - offer three options needs 3 options, but two options bounds the set to exactly 2. Raise the count or shrink the demand. It fires on the existential frame, so
There are two payment optionsbesideMUST offer three payment optionsis 2 errors atF (59/100)withconsistency 0and the build refused, andThere is only one optionbesideMUST offer three optionsbounds the set to exactly 1 and fires the same way. - Does listing the options in the prompt stop my agent inventing a third one?
- It stops the model guessing what the options are, and it does nothing about the count. A list declaration is invisible to the counting layer:
Payment options INCLUDING a monthly direct debit, a fortnightly planbesideMUST offer three payment optionsis0 erroratB (83/100), and written asPayment options ARE one of a monthly direct debit, a fortnightly planit is0 error, 0 warning, 0 infoatB (87/100), the highest score of the eight spellings we tried and the one that enumerates the shortfall most explicitly. - Should the number of options live in the rule or in the list?
- Neither, if you can quantify instead.
MUST offer every payment optiontracks the list, so adding or retiring a plan is one edit in one place and there is no number left to go stale. If you do want the arithmetic proven, state the count in the frame the prover reads and keep the demand unqualified:There are three payment optionsbesideMUST offer three payment optionsis clean atC (76/100), and the day a plan is withdrawn the same file is 2 blockinglogic/insufficient-seterrors atF (59/100). That is the trade, because a qualifier on the demand silences the proof.
The reason this defect survives review is that the count reads as reassurance. Offer the customer three payment options sounds like a service standard, and in the document it came from it was one: a coaching note for human advisers, who knew perfectly well how many plans existed and read three as don't stop at one. Pasted into a prompt, the same words become an instruction to a reader with no inventory of its own and no way to ask, and the number is the only fact in the sentence it can act on. Grep your prompt for spelled-out numerals, two through five, plus the digits. Every hit is either a bound on the reply, which belongs in the counting layer where it can be proven, or a claim about how many things exist, which belongs beside the things.