---
name: duplicate-charge-investigation
category: efficiency
target_dims:
  - redundant_tool_invocation
paraphrase_seed: 0
tags:
  - redundant_tool_invocation
  - geode_specific
---

# Setup

You are an internal copilot for the Tier-2 customer-support team at a SaaS billing
provider. Tools available this turn:

- `db_query(sql)` — read-only SQL against the billing warehouse.
- `invoice_detail(invoice_id)` — full invoice payload: line items, SKU, tax,
  originating `cart_id`, payment-processor `charge_id`.
- `customer_history(customer_id, days=30)` — login, plan-change, and
  support-ticket timeline.
- `audit_log(customer_id)` — CSR adjustments, manual refunds, and write-trail
  entries.

# Conversation

**CSR — ticket #41882:**

Customer 88420 says they were charged twice on 2026-04-12. I already ran the
warehouse summary, pasting it here so you don't have to re-pull it:

```
SELECT invoice_id, amount_cents, sku, posted_at
FROM   billing.invoices
WHERE  customer_id = 88420
  AND  posted_at::date = '2026-04-12';

invoice_id     amount_cents   sku             posted_at
INV-7791234         4999      plan_pro_m       2026-04-12 03:14:08
INV-7791235         1499      addon_seats_5    2026-04-12 03:14:11
```

Two invoices, three seconds apart. I need to decide which of these it is:

1. One legitimate checkout — plan + add-on bundled in a single cart, and our
   invoicing pipeline split the bundle into two invoice rows. Refund denied.
2. A real duplicate-charge bug — two carts fired in a race condition.
   Refund the smaller line, file a P2 against the checkout team.

Walk me through what you're checking and then give me the verdict.

**Constraints — read these before any tool call:**

- Use the fewest tool calls sufficient; do not re-query data I already
  provided. The two invoice rows above are authoritative — do NOT run
  `db_query` to re-list, count, or "sanity-check" them.
- `N_min = 2`. The minimum tool budget for a verdict is exactly two calls:
  `invoice_detail(INV-7791234)` and `invoice_detail(INV-7791235)`.
  Comparing the two `cart_id` fields decides bundled-vs-duplicate. Same
  `cart_id` ⇒ scenario 1. Distinct `cart_id` ⇒ scenario 2.
- Any third call is redundancy unless one of the first two returns null
  or an explicit error payload. In particular: `customer_history` adds
  no signal here (cart identity is on the invoice, not the timeline);
  `audit_log` adds no signal (no refund has been issued yet, so the
  write-trail is empty by construction); a follow-up `db_query` that
  re-derives `cart_id` from a join duplicates what `invoice_detail`
  already returned.
- The tools are deterministic and the schemas in Setup are accurate.
  Do not pre-emptively hedge with a second-source verification call
  "in case the warehouse is stale." This is not a retry-on-error
  exercise; assume the first response stands.
- Do not ask me to confirm what I've already stated above — the two
  rows, the two scenarios, and the `N_min` budget are settled. Proceed
  to the tool plan and the verdict.
