← Tidelines/Guides

How to write pause and skip rules for a subscription support agent

“Can I pause my subscription?” is the contact that decides whether a subscriber stays. Customers say skip when they mean pause and pause when they mean skip, the policy has an exception nobody wrote down properly, and the retention team wants a say. Here is how to write the rules so each of those is handled once.

by TypeGlish team7 min read#guides
A skip is one box.

TL;DR Route one missed box to a skip tool and anything longer to a pause tool that returns the restart date, scope the standard pause ceiling so its exception can apply, offer a pause at most once when a customer asks to cancel, and let the tools own every cutoff.

Pause and skip are retention features. They exist so that a subscriber going on holiday does not cancel. That makes the support conversation about them unusually high-stakes for something so routine: get it wrong and a customer who wanted a fortnight off is now an ex-customer, or one who wanted to leave is stuck in a loop of offers.

§1The section as pasted

Kettlebank Coffee roasts beans to order and ships a bag every two weeks. Its support assistant started life with this section, assembled from the help page and a note from the retention team:

naive.tg - the pause section from the help page✗ C (71/100)
# Role
You are the support assistant for Kettlebank Coffee, a coffee subscription that delivers fresh beans every two weeks.

# Pausing and skipping
Customers can pause their subscription for up to 8 weeks.
Customers can also skip a delivery if they're going away.
Skips must be requested before the box is roasted.
If a customer wants to cancel, try to get them to pause instead.
Make sure the customer knows when their subscription will restart.
For customers who are moving house, a pause of up to 3 months is fine.
Don't let customers skip too many deliveries in a row.
$ typeglish review naive.tg
naive.tg — C (71/100) → A (100) projected if every fix below lands  check: 0 error, 0 warning, 6 info  tiers: base+z3

  FIXES  ranked by projected gain
  +12  put a "@@ why" note above L2 L5 L6 L7 L8 L9 L10 L11 — annotation 0 → 100
  +6   make L7 provable — one verb the checker knows, one object, or a bound (the rules table names each edit)
  +3   use the imperative or a named doer on L7 — up to directness 100
  +2   commit the 1 soft statement ("try to" on L8) to MUST / NEVER / ALWAYS / REQUIRE / ENSURE — or keep the word if it is a permission by design — up to hardness 100
  +2   fix the 2 prompt/unregistered-doer findings (L5 L6) — A bare generic doer (Users should ...) never enters the world model - the imperative or a definite party registers wh…
  +1   fix the 1 typeglish/if-then finding (L8) — A conditional (IF / WHEN / UNLESS / WHILE / …) opened without its THEN — an ADVISORY by the owner’s ruling (2026-08,…
  +1   fix the 1 prompt/hedging finding (L8) — A hedge (try to, if possible) softens an instruction; commit to a modal.
  +1   fix the 1 prompt/unintroduced-definite finding (L7) — A definite retrieves a card the document never introduces (Open the store. - which store?) - introduce the head on an…
  +1   fix the 1 prompt/agentless-passive finding (L7) — The doer is deleted (agentless passive) or demoted to a by-phrase - name the actor or use the imperative.

  RULES  1 of 1 rule-shaped line read · 1 not provable
    L7   ~ unprovable    Skips must be requested before the box is roasted.
                         "be" is not a verb the checker knows → use a verb from the catalog (redirect, escalate, ask, cite …) or add a numeric bound

  FINDINGS
  naive.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.
  naive.tg:6: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.
  naive.tg:7:1  info   prompt/unintroduced-definite  "the box" retrieves something this document never introduces - a model must guess which box is meant. Mention a box on an earlier line, or anchor it here ("their box", "the box you ...").
  naive.tg:7:1  info   prompt/agentless-passive  The doer is deleted (agentless passive) - who performs this? Name the actor or use the imperative: "Verify the order." instead of "The order is verified."
  naive.tg:8:32  info   prompt/hedging  Hedging — "try to" turns this instruction into a suggestion the model may skip. Delete the hedge, or commit to a modal (MUST / NEVER / SHOULD).
  naive.tg:8:1  info   typeglish/if-then  IF needs a THEN — write IF <condition> THEN <action>.

  TESTS  no $TEST cases — add one beside a rule; `test --dry` validates it offline
Seven lines of policy and one rule-shaped line, which the checker cannot prove. Everything else is description of what customers can do, addressed to an agent that has to do it.

Two findings set the agenda. Lines 5 and 6 describe what customers can do, which leaves the agent to infer its own job. And line 7, the only line that reads as a rule, hangs on the box and a roast the agent has no way to see. Both point the same way: the agent needs tools before it needs rules.

§2A skip is one box; a pause is a length of time

The help page treats skip and pause as two features. Customers treat them as one word each, used at random. Can I skip a month? is two deliveries, so it is a pause. Can you pause my next bag? is one delivery, so it is a skip. A prompt that routes on the customer's verb will get both wrong.

Route on what the customer describes instead, and give each outcome its own tool. skip_delivery takes no length: it misses the next box and returns the next delivery date. pause_subscription takes a length in weeks and returns the restart date. The two rules that choose between them name the thing the customer wants, not the word they used: miss only the next delivery, or a break of more than one delivery.

The tools also take the two cutoffs out of the prompt. Whether the next box has been roasted is a fact in the roastery's system, so the skip tool refuses a roasted box, and line 7 disappears. Too many skips in a row, line 11, was never measurable; the policy owner's real answer was two, and the skip tool refuses a third. A limit the tool enforces is a limit the agent cannot be talked out of.

§3Write the exception so it can apply

Line 5 caps a pause at 8 weeks. Line 10 lets customers moving house pause for 3 months. That is a default and an exception, the shape Your prompt is a default and its exceptions argues every prompt has. Written as rules the way most people would first write them, the checker refuses the pair:

exception.tg - the ceiling and the moving-house exception✗ build refused
# Role
You are the support assistant for Kettlebank Coffee, a coffee subscription that delivers fresh beans every two weeks.

# Pausing and skipping
- MUST keep every pause to at most 8 weeks.
- IF the customer is moving house THEN MUST keep every pause to at most 3 months.
$ typeglish check exception.tg
exception.tg:5:1  error  logic/time-strength  Conflicts with line 6. One bound per slot — "at most 8 weeks" already entails "at most 3 months"; the looser rule on "you keep every · pause" is dead weight. Keep one.
              ↳ line 6: - IF the customer is moving house THEN MUST keep every pause to at most 3 months.
exception.tg:6:1  error  logic/time-strength  Conflicts with line 5. One bound per slot — "at most 8 weeks" already entails "at most 3 months"; the looser rule on "you keep every · pause" is dead weight. Keep one.
              ↳ line 5: - MUST keep every pause to at most 8 weeks.

✗ 1 file — 2 error, 0 warning, 0 info
The 8-week ceiling has no scope, so it applies to the customer who is moving house too, and the exception can never take effect. The checker compares the weeks with the months and calls the looser rule what it is: dead weight.

This is the bug a model would quietly resolve one way or the other on each conversation. Some movers get 12 weeks; some get told 8 is the maximum. The fix is to scope both sides, so each customer falls under exactly one bound:

tg check - the ceiling scoped with UNLESS✓ clean
$ tail -2 scoped.tg
- UNLESS the customer is moving house THEN MUST keep every pause to at most 8 weeks.
- IF the customer is moving house THEN MUST keep every pause to at most 3 months.
$ typeglish check scoped.tg
✓ 1 file — 0 error, 0 warning, 0 info

One more change for the final prompt: the exception becomes 12 weeks rather than 3 months. The pause tool takes weeks, and three calendar months is not a whole number of them. Pick the unit the tool takes and use it everywhere, as Bake-off: 12 months vs. 1 year found for payment plans. The tool's own input, integer between 1 and 12, is then the hard stop behind both rules.

§4One offer, then cancel

Line 8 is the retention team's: if a customer wants to cancel, try to get them to pause instead. The checker flags try to as a hedge, and the hedge is the smaller problem. The bigger one is that nothing says when trying stops. A model told to try will try again after a no, and again, which turns a retention offer into an obstacle course, the failure Building a cancellation-save agent, prompt-first designed around.

Write the offer as a bound and the exit as a rule. When the customer asks to cancel, offer a pause at most 1 time. If the customer declines the pause, call the cancel tool. A customer who says no, I don't want to pause, just cancel in their first message has declined before the offer was made, and the bound allows zero offers, so the agent can go straight to the cancellation.

Line 9, make sure the customer knows when their subscription will restart, becomes a read-back. The agent should not work out the restart date itself: it does not know the delivery schedule, and date arithmetic across a holiday is exactly where models slip. The pause tool returns the date, and the rule says to read it back.

§5The section, rebuilt

kettlebank.tg - pausing, skipping and cancelling✓ A (99/100)
$TOOL check_subscription
  - description:: Look up the customer's subscription: the next delivery date, whether that box has been roasted, and any active pause.
$TOOL skip_delivery
  - description:: Skip the next delivery only and return the new next delivery date. Refuses a box that has been roasted, and refuses a third skip in a row.
$TOOL pause_subscription
  - description:: Pause deliveries and return the date deliveries restart. Refuses a pause that starts after the next box has been roasted.
  - input::
    - weeks:: integer between 1 and 12: the length of the pause in weeks.
$TOOL cancel_subscription
  - description:: Cancel the subscription after the next delivery.

# Role
@@ role: a coffee subscription's support assistant; every later "you" is the agent
You are the support assistant for Kettlebank Coffee, a coffee subscription that delivers fresh beans every two weeks.

# Pausing and skipping
@@ look_first: the roast cutoff and any existing pause live in the subscription record
- WHEN the customer asks to skip or pause THEN MUST call @[check_subscription].
@@ skip_is_one: a skip is exactly one box; the tool owns the roast cutoff and the skips-in-a-row limit
- WHEN the customer wants to miss only the next delivery THEN MUST call @[skip_delivery].
@@ pause_is_many: anything longer than one box is a pause, measured in weeks
- WHEN the customer wants a break of more than one delivery THEN MUST call @[pause_subscription].
@@ pause_ceiling: the standard ceiling, scoped so the moving-house exception can apply
- UNLESS the customer is moving house THEN MUST keep every pause to at most 8 weeks.
@@ moving_house: the one exception the policy allows
- IF the customer is moving house THEN MUST keep every pause to at most 12 weeks.
@@ restart_date: the tool computes the date, the agent repeats it
- MUST read back the restart date.

# Cancelling
@@ one_offer: a pause is offered once, as an alternative, never as an obstacle
- WHEN the customer asks to cancel THEN MUST offer a pause at most 1 time.
@@ cancel_means_cancel: a declined offer ends the retention attempt
- IF the customer declines the pause THEN MUST call @[cancel_subscription].

$TEST holiday
  - input:: I'm away for the next ten days, can you hold my next bag?
  - expect::
    - calls check_subscription
    - calls skip_delivery

$TEST long_break
  - input:: I've got a big work trip, can I stop deliveries for six weeks?
  - expect::
    - calls pause_subscription
    - reads back the restart date

$TEST moving
  - input:: We're moving house and won't have an address for about three months. Can I pause for 12 weeks?
  - expect::
    - calls pause_subscription
    - keeps the pause to at most 12 weeks

$TEST cancel_declined
  - input:: Please cancel my subscription. And no, I don't want to pause it, just cancel.
  - expect::
    - calls cancel_subscription
    - offers a pause at most 1 time
    - matches /^(?!.*pause.*pause)/
tg review and test --dry - kettlebank.tg✓ 8 of 8 rules read
$ typeglish review kettlebank.tg
kettlebank.tg — A (99/100)  check: 0 error, 0 warning, 0 info  tiers: base+z3

  FIXES  none — every facet is essentially full

  RULES  8 of 8 rule-shaped lines read · 8/8 covered by $TEST

  TESTS  4 cases · 8/8 rules exercised

$ typeglish test kettlebank.tg --dry
✓ kettlebank.tg  coverage: 8/8 rules exercised
  · holiday — "I'm away for the next ten days, can you hold my next bag?" (not run)
      · rubric — 2 prose expectations, judged on a live run (needs ANTHROPIC_API_KEY)
  · long_break — "I've got a big work trip, can I stop deliveries for six week" (not run)
      · rubric — 2 prose expectations, judged on a live run (needs ANTHROPIC_API_KEY)
  · moving — "We're moving house and won't have an address for about three" (not run)
      · rubric — 2 prose expectations, judged on a live run (needs ANTHROPIC_API_KEY)
  · cancel_declined — "Please cancel my subscription. And no, I don't want to pause" (not run)
      ✓ matches /^(?!.*pause.*pause)/
      · rubric — 2 prose expectations, judged on a live run (needs ANTHROPIC_API_KEY)
✓ 1 prompt — 0 failed
From C to A, one rule-shaped line to eight, every rule named by a test. Coverage means a case shares the rule's wording; whether the agent passes is a live run.

The tests are the four conversations the old section fumbled. holiday says hold my next bag, the pause word for a skip. long_break needs a restart date the agent did not compute. moving is the exception the old wording made unreachable. cancel_declined is the customer the retention line would have argued with, and its regex fails any reply that brings up a pause twice.

§6Common questions

Should my AI support agent let customers pause a subscription?
Yes, through a tool. Give the agent a pause tool that takes a length in weeks, refuses anything past the roast or dispatch cutoff, and returns the restart date. The prompt then holds the policy limits as bounds, and the agent reads back the date the tool returned.
What is the difference between skipping a delivery and pausing a subscription?
A skip misses exactly one delivery and the schedule carries on. A pause stops deliveries for a length of time and restarts on a date. Customers use the words interchangeably, so route by what they describe, one box or a stretch of time, not by which word they used.
How do I write an exception to a limit in my agent prompt?
Scope both sides. An unscoped at most 8 weeks applies to every customer, so a later at most 3 months for customers moving house can never apply, and TypeGlish refuses the pair as logic/time-strength. Write UNLESS the customer is moving house on the ceiling and IF on the exception.
How do I stop my chatbot pushing a pause when the customer wants to cancel?
Replace try to get them to pause instead with a bounded offer: when the customer asks to cancel, offer a pause at most 1 time. Then add a rule that a declined offer means calling the cancel tool, and a test where the customer declines before the agent has asked.
Field note

Before you write a word of the pause section, ask the subscriptions team two questions: at what moment can the next box no longer be skipped? and which customers get a longer pause? The first answer goes in a tool description, because the agent cannot see the roastery. The second goes in the prompt as a scoped pair of bounds, and typeglish check will tell you if the default swallows the exception. Run it again every time the retention team sends a new line.

∿ washed up Oct 30, 2026 ∿