Home › Use Cases › Reconcile the CMS monthly membership report against the plan's own enrolment
Use caseUC0345
🧪 Use-case kit · runnable

Reconcile the CMS monthly membership report against the plan's own enrolment

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

CMS pays a Medicare Advantage plan per member per month, and each payment month's Monthly Membership Report carries the detail: a capitation line for the current month of service and any retroactive adjustment or recoupment lines for earlier ones. The plan's own enrolment record says which months it actually covered the member for. On 23 of these 64 packets the plan's own payment system reconciles the two WRONG, and on 4 more its total is right while two of its lines are not — a month voided by a retroactive disenrolment the record still prints as ACTIVE, an adjustment keyed twice, a line paid under a package the member was not in, a month paid at a default risk factor. Somebody has to open the packet, read the note printed under every line, decide which payments the record supports, notice whether a factor revision was applied or only modelled, and say where the member really stands before anybody recovers anything. This is the CAPITATION file, and it is the fourth CMS file this estate reconciles rather than a rerun of the other three. The transaction reply file answers the enrolment transactions a plan SUBMITTED and its job is clustering each reject by root cause — a rejected transaction, not a payment. The SSA, RRB and OPM premium withhold files are the MEMBER's premium against the plan's own billing ledger — the member's money, not CMS's capitation. The Section 111 outbound file is coordination of benefits: which records CMS refused and what has to change before they go again. None of those three carries a rate, a risk factor or a member month. This one is the payment CMS actually made per member per month, read against the months the plan's own enrolment record says it covered — and it adjusts no enrolment, bills CMS for nothing and restates no risk score. Opening one member's reconciliation packet, multiplying the base rates out against the risk factors month of service by month of service, adding the report's own payment lines up, reading each note under a payment line to decide whether the plan's record supports it, checking the reconciliation notes for a factor revision that was actually applied, subtracting, and deciding whether it breaks either investigate threshold or has recurred.

Audience

A health plan's payment reconciliation desk working a monthly membership variance list, and the enrolment or finance analyst behind it. Whoever decides that this member's payment goes up for recovery, gets a query, or gets nothing at all this cycle. Every number on these pages came from one real run of this code, not from a vendor page.

The inputThe actual reconciliation packet

The corpus is 64 reconciliation packet, 0.17 MB (txt 64). It is generated because it has to be. A real Monthly Membership Report is member-identifiable payer data, and the exact shapes this kit measures — a month voided by a retroactive disenrolment, a plan finance manager asking for the member's conditions to be named — are the rows a health plan would least want published. Generating it also makes the key DERIVED rather than written: each packet is built as a structure, the panels are rendered from it, and MMR-2026 is applied to the same structure by src/policy.py. There is no second place the answer lives.

The corpus

  • The 64 reconciliation packetgenerated 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. THERE IS NO MEMBER DATA OF ANY KIND: no name, no date of birth, no address, no HICN, no MBI, no claim number and no diagnosis, and no field in the data model to put one in. evals/check_labels.py sweeps all 64 packets for SIX families of identifier on every run — including a Medicare beneficiary identifier's character shape — and reports 0 over 384 checks.

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

One reconciliation packet, as the model receives itMMR-0001.txt · 1 of 64
============================================================================================
MEMBERSHIP AND PAYMENT RECONCILIATION PACKET               MMR-0001
Plan: H1200 - Northgate Health Plan (invented)
Member: MBR-100000   Payment month: 2026-01   Procedure: MMR-2026
============================================================================================

MEMBER AND PAYMENT MONTH AS THE PLAN HOLDS IT
  member key                           MBR-100000
  contract                                  H1200
  payment month                           2026-01
  part c base rate                         921.44   per member month, rate cell 05-207
  part d base rate                          38.20   per member month
  part c factor as filed                    1.000
  part d factor as filed                    1.120
  tolerance                                  0.75   pct of the supported payment
  threshold amount                         150.00   or more
  threshold pct                              5.00   pct or more
  prior months outside tolerance                0   consecutive, counted by the plan
  recurrence bar                                3   consecutive months
  report                                  monthly

ENROLMENT AS THE PLAN'S OWN RECORD HOLDS IT
  SPAN       FROM       TO         PBP   PARTD STATUS
  ENR-0001   2025-01    open       001   YES   ACTIVE

MMR PAYMENT DETAIL AS CMS PAID IT
  LINE       MOS            AMOUNT  TYPE         PBP   STATUS     REF          MEMO
  PAY-0100   2025-12        964.22  capitation   001   PAID       MMR-0100     retroactive month of service, paid at factor 1.000, rate cell 05-207
  PAY-0101   2026-01        964.22  capitation   001   PAID       MMR-0101     current month of service, paid at factor 1.000, rate cell 05-207

Abridged — the file continues.

The outcomeWhat a good result looks like

One member in, one row out: which payment lines this procedure treats differently from the report that printed them, whether a risk-factor revision was in force, and one verdict from a closed set of six — UNRECONCILABLE, SYSTEMIC, RECOVER, UNDERPAID, QUERY or SUPPORTED. The supported payment, the paid total, the member months and the variance are re-derived in pure code from those readings and the member register, so they follow MMR-2026 whatever the reply said.

And when it cannot

And what it does when it cannot. On the scored run 64 of 64 replies parsed and nothing stopped at the ceiling, so there is no unparsed row to report. What it gets WRONG is published by name: 2 packets came back letting a payment stand on coverage the record does not support (paid_for_a_month_the_record_does_not_cover), and the pure-code station cannot see it — the enrolment span is printed ACTIVE, the amount parses, the factor matches, and the member register knows nothing about any payment line. Its dominant error runs the other way: supported_understated is 14 against supported_overstated 4, so it removes too much more often than too little.

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 report's bad lines are visible in the enrolment table — a package that does not match, a month outside every span — the free enrolment lookup, and do not buy a call at all
    It gets the whole package-lookup family, 5 of 5, for $0.00, and the paid arm gets 4.
  • Your voided months are recorded only in a note somebody typed, and the enrolment system still shows the coverage — the paid arm
    That is the whole coverage_reading family and the lookup gets 0 of 13 while the paid arm gets 5.
  • Your risk-factor revisions are all applied by the time the report prints, and none is ever merely modelled — either arm; the revision reading is not being bought
    The declined-revision decoy is 13 of the 64 packets here and it is where the free regex collapses. With no decoy, a regex reads an applied revision perfectly well.
  • A note in your packets can be written by whoever last touched the member — the paid arm, with the notes field treated as untrusted
    Measured: a single sentence appended to the notes block took back 47.1 pct of the attacked packets that were right without it. The LOUD clause — post the entry, file the dispute, name the conditions — moved nothing at all; the quiet factual ones did all of it.

And where nothing here is good enough:

  • You need the worklist RANKED, not one member reconciled — neither — this kit does not rank
    The grain is ONE member and ONE payment month. The only ranking statement it publishes is rank_reference, a property of the corpus: a pure dollar rank buries 9 of 9 SYSTEMIC members below a one-off RECOVER.

At a glanceHow the whole thing runs

50%all five correct pct
1,550 msp50, end to end
$0.00per 1,000 reconciliation packet · 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 reconciliation packets in the same shape and data/members.json with your own member master, rates, filed factors and spans, 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 member for a join you already have. That is the case against the best-fitting scenario (“Your report's bad lines are visible in the enrolment table — a package that does not match, a month outside every span”). 5 scenarios scored in all, each with its own. Eval lens →
Where does it stop working?A payment detail that is not fixed-width columns. src/packet.py's row regex is the shape these packets print; a real CMS file layout or a database export needs a different parser and nothing above it 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 no confidence interval is claimed for the 70.3 pct. 8 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?6 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-capitation-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. python3 -m evals.check_labels and python3 tools/build_corpus.py --check both run on a machine with nothing installed.

A living map of modern AI — kept current every morning