# Clinical claim evidence mapper

> Persist a citation from every clinical claim (diagnosis, prior therapy, contraindication, lab value, score, outcome, coverage criterion, guideline) asserted in a drafted appeal or letter of medical necessity back to a chart excerpt. Blocks export of any drafting skill's output when claims are unmapped — the trust gate for all pilot-ready healthcare packets.



Tags: Healthcare, Prior Authorization, Denial Appeals, Clinical Claims, Citations, Validation


## Example Prompts

- Map the claims in this appeal draft back to the chart notes I uploaded
- Check whether every factual claim in the letter of medical necessity is cited to a source document
- Show me the claim-to-source index for case 2026-0417-A before I submit
- List the unmapped claims still blocking export of this appeal packet

URL: https://rakenne.app/skills/clinical-claim-evidence-mapper/index.md

Try this skill: https://rakenne.app/a/?skill=clinical-claim-evidence-mapper



## Overview

Specialty-clinic and revenue-cycle buyers all ask the same question about an AI-drafted appeal letter or letter of medical necessity: *how do I know the model didn't make something up?* Unsupported clinical language is the single largest trust barrier in this segment. A strong packet is not just well-written — every diagnosis, ICD-10 code, dose, date, failed therapy, score, lab value, and policy excerpt it asserts must trace back to a verifiable source.

The clinical claim evidence mapper is the shared trust gate that makes that guarantee enforceable. It sits behind every drafting skill in the healthcare wedge — `letter-of-medical-necessity-builder`, `appeal-letter-builder`, `peer-to-peer-prep`, `packet-checklist-and-index-generator` — and blocks export until every clinical claim in the draft has a verbatim quote from a source document in the workspace.

A **clinical claim** is any reviewable assertion in a payer-facing document: a diagnosis, a prior therapy the patient failed, a contraindication, a lab or imaging result, a CPT/HCPCS code with a date of service, a clinical score (UAS7, PASI, DAS28, ODI, ECOG, PHQ-9…), an outcome, a verbatim coverage-policy excerpt, or a specialty-society guideline citation. Narrative glue, salutations, and payer-routing sentences are not clinical claims and are not mapped.

## What it covers

- **Candidate extraction.** Heuristic scan of a draft letter for sentences containing an ICD-10 code, CPT/HCPCS/NDC, dose + frequency, named severity score, prior-therapy cues ("failed," "discontinued," "refractory"), contraindication cues, outcome cues, or specialty-society guideline tokens. Deliberately noisy — the agent triages the output and adds domain-specific claims the regex missed.
- **Claim-to-source citation.** One stable `claim_id` per assertion, linked to `doc_path + page + span + quote`. Quotes are verbatim from the cited document — paraphrasing is rejected at the skill level.
- **Pre-export quality gate.** Re-extracts candidates from the current draft, compares against the saved citations, and refuses export while any claim is unmapped. Also surfaces *orphaned* citations whose claims no longer appear in the draft after a revision.
- **Packet appendix.** Renders a markdown claim-to-source index table that can be appended to the final packet so the payer reviewer can follow every clinical claim back to the chart.
- **Per-case isolation.** Citations are written to `./clinical-claims/{case_id}.json`; path-traversal outside the workspace is rejected, and the `case_id` must match the record produced by `denial-intake-normalizer`.

## Example conversation

> **You:** I'm ready to check the appeal letter I just drafted for case 2026-0417-A before I send it. Can you map the claims back to the chart?
>
> **Agent:** Running `clinical_claim_extract_candidates` on the draft. Found 14 candidate clinical claims: 3 diagnoses, 4 prior-therapy assertions, 2 contraindications, 3 lab/imaging findings, 1 clinical score (ODI 56%), and 1 guideline citation (ACR 2024). Two candidates look like boilerplate and I'm dropping them.
>
> **Agent:** For the 12 real claims, I need to cite each one to a chart excerpt. I'll start with the diagnoses. The draft says "The patient carries a diagnosis of chronic low back pain (M54.16)." I'm citing that to `inputs/chart-note-2026-02-12.pdf` page 2: *"Assessment: Chronic low back pain, right-sided, lumbar region (ICD-10 M54.16), duration > 12 months."* Calling `clinical_claim_cite`.
>
> **Agent:** The draft also asserts "The patient failed a 12-week trial of gabapentin at 900 mg TID with no functional improvement and persistent somnolence." I'm citing to `inputs/chart-note-2025-11-03.pdf` page 1: *"Gabapentin 300 mg TID titrated to 900 mg TID over 4 weeks; at 12-week follow-up, no reduction in VAS or ODI; patient reports daytime somnolence limiting work."* Cited.
>
> **Agent:** I cannot find a source for one claim: "MRI demonstrated L4-L5 disc extrusion with S1 nerve-root impingement." There is no MRI report in the uploaded inputs. Do you want to upload it, remove the claim from the draft, or soften it to the reading in the 2026-02-12 chart note ("imaging consistent with L4-L5 pathology")?
>
> **You:** The MRI report is at `inputs/mri-2026-02-03.pdf`. Add it.
>
> **Agent:** Read the MRI report. Citing to page 2: *"Impression: L4-L5 disc extrusion with effacement of the right S1 nerve root." *Calling `clinical_claim_cite`. That was the last unmapped claim.
>
> **Agent:** Running `clinical_claim_check_draft` now. **Result: `export_ready: true`** — 12 of 12 clinical claims cited, 0 orphaned citations, no unsupported assertions. Rendering the claim-to-source index for the packet appendix with `clinical_claim_render_index`.
>
> **You:** Good. If I revise the draft to remove the gabapentin paragraph, will the check still pass?
>
> **Agent:** The check will still pass on the *draft* side (no unmapped claims), but the gabapentin citation will show up as `orphaned` — a stored citation whose claim no longer appears in the draft. I'll prompt you to either restore the claim or call `clinical_claim_uncite` to drop the orphaned entry before we export.

## Sample output excerpt

The skill produces two artifacts. The primary data artifact is `./clinical-claims/{case_id}.json`, one entry per cited claim. The rendered packet appendix is a markdown claim-to-source index suitable for attaching to the final submission.

---

```json
{
  "case_id": "2026-0417-A",
  "updated_at": "2026-04-21T18:14:02Z",
  "entries": [
    {
      "claim_id": "diagnosis-chronic-low-back-pain-m54-16-1",
      "claim_text": "The patient carries a diagnosis of chronic low back pain (M54.16).",
      "claim_type": "diagnosis",
      "doc_path": "inputs/chart-note-2026-02-12.pdf",
      "page": 2,
      "span": [143, 238],
      "quote": "Assessment: Chronic low back pain, right-sided, lumbar region (ICD-10 M54.16), duration > 12 months.",
      "confidence": "high",
      "notes": null,
      "created_at": "2026-04-21T18:11:44Z"
    },
    {
      "claim_id": "prior-therapy-gabapentin-900mg-tid-12-weeks-2",
      "claim_text": "The patient failed a 12-week trial of gabapentin at 900 mg TID with no functional improvement and persistent somnolence.",
      "claim_type": "prior-therapy",
      "doc_path": "inputs/chart-note-2025-11-03.pdf",
      "page": 1,
      "span": [812, 1007],
      "quote": "Gabapentin 300 mg TID titrated to 900 mg TID over 4 weeks; at 12-week follow-up, no reduction in VAS or ODI; patient reports daytime somnolence limiting work.",
      "confidence": "high",
      "notes": null,
      "created_at": "2026-04-21T18:12:09Z"
    },
    {
      "claim_id": "lab-imaging-mri-l4-l5-disc-extrusion-3",
      "claim_text": "MRI lumbar spine (2026-02-03) demonstrated L4-L5 disc extrusion with right S1 nerve-root impingement.",
      "claim_type": "lab-or-imaging",
      "doc_path": "inputs/mri-2026-02-03.pdf",
      "page": 2,
      "span": [54, 142],
      "quote": "Impression: L4-L5 disc extrusion with effacement of the right S1 nerve root.",
      "confidence": "high",
      "notes": null,
      "created_at": "2026-04-21T18:13:31Z"
    },
    {
      "claim_id": "clinical-score-odi-56-2026-03-10-4",
      "claim_text": "ODI score was 56% on 2026-03-10, indicating severe functional limitation.",
      "claim_type": "clinical-score",
      "doc_path": "inputs/pt-eval-2026-03-10.pdf",
      "page": 1,
      "span": [201, 248],
      "quote": "Oswestry Disability Index: 56% (severe disability).",
      "confidence": "high",
      "notes": null,
      "created_at": "2026-04-21T18:13:48Z"
    }
  ]
}
```

Rendered as a packet appendix by `clinical_claim_render_index`:

```markdown
# Clinical claim-to-source index — case 2026-0417-A

Generated: 2026-04-21T18:14:02Z

| # | Claim | Type | Source document | Page | Excerpt | Confidence |
|---|---|---|---|---|---|---|
| 1 | The patient carries a diagnosis of chronic low back pain (M54.16). | diagnosis | inputs/chart-note-2026-02-12.pdf | 2 | Assessment: Chronic low back pain, right-sided, lumbar region (ICD-10 M54.16), duration > 12 months. | high |
| 2 | The patient failed a 12-week trial of gabapentin at 900 mg TID with no functional improvement and persistent somnolence. | prior-therapy | inputs/chart-note-2025-11-03.pdf | 1 | Gabapentin 300 mg TID titrated to 900 mg TID over 4 weeks; at 12-week follow-up, no reduction in VAS or ODI; patient reports daytime somnolence limiting work. | high |
| 3 | MRI lumbar spine (2026-02-03) demonstrated L4-L5 disc extrusion with right S1 nerve-root impingement. | lab-or-imaging | inputs/mri-2026-02-03.pdf | 2 | Impression: L4-L5 disc extrusion with effacement of the right S1 nerve root. | high |
| 4 | ODI score was 56% on 2026-03-10, indicating severe functional limitation. | clinical-score | inputs/pt-eval-2026-03-10.pdf | 1 | Oswestry Disability Index: 56% (severe disability). | high |
```

<!-- /excerpt -->

## Extension tools and validations

The skill registers six deterministic tools. All are workspace-scoped (paths resolving outside the project root are rejected) and key off `case_id` for per-case isolation.

### Claim extraction

- **`clinical_claim_extract_candidates`** — Splits the draft into sentences and classifies each one with a claim type using regex heuristics: ICD-10-CM codes (`[A-TV-Z][0-9][0-9A-Z](\.[0-9A-Z]{1,4})?`), CPT (5-digit with procedure cue), HCPCS (`[A-V]\d{4}`), NDC, ISO and US-format dates, doses with frequency (`BID`, `TID`, `QD`, `q\d+h`), named severity scores (UAS7, PASI, DAS28, ODI, NDI, ECOG, KPS, PHQ-9, GAD-7, HAM-D, MMSE, MoCA, RAPID3, BASDAI, HAQ-DI, FEV1, 6MWT), prior-therapy cues (`failed`, `trialed`, `discontinued`, `intolerant`, `refractory`), outcome cues (`worsened`, `progression`, `exacerbation`, `hospitalized`), contraindication cues (`contraindicated`, `allergy to`, `angioedema`, `hypersensitivity`), guideline tokens (NCCN, ACR, ADA, APA, AAN, CHEST, IDSA, ASCO, ASH, AHA, ACC, AGA, USPSTF), and coverage-policy cues (`policy`, `section \d`, `coverage criteria`, `formulary`). Returns a stable `claim_id`, the sentence, and a guessed `claim_type` from the 9-type taxonomy. Deliberately over-produces — the agent is expected to triage.

### Citation persistence

- **`clinical_claim_cite`** — Writes or overwrites an entry keyed by `claim_id`. Required fields: `case_id`, `claim_id`, `claim_text`, `claim_type` (one of `diagnosis`, `prior-therapy`, `contraindication`, `lab-or-imaging`, `procedure-or-service`, `clinical-score`, `outcome`, `coverage-criterion`, `guideline-citation`, `unknown`), `doc_path`, `page`, `quote`. Optional: `span`, `confidence` (`high`/`medium`/`low`), `notes`. `doc_path` must resolve inside the workspace.
- **`clinical_claim_uncite`** — Removes a citation by `claim_id`. Used when the draft no longer asserts the claim or the source excerpt turns out to be wrong.
- **`clinical_claim_list`** — Returns the full JSON map for audit or further tooling.

### Quality gate (pre-export)

- **`clinical_claim_check_draft`** — Re-extracts candidates from the current draft, compares to the saved citations, and returns:
  - `unmapped_claims` — claims the draft makes that have no matching citation (match is by `claim_id` or by trimmed, whitespace-collapsed, case-insensitive `claim_text`);
  - `orphaned_entries` — citations whose claim no longer appears in the draft;
  - `export_ready` — `false` if any claim is unmapped.

  When `export_ready` is false the tool returns `isError: true`, which blocks the calling drafting skill from producing a final packet.

### Packet appendix

- **`clinical_claim_render_index`** — Renders the citations as a markdown table (claim, type, source document, page, quoted excerpt, confidence) suitable for appending to the packet as an auditable appendix for the payer reviewer.

### Validation invariants enforced by the skill

- **No invented quotes.** The `quote` field is always a verbatim excerpt; there is no paraphrasing path.
- **Workspace isolation.** `case_id` must match `^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$`; `doc_path` and the storage file path must resolve inside the project workspace.
- **Per-case file integrity.** If a map file exists and its `case_id` does not match the requested `case_id`, the tool errors rather than overwriting.
- **Export gate is always on.** `clinical_claim_check_draft` cannot be bypassed; drafting skills that write final packets must call it and respect its `isError` return.
- **Audit pairing.** Citations and removals should be paired with `audit_log_writer` entries from `denial-intake-normalizer` so every change to the map is reflected in the per-case audit trail required by HIPAA-sensitive buyers.

## Getting started

1. Run `denial-intake-normalizer` first. The `case_id` on `case.json` is the key this skill uses for per-case storage.
2. Draft the appeal letter, letter of medical necessity, or peer-to-peer brief with the appropriate drafting skill, then call `clinical_claim_extract_candidates` on the draft to get a starting list of clinical claims.
3. For each real claim, call `clinical_claim_cite` with the source document path (relative to the workspace), the page, and a verbatim quote that supports the claim. If no source supports it, change the draft — do not force a citation.
4. Before exporting, call `clinical_claim_check_draft`. Resolve every `unmapped_claim` by adding a citation, and every `orphaned_entry` by either restoring the claim in the draft or removing the citation.
5. When the check returns `export_ready: true`, call `clinical_claim_render_index` to append the claim-to-source index to the packet.

The skill does not draft letters and does not submit appeals. It is the trust gate that makes every drafting skill's output defensible to a payer reviewer — no unsupported clinical claim leaves the workspace.



---

Back to [Skill Library](https://rakenne.app/skills/index.md)
