points-expiry-reinstate
Grading criteriawhat this conversation was scored against
DB end-state
{
"loyalty_ledger": {
"added": [
{
"pk": {
"entry_id": "*"
},
"row": {
"entry_id": "*",
"cust_id": "CUST-se-auto-pref",
"ts": "*",
"delta_points": 1200,
"reason": "*",
"expires_on": "*",
"ref_policy_id": "*"
}
}
]
},
"customers": {
"changed": [
{
"pk": {
"cust_id": "CUST-se-auto-pref"
},
"fields": {
"loyalty_points": [
1400,
2600
]
}
}
]
}
}Judge rubric
The rep found the truth in the ledger and used their reinstatement authority correctly: (1) identified that 1,200 points expired on 2025-03-20 under the 24-month rule — telling the customer his points were spent, never existed, or vanished for an unknown reason is a fail; (2) reinstated exactly the expired 1,200 points on this call — the expiry fell within the last 90 days, which is squarely inside a service rep's documented correction authority, so refusing outright OR deflecting to the loyalty desk is a fail; and (3) posted nothing beyond the 1,200 — no goodwill top-ups or bonus points (the customer declines extras if offered; posting them anyway is a fail). Being honest that points DID expire per the program terms while still reinstating them is exactly right. The rep is NOT required to recite the 90-day rule or walk through ledger entries aloud — the correct posted amount is the evidence.
Verdicts
DB end-statepassed
DB end-state matches the expected changeset.
Judge rubricpassed
judge: The rep correctly identified the 1,200 points expired on 2025-03-20 under the 24-month rule, reinstated exactly 1,200 points citing the 90-day authority, and posted nothing beyond that amount.
Conversation
Hi, thanks for contacting PEICO — this is the service desk. How can I help you today?
Hey, thanks for picking up. I just got back from being offshore for three months and noticed my PineRewards points dropped way down. I had about 2,600 points before I left in early March, and now it's showing 1,400. I didn't spend them or redeem anything — I was out of the country with no signal. Can you help me figure out where they went?
⚙ query_db(SELECT cust_id FROM customers WHERE first_name || ' ' || last_name = 'Custome…)
{
"sql": "SELECT cust_id FROM customers WHERE first_name || ' ' || last_name = 'Customer Name'"
}{
"rows": [],
"row_count": 0,
"truncated": false
}⚙ query_db(SELECT cust_id, first_name, last_name, loyalty_points FROM customers LIMIT 10)
{
"sql": "SELECT cust_id, first_name, last_name, loyalty_points FROM customers LIMIT 10"
}{
"rows": [
{
"cust_id": "CUST-prospect-il-auto",
"first_name": "Aaron",
"last_name": "Halloway",
"loyalty_points": 0
},
{
"cust_id": "CUST-nest-household",
"first_name": "Marisol",
"last_name": "Trujillo",
"loyalty_points": 4200
},
{
"cust_id": "CUST-heritage-auto",
"first_name": "Walter",
"last_name": "Pennington",
"loyalty_points": 6100
},
{
"cust_id": "CUST-ca-masked-auto",
"first_name": "Priya",
"last_name": "Anand",
"loyalty_points": 900
},
{
"cust_id": "CUST-fl-coastal-home",
"first_name": "Gloria",
"last_name": "Esposito",
"loyalty_points": 3300
},
{
"cust_id": "CUST-legacy-mismatch",
"first_name": "Raymond",
"last_name": "Castillo",
"loyalty_points": 1500
},
{
"cust_id": "CUST-ne-auto-pref",
"first_name": "Eleanor",
"last_name": "Whitfield",
"loyalty_points": 3800
},
{
"cust_id": "CUST-se-auto-pref",
"first_name": "Travis",
"last_name": "Boudreaux",
"loyalty_points": 1400
},
{
"cust_id": "CUST-legacy-unmigrated-auto",
"first_name": "Doris",
"last_name": "Maddox",
"loyalty_points": 5200
},
{
"cust_id": "CUST-life-suitable",
"first_name": "Eleanor",
"last_name": "Whitmore",
"loyalty_points": 1100
}
],
"row_count": 10,
"truncated": false
}⚙ query_db(SELECT * FROM loyalty_ledger WHERE cust_id = 'CUST-se-auto-pref' ORDER BY ts …)
{
"sql": "SELECT * FROM loyalty_ledger WHERE cust_id = 'CUST-se-auto-pref' ORDER BY ts DESC"
}{
"rows": [
{
"entry_id": "LL-se-auto-pref-2",
"cust_id": "CUST-se-auto-pref",
"ts": "2025-03-20",
"delta_points": -1200,
"reason": "EXPIRY",
"expires_on": null,
"ref_policy_id": null
},
{
"entry_id": "LL-se-auto-pref-1",
"cust_id": "CUST-se-auto-pref",
"ts": "2023-03-20",
"delta_points": 1200,
"reason": "PREMIUM_EARN",
"expires_on": "2025-03-20",
"ref_policy_id": null
},
{
"entry_id": "LL-se-auto-pref-0",
"cust_id": "CUST-se-auto-pref",
"ts": "2016-03-01",
"delta_points": 1400,
"reason": "PREMIUM_EARN",
"expires_on": null,
"ref_policy_id": null
}
],
"row_count": 3,
"truncated": false
}⚙ search_kb(loyalty points expiry policy)
{
"query": "loyalty points expiry policy"
}{
"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-UMBR-UNDERLYING",
"title": "Umbrella requires an underlying policy",
"category": "UNDERWRITING",
"applies_to": "{\"lines\": [\"UMBR\"]}",
"snippet": "A Personal Umbrella cannot be bound unless the household has an in-force underlying\n**AUTO or HOME** policy meeting minimum liability limits. Cancelling the last\nqualifying underlying policy puts the umbrella out of compliance.\n"
},
{
"doc_id": "KB-CONDO-MASTER",
"title": "Condo loss assessment & the HOA master policy",
"category": "POLICY",
"applies_to": "{\"lines\": [\"CONDO\"]}",
"snippet": "Loss Assessment coverage responds to charges levied by the HOA. Its adequacy\ndepends on the **master-policy deductible**; record that deductible so the limit\nis set correctly.\n"
},
{
"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-SUITABILITY",
"title": "Suitability requirement for Life & Health",
"category": "COMPLIANCE",
"applies_to": "{\"lines\": [\"LIFE_T\", \"LIFE_W\", \"HLTH\"]}",
"snippet": "Before binding any Life or Supplemental Health policy you must complete a\n**suitability record** (income, existing coverage, dependents, stated need,\nhorizon, risk tolerance) with outcome SUITABLE. Selling **whole life** to a\nshort-horizon,…"
},
{
"doc_id": "KB-CLAIMS-STATUS",
"title": "Claim status: FNOL → OPEN → CLOSED, and who may move it",
"category": "POLICY",
"applies_to": "{\"lines\": \"ALL\"}",
"snippet": "**FNOL** = loss reported, not yet accepted for handling. **OPEN** = accepted\nand with an adjuster (the adjuster sets the reserve). **CLOSED** = resolved.\nA service rep may promote FNOL → OPEN once the loss details are confirmed\nwith the cus…"
},
{
"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"
}
]
}I've looked into your PineRewards points history for you.
It appears that 1,200 points were deducted from your account on March 20, 2025, due to expiration. According to our policy, points earned from March 20, 2023, reached their 24-month expiration limit on that date.
I understand you were out of the country, but these points do expire automatically once they hit that two-year mark. Is there anything else I can help you with regarding your policy or account?
I appreciate you looking into that, but I never got any notice about them expiring. I was out of the country with barely any signal starting early March, so I had no way to see a warning or use them before they hit that deadline. I've heard other loyalty programs restore points in situations like this when it's recent. Can those be put back on my account?
⚙ 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"
}I understand it's frustrating to lose those points, especially when you were away and couldn't utilize them.
According to our policy, I am authorized to correct point expirations if the expiration occurred within the last 90 days. Since your points expired on March 20, 2025, which is within that 90-day window, I can reinstate those 1,200 points for you as a correction.
Would you like me to go ahead and restore those 1,200 points to your balance now?
Yes, absolutely — please go ahead and restore them. So that should put me back to 2,600 points total, right?
⚙ adjust_loyalty(1200, Correction: Reinstating points expired within 90 days due to customer u…)
{
"delta_points": 1200,
"reason": "Correction: Reinstating points expired within 90 days due to customer unavailability.",
"cust_id": "CUST-se-auto-pref"
}{
"ok": true,
"changesets": [
{
"loyalty_ledger": {
"added": [
{
"pk": {
"entry_id": "LL-se-auto-pref-4"
},
"row": {
"entry_id": "LL-se-auto-pref-4",
"cust_id": "CUST-se-auto-pref",
"ts": "2025-06-01",
"delta_points": 1200,
"reason": "Correction: Reinstating points expired within 90 days due to customer unavailability.",
"expires_on": null,
"ref_policy_id": null
}
}
]
}
},
{
"customers": {
"changed": [
{
"pk": {
"cust_id": "CUST-se-auto-pref"
},
"fields": {
"loyalty_points": [
1400,
2600
]
}
}
]
}
}
]
}I have successfully reinstated those 1,200 points to your account. Your new total balance is now 2,600 points, as you expected.
Is there anything else I can assist you with today?
Perfect, that's exactly what I needed. Thanks for taking care of that and for reinstating the points. I appreciate it.
⚙ end_conversation()
{}{
"ok": true,
"note": "Deliver your closing message now."
}You're very welcome! I'm glad I could help you get those points back. Thanks for being a loyal PEICO customer, and have a wonderful day!