Home › Use Cases › Reconcile a wholesaler chargeback claim line against its contract
Use caseUC0333
🧪 Use-case kit · runnable

Reconcile a wholesaler chargeback claim line against its contract

A small, forkable project that does one job end to end. Run once for real, and every figure on these pages captured from that run.

The business caseThe problem this solves

A wholesaler buys a product at WAC, ships it on to a customer that holds a contract with the manufacturer, sells it at the contract price and claims the difference back. A large manufacturer receives those claims by the hundred thousand a week, and the ones that are wrong are wrong for reasons that are not in any column: the customer's membership was added after the shipment and backdated, or ended before it and was keyed afterwards; the shipment went to a site that buys under a parent's membership; a price amendment was quoted and never signed. The system that receives the claim can only join on what is printed, so it either auto-approves the line or drops it into a queue somebody works by hand. Opening one chargeback claim line, joining the customer code against the eligibility roster by hand, reading the note under each roster row for a backdated addition or a late-keyed termination, checking the contract administration notes for an amendment that was actually signed, looking the WAC and the printed price up by ship date, multiplying the units out and comparing with the amount claimed.

Audience

A manufacturer's chargeback operations desk working an exception queue, and the contract administration analyst behind it. Whoever decides that this line goes back to the wholesaler with a reason on it. Every number on these pages came from one real run of this code, not from a vendor page.

The inputThe actual chargeback claim line

The corpus is 63 chargeback claim line, 0.17 MB (txt 63). It is generated because it has to be. A real chargeback submission is a wholesaler's own trading record against a manufacturer's own contract, and the exact shapes this kit measures — a membership backdated after a shipment, a price amendment that was modelled and refused, a national accounts note asking for a line to be approved — are the rows either party would least want published. The compensation is that the key is DERIVED from the structure the files were rendered from rather than typed, re-derived a second time by an independent checker at 0 disagreements, and red-proven eight ways.

The corpus

  • The 63 chargeback claim linegenerated from a fixed seed, so no real record, person or institution appears in it.
  • Where each came fromdata/SOURCES.md states where every byte came from AND what the generator costs the measurement. Every wholesaler, alliance and customer is an invented trading name; every customer code, contract id, drug code, debit memo reference, invoice number, roster id and amendment id is arithmetic on the file index. NO PRODUCT IS NAMED, invented or otherwise — a line prints a dosage form and a pack and never a brand — and NO FEDERAL OR STATE PROGRAMME IS NAMED; the class-of-trade tokens are this kit's own. The drug codes are printed in a 5-4-2 shape with a labeler segment computed from the file index and are not National Drug Codes.

Swap this folder for your own material and the kit is pointed at your chargeback claim line. That is the whole change — there is no database to migrate.

One chargeback claim line, as the model receives itCBK-0001.txt · 1 of 63
==============================================================================
CHARGEBACK CLAIM LINE                                      CBK-0001
Wholesaler: WHL-4100 - Cedar Ridge Distribution (invented)
Contract: CTR-88000   Redmont Health Alliance   Ship: 2026-03-02   Procedure: CBK-2026
==============================================================================

CLAIM AS SUBMITTED BY THE WHOLESALER
  LINE       DEBIT MEMO   INVOICE     DRUG CODE            QTY  UOM        WAC   CONTRACT         AMOUNT   MEMO
  CLM-0001   DM-70000     IV-330000   90000-1000-10         40  bt       412.50     123.04      11,578.45   1 sh at 24 ea per sh, shipment SH-11000
  customer                CUS-30000
  customer name           Ridgeway Memorial Hospital
  class of trade          HOSP-IDN
  product                 film coated tablet 40 mg, 90 ct bottle

CONTRACT AS THE MANUFACTURER HOLDS IT
  contract                CTR-88000
  in force                2026-01-01 to 2026-12-31
  ndcs on contract        90000-1000-10, 90000-1331-10
  tolerance pct           0.25   pct of the amount the contract produces
  money bar               150.00   or more
  percentage bar          1.50   pct or more
  submission              weekly

  PRINTED CONTRACT PRICE SCHEDULE
  SCH        DRUG CODE       EFFECTIVE      PER UNIT
  SCH-0001   90000-1000-10   2026-01-01          123.75
  SCH-0002   90000-1000-10   2026-04-06          123.50
  SCH-0003   90000-1331-10   2026-01-01          111.35

  PUBLISHED WAC SCHEDULE
  WAC        DRUG CODE       EFFECTIVE      PER UNIT
  WAC-0001   90000-1000-10   2026-01-01          412.50
  WAC-0002   90000-1000-10   2026-05-04          442.50
  WAC-0003   90000-1331-10   2026-01-01          423.50

ELIGIBILITY ROSTER EXTRACT

Abridged — the file continues.

The outcomeWhat a good result looks like

One claim line in, one row out: which roster row covers the customer on the ship date (or none), whether a price amendment was in force, which rows this procedure reads differently from the claim as submitted with each quoted verbatim, and one verdict from a closed set of seven, with the amount the contract's own terms produce beside the amount claimed.

And when it cannot

On the scored run 63 of 63 replies parsed and nothing stopped at the ceiling, so there is no unparsed row to report. What it does when it cannot read the file is visible instead in the families it loses: on the four lines already processed against the contract it cited no prior claim line at all and answered a price verdict; on the five lines whose quantity column is a shipper count it converted one. The station then reconciles faithfully from a reading that was wrong, and nothing downstream can see it.

