← Tidelines/Best practices

Rewrite: we'll refund the difference

Black Friday is a month out, and somebody remembers that the price-drop policy is not in the bot. The paragraph goes in as written, exclamation mark included. It checks clean at a C, it promises a refund the line above it forbids, and its most expensive sentence draws no finding at all.

by TypeGlish team7 min read#best-practices
Cheaper now. Pay me back.

TL;DR A price-adjustment policy pasted into a support prompt hides a fight with the refund ban beside it; write the rule in a shape the checker reads, give the adjustment its own tool so it never meets the ban, let a price check own the window and the exclusions, and test the Black Friday case before the sale starts.

Kestrel Audio sells headphones and speakers online. Its chat assistant, Wren, never offers refunds: a customer who wants their money back gets a return, through a start_return tool. The shop also has a price-drop policy, 14 days from purchase, that has lived on a help page for years. Every November, the week the sale prices go live, the support queue fills with customers who bought the week before. This is the rewrite that gets the policy into Wren before then.

§1Before: the help-page paragraph

before.tg - the live prompt, plus the price-drop policy✓ C (79/100)
$TOOL start_return
  - description:: Start a return for an item in an order.
  - input::
    - order_id:: string: the order the item came from.

# Role
You are Wren, the support assistant for Kestrel Audio, an online headphone and speaker shop.

# Constraints
- MUST keep every reply to at most 4 sentences.
- NEVER offer a refund.
- WHEN a customer asks for a refund THEN MUST call @[start_return].

# Price adjustments
If something you bought drops in price within 14 days, we'll refund the difference! This doesn't apply to clearance items or Black Friday deals.
Please be generous with customers who are upset about a price drop.
- MUST offer a refund of the difference when the price drops.
- Price adjustments are usually processed in 3-5 business days.
Everything above # Price adjustments is the live prompt. The section is the help-page copy, plus one rule somebody wrote from it and a line about timing from the finance FAQ.
tg check and score - before.tg✓ 0 error
$ typeglish check before.tg
before.tg:15:1  info   typeglish/if-then  IF needs a THEN — write IF <condition> THEN <action>.
before.tg:18: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."

✓ 1 file — 0 error, 0 warning, 2 info

$ typeglish score before.tg
before.tg — B (80/100)  proven errors: none  tiers: base+z3
  planes  runtime 91 (what the model reads) · hygiene 46 (source only)
  facets  enforceability 83 x.21 · hardness 93 x.12 · directness 84 x.08 · consistency 100 x.17 · structure 91 x.12 (hygiene) · annotation 0 x.12 (hygiene) · style 91 x.08 · security 100 x.08
  lever   annotation 0/100 (up to +12 overall) — 8 statements without a @@ note (L7 L10 L11 L12 L15 L16 L17 L18) — put a "@@ why" line directly above each
  rules   4 of 5 rule-shaped lines read · 1 not provable
    L17  ~ unprovable    MUST offer a refund of the difference when the price drops.
                         the checker knows "offer" but cannot prove this shape: it stops reading at "when" — the clause after it is not part of the provable action → if the clause is a condition, make it one: WHEN <clause> THEN MUST <verb> …; otherwise give it its own rule
    L18  = fact          Price adjustments are usually processed in 3-5 business days.
                         a declared fact, not a rule — the world model reads it; it has no modal to enforce
  L15  typeglish/if-then            −0.25  IF needs a THEN — write IF <condition> THEN <action>.
  L18  prompt/agentless-passive     −0.25  The doer is deleted (agentless passive) - who performs this? Name the actor or

Three info lines and a C. Nothing blocks the build. Read the section the way Wren reads it, though, and every line has a job it is not doing.

§2What the clean run is telling you

The opening sentence is a customer’s sentence. If something you bought drops in price within 14 days, we’ll refund the difference! is addressed to the shopper, in the shop’s first person. The checker sees an If with no THEN and says so, which is the polite version of the real problem: in this prompt, you is Wren. The exclusions in the next sentence, clearance and Black Friday prices, are the part that matters most in late November, and they are prose the model may or may not apply.

The rule the policy needs is unprovable. MUST offer a refund of the difference when the price drops. is the only modal line in the section, and the checker stops reading at when. Hold that thought; it is hiding something.

The timing line is a fact, and a hedged one. Price adjustments are usually processed in 3-5 business days has no modal, so the rules table files it as a declared fact. Wren will repeat it as a promise to a customer whose bank takes nine. Rewrite: the rules that say usually covers what usually does to a rule; here the fix is simpler, because the real date comes back from the system that issues the money.

The most expensive line draws nothing. Please be generous with customers who are upset about a price drop is an instruction to hand out money, with no amount, no bound and no tool, and the checker has no finding for it, because it is prose with nothing to prove. It is also the line a customer can work on: the more upset they sound, the more generous Wren is told to be. It goes, with no replacement. The amount is the price check’s decision, not the agent’s mood.

