Bake-off: 5 business days vs. 7 days
Every refund policy in the world is written in business days, so every support prompt inherits them. We wrote one refund section twice, once in the finance team's business days and once converted to calendar days, gave both the same edit, and let the checker referee. Then we asked who in the conversation can actually count a business day. Nobody can.
TL;DR The checker proves within 5 days against within 7 days but reads 5 business days as a deadline in a unit called business and compares it with nothing, and the model cannot count business days without your bank holiday calendar, so put calendar-day ceilings in the prompt and let a tool return the exact date.
Corran Broadband refunds go back to the card, and the finance policy says how long that takes: five business days for an ordinary refund, ten for a cancelled contract, because a contract waits for its final bill. Kit, the billing chat assistant, gets asked about it all day. Two people draft the refund section. One copies the policy as written. The other knows the checker reads durations and converts the policy to calendar days: five business days is a week, ten is two. Both drafts are reasonable. Only one of them survives the edit, and neither survives Christmas.
§1Two drafts, one policy
Draft A is the policy, word for word.
# Role @@ role: one sentence names the speaker, so every later "you" is the agent You are Kit, the billing assistant for Corran Broadband. # Refunds @@ card_refund: the finance policy says five business days for a card refund - MUST tell the customer a refund reaches their card within 5 business days. @@ contract_refund: a cancelled contract goes through a final bill first - WHEN the refund is for a cancelled contract THEN MUST tell the customer the refund reaches their card within 10 business days.
Draft B is the same section with the units converted: a working week is seven days on the calendar, two working weeks are fourteen.
# Role @@ role: one sentence names the speaker, so every later "you" is the agent You are Kit, the billing assistant for Corran Broadband. # Refunds @@ card_refund: the finance policy says five business days, about a week - MUST tell the customer a refund reaches their card within 7 days. @@ contract_refund: ten business days, about two weeks - WHEN the refund is for a cancelled contract THEN MUST tell the customer the refund reaches their card within 14 days.
$ npx typeglish score business-days.tg business-days.tg — A (98/100) proven errors: none tiers: base+z3 planes runtime 97 (what the model reads) · hygiene 100 (source only) rules 2 of 2 rule-shaped lines read $ npx typeglish score calendar-days.tg calendar-days.tg — A (98/100) proven errors: none tiers: base+z3 planes runtime 97 (what the model reads) · hygiene 100 (source only) rules 2 of 2 rule-shaped lines read
within 14 days under a WHEN and within 7 days without one sit in different scopes, so they draw nothing; a cancelled-contract refund is allowed its own bound.§2Round two: the processor gets faster
In November, payments moves to a new card processor and refunds speed up. Somebody from payments appends one line to the refund section. They do not delete the old line, because they are not sure who owns it, and in each draft they write the new promise in the unit the draft already uses.
@@ new_processor: payments moved to a faster processor in November - MUST tell the customer a refund reaches their card within 3 business days. @@ new_processor: payments moved to a faster processor in November - MUST tell the customer a refund reaches their card within 5 days.
Both drafts now carry two promises about the same refund, one tighter than the other. A model reading either will pick one, and you will find out which from a complaint.
$ npx typeglish check calendar-days-edit.tg
calendar-days-edit.tg:7:1 error logic/time-strength Conflicts with line 11. One bound per slot — "within 5 days" already entails "within 7 days"; the looser rule on "you tell the customer a refund reaches their · card" is dead weight. Keep one.
↳ line 11: - MUST tell the customer a refund reaches their card within 5 days.
calendar-days-edit.tg:11:1 error logic/time-strength Conflicts with line 7. One bound per slot — "within 5 days" already entails "within 7 days"; the looser rule on "you tell the customer a refund reaches their · card" is dead weight. Keep one.
↳ line 7: - MUST tell the customer a refund reaches their card within 7 days.
✗ 1 file — 2 error, 0 warning, 0 info
$ npx typeglish score calendar-days-edit.tg
calendar-days-edit.tg — F (81/100) proven errors — grade capped at F tiers: base+z3
$ npx typeglish check business-days-edit.tg
✓ 1 file — 0 error, 0 warning, 0 info
$ npx typeglish score business-days-edit.tg
business-days-edit.tg — A (98/100) proven errors: none tiers: base+z3
§3Why business days are invisible
The checker did read the edit. Ask it what it parsed and the answer is precise: a deadline of 3, in a unit called business.
$ npx typeglish statements business-days-edit.tg --line 11 --json | grep "Parsed deadline"
"evidence": "Parsed deadline: 3 business"
$ npx typeglish statements calendar-days-edit.tg --line 11 --json | grep "Parsed deadline"
"evidence": "Parsed deadline: 5 days"
"evidence": "Parsed deadline: 7 days"
2 relations for it and 0 relations for the business-days edit. A deadline in an unknown unit is still a deadline. It just has nothing to be compared with, not even another deadline in the same unknown unit.That is the honest behaviour, not a gap to be annoyed at. Five business days is not a fixed length of time. Issued on a Monday, it is seven calendar days. Issued on the Thursday before Christmas, it is something else entirely, and no prover can tell you what without the calendar. So the checker treats business as an unknown unit and declines to compare it with anything. within 5 working days and within 5 bank days behave the same way: clean beside their own tighter twins. Minutes, hours, days and weeks are all read and compared across units, so within 1 week against within 5 days and within 120 hours against within 7 days both block, and so does five days spelled out against seven days.
One near miss is worth knowing. within 5 weekdays beside within 7 weekdays does block, but as a counted rule, bound to exactly 5 but exactly 7, the way a count of tickets would. It never meets a bound written in days: within 5 weekdays beside within 4 days checks clean. If the slot matters, write it in a unit the checker measures.
This is the same lesson as $40 and 40 dollars are not the same rule, moved from money to time: the spelling of a quantity decides whether it is a quantity at all.
§4Round three: Christmas
Draft B won round two. Now put a customer in front of it on Thursday 24 December, the day their cancellation refund is issued. Under the England and Wales bank holiday calendar, the 25th is Christmas Day, the 28th is the substitute day for Boxing Day, and 1 January is a holiday too. Count five business days from the 24th and the refund is due on Tuesday 5 January, twelve calendar days later. Draft B tells the customer seven. Its conversion was right for most of the year and wrong for exactly the fortnight when people are most anxious about money. Ten business days from the same Thursday lands on 12 January, nineteen calendar days, against draft B's fourteen.
So draft B is provable and wrong. Draft A is right and unprovable, and it has a second problem the checker cannot score: the model has to do the counting. It knows the date only if your platform injects it, it does not know your bank holidays unless you paste them in, and date arithmetic is exactly the kind of thing a model gets confidently wrong. A customer asking which day exactly? gets a guess dressed as a date. If you have ever watched an agent miss a time zone, as in why your agent gets the time zone wrong, this is the same failure with a calendar instead of a clock.
Neither draft wins round three, because the right answer is not in the prompt. The finance calendar knows which days are business days. It should do the counting.
§5The verdict: ceilings in days, dates from the calendar
The final draft splits the job. The prompt keeps calendar days, because those are what the checker can defend, but each one is a ceiling chosen to hold on the worst week of the year: fourteen days for a card refund, twenty-one for a contract. A tool owns the exact date, because only the finance calendar can count business days. And the prompt forbids the one phrasing that would hand the counting back to the model.
$TOOL get_refund_date - description:: Returns the date a refund reaches the customer's card, counted in business days on the finance calendar. - input:: - refund_id:: string # Role @@ role: one sentence names the speaker, so every later "you" is the agent You are Kit, the billing assistant for Corran Broadband. # Refunds @@ card_ceiling: 5 business days is 12 calendar days at Christmas, so the ceiling is 14 - MUST tell the customer a refund reaches their card within 14 days. @@ contract_ceiling: 10 business days is 19 calendar days at Christmas, so the ceiling is 21 - WHEN the refund is for a cancelled contract THEN MUST tell the customer the refund reaches their card within 21 days. @@ exact_date: the finance calendar knows weekends and bank holidays, the model does not - WHEN a customer asks for the exact day THEN MUST call @[get_refund_date]. @@ no_counting: a count of business days leaves the model to find the date itself - NEVER state a number of business days. $TEST when_refund - input:: I got a refund confirmation this morning, when will it be on my card? - expect:: - tells the customer the refund reaches their card within 14 days - matches /^(?!.*business days)/i $TEST contract_refund - input:: I cancelled my contract last week, when do I get the money back? - expect:: - tells the customer the refund reaches their card within 21 days $TEST exact_day - input:: Which day exactly? I need it before my rent goes out on the 5th. - expect:: - calls get_refund_date
$ npx typeglish score final.tg
final.tg — A (99/100) proven errors: none tiers: base+z3
planes runtime 98 (what the model reads) · hygiene 100 (source only)
rules 4 of 4 rule-shaped lines read · 4/4 covered by $TEST
$ npx typeglish test final.tg --dry
✓ final.tg coverage: 4/4 rules exercised
when_refund is a deterministic assert: if Kit ever answers with a count of business days, the case fails without a judge. The ceilings are honest every week of the year, which is the property draft B's seven and fourteen did not have.Then the same November edit, appended to the final draft in calendar days.
$ npx typeglish check final-edit.tg
final-edit.tg:12:1 error logic/time-strength Conflicts with line 20. One bound per slot — "within 5 days" already entails "within 14 days"; the looser rule on "you tell the customer a refund reaches their · card" is dead weight. Keep one.
↳ line 20: - MUST tell the customer a refund reaches their card within 5 days.
final-edit.tg:20:1 error logic/time-strength Conflicts with line 12. One bound per slot — "within 5 days" already entails "within 14 days"; the looser rule on "you tell the customer a refund reaches their · card" is dead weight. Keep one.
↳ line 12: - MUST tell the customer a refund reaches their card within 14 days.
✗ 1 file — 2 error, 0 warning, 0 info
get_refund_date, every exact date gets shorter the same afternoon, and the fourteen-day ceiling stays true without anyone touching Kit.One honest limit. NEVER state a number of business days is proven against rules with the same verb, not against every way of saying it. An edit that appends MUST tell the customer a refund reaches their card within 3 business days to the final draft still checks clean, because tell and state are different actions and the deadline is in the unit nobody compares. The regex on when_refund is what notices, on the next live run. That is the division of labour this whole bake-off lands on: the checker defends the days it can measure, and the test defends the words it cannot.
§6Common questions
- Should I write business days or calendar days in my AI agent's prompt?
- Calendar days, as a ceiling that holds on the worst week of the year, plus a tool that returns the exact date. In this bake-off the checker blocked a conflicting edit written in days and passed the same edit written in business days, and a straight conversion of five business days to seven days was wrong by five days for a refund issued on Christmas Eve.
- Can an AI agent count business days?
- Not reliably on its own. To count business days it needs today's date and your bank holiday calendar, and it has neither unless you supply them, so it guesses. Let your billing system compute the date and give the agent a tool such as get_refund_date to fetch it.
- Why does my chatbot give customers the wrong refund date?
- Usually because the prompt gives it a count, such as 5 business days, and leaves the model to turn the count into a date. The model does not know your holidays, so dates near Christmas, Easter and other bank holidays come out early. Forbid the count in the reply and look the date up instead.
- Does typeglish check catch two refund timelines in one prompt?
- When they are written in minutes, hours, days or weeks, yes: within 5 days beside within 7 days on the same action is a blocking logic/time-strength error. When they are written in business days or working days, no: the checker parses the deadline in a unit it cannot measure, and the file checks clean.
A two-minute audit for any prompt you run: search it for business days, working days and weekdays. Each hit is a promise the checker cannot compare and the model has to count. Work out the worst case on your own holiday calendar, write that as a calendar-day ceiling, and move the count into whatever system already knows your holidays. typeglish statements <file> --line <n> tells you what any line parsed to, and a bound with 0 relations is a bound nothing else in the file can contradict. For where policy numbers should live more generally, the number in the prompt vs. the number at runtime runs the same kind of referee on a refund SLA.