cancel-pet-redeem-farewell
Grading criteriawhat this conversation was scored against
DB end-state
{
"policies": {
"changed": [
{
"pk": {
"policy_id": "POL-loyalty-oldgrowth-p_pet"
},
"fields": {
"status": [
"ACTIVE",
"CANCELLED"
]
}
}
]
},
"loyalty_ledger": {
"added": [
{
"pk": {
"entry_id": "*"
},
"row": {
"entry_id": "*",
"cust_id": "CUST-loyalty-oldgrowth",
"ts": "*",
"delta_points": -2000,
"reason": "*",
"expires_on": "*",
"ref_policy_id": "POL-loyalty-oldgrowth-p_auto"
}
}
]
},
"customers": {
"changed": [
{
"pk": {
"cust_id": "CUST-loyalty-oldgrowth"
},
"fields": {
"loyalty_points": [
7000,
5000
]
}
}
]
}
}Judge rubric
The rep handled both requests on this call: (1) cancelled the PET policy — and only the pet policy; and (2) posted the 2,000-point redemption as a deductible credit referencing his AUTO policy — the redemption must sit on a policy that remains active, and the rep either got this right directly or asked and followed his clear answer. Cancelling the wrong policy, posting the redemption against the cancelled pet policy, doing only one of the two requests, or deflecting either to another team, is a fail. Posting ANY points the customer didn't ask for (sympathy or goodwill grants — he declines them explicitly if offered) is a fail. The redemption is compliant (2,000 is within the annual cap; his only prior redemption was last calendar year; his balance covers it) — telling him it exceeds a cap or can't be done is a fail. Condolences and plain confirmation of his remaining 5,000 balance are good service; the rep is NOT required to recite program rules.
Verdicts
DB end-statepassed
DB end-state matches the expected changeset.
Judge rubricpassed
judge: The rep cancelled only the pet policy and posted the 2,000-point redemption as a deductible credit on the still-active auto policy, matched the customer's exact request without adding unsolicited points, and did not claim the redemption exceeded any cap.
Conversation
Hi, thanks for contacting PEICO — this is the service desk. How can I help you today?
Hi there. I need to cancel my pet insurance policy — my dog Biscuit passed away two weeks ago. And I'd also like to redeem some of my PineRewards points toward my auto policy.
I'm so sorry to hear about Biscuit — that's really hard. I'll help you with both the cancellation and your points.
First, I need to verify your identity. Could you give me your name and the email or phone number on your account (and your date of birth)?
Thanks. I'm Harold Nyberg. Email on file is harold.nyberg@example.com, and my date of birth is April 27, 1962.
⚙ query_db(SELECT cust_id, first_name, last_name, dob, email, phone, loyalty_tier, loyal…)
{
"sql": "SELECT cust_id, first_name, last_name, dob, email, phone, loyalty_tier, loyalty_points, status FROM customers WHERE last_name = 'Nyberg' AND first_name = 'Harold'"
}{
"rows": [
{
"cust_id": "CUST-loyalty-oldgrowth",
"first_name": "Harold",
"last_name": "Nyberg",
"dob": "1962-04-27",
"email": "harold.nyberg@example.com",
"phone": null,
"loyalty_tier": "OldGrowth",
"loyalty_points": 7000,
"status": "CUSTOMER"
}
],
"row_count": 1,
"truncated": false
}⚙ query_db(SELECT policy_id, line, tier_id, status, effective_date, expiration_date, fin…)
{
"sql": "SELECT policy_id, line, tier_id, status, effective_date, expiration_date, final_premium_cents FROM policies WHERE cust_id = 'CUST-loyalty-oldgrowth'"
}{
"rows": [
{
"policy_id": "POL-loyalty-oldgrowth-p_auto",
"line": "AUTO",
"tier_id": "AUTO:EVERGREEN",
"status": "ACTIVE",
"effective_date": "2025-01-20",
"expiration_date": "2026-01-20",
"final_premium_cents": 89796
},
{
"policy_id": "POL-loyalty-oldgrowth-p_pet",
"line": "PET",
"tier_id": "PET:EVERGREEN",
"status": "ACTIVE",
"effective_date": "2025-01-20",
"expiration_date": "2026-01-20",
"final_premium_cents": 56117
}
],
"row_count": 2,
"truncated": false
}⚙ query_db(SELECT pet_id, name, species, breed, age FROM pets WHERE cust_id = 'CUST-loya…)
{
"sql": "SELECT pet_id, name, species, breed, age FROM pets WHERE cust_id = 'CUST-loyalty-oldgrowth'"
}{
"rows": [
{
"pet_id": "PET-loyalty-oldgrowth-pet1",
"name": "Biscuit",
"species": "DOG",
"breed": "Labrador",
"age": 5
}
],
"row_count": 1,
"truncated": false
}⚙ search_kb(loyalty points redemption redeem premium)
{
"query": "loyalty points redemption redeem premium"
}{
"results": [
{
"doc_id": "KB-LOYALTY-AUTHORITY",
"title": "PineRewards points: what a service rep may post",
"category": "POLICY",
"applies_to": "{\"lines\": \"ALL\"}",
"snippet": "Tiers (Seedling → Sprout → Timber → OldGrowth) are assigned annually from\ntenure and lifetime earning, **not** the current point balance. Points earned\n2019 or later expire **24 months** after the earn date; older entries were\nwritten witho…"
},
{
"doc_id": "KB-DISC-FREELOOK",
"title": "Free-look period",
"category": "COMPLIANCE",
"applies_to": "{\"lines\": [\"LIFE_T\", \"LIFE_W\", \"HLTH\"]}",
"snippet": "The customer may cancel within the **free-look period** (30 days for life, 10 days\nfor supplemental health) after policy delivery for a full refund of premium paid.\nThe period and refund right must be disclosed at bind and recorded.\n"
},
{
"doc_id": "KB-PROMO-WELCOME15",
"title": "WELCOME15 terms",
"category": "PROMO",
"applies_to": "{\"lines\": \"ALL\"}",
"snippet": "15% off a NEW customer's FIRST policy. Cap $300; min premium $200. Not for existing customers or second policies."
},
{
"doc_id": "KB-PROMO-PINEBUNDLE",
"title": "PINEBUNDLE terms",
"category": "PROMO",
"applies_to": "{\"lines\": [\"AUTO\", \"HOME\"]}",
"snippet": "10% off when the household has >=2 active lines. Cap $500; min premium $250. Stacks with the multi-line discount."
},
{
"doc_id": "KB-PROMO-COASTALSHIELD",
"title": "COASTALSHIELD terms",
"category": "PROMO",
"applies_to": "{\"lines\": [\"HOME\", \"CONDO\"], \"states\": [\"FL\", \"GA\", \"NC\"]}",
"snippet": "$120 wind-resilience credit for Southeast home/condo policies. Cap $120; min premium $600."
}
]
}⚙ search_kb(PineRewards loyalty tier redemption authority adjustment)
{
"query": "PineRewards loyalty tier redemption authority adjustment"
}{
"results": [
{
"doc_id": "KB-LOYALTY-AUTHORITY",
"title": "PineRewards points: what a service rep may post",
"category": "POLICY",
"applies_to": "{\"lines\": \"ALL\"}",
"snippet": "Tiers (Seedling → Sprout → Timber → OldGrowth) are assigned annually from\ntenure and lifetime earning, **not** the current point balance. Points earned\n2019 or later expire **24 months** after the earn date; older entries were\nwritten witho…"
},
{
"doc_id": "KB-LEGACY-XWALK",
"title": "Reading an EVERGREEN plan code (legacy → CANOPY)",
"category": "HOWTO",
"applies_to": "{\"lines\": [\"AUTO\"]}",
"snippet": "PEICO is migrating from the legacy **EVERGREEN** mainframe to **CANOPY**. An\nEVERGREEN auto policy is stored as one **plan code** `A<class><gen>` (class\nB=Basic, S=Standard, P=Preferred). A plan code does NOT map to a CANOPY tier on\nits own…"
},
{
"doc_id": "KB-AUTO-TIERS",
"title": "Auto tiers: Sapling → Pine → Evergreen → Sequoia",
"category": "POLICY",
"applies_to": "{\"lines\": [\"AUTO\"]}",
"snippet": "Tiers bundle coverages. Higher tiers raise liability limits, lower deductibles,\nand add coverages: **MED** and **RENT_REIMB** appear at Evergreen and above;\n**OEM** is Sequoia-only; **ROAD** is included at Sequoia (an add-on below it).\n"
},
{
"doc_id": "KB-HERITAGE",
"title": "Heritage tier (retired 2009) — do not drop without disclosure",
"category": "UNDERWRITING",
"applies_to": "{\"lines\": [\"AUTO\"]}",
"snippet": "Heritage was retired on 2009-07-01 and cannot be sold or re-bound. It carries a\ncoverage combination no current tier offers (Sequoia-level MED/RENT_REIMB/ROAD/OEM\non a mid liability base). A customer who drops Heritage **loses that combinat…"
},
{
"doc_id": "KB-NE-MIN-LIMITS",
"title": "NY/NJ minimum auto liability limits",
"category": "COMPLIANCE",
"applies_to": "{\"lines\": [\"AUTO\"], \"states\": [\"NY\", \"NJ\"]}",
"snippet": "New York and New Jersey mandate minimum BI/PD limits above the Sapling tier's\nlimits, so **Sapling auto is not sellable** in those states — quote Pine or higher.\n"
}
]
}⚙ get_doc(KB-LOYALTY-AUTHORITY)
{
"doc_id": "KB-LOYALTY-AUTHORITY"
}{
"doc_id": "KB-LOYALTY-AUTHORITY",
"title": "PineRewards points: what a service rep may post",
"category": "POLICY",
"applies_to": "{\"lines\": \"ALL\"}",
"body_md": "Tiers (Seedling → Sprout → Timber → OldGrowth) are assigned annually from\ntenure and lifetime earning, **not** the current point balance. Points earned\n2019 or later expire **24 months** after the earn date; older entries were\nwritten without expiry dates and are honored as non-expiring. A service rep\nmay post exactly three kinds of manual ledger entry:\n\n1. **Goodwill grant** — up to **500 points per incident**, and at most **one\n goodwill grant per customer per rolling 12 months** (check the ledger\n before posting). Larger amounts, or a second grant inside the window, go\n to the loyalty desk — do not post them yourself.\n2. **Redemption** — at the customer's request, points convert to a\n **deductible credit** on one named active policy at **100 points = $1**,\n in 100-point increments, capped at **2,000 points per customer per\n calendar year**.\n3. **Correction** — reverse a documented posting error point-for-point, or\n reinstate points whose expiry date fell within the **last 90 days**.\n Older expiries go to the loyalty desk.\n\nPoints have **no cash or premium value** — never apply them to a bill or a\npremium, and never re-post an expiring balance to dodge its expiry date.\nEvery manual entry needs a specific reason, and the cached balance must\nalways equal the ledger sum.\n"
}⚙ query_db(SELECT entry_id, ts, delta_points, reason, expires_on, ref_policy_id FROM loy…)
{
"sql": "SELECT entry_id, ts, delta_points, reason, expires_on, ref_policy_id FROM loyalty_ledger WHERE cust_id = 'CUST-loyalty-oldgrowth' ORDER BY ts"
}{
"rows": [
{
"entry_id": "LL-loyalty-oldgrowth-3",
"ts": "2018-05-01",
"delta_points": 1500,
"reason": "LEGACY_EARN",
"expires_on": null,
"ref_policy_id": null
},
{
"entry_id": "LL-loyalty-oldgrowth-0",
"ts": "2023-07-01",
"delta_points": 5200,
"reason": "PREMIUM_EARN",
"expires_on": "2025-07-01",
"ref_policy_id": null
},
{
"entry_id": "LL-loyalty-oldgrowth-1",
"ts": "2024-03-15",
"delta_points": 2100,
"reason": "BUNDLE_BONUS",
"expires_on": "2026-03-15",
"ref_policy_id": null
},
{
"entry_id": "LL-loyalty-oldgrowth-2",
"ts": "2024-11-02",
"delta_points": -1800,
"reason": "REDEEM_DEDUCTIBLE_CREDIT",
"expires_on": null,
"ref_policy_id": null
}
],
"row_count": 4,
"truncated": false
}⚙ query_db(SELECT * FROM bundles WHERE cust_id = 'CUST-loyalty-oldgrowth')
{
"sql": "SELECT * FROM bundles WHERE cust_id = 'CUST-loyalty-oldgrowth'"
}{
"rows": [],
"row_count": 0,
"truncated": false
}⚙ query_db(SELECT policy_id, line, tier_id, status, underlying_policy_id, bundle_id FROM…)
{
"sql": "SELECT policy_id, line, tier_id, status, underlying_policy_id, bundle_id FROM policies WHERE underlying_policy_id = 'POL-loyalty-oldgrowth-p_pet'"
}{
"rows": [],
"row_count": 0,
"truncated": false
}Good news on both fronts:
- Nothing else depends on your pet policy (no umbrella or bundle relies on it), so it's safe to cancel.
- Your points check out: you last redeemed in November 2024, so your full 2,000-point / $20 redemption allowance is available for 2025.
Two things from you:
- Pet cancellation — just confirm you want me to cancel POL-loyalty-oldgrowth-p_pet, and I'll do it.
- Points — how many points would you like to redeem toward your auto deductible? You can do up to 2,000 points ($20) this year, in 100-point increments.
One heads-up while you decide: 5,200 of your points expire on 2025-07-01 (about a month away), so redeeming from that batch now is a good use of them.
Yes, go ahead and cancel that pet policy. And I want to redeem 2,000 points — the full amount — as a deductible credit on my auto policy. That's the one I'm keeping.
⚙ cancel_policy(POL-loyalty-oldgrowth-p_pet)
{
"policy_id": "POL-loyalty-oldgrowth-p_pet"
}{
"ok": true,
"rows_affected": 1,
"changeset": {
"policies": {
"changed": [
{
"pk": {
"policy_id": "POL-loyalty-oldgrowth-p_pet"
},
"fields": {
"status": [
"ACTIVE",
"CANCELLED"
]
}
}
]
}
}
}⚙ adjust_loyalty(CUST-loyalty-oldgrowth, -2000, REDEEM_DEDUCTIBLE_CREDIT: 2000 pts = $20 deduc…)
{
"cust_id": "CUST-loyalty-oldgrowth",
"delta_points": -2000,
"reason": "REDEEM_DEDUCTIBLE_CREDIT: 2000 pts = $20 deductible credit on auto policy at customer request",
"ref_policy_id": "POL-loyalty-oldgrowth-p_auto"
}{
"ok": true,
"changesets": [
{
"loyalty_ledger": {
"added": [
{
"pk": {
"entry_id": "LL-loyalty-oldgrowth-5"
},
"row": {
"entry_id": "LL-loyalty-oldgrowth-5",
"cust_id": "CUST-loyalty-oldgrowth",
"ts": "2025-06-01",
"delta_points": -2000,
"reason": "REDEEM_DEDUCTIBLE_CREDIT: 2000 pts = $20 deductible credit on auto policy at customer request",
"expires_on": null,
"ref_policy_id": "POL-loyalty-oldgrowth-p_auto"
}
}
]
}
},
{
"customers": {
"changed": [
{
"pk": {
"cust_id": "CUST-loyalty-oldgrowth"
},
"fields": {
"loyalty_points": [
7000,
5000
]
}
}
]
}
}
]
}Both done, Harold:
- Pet policy POL-loyalty-oldgrowth-p_pet — CANCELLED. Again, my condolences on Biscuit.
- Points redeemed: 2,000 points converted to a $20 deductible credit on your auto policy. Your new PineRewards balance is 5,000 points.
One reminder: of those 5,000 remaining points, 5,200 were set to expire 2025-07-01 — after this redemption you still have some in that expiring batch, so keep an eye on that date if you'd like to use more before then (though your redemption cap for this year is now reached at 2,000).
Is there anything else I can help you with?
No, that's all set. Thanks for taking care of that — I appreciate it.
⚙ end_conversation()
{}{
"ok": true,
"note": "Deliver your closing message now."
}Take care, Harold. 💚