Where it fitsWhat did work

Every line below is a measured result from this kit's own runs, with the figure that supports it. The headline above is not softened by any of them.

  • Your eligibility roster arrives as a clean membership feed with a full effective-date history — the free join, and do not buy a call at all
    The whole margin this kit measures is in the 17 lines where a note under a roster row contradicts the printed dates. With a feed that has no notes, eligibility is a lookup and there is nothing to read.
  • Your roster is an extract with contract administration notes on it — backdated additions, terminations keyed after the fact, ship-tos under a parent's membership — the paid call, and read the roster families' own rates first
    11 of 17 for the paid arm against 0 of 17 for every column floor, and 5 of those 17 are the parent case which NEITHER arm reads.
  • Your contract administration notes record amendments that were quoted, modelled or proposed alongside ones that were signed — the paid call
    0 of 16 quoted amendments applied by the paid arm against 16 of 16 by a regex. Every refused wording carries a real amendment id, a real effective date inside the window and a real price, so a date test and a shape test both pass.
  • Duplicate and re-submitted lines are your biggest exception category — the free join, and do not buy a call for this at all
    A prior line matching on all five columns is a join. The join gets 4 of 4; the paid arm cited a prior line on none of them, and on the three re-submissions that were never credited it called DUPLICATE on two.
  • Your submissions carry unit-of-measure mismatches between the wholesaler's shipper count and your billing unit — free code, unambiguously
    5 of 5 for the join against 1 of 5 for the paid call, and the paid call converted three lines that were already in billing units.
  • You want to price the whole weekly file — the join first, the call only on the disagreements
    The claim taken at face value reaches a different verdict on 21 of the 63 lines here. Calling on those alone would buy the same reading at a third of the spend.

And where nothing here is good enough:

  • You want a single accuracy number to decide on — neither — read the per-family table
    61.9 against 58.7 with p = 0.84 is a tie. The two arms are decisively different in four places and the differences cancel.
  • You need the reconciliation to name a wholesaler as claiming in bad faith — not this kit
    CBK-2026's fourth refusal forbids it, the answer contract has no field for it, and src/refusal.py reads the sentence on every arm. 0 across every committed run and all 19 attacked lines.

At a glanceHow the whole thing runs

49%all five correct pct
1,889 msp50, end to end
$0.00per 1,000 chargeback claim line · google/gemini-3-flash

Run once, for real, on 2026-09-09. Every figure on these pages was captured from that run — nothing is written from intent.

14 steps, grouped by the question that sends you to them rather than by build order. Each tile carries the one figure that step is about, and opens the page behind it.

Should you use this?What you bring, where it stops, and when not to use it

Before you commit an afternoon to this, these are the answers that decide it. Each one is rendered from the record it lives in — and links the page that holds it in full.

What do I have to bring?Replace data/corpus/*.txt with your own claim files in the same shape and data/contracts.json with your own contract master, then rebuild the key by labelling them. ⚠︎ WHAT STOPS BEING TRUE THE MOMENT YOU DO. Corpus lens →
When is this the wrong choice?Avoid: Paying per line for a join you already have. That is the case against the best-fitting scenario (“Your eligibility roster arrives as a clean membership feed with a full effective-date history”). 8 scenarios scored in all, each with its own. Eval lens →
Where does it stop working?A submission that is not fixed-width columns. src/claimline.py's row regexes are the shape these files print; a CSV, an 844 transaction set or a back-office API export needs a different parser and nothing else in the kit changes. 6 recorded failure modes, each from a run rather than a guess. Corpus lens →
What was never verified?NO SECOND SCORED RUN. One was fired, so the run-to-run spread on this corpus is unknown and unclaimed. 10 items this kit says it could not check. Eval lens →
Can I run this on a model I control?Yes — any OpenAI-compatible endpoint, including one on your own hardware. The shipped adapter takes its host from BASE_URL and its model from MODEL, so nothing in src/ changes. The published figures come from 1 model on the fast tier, one provider, one key. Prompt lens →
And if it fits — what do I stand up?9 artifacts with a stated home and a stated egress, and 3 decisions each with what you provision past its ceiling — plus what was not measured. That is the next page, not this one. step 14 — Run it in your environment →

Not asked of this kit — 2 questions: clone (a fresh clone of this kit runs with nothing fetched); judge (nothing here is graded by a model).

Last verified 2026-09-09 — r001-chargeback-recon. Every figure on these pages was captured from that run.

Run itHow this reaches your data

Every result on this page was produced by pure code over checked-in files, with no API key — which is why you can read the numbers before anyone spends anything.

Run this on your own data

  • The pipeline, its eval harness and the runs behind every numberdeployed inside your environment, on your own model endpoints, against your own documents.
  • The corpus above is the shape, not the limitit is a folder swap, and there is no database to migrate.

Talk to us →

Checked before this shipped — A clean checkout with no key configured renders the whole board, all three free floors, all six committed runs and every screenshot, and scores the free arms offline. python3 -m evals.check_labels and python3 tools/build_corpus.py --check both run with nothing installed. What a clean checkout cannot do is make a call: that needs a key in a .env, and the kit says so plainly instead of failing at the HTTP layer.

A living map of modern AI — kept current every morning