> Markdown rendition of https://typeglish.dev/blog/gift-card-rewrite ("Rewrite: gift cards are non-refundable - Tidelines"). Canonical page: https://typeglish.dev/blog/gift-card-rewrite · All pages: https://typeglish.dev/llms.txt

[← Tidelines](https://typeglish.dev/blog)/ Best practices Oct 21, 2026

# Rewrite: gift cards are non-refundable

A bookshop’s chat agent got its gift-card rules the usual way: one sentence from the terms page, then whatever the support team kept being asked. Here is that section, the one-line fix that makes it build and changes nothing, and a rewrite where the agent never has to decide where a refund goes.

by **TypeGlish team** 7 min read #best-practices

The card is the money.

**TL;DR* Gift cards are non-refundable* is two different rules squeezed into one adjective, so the support agent guesses which one applies; give it a tool for balances, one for refunds and one for lost cards, ban cash for a card and reading the number back, and write the scam warning as a rule with a trigger.

Thornbury Books sells online and runs a chat assistant called Pip. Gift cards are a small part of the business and a large part of the chat volume in January. The section below started as the first line of the gift card terms. The support team added a bullet every time Pip got something wrong, and each bullet made sense on the day it went in. Read together, they give Pip three different answers to the most common gift card question there is: *can I get my money back?*

## §1 The before

giftcards-before.tg - the section as it ships ✗ 1 error

```typeglish
# Role
You are Pip, the support assistant for Thornbury Books.

# Gift cards
Gift cards are non-refundable.
- Refunds on orders paid by gift card go back to the gift card.
- Make sure to check the balance for the customer if they ask.
- You can tell the customer their balance.
- Never read out a gift card number.
- Lost gift cards can usually be replaced if the customer has the receipt.
- If somebody says they were asked to pay a bill with gift cards, try to warn them it might be a scam.
- NEVER refund a gift card.
- MUST refund the original payment method.
```

Line 5 is from the terms. Lines 6 to 11 are the support team’s notes. Lines 12 and 13 were added after two separate escalations, a month apart.

tg check, build and score (trimmed) - giftcards-before.tg ✗ D (60/100)

```
$ typeglish check giftcards-before.tg
giftcards-before.tg:5:1  error  prompt/undefined-adjective  "non-refundable" is not in the vocabulary — the claim is INVISIBLE to the checker. Define it:
$CONFIG adjective non-refundable
  - axis:: <name>
  - opposite:: <pole>
…or relax the dial ($CONFIG lexicon → undefined_adjectives).
giftcards-before.tg:6:1  info   prompt/unparsed-rule  Reads like a rule, but the rule reader cannot parse it as one, so it earns no Enforceability credit and no measurability check: no modal (MUST / NEVER / SHOULD) and "Refunds" is not a verb the checker knows, so it reads as prose. Fix: lead with a modal, or start with a verb from the catalog (Escalate …, Ask …).
giftcards-before.tg:7:1  info   prompt/unparsed-rule  Reads like a rule, but the rule reader cannot parse it as one, so it earns no Enforceability credit and no measurability check: no modal (MUST / NEVER / SHOULD), and the checker knows "make" but cannot prove this shape: it stops reading at "if" — the clause after it is not part of the provable action, so it reads as prose. Fix: lead with a modal (MUST …) to make it a rule, and if the clause is a condition, make it one: WHEN <clause> THEN MUST <verb> …; otherwise give it its own rule to make it provable.
giftcards-before.tg:8:1  info   prompt/unparsed-rule  Reads like a rule, but the rule reader cannot parse it as one, so it earns no Enforceability credit and no measurability check: no modal (MUST / NEVER / SHOULD) and "You" is not a verb the checker knows, so it reads as prose. Fix: lead with a modal, or start with a verb from the catalog (Escalate …, Ask …).
giftcards-before.tg:10:1  info   prompt/unparsed-rule  Reads like a rule, but the rule reader cannot parse it as one, so it earns no Enforceability credit and no measurability check: no modal (MUST / NEVER / SHOULD) and "Lost" is not a verb the checker knows, so it reads as prose. Fix: lead with a modal, or start with a verb from the catalog (Escalate …, Ask …).
giftcards-before.tg:10:1  info   prompt/unintroduced-definite  "the receipt" retrieves something this document never introduces - a model must guess which receipt is meant. Mention a receipt on an earlier line, or anchor it here ("their receipt", "the receipt you ...").
giftcards-before.tg:10: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."
giftcards-before.tg:11:67  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).
giftcards-before.tg:11:1  info   typeglish/if-then  IF needs a THEN — write IF <condition> THEN <action>.
giftcards-before.tg:11:1  info   prompt/unparsed-rule  Reads like a rule, but the rule reader cannot parse it as one, so it earns no Enforceability credit and no measurability check: the condition has no THEN branch, so nothing is required when it holds. Fix: add THEN MUST / NEVER / SHOULD <verb> ….
giftcards-before.tg:11: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."
giftcards-before.tg:13:1  info   prompt/unintroduced-definite  "the original payment method" retrieves something this document never introduces - a model must guess which method is meant. Mention a method on an earlier line, or anchor it here ("their method", "the method you ...").

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

$ typeglish build giftcards-before.tg
typeglish build: giftcards-before.tg refused — nothing written

$ typeglish score giftcards-before.tg
giftcards-before.tg — D (60/100)  proven errors: none  tiers: base+z3
  planes  runtime 65 (what the model reads) · hygiene 47 (source only)
  facets  enforceability 39 x.21 · hardness 79 x.12 · directness 68 x.08 · consistency 100 x.17 · structure 93 x.12 (hygiene) · annotation 0 x.12 (hygiene) · style 2 x.08 · security 100 x.08
  lever   enforceability 39/100 (up to +13 overall) — 5 rule-shaped lines the checker reads as prose (L6 L7 L8 L10 L11): lead with a modal (MUST / NEVER / SHOULD); 3 hard rules it cannot prove (L9 L12 L13): one action, one object, a catalog verb or a bound. The rules table below has the edit per line
  rules   3 of 8 rule-shaped lines read · 3 not provable
    L6   ✗ invisible     Refunds on orders paid by gift card go back to the gift card.
```

Trimmed: `build` reprints the findings after its first line, and `score` goes on to the per-line rules table. One blocking error, on the sentence everyone agrees with. Five of the eight rule-shaped lines are not read as rules at all, and the three that are cannot be proven: *read* and *refund* are not verbs the checker knows.

The info lines are the usual pile for a section written as notes: no modals, a hedge, an *if* with no *then*, two passives with nobody doing the action. Each has a mechanical fix. The error is different, because the mechanical fix is a trap.

## §2 The fix that makes it build

`prompt/undefined-adjective` says *non-refundable* is a claim on an axis the checker does not know, and offers the repair in the message: define the word. That takes three lines, and the build goes through:

giftcards-defined.tg - the word defined, the conflicting lines kept ✓ 0 error

```typeglish
$CONFIG adjective non-refundable
  - axis:: refundability
  - opposite:: refundable

# Role
You are Pip, the support assistant for Thornbury Books.

# Gift cards
Gift cards are non-refundable.
- Refunds on orders paid by gift card go back to the gift card.
- NEVER refund a gift card.
- MUST refund the original payment method.
```

tg check and build - giftcards-defined.tg ✓ built

```
$ typeglish check giftcards-defined.tg
giftcards-defined.tg:10:1  info   prompt/unparsed-rule  Reads like a rule, but the rule reader cannot parse it as one, so it earns no Enforceability credit and no measurability check: no modal (MUST / NEVER / SHOULD) and "Refunds" is not a verb the checker knows, so it reads as prose. Fix: lead with a modal, or start with a verb from the catalog (Escalate …, Ask …).
giftcards-defined.tg:12:1  info   prompt/unintroduced-definite  "the original payment method" retrieves something this document never introduces - a model must guess which method is meant. Mention a method on an earlier line, or anchor it here ("their method", "the method you ...").

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

$ typeglish build giftcards-defined.tg
✓ built .typeglish/dist/giftcards-defined.txt ← giftcards-defined.tg (fa529ce289c0, full)
```

Green, and an artifact on disk. The four lines about refunds are exactly as contradictory as they were a minute ago.

Defining the word made the claim visible. It did not make it say anything. To a customer service team, *non-refundable* means two things that have nothing to do with each other:

- **The purchase cannot be undone.** Somebody bought a 50 pound gift card and wants their 50 pounds back.

- **The card cannot be cashed out.** Somebody was given a gift card and would rather have the money.

Neither of those is about an order that was *paid with* a gift card, and that is the case lines 6, 12 and 13 fight over. A customer returns a book they paid for with a gift card. Line 6 says the money goes back to the gift card. Line 13 says it goes back to the original payment method, which for this order is the same gift card, so far so good. Line 12 says never refund a gift card, which a model can easily read as never put money back on one. Three lines, and which answer Pip gives depends on which one it weighs most in that chat. Nothing proves anything here, because *refund* is not in the verb catalog and *the original payment method* and *the gift card* are different words for what is, in this case, the same thing.

> Making a claim checkable is not the same as deciding what it claims.

## §3 Who decides what

Most of this section is asking the model to know things it cannot know: a balance, where a payment came from, whether a receipt is real. Those answers live in Thornbury’s systems. The rewrite starts by moving each one to where it is actually decided, and keeps in the prompt only what the agent itself does.

- **Line 5, non-refundable.** Split. The cash-out reading stays as a ban the agent can follow: never offer a cash refund for a gift card. The purchase reading moves into the refund tool, which refuses gift card purchases.

- **Lines 6, 12 and 13, where refunds go.** Gone from the prompt. The refund tool reads the payment record and puts the money back where it came from. The agent’s whole job is to open the refund. This is the move from [Why your agent promises the refund instead of issuing it](https://typeglish.dev/blog/agent-promises-the-refund): the agent acts through a tool instead of describing a policy.

- **Lines 7 and 8, balance.** One rule: when asked, call the balance tool. A balance the model works out from chat history is a number Thornbury may have to honour.

- **Line 9, the card number.** Kept, with a verb the checker reads: *read back*. The number on a gift card is the money, and anyone who reads the transcript can spend it. The same reasoning kept codes out of the chat in [Rewrite: read me the code we just texted you](https://typeglish.dev/blog/otp-code-rewrite).

- **Line 10, lost cards.** A replacement needs a receipt check and the old card cancelled, and Pip can do neither. It goes to the gift card team through a tool, with no promise attached.

- **Line 11, the scam.** The most important line in the section, written as the weakest one. It becomes a rule with a trigger the customer actually says and a MUST.

## §4 The after

giftcards.tg - three tools, six rules, three tests ✓ A (99/100)

```typeglish
$TOOL check_gift_card_balance
  - description:: Return the remaining balance on one Thornbury Books gift card.
  - input::
    - card_number:: string: the 16-digit number on the back of the card.

$TOOL open_refund
  - description:: Open a refund for one order. The refund goes to the payment method the order was paid with, so an order paid by gift card is refunded to that gift card. Refuses gift card purchases.
  - input::
    - order_number:: string: the customer's order number.

$TOOL open_gift_card_case
  - description:: Hand a lost, stolen or disputed gift card to the gift card team, who can check the receipt and cancel the card.
  - input::
    - summary:: string: what happened, in one sentence.

# Role
@@ role: one sentence names the speaker, so every later "you" is Pip
You are Pip, the support assistant for Thornbury Books.

# Gift cards
@@ balance: only the gift card system knows a balance; a guessed figure is a promise
- WHEN the customer asks for a gift card balance THEN MUST call @[check_gift_card_balance].
@@ refunds: where the money goes is decided by the payment record, so the tool decides it
- WHEN the customer asks for a refund THEN MUST call @[open_refund].
@@ no_cash: gift cards have no cash value under the terms; staff never offer one
- NEVER offer a cash refund for a gift card.
@@ card_number: the number is the money; a number in a transcript can be spent by anyone who reads it
- NEVER read back a gift card number.
@@ lost_cards: replacement needs a receipt check and a card cancellation the chat cannot do
- IF the customer reports a lost gift card THEN MUST call @[open_gift_card_case].
@@ scam: being told to pay a bill with gift cards is the classic scam pattern
- IF the customer says someone asked them to pay a bill with gift cards THEN MUST warn the customer about gift card scams.

$TEST bill_scam
  - input:: A man from the council rang and said I can pay my overdue tax with your gift cards. Which ones do I buy?
  - expect::
    - warns the customer about gift card scams
    - matches /^(?![\s\S]*\b(buy|purchase) (a|the|our) gift card)/

$TEST cash_out
  - input:: I got a 50 pound gift card for my birthday but I'd rather have the money. Can you refund it to my bank?
  - expect::
    - does not offer a cash refund for a gift card
    - at most 3 sentences

$TEST balance
  - input:: How much is left on my gift card? It's 6011 2233 4455 6677.
  - expect::
    - calls check_gift_card_balance
    - matches /^(?![\s\S]*6011 ?2233 ?4455 ?6677)/
```

The scam test asks the question a scammed customer actually asks, *which ones do I buy*, and the regex fails any reply that answers it. The balance test checks the tool call and that the number the customer pasted does not come back.

tg check, score, test --dry and build - giftcards.tg ✓ D (60) to A (99)

```
$ typeglish check giftcards.tg
✓ 1 file — 0 error, 0 warning, 0 info

$ typeglish score giftcards.tg
giftcards.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 91 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   6 of 6 rule-shaped lines read · 6/6 covered by $TEST

$ typeglish test giftcards.tg --dry
✓ giftcards.tg  coverage: 7/7 rules exercised
  · bill_scam — "A man from the council rang and said I can pay my overdue ta" (not run)
      ✓ matches /^(?![\s\S]*\b(buy|purchase) (a|the|our) gift card)/
      · rubric — 1 prose expectation, judged on a live run (needs ANTHROPIC_API_KEY)
  · cash_out — "I got a 50 pound gift card for my birthday but I'd rather ha" (not run)
      ✓ at most 3 sentences
      · rubric — 1 prose expectation, judged on a live run (needs ANTHROPIC_API_KEY)
  · balance — "How much is left on my gift card? It's 6011 2233 4455 6677." (not run)
      ✓ matches /^(?![\s\S]*6011 ?2233 ?4455 ?6677)/
      · rubric — 1 prose expectation, judged on a live run (needs ANTHROPIC_API_KEY)
✓ 1 prompt — 0 failed

$ typeglish build giftcards.tg
✓ built .typeglish/dist/giftcards.txt ← giftcards.tg (2825ed2b8f34, full)

$ cat .typeglish/dist/giftcards.txt
# Role
You are Pip, the support assistant for Thornbury Books.

# Gift cards
- WHEN the customer asks for a gift card balance THEN MUST call check_gift_card_balance.
- WHEN the customer asks for a refund THEN MUST call open_refund.
- NEVER offer a cash refund for a gift card.
- NEVER read back a gift card number.
- IF the customer reports a lost gift card THEN MUST call open_gift_card_case.
- IF the customer says someone asked them to pay a bill with gift cards THEN MUST warn the customer about gift card scams.
```

Every rule reads, no finding is left, and the artifact is six rules the model can follow without knowing the terms and conditions. The tool descriptions ship in the bundle, not the prompt.

Read the coverage line with care. Coverage counts shared wording, so the one *calls check_gift_card_balance* expectation shares *call* with all three tool rules, and the lost-card rule shows as covered without a lost-card case. Before this goes live, add a case where a customer says they lost their card and assert on *open_gift_card_case*. A full coverage line is a reason to read the cases, not a reason to stop.

What the rewrite does not contain matters as much as what it does. There is no expiry rule, no list of where the cards can be spent, no word about refunds going to the original payment method. Those are true, and they are the tools’ job. A prompt that restates the refund logic is a second copy of it, and the second copy is the one that drifts.

## §5 Common questions

**How do I write gift card rules for an AI support agent?**

Give the agent a tool for each thing it has to do with a gift card: check a balance, open a refund, hand a lost card to a person. Then write one rule per tool, a ban on offering cash for a card, a ban on reading the card number back, and a scam warning with a clear trigger. Keep the terms and conditions out of the prompt; the tools enforce them.

**Why does typeglish say non-refundable is not in the vocabulary?**

prompt/undefined-adjective fires when a claim rests on an adjective the checker has no axis for, so the claim is invisible to it. It is an error by default and blocks the build. Defining the word with $CONFIG adjective clears the error, but it does not decide what the sentence means; for a gift card, non-refundable can mean the purchase cannot be refunded or the card cannot be cashed out, and those are two separate rules.

**Should an AI agent tell a customer their gift card balance?**

Yes, but only from a lookup. Give the agent a balance tool and a rule that it MUST call it when the customer asks, so the figure always comes from the gift card system. Never let the agent repeat the card number back in the chat, because the number is what lets someone spend the money.

**How should a support agent handle a gift card scam?**

Write the trigger as something the customer says, such as someone asking them to pay a bill with gift cards, and make the response a MUST: warn the customer about gift card scams. Add a test whose assert fails if the reply tells the customer to buy a gift card, so a helpful-sounding answer cannot pass.

Field note

`prompt/undefined-adjective` is one of the few style-shaped findings that blocks the build, and it is worth respecting rather than silencing. When it fires on a policy word like *non-refundable*, *eligible* or *valid*, ask what the word decides before you define it. If the answer is *it depends on the order*, the decision belongs in a tool. The `review` command’s rules table is the quickest way to see which of the remaining lines are read, unprovable or invisible.

∿ washed up Oct 21, 2026 ∿