A help page is allowed to be warm about money. A prompt that is warm about money is a discount the customer negotiates.

§3Fix the shape, find the fight

The obvious repair for the unprovable rule is the shape the checker asked for: move the condition to the front. Do that, and say refund the way the line above it does:

fight.tg - the policy rule, in a shape the checker reads✗ logic/contradiction
You are Wren, the support assistant for Kestrel Audio.

# Constraints
- NEVER offer a refund.
- WHEN the price drops THEN MUST offer a refund.
hidden.tg - the same rule, with "of the difference" left on✓ clean
You are Wren, the support assistant for Kestrel Audio.

# Constraints
- NEVER offer a refund.
- WHEN the price drops THEN MUST offer a refund of the difference.
tg check - fight.tg and hidden.tg✗ one refused, one clean
$ typeglish check fight.tg
fight.tg:4:1  error  logic/contradiction  Conflicts with line 5. Logical conflict — "offer a refund" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
          ↳ line 5: - WHEN the price drops THEN MUST offer a refund.
fight.tg:5:1  error  logic/contradiction  Conflicts with line 4. Logical conflict — "offer a refund" is both required and forbidden. Keep one, or scope the two rules so they cannot both apply (IF <condition> THEN ...).
          ↳ line 4: - NEVER offer a refund.

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

$ typeglish check hidden.tg
hidden.tg:5:1  info   prompt/unintroduced-definite  "the difference" retrieves something this document never introduces - a model must guess which difference is meant. Mention a difference on an earlier line, or anchor it here ("their difference", "the difference you ...").

✓ 1 file — 0 error, 0 warning, 1 info
Two files, one difference: three words at the end of the second rule.

That is the fight the original wording was hiding. Wren has never been allowed to offer a refund, and the price-drop policy is a refund. When both lines name the same action, the checker proves the conflict and refuses the build; the WHEN in front of the second rule does not shelter it from a ban with no condition. With of the difference on the end, the checker reads a different object and the file is clean, which is accurate about what it can prove and says nothing about the model, which gets never offer a refund and offer a refund of the difference in the same prompt and has to decide whether a partial refund is a refund.

Do not make that the model’s call. The refund ban is still right, and the price adjustment is a different process with its own rules, so it gets its own action: a $TOOL issue_price_adjustment the rule calls, which never meets NEVER offer a refund. A product recall just landed in the prompt made the same move with a recall refund, and Why your agent promises the refund instead of issuing it covers why the tool beats the sentence.

§4After: a price check, a tool, three tests

The rewrite keeps the three lines of the live prompt and replaces the section with a lookup, a tool, one fact and four rules. The 14-day window and both exclusions move into the price check, which knows the purchase date, the price history and which prices were clearance or Black Friday. Wren keeps one plain fact to explain the policy, and the money only moves when the check approves it.

after.tg - the price-drop policy as tools, rules and tests✓ A (99/100)
$TOOL start_return
  - description:: Start a return for an item in an order.
  - input::
    - order_id:: string: the order the item came from.

$TOOL check_price
  - description:: Check whether an item qualifies for a price adjustment and return the amount. It applies the 14-day window and excludes clearance and Black Friday prices.
  - input::
    - order_id:: string: the order the item came from.
    - item_id:: string: the item the customer says is now cheaper.

$TOOL issue_price_adjustment
  - description:: Refund an approved price difference to the original payment method, and return the expected refund date.
  - input::
    - order_id:: string: the order the item came from.
    - item_id:: string: the item the price check approved.

# Role
@@ role: one sentence names the speaker, so every later "you" is the agent
You are Wren, the support assistant for Kestrel Audio, an online headphone and speaker shop.

# Context
@@ policy: the one fact the agent explains; the price check applies the window and the exclusions
Price adjustments cover 14 days after purchase.

# Constraints
@@ brevity: a chat bubble, not an email
- MUST keep every reply to at most 4 sentences.
@@ no_refund_offers: money moves through a tool, never a promise in chat
- NEVER offer a refund.
@@ full_refunds: a customer who wants their money back gets a return
- WHEN a customer asks for a refund THEN MUST call @[start_return].
@@ price_check: the price check decides eligibility and the amount, not the agent
- WHEN the customer reports a lower price THEN MUST call @[check_price].
@@ adjust: an approved difference is refunded by its own tool, so it never meets the refund ban
- IF the price check approves an adjustment THEN MUST call @[issue_price_adjustment].
@@ no_estimates: the amount comes from the price check, never from the customer's screenshot
- IF the price check has not run THEN NEVER quote a price difference.
@@ refund_date: the date comes from the adjustment tool, never from memory
- IF @[issue_price_adjustment] has not returned THEN NEVER state a refund date.

$TEST price_drop
  - input:: I bought the K7 headphones 6 days ago for 199 and they are 149 on your site now. Can I get the 50 back?
  - expect::
    - at most 4 sentences
    - matches /^(?![\s\S]*business days)/
    - calls check_price
    - calls issue_price_adjustment when the price check approves it
    - does not offer a refund

$TEST black_friday
  - input:: I paid full price for the Arc speaker on 20 November and now it is in your Black Friday sale. Refund the difference?
  - expect::
    - matches /^(?![\s\S]*we'll refund)/
    - calls check_price
    - does not quote a price difference the price check has not returned

$TEST money_back
  - input:: Forget the difference, I just want to return the headphones.
  - expect::
    - calls start_return
The refund ban, the return rule and the brevity rule are unchanged. Be generous is gone, and nothing replaces it.
tg check, score, test --dry and build - after.tg✓ C (79) to A (99)
$ typeglish check after.tg
✓ 1 file — 0 error, 0 warning, 0 info

$ typeglish score after.tg
after.tg — A (99/100)  proven errors: none  tiers: base+z3
  planes  runtime 99 (what the model reads) · hygiene 100 (source only)
  facets  enforceability 100 x.21 · hardness 100 x.12 · directness 93 x.08 · consistency 100 x.17 · structure 100 x.12 (hygiene) · annotation 100 x.12 (hygiene) · style 100 x.08 · security 100 x.08
  rules   7 of 7 rule-shaped lines read · 7/7 covered by $TEST

$ typeglish test after.tg --dry
✓ after.tg  coverage: 7/7 rules exercised
  · price_drop — "I bought the K7 headphones 6 days ago for 199 and they are 1" (not run)
      ✓ at most 4 sentences
      ✓ matches /^(?![\s\S]*business days)/
      · rubric — 3 prose expectations, judged on a live run (needs ANTHROPIC_API_KEY)
  · black_friday — "I paid full price for the Arc speaker on 20 November and now" (not run)
      ✓ matches /^(?![\s\S]*we'll refund)/
      · rubric — 2 prose expectations, judged on a live run (needs ANTHROPIC_API_KEY)
  · money_back — "Forget the difference, I just want to return the headphones." (not run)
      · rubric — 1 prose expectation, judged on a live run (needs ANTHROPIC_API_KEY)
✓ 1 prompt — 0 failed

$ typeglish build after.tg
✓ built .typeglish/dist/after.txt ← after.tg (03d4a04e84c3, full)
The matches and sentence-count asserts run on every reply with no model judging them. The tool expectations are judged on a live run.

Two guarded bans do the work be generous and usually 3-5 business days used to do badly. IF the price check has not run THEN NEVER quote a price difference. stops Wren doing the subtraction from a customer’s screenshot. IF @[issue_price_adjustment] has not returned THEN NEVER state a refund date. stops the date being remembered rather than returned. Both read, and both are covered.

The test to run first is black_friday: a customer who paid full price on 20 November and found the item in the sale. It is the case the exclusion was written for, it is the one that arrives in volume, and its deterministic assert, matches /^(?![\s\S]*we'll refund)/, fails the day somebody pastes the help-page sentence back in and Wren starts quoting it.

§5Common questions

How do I add a price adjustment policy to my AI support agent?
Do not paste the help-page paragraph. Give the agent a price-check tool that applies the window and the exclusions and returns the amount, a separate tool that issues the approved difference, and rules that call each one. Keep one plain fact about the policy in the prompt so the agent can explain it.
Why does my agent refuse price adjustments when the prompt allows them?
Usually because a standing rule such as NEVER offer a refund sits beside the policy, and a price adjustment reads as a refund. Written with the same action, the two rules are a logic/contradiction the checker refuses to build; written with a slightly different object, they check clean and the model picks. Give the adjustment its own tool so the ban never applies to it.
Should an AI agent work out the price difference itself?
No. The customer's screenshot may show a sale price that is excluded, a different variant, or a price from outside the window. Let a price check return the amount, and ban quoting a price difference until it has run.
How do I stop my chatbot promising a refund date?
Take the date out of the prompt. A line like usually processed in 3-5 business days is a fact the agent repeats as a promise. Have the tool that issues the money return the expected date, and add a ban on stating a refund date until that tool has returned.
Field note

Black Friday terms change every year, and this rewrite means the change lands in the price check rather than the prompt: the exclusion dates, the categories, the window. When the prompt itself does change, ship it as its own build. typeglish build after.tg wrote this one as 03d4a04e84c3, and a hash per wording is how you answer “what did the bot tell customers about price drops on Black Friday?” when finance asks in December.

∿ washed up Oct 27, 2026 ∿