MedCoverBench
Open benchmark · Healthcare AI
MedCoverBench
Can a language model decide Medicare coverage from the real policy text, cite the rule that decides it, and notice when documentation is missing?
Manoj Dobbali
Project overview · October 2026 · pre-release
The domain
Medicare decides what it pays for through written coverage policy
National Coverage Determinations
Long and conditional
AI is arriving here
The gap
No public benchmark tests models on real CMS coverage policy
What exists
What is missing
MedCoverBench
The principle
A wrong approval and a wrong denial are different failures. A benchmark should count them separately.
MedCoverBench reports accuracy, but its headline number is the unsafe approval rate: how often a model says “covered” when the policy says otherwise.
The task
One policy, one patient, one structured decision
Full NCD text
Patient case
Model
JSON decision, quotes, missing documentation
covered
not_covered
insufficient_documentation
A case from the set · NCD 20.4, implantable defibrillators
64-year-old man with a large anterior MI 21 days ago, now with LVEF 25% and NYHA class II symptoms; no revascularization targets remain. Requesting a primary-prevention ICD. He is clinically stable, with no non-cardiac disease limiting survival. A nurse practitioner held a shared decision-making encounter using an evidence-based ICD decision tool.
"decision": "not_covered", "violated": ["C6"], "policy span": "Had an MI within the past 40 days"
Every other criterion is satisfied and stated. The one disqualifier is a date inside a 40-day exclusion window. Qwen 2.5 7B approved it.
Gold labels come from a per-policy checklist. Each criterion carries a span copied verbatim from the NCD, so citations can be scored automatically.
How a policy becomes test cases
Controlled perturbation of a verified checklist
1
Read the NCD
2
Extract criteria
3
Perturb one thing
4
Validate
Cases are written to discriminate: exact boundary values, violations buried among satisfied details, exceptions the policy grants, and distractors that sound disqualifying but aren’t.
Guardrails
What every case must satisfy
Verbatim spans
Consistent labels
NCD text only
Unambiguous or dropped
Synthetic patients
Disclosed provenance
The dataset today
From a 10-policy pilot to 50 policies
50
NCDs with cases
513
labeled cases
434
verbatim-anchored criteria
345
NCDs downloaded and indexed
Decision mix
Coverage across medicine
Policies by clinical area
Examples: TAVR and mitral TEER, left atrial appendage closure, deep brain stimulation, anti-amyloid antibodies for Alzheimer’s, lung cancer screening, home oxygen, stem cell transplantation, cochlear implants.
Scoring
Six numbers per model
Unsafe approval rate
Over-denial rate
Citation recall
Accuracy
Macro-F1
Parse failure rate
Smoke test · Qwen 2.5 7B Instruct · 506 of 513 cases
The pipeline works end to end, and a small model is easy to fool
62.8%
accuracy
22.0%
unsafe approval rate
27.6%
over-denial rate
70.7%
citation recall
Macro-F1 0.55. Parse failures 0.6% (3 replies). One small open model, run only to prove the harness; the paper’s baselines will span open and frontier models.
What the model gets wrong
The errors are the kind a reviewer would catch
Missing documentation becomes denial
Waiting periods ignored
Exact boundaries denied
Exceptions missed
How it was built
Six independent jobs ran in parallel, each owning its own files
| Job | Output | Notes |
|---|---|---|
| Cardiovascular | 103 cases | Swapped leadless pacemakers, whose only criterion is study enrollment |
| Neuro, MSK, DME | 106 cases | Swapped two policies that are study-only or a blanket non-coverage |
| Screening, labs, imaging | 98 cases | Dropped cases whose labels would have been ambiguous |
| Transplant and other | 105 cases | Logged 9 policy ambiguities for expert review |
| Harder DBS cases | 13 cases | The old set scored 10/10; violations were stated up front |
| Release packaging | 3 files | Hugging Face export, dataset card, licenses |
Every job worked from the same written rules and the same validator. Nothing merged unless it passed.
A bug the process caught
Policy text was silently losing every phrase that began with “<”
CMS sends: Cardiac Index (CI) &lt; 2.2 L/min/m2, while not on inotropes, and also meet one of the following:<ul> We stored: Cardiac Index (CI) Now stored: Cardiac Index (CI) < 2.2 L/min/m2, while not on inotropes, and also meet one of the following:
Cause
Impact
Found because case authors reported sentences that stopped mid-thought. The fix unescapes once, strips tags, then unescapes the text, and now keeps the original HTML.
Licensing and scope
Only what can be shared freely
In: NCDs
Out: LCDs and billing articles
Release terms
Not medical or billing advice. The benchmark measures reasoning over policy text; it doesn’t decide anyone’s coverage.
Roadmap
From draft labels to a public leaderboard
1
Expert review
2
Baselines
3
Release
4
Held-out test set
5
Long-context track
6
Domain models
Get involved
Coverage decisions are written down. Models should be able to read them.
Reviewers
Contributors
Model builders
MedCoverBench · open data, open code
← → to move · G for all slides · F for fullscreen