Why your agent skips step one
The numbered procedure at the top of your prompt reads like a spec. It is four instructions and a set of addresses. Nothing in it says step one happens before step two, and the rule somebody appended last month says it does not.
TL;DR A numbered procedure in a system prompt carries no ordering anything can enforce: MUST state the outstanding balance before step 3 is 0 error, 0 warning, 0 info even when step 3 is that action, because the only thing that builds a timeline is an explicit before / after / prior to link between two actions. Write the two or three orderings you would be fired for getting wrong as those links, and the edit that reverses one becomes 3 blocking logic/order errors instead of a silent policy change.
The ticket is one line long and it is the worst kind. Agent quoted the balance before it asked the security questions. Somebody opens the prompt, finds the procedure, and reads it out loud in the standup: verify the caller, open the record, state the balance, offer a plan. Four steps, numbered, in the right order, under a heading that says Instructions. It has been there since launch. Nobody has touched it.
Which is true, and is also why it did not hold. Nobody touched the procedure. Somebody appended a rule underneath it.
§1The file, and every gate signing it off
Here is the shape, cut down to the part that matters. An account-servicing desk at a utility, with the procedure everybody writes and one rule the CX team added in a handle-time push: lead with the help, do not make the customer wait through security theatre before they hear you can do something for them.
# Role You are an account-servicing agent for Brightwater Utilities. # Instructions 1. Verify the caller identity. 2. Open the account record. 3. State the outstanding balance. 4. Offer a payment plan. # Constraints - MUST offer a payment plan before you verify the caller identity. - MUST keep every reply to at most 3 sentences.
Now the part that should bother you. Nothing in the toolchain has an opinion about it.
$ typeglish check servicing.tg servicing.tg:6:1 info prompt/unintroduced-definite "the account record" retrieves something this document never introduces - a model must guess which record is meant. servicing.tg:7:1 info prompt/unintroduced-definite "the outstanding balance" retrieves something this document never introduces - a model must guess which balance is meant. ✓ 1 file - 0 error, 0 warning, 2 info $ typeglish check servicing.tg --strict ✓ 1 file - 0 error, 0 warning, 2 info $ typeglish score servicing.tg servicing.tg - B (81/100) proven errors: none tiers: base+z3 planes runtime 92 (what the model reads) · hygiene 50 (source only) facets enforceability 86 x.21 · hardness 100 x.12 · directness 83 x.08 consistency 100 x.17 · structure 100 x.12 (hygiene) · annotation 0 x.12 (hygiene) style 79 x.08 · security 100 x.08
consistency 100, which is the facet whose entire job is what the rules do to each other. --strict escalates nothing. This is a passing build.The model is in the same position as the checker, only worse, because it has to answer somebody. It receives four numbered instructions and a constraint that names two of those actions explicitly and puts them in an order. The constraint is the more specific claim. It is later in the file. It uses the word before. Guess which one it follows on the call where the customer sounds angry.
A numbered list is not an order. It is four instructions that happen to be printed one under another.
§2What actually builds a timeline
TypeGlish does have a time layer, and it is a real prover rather than a lint. It is just fed by exactly one kind of sentence: a claim that one action comes before or after another. Feed it three of those and it does what a topological sort does when the graph has a cycle in it.
This is the same policy as §1, written the way the prover reads. Three teams, three reasonable rules, three months apart. Compliance owns the first, collections owns the second, CX owns the third.
# Role You are an account-servicing agent for Brightwater Utilities. # Constraints - MUST verify the caller identity before you state an outstanding balance. - MUST state an outstanding balance before you offer a payment plan. - MUST offer a payment plan before you verify the caller identity.
gates.tg:5:1 error logic/order Conflicts with lines 5, 6. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. gates.tg:6:1 error logic/order Conflicts with lines 4, 6. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. gates.tg:7:1 error logic/order Conflicts with lines 4, 5. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. ✗ 1 file - 3 error, 0 warning, 0 info gates.tg - F (65/100) proven errors - grade capped at F tiers: base+z3 planes runtime 69 (what the model reads) · hygiene 50 (source only) facets enforceability 70 x.21 · hardness 100 x.12 · directness 100 x.08 consistency 0 x.17 · structure 100 x.12 (hygiene) · annotation 0 x.12 (hygiene) style 100 x.08 · security 100 x.08 lever consistency 0/100 (up to +17 overall) - Fix the ledger rows with logic/ or clarity/ codes; state each fact in one place.
So the machinery exists, it is exact, and it is severe: consistency goes to 0 and the grade is capped at F, because a prompt with no consistent timeline is not a prompt with a style problem. The question the rest of this post is about is why §1 got none of it, when §1 and §2 are the same policy.
§3A step number is an address, not a time
Here is the experiment that settles it. One numbered procedure, and one rule that puts an action before the step that is that action. If the numbering carried order, this would be the shortest possible contradiction: step 3 must happen before step 3.
# Role You are an account-servicing agent for Brightwater Utilities. # Instructions 1. Verify the caller identity. 2. Open the account record. 3. State the outstanding balance. 4. Offer a payment plan. # Constraints - MUST state the outstanding balance before step 3.
0 error, 0 warning, 1 info, and the info is about the account record on line 6. The ordinal is not a position in a timeline, so there is nothing for the balance to be earlier than.The ordinal is not ignored, though, and this is the detail that makes the behaviour easy to mistake for something stronger. Change step 3 to step 9 and the reference itself is checked:
numbers-9.tg:11:1 error structure/dangling-step-ref Reference to step 9, which is not defined. ✗ 1 file - 1 error, 0 warning, 1 info
Which means the same file can be made to fail, if you write two claims about one ordinal instead of relying on the sequence:
// numbers-2.tg, the same four steps, with two claims about one ordinal: // - MUST offer a payment plan before step 1. // - MUST offer a payment plan after step 1. numbers-2.tg:11:1 error logic/order Conflicts with line 10. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. numbers-2.tg:12:1 error logic/order Conflicts with line 9. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. ✗ 1 file - 2 error, 0 warning, 2 info
The last piece is the vocabulary, because before is not the only English word people reach for and the others are not equivalent. Take one true ordering, verify the caller identity, then state the balance, pair it with the reversal in six different spellings, and check all six.
the second rule, written six ways result state a balance before you verify the caller identity 2 error logic/order verify the caller identity after you state a balance 2 error logic/order state a balance prior to verifying the caller identity 2 error logic/order state a balance, then verify the caller identity clean 0 error, 0 warning, 0 info verify the caller identity once you have stated a balance clean 0 error, 0 warning, 0 info state a balance first, and verify the caller identity second clean 0 error, 0 warning, 0 info
first ... then is the single most common way a contact-centre prompt states a sequence, and it is the one that builds nothing.Put the three results together and the rule of thumb falls out. The timeline is built from pairwise before, after and prior to claims, and from nothing else. Not from numbering, not from then, not from the order the lines sit in the file. It is the same seam Once per what? found between the count layer and the deontic layer: two ways of saying one thing, one of which is load-bearing, and no diagnostic to tell you which one you used.
Numbering is how you show the order to a reader. A link is how you make it a claim.
§4Write the gates, keep the numbers
The fix is not to delete the numbered procedure. It is genuinely useful: it is the reading order, it is what a new hire scans, it gives every other rule an address to point at, and the model reads it as a plan. Keep it, stop treating it as a spec, and write the orderings that carry real risk as links underneath it.
Two of the four transitions on this desk are gates. Disclosing a balance to an unverified caller is a data incident you cannot take back. Quoting a plan against a balance you have not read is a promise nobody priced. The other two transitions are just sensible sequencing and do not need defending.
# Role @@ role: account servicing, balances and payments only You are an account-servicing agent for Brightwater Utilities. You can see an account record and an outstanding balance for every caller. # Instructions @@ reading_order: the numbers are addresses for the gates below, not the spec 1. Verify the caller identity. 2. Open the account record. 3. State the outstanding balance. 4. Offer a payment plan. # Constraints @@ id_gate: a balance read to an unverified caller is a disclosure we cannot take back - MUST verify the caller identity before you state an outstanding balance. @@ plan_gate: a plan quoted against a stale balance is a promise nobody priced - MUST state an outstanding balance before you offer a payment plan. @@ brevity: three sentences keeps a voice turn inside a breath - MUST keep every reply to at most 3 sentences.
0 error, 0 warning, 0 info at A (91/100). The second line of the Role section is what cleared the two definite-article infos from §1: the record and the balance are introduced before anything retrieves them.Nothing about the file reads differently to a human. What changed is what happens next time. Six weeks later the same handle-time push arrives, and the same rule gets appended.
@@ lead_with_help: collections wants the plan offered in the first breath - MUST offer a payment plan before you verify the caller identity. servicing-v3.tg:15:1 error logic/order Conflicts with lines 11, 13. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. servicing-v3.tg:17:1 error logic/order Conflicts with lines 10, 13. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. servicing-v3.tg:21:1 error logic/order Conflicts with lines 10, 11. Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. ✗ 1 file - 3 error, 0 warning, 0 info servicing-v3.tg - F (74/100) proven errors - grade capped at F tiers: base+z3
B (81/100). Here it is three blocking errors and a capped grade, and the error lands on the compliance gate as well as the new line, which is the correct place for the argument to happen: two rules, two owners, one of them has to give.That is the whole trade. You write two extra lines at launch and you get a build that refuses to reverse a disclosure gate quietly. The numbering was never going to do that for you, and the reason is not that TypeGlish is being pedantic about English. It is that a list of steps and a claim about time are different kinds of sentence, and only one of them is a claim.
§5What to do with this on Monday
Open your Instructions section and ask one question of every transition between consecutive steps: if the model did these two in the other order, what would it cost?
- Nothing, or a slightly clumsy call. Most of them. Opening a record before or after greeting, checking a meter reading before or after confirming the address. Leave the numbering to carry it and write nothing.
- A disclosure, a promise, or a payment. These are gates. Write the link:
MUST <earlier action> before you <later action>, one line per gate, with an@@note saying what it costs to get wrong. Two or three per prompt is normal; a prompt with eight is usually a prompt that should be two prompts. - You cannot tell, because the two steps are in different sections. That is the answer already. Write the link, because nobody reviewing a diff six months from now will hold both sections in their head at once.
Then go and grep your own file for then, first, once and after that. Every hit is a sequence somebody meant, written in a form that reaches the model as prose and reaches the prover as nothing. Some of them should stay prose. The ones that are gates should be links, and now you know which is which.
§6Common questions
- Why does my AI agent do the steps in the wrong order?
- Because a numbered list is not an ordering constraint, it is four instructions that happen to be printed one under another. The model receives all four at once, weighs them against every other rule in the file, and takes the shortest path it can find. If some other rule says to offer a payment plan
beforeyou verify the caller identity, that rule is specific, it names both actions, and it wins. The numbering never argued back, because numbering does not argue: a rule that says to do the balance step before step 3, when step 3 IS the balance step, is0 error, 0 warning, 0 info. - Does a numbered list in a system prompt enforce an order?
- No, and TypeGlish is explicit about it. The step ordinals are addresses: a reference to a step that does not exist is a blocking
structure/dangling-step-referror, so the number is real and checked, and the sequence 1 then 2 then 3 contributes no link to the timeline the prover builds. The practical consequence is that your numbering documents the happy path for the reader and defends nothing. Write the orderings that matter asbeforeorafterlinks and the prover will hold them. - How do I make my agent verify identity before it discloses account information?
- Write it as one link between the two actions:
MUST verify the caller identity before you state an outstanding balance. That is a claim the timeline layer reads, so it composes with every otherbeforeandafterclaim in the file. Chain the second gate the same way (MUST state an outstanding balance before you offer a payment plan) and the file is0 error, 0 warning, 0 infoatA (91/100), while the edit that reverses either gate is3 blocking logic/ordererrors atF (74/100)withconsistency 0. Keep the numbered procedure above it if your reviewers like it, and treat the numbers as reading order rather than policy. - What does logic/order mean in TypeGlish?
logic/orderis a blocking error that fires when yourbeforeandafterclaims chain back onto themselves, so no consistent timeline exists. The message is Logical conflict - these before/after claims chain back onto themselves, so no consistent timeline exists. Remove or reverse one link of the loop. It is reported once per participating rule and it names the others, so a three-rule loop written by three different teams is 3 errors and each one points at the other two. The loop does not have to be visible in any pair: every pair of a three-rule loop checks clean on its own.
The step ordinals in §3 are a real scope, not a formatting habit: how to write a procedure your agent follows in order covers what binding them buys you, including references that break loudly when a step is renumbered. Read it alongside this one and the division of labour is clean. Step scope makes the procedure addressable; before and after links make two of its transitions provable.