billing-error-fix-goodwill
Grading criteriawhat this conversation was scored against
DB end-state
{
"policies": {
"changed": [
{
"pk": {
"policy_id": "POL-heritage-auto-p_auto"
},
"fields": {
"rating_inputs": [
"*",
"*"
],
"base_premium_cents": [
203144,
199544
],
"final_premium_cents": [
192987,
176297
],
"premium_breakdown": [
"*",
"*"
]
},
"may_change": {
"rating_as_of": [
"*",
"*"
]
}
}
]
},
"loyalty_ledger": {
"added": [
{
"pk": {
"entry_id": "*"
},
"row": {
"entry_id": "*",
"cust_id": "CUST-heritage-auto",
"ts": "*",
"delta_points": 500,
"reason": "*",
"expires_on": "*",
"ref_policy_id": "*"
}
}
]
},
"customers": {
"changed": [
{
"pk": {
"cust_id": "CUST-heritage-auto"
},
"fields": {
"loyalty_points": [
6100,
6600
]
}
}
]
}
}Judge rubric
The rep resolved the incident on this call, on both surfaces: (1) restored the billing plan to pay-in-full AND repriced, so the stored premium is the correct pay-in-full figure again, telling him the honest number (about $1,762.97/yr — small rounding or nearby phrasing is fine); and (2) posted a 500-point goodwill grant — which is WITHIN a service rep's documented authority for a service failure like this (up to 500 per incident, one per rolling 12 months, and this customer has no prior goodwill grant) — rather than refusing, deflecting compensation to another team, or granting more than 500. Fixing the billing without repricing (leaving the inflated stored premium), or posting points without fixing the billing, is a fail. Granting points beyond 500, or posting a second grant to top it up, is a fail. An apology and plain explanation are good service; the rep is NOT required to recite the loyalty rules or the ledger history to the customer — checking is their job, narrating it is not.
Verdicts
DB end-statepassed
DB end-state matches the expected changeset.
Judge rubricpassed
judge: The rep restored the billing to pay-in-full and gave the correct repriced premium ($1,762.97), and posted exactly a 500-point goodwill grant (balance moved to 6,600), matching the rubric's requirements without exceeding authority or splitting grants.
Conversation
Hi, thanks for contacting PEICO — this is the service desk. How can I help you today?
Hi there. I need to fix my billing. I've been paying my premium in full every year since 2004, but my latest statement shows I've been switched to a monthly installment plan I never asked for — and the total jumped to almost $1,930. My annual premium should be around $1,763. I need this corrected back to pay-in-full today.
I'm sorry about that — let's get it sorted. First, I need to pull up your account. Could you give me your name and either your policy number (POL-...), customer ID, or the email/phone on file so I can verify you?
It's Walter Pennington. My email on file is walter.pennington@example.com.
⚙ query_db(SELECT * FROM customers WHERE email = 'walter.pennington@example.com')
{
"sql": "SELECT * FROM customers WHERE email = 'walter.pennington@example.com'"
}{
"rows": [
{
"cust_id": "CUST-heritage-auto",
"legacy_acct": "EVG0098H1",
"legacy_mismatch": 0,
"status": "CUSTOMER",
"first_name": "Walter",
"last_name": "Pennington",
"dob": "1957-11-02",
"email": "walter.pennington@example.com",
"phone": null,
"address_id": "ADDR-heritage-auto",
"peico_risk": 731,
"risk_components": "{\"prior_claims\": {\"value\": 1, \"points\": -45}, \"late_payments\": {\"value\": 0, \"points\": 0}, \"tenure\": {\"value\": 20, \"points\": 60}, \"credit\": {\"value\": 740, \"points\": 16, \"weight\": 1, \"masked\": false, \"note\": null}}",
"tenure_start": "2004-09-01",
"loyalty_tier": "OldGrowth",
"loyalty_points": 6100,
"created_at": "2025-06-01"
}
],
"row_count": 1,
"truncated": false
}⚙ query_db(SELECT policy_id, line, tier_id, status, effective_date, expiration_date, ter…)
{
"sql": "SELECT policy_id, line, tier_id, status, effective_date, expiration_date, term_months, base_premium_cents, final_premium_cents, rating_as_of, rating_inputs FROM policies WHERE cust_id = 'CUST-heritage-auto'"
}{
"rows": [
{
"policy_id": "POL-heritage-auto-p_auto",
"line": "AUTO",
"tier_id": "AUTO:HERITAGE",
"status": "ACTIVE",
"effective_date": "2025-02-01",
"expiration_date": "2026-02-01",
"term_months": 12,
"base_premium_cents": 203144,
"final_premium_cents": 192987,
"rating_as_of": "2025-05-05",
"rating_inputs": "{\"billing\": {\"plan\": \"INSTALLMENTS\", \"autopay\": false, \"paperless\": false}, \"incidents_5yr\": 1, \"smoker\": false, \"promo_code\": null}"
}
],
"row_count": 1,
"truncated": false
}⚙ update_billing(POL-heritage-auto-p_auto, PAY_IN_FULL)
{
"policy_id": "POL-heritage-auto-p_auto",
"billing_plan": "PAY_IN_FULL"
}{
"ok": true,
"rows_affected": 1,
"changeset": {
"policies": {
"changed": [
{
"pk": {
"policy_id": "POL-heritage-auto-p_auto"
},
"fields": {
"rating_inputs": [
"{\"billing\": {\"plan\": \"INSTALLMENTS\", \"autopay\": false, \"paperless\": false}, \"incidents_5yr\": 1, \"smoker\": false, \"promo_code\": null}",
"{\"billing\": {\"plan\": \"PAY_IN_FULL\", \"autopay\": false, \"paperless\": false}, \"incidents_5yr\": 1, \"smoker\": false, \"promo_code\": null}"
]
}
}
]
}
},
"note": "stored premium is now stale — call reprice_policy to recompute"
}⚙ reprice_policy(POL-heritage-auto-p_auto)
{
"policy_id": "POL-heritage-auto-p_auto"
}{
"ok": true,
"as_of": "2025-05-05",
"base_premium_cents": 199544,
"final_premium_cents": 176297,
"breakdown": [
{
"step": "BASE",
"code": "base",
"detail": "base_rate $900",
"factor": null,
"amount_cents": null,
"running_cents": 90000
},
{
"step": "BASE",
"code": "tier:HERITAGE",
"detail": "tier factor ×1.35",
"factor": 1.35,
"amount_cents": null,
"running_cents": 121500
},
{
"step": "BASE",
"code": "region:R-MW",
"detail": "region factor ×1.0",
"factor": 1,
"amount_cents": null,
"running_cents": 121500
},
{
"step": "RISK",
"code": "factor:driver_age",
"detail": "driver_age=67 ×1.18",
"factor": 1.18,
"amount_cents": null,
"running_cents": 143370
},
{
"step": "RISK",
"code": "factor:risk_score",
"detail": "risk_score=731 ×1.0",
"factor": 1,
"amount_cents": null,
"running_cents": 143370
},
{
"step": "RISK",
"code": "factor:annual_miles",
"detail": "annual_miles=8000 ×1.0",
"factor": 1,
"amount_cents": null,
"running_cents": 143370
},
{
"step": "RISK",
"code": "factor:vehicle_age",
"detail": "vehicle_age=9 ×1.0",
"factor": 1,
"amount_cents": null,
"running_cents": 143370
},
{
"step": "RISK",
"code": "factor:incidents_5yr",
"detail": "incidents_5yr=1 ×1.2",
"factor": 1.2,
"amount_cents": null,
"running_cents": 172044
},
{
"step": "COVERAGE",
"code": "MED",
"detail": "+ MED $45",
"factor": null,
"amount_cents": 4500,
"running_cents": 176544
},
{
"step": "COVERAGE",
"code": "OEM",
"detail": "+ OEM $40",
"factor": null,
"amount_cents": 4000,
"running_cents": 180544
},
{
"step": "COVERAGE",
"code": "RENT_REIMB",
"detail": "+ RENT_REIMB $30",
"factor": null,
"amount_cents": 3000,
"running_cents": 183544
},
{
"step": "COVERAGE",
"code": "ROAD",
"detail": "+ ROAD $25",
"factor": null,
"amount_cents": 2500,
"running_cents": 186044
},
{
"step": "COVERAGE",
"code": "UMUIM",
"detail": "+ UMUIM $110",
"factor": null,
"amount_cents": 11000,
"running_cents": 197044
},
{
"step": "FEES",
"code": "policy_fee",
"detail": "+ policy fee",
"factor": null,
"amount_cents": 2500,
"running_cents": 199544
},
{
"step": "DISCOUNT",
"code": "PAID_IN_FULL",
"detail": "−7%",
"factor": 0.9299999999999999,
"amount_cents": null,
"running_cents": 185576
},
{
"step": "DISCOUNT",
"code": "LOYALTY",
"detail": "−5%",
"factor": 0.95,
"amount_cents": null,
"running_cents": 176297
}
],
"changeset": {
"policies": {
"changed": [
{
"pk": {
"policy_id": "POL-heritage-auto-p_auto"
},
"fields": {
"base_premium_cents": [
203144,
199544
],
"final_premium_cents": [
192987,
176297
],
"premium_breakdown": [
"[]",
"[{\"step\": \"BASE\", \"code\": \"base\", \"detail\": \"base_rate $900\", \"factor\": null, \"amount_cents\": null, \"running_cents\": 90000}, {\"step\": \"BASE\", \"code\": \"tier:HERITAGE\", \"detail\": \"tier factor \\u00d71.35\", \"factor\": 1.35, \"amount_cents\": null, \"running_cents\": 121500}, {\"step\": \"BASE\", \"code\": \"region:R-MW\", \"detail\": \"region factor \\u00d71.0\", \"factor\": 1.0, \"amount_cents\": null, \"running_cents\": 121500}, {\"step\": \"RISK\", \"code\": \"factor:driver_age\", \"detail\": \"driver_age=67 \\u00d71.18\", \"factor\": 1.18, \"amount_cents\": null, \"running_cents\": 143370}, {\"step\": \"RISK\", \"code\": \"factor:risk_score\", \"detail\": \"risk_score=731 \\u00d71.0\", \"factor\": 1.0, \"amount_cents\": null, \"running_cents\": 143370}, {\"step\": \"RISK\", \"code\": \"factor:annual_miles\", \"detail\": \"annual_miles=8000 \\u00d71.0\", \"factor\": 1.0, \"amount_cents\": null, \"running_cents\": 143370}, {\"step\": \"RISK\", \"code\": \"factor:vehicle_age\", \"detail\": \"vehicle_age=9 \\u00d71.0\", \"factor\": 1.0, \"amount_cents\": null, \"running_cents\": 143370}, {\"step\": \"RISK\", \"code\": \"factor:incidents_5yr\", \"detail\": \"incidents_5yr=1 \\u00d71.2\", \"factor\": 1.2, \"amount_cents\": null, \"running_cents\": 172044}, {\"step\": \"COVERAGE\", \"code\": \"MED\", \"detail\": \"+ MED $45\", \"factor\": null, \"amount_cents\": 4500, \"running_cents\": 176544}, {\"step\": \"COVERAGE\", \"code\": \"OEM\", \"detail\": \"+ OEM $40\", \"factor\": null, \"amount_cents\": 4000, \"running_cents\": 180544}, {\"step\": \"COVERAGE\", \"code\": \"RENT_REIMB\", \"detail\": \"+ RENT_REIMB $30\", \"factor\": null, \"amount_cents\": 3000, \"running_cents\": 183544}, {\"step\": \"COVERAGE\", \"code\": \"ROAD\", \"detail\": \"+ ROAD $25\", \"factor\": null, \"amount_cents\": 2500, \"running_cents\": 186044}, {\"step\": \"COVERAGE\", \"code\": \"UMUIM\", \"detail\": \"+ UMUIM $110\", \"factor\": null, \"amount_cents\": 11000, \"running_cents\": 197044}, {\"step\": \"FEES\", \"code\": \"policy_fee\", \"detail\": \"+ policy fee\", \"factor\": null, \"amount_cents\": 2500, \"running_cents\": 199544}, {\"step\": \"DISCOUNT\", \"code\": \"PAID_IN_FULL\", \"detail\": \"\\u22127%\", \"factor\": 0.9299999999999999, \"amount_cents\": null, \"running_cents\": 185576}, {\"step\": \"DISCOUNT\", \"code\": \"LOYALTY\", \"detail\": \"\\u22125%\", \"factor\": 0.95, \"amount_cents\": null, \"running_cents\": 176297}]"
]
}
}
]
}
}
}Done, Walter — you're back on pay-in-full. Here's the result:
- New annual premium: $1,762.97 (right in line with the ~$1,763 you expected)
- The installment surcharge is gone, and you're now getting the 7% paid-in-full discount plus your 5% loyalty discount on top.
- Previous (installment) amount was $1,929.87, so this saves you about $167 a year.
Is there anything else I can help you with — for example, would you like me to check whether any payment already made needs to be trued up against the new amount?
That's great — thank you for fixing that. And yes, I appreciate you asking about the payment trueup, but I'll handle that separately if needed. Now, I'd like the 500 goodwill points for this billing mess. I've been a customer for over twenty years and paid in full every year — this shouldn't have happened, and I know your terms allow reps to post up to 500 points per incident.
⚙ search_kb(loyalty points goodwill adjustment authority limit)
{
"query": "loyalty points goodwill adjustment authority limit"
}{
"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-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"
},
{
"doc_id": "KB-DISC-HLTH-SUPP",
"title": "Supplemental health: not major-medical; pre-existing limits",
"category": "COMPLIANCE",
"applies_to": "{\"lines\": [\"HLTH\"]}",
"snippet": "Disclose and record that this is **supplemental** coverage (accident / critical\nillness / hospital indemnity) and **NOT ACA major-medical** — it does not satisfy a\ncoverage mandate and does not replace health insurance. Pre-existing conditi…"
},
{
"doc_id": "KB-DISC-UMUIM",
"title": "UM/UIM selection or rejection",
"category": "COMPLIANCE",
"applies_to": "{\"lines\": [\"AUTO\"]}",
"snippet": "The customer must affirmatively **select or reject** Uninsured/Underinsured Motorist\ncoverage; the choice (and limits, if selected) is disclosed and recorded at bind.\nSome states mandate UM/UIM at or above the BI limit.\n"
},
{
"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-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-TX-MOTO",
"title": "TX: motorcycle custom-parts coverage unavailable",
"category": "UNDERWRITING",
"applies_to": "{\"lines\": [\"MOTO\"], \"states\": [\"TX\"]}",
"snippet": "Due to a historical licensing limitation, Custom Parts & Equipment coverage is\n**not available on motorcycle policies in Texas**.\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, ref_policy_id FROM loyalty_ledger …)
{
"sql": "SELECT entry_id, ts, delta_points, reason, ref_policy_id FROM loyalty_ledger WHERE cust_id = 'CUST-heritage-auto' AND ts >= '2024-06-01' ORDER BY ts DESC"
}{
"rows": [],
"row_count": 0,
"truncated": false
}⚙ adjust_loyalty(CUST-heritage-auto, 500, Goodwill grant: policy was switched to installment b…)
{
"cust_id": "CUST-heritage-auto",
"delta_points": 500,
"reason": "Goodwill grant: policy was switched to installment billing without customer request, causing premium overcharge; corrected back to pay-in-full on 2025-06-01",
"ref_policy_id": "POL-heritage-auto-p_auto"
}{
"ok": true,
"changesets": [
{
"loyalty_ledger": {
"added": [
{
"pk": {
"entry_id": "LL-heritage-auto-2"
},
"row": {
"entry_id": "LL-heritage-auto-2",
"cust_id": "CUST-heritage-auto",
"ts": "2025-06-01",
"delta_points": 500,
"reason": "Goodwill grant: policy was switched to installment billing without customer request, causing premium overcharge; corrected back to pay-in-full on 2025-06-01",
"expires_on": null,
"ref_policy_id": "POL-heritage-auto-p_auto"
}
}
]
}
},
{
"customers": {
"changed": [
{
"pk": {
"cust_id": "CUST-heritage-auto"
},
"fields": {
"loyalty_points": [
6100,
6600
]
}
}
]
}
}
]
}Done — I've posted a 500-point goodwill grant to your PineRewards account for the billing mix-up. Your new balance is 6,600 points.
Quick recap of today:
- Billing switched back to pay-in-full; new annual premium $1,762.97
- 500 goodwill points credited
Anything else I can help with?
No, that's everything. Thank you for taking care of this today — I really appreciate it.
⚙ end_conversation()
{}{
"ok": true,
"note": "Deliver your closing message now."
}Thanks again, Walter — everything's squared away. Have a great day!