commvita
Connected care platform
United States · risk adjustment

Risk adjustment done properly: documenting what is already true

Hierarchical condition categories, risk adjustment factor scores and the annual recapture cycle, built around clinical accuracy and defensibility. The platform finds conditions the record already evidences and the current year’s codes are missing, shows the evidence beside the suggestion, and hands the decision to a clinician. Nothing is coded automatically.

Live vs demonstrated: Live — real, API-backed platform logic (wired end-to-end today) Demonstrated — representative control surface with seeded data / illustrative UI mock-up
© 2026 Commvita Digital Health Solutions Ltd. All rights reserved.

1 What risk adjustment is for

A capitated payment has to reflect how sick the population is. If it doesn’t, the organisation that takes the sickest patients loses money for taking them, and the organisation that avoids them profits. Risk adjustment is the mechanism that stops that. It only works if the coded record is a true picture of the patient.

So the job is documentation quality. A patient with stage 4 chronic kidney disease, a documented eGFR of 22 and a nephrology follow-up has stage 4 chronic kidney disease whether or not anybody put N18.4 on a claim this year. If nobody did, the payment is set as though the disease is absent. The clinical record and the coded record have come apart, and the coded record is the one the money runs on.

I built these surfaces to close that distance. They find conditions the record already evidences and the current year’s codes are missing, put the evidence next to the suggestion, and hand it to a clinician. The clinician decides. Nothing is coded by the platform. There’s a wider tour of the US module pack in Supporting the US health system; this one stays in risk adjustment.

Chief medical officer

Clinical accuracy · clinician time

Wants the coded record to match the clinical record, and wants the work of getting there to land in the clinician’s day at a moment that makes sense. Wants to be able to say no to a suggestion and have that stick.

Compliance lead

Defensibility · audit trail

Wants to know, for any code added through this route, who added it, what they saw when they added it, what note they wrote, and what the platform suggested before they touched it. Wants dismissals kept rather than deleted.

Coding lead

Recapture cycle · year end

Wants a list of chronic conditions coded last year and not yet this year, ranked and dated, in time to schedule an encounter before the year closes.

2 Hierarchical condition categories, and how a score is built

A hierarchical condition category groups diagnosis codes that cost about the same to treat. Each category carries a weight. The weights that apply to a patient are added to a demographic base, and the total is that patient’s risk adjustment factor score. A score of 1.0 is the national average.

Two properties of the model matter more than the arithmetic. The first is the hierarchy. Categories sit in families, and within a family only the most severe one scores, so coding a diabetic patient’s complications properly drops the milder diabetes category out. You don’t get paid twice for the same organ. The second is that the model resets. Chronic conditions don’t carry forward. A condition has to be documented in a face-to-face encounter in the payment year to count in the payment year, every year, for as long as the patient has it.

The surfaces here run against the CMS-HCC version 28 model, for shared savings and Medicare Advantage populations. The gap worklist shows the category, the category weight and the evidence. The trend line puts the panel’s score against the 1.0 average month by month.

HCC Risk Coding headline tiles reading Total HCC Gaps 12, Open Gaps 8, RAF Opportunity plus 2.476 and Patients Affected 4, above a RAF Score Trend chart plotting twelve monthly points from July 2024 to June 2025 rising from just under 1.0 to just above it, with a dashed national average line at 1.0.
HCC Risk Coding · gap summary and score trendCaptured from the running system, build B-591 · seeded data

The RAF opportunity tile is the sum of the category weights on the open gaps. It measures how much of the panel’s documented illness is missing from the codes. It isn’t a target and nobody is measured on it. If a clinician works the list and dismisses every row, the tile goes to zero and the panel is correctly coded.

3 Conditions the record already holds

The gap worklist is the core of it. Each row is a condition with support somewhere in the patient’s record and no current-year code. The row carries the evidence that raised it, in the same line of the table as the suggestion, so nobody has to take the suggestion on trust.

HCC Gap Closure Worklist table with filter pills for All, Open, Coded and Dismissed. Twelve rows across four patients. Each row shows the HCC category, the category weight, an evidence line and a status. Examples: HCC18 weight 0.302 with evidence HbA1c 9.2 per cent, nephropathy noted in 2024 encounter, status Open; HCC22 weight 0.289 with evidence eGFR 22 ml per min, CKD stage 4 not documented this year, status Open; HCC111 weight 0.346 with evidence GOLD Stage III spirometry 2025, no ICD-10 in current year; HCC108 weight 0.299 with evidence PAD query, vascular review inconclusive, status Dismissed; HCC85 weight 0.323 with evidence Echo 2025 EF 38 per cent, coded by Dr Patel, status Coded. Open rows carry a Code it button and a Dismiss link.
HCC Risk Coding · gap closure worklistCaptured from the running system, build B-591 · seeded data

Read the evidence column and you can see what kind of thing this is. “eGFR 22 ml/min, CKD stage 4 not documented this year.” “GOLD Stage III spirometry 2025, no ICD-10 in current year.” “Carotid Doppler 60% stenosis, I73.9 not documented.” Each one is a finding already in the record that nobody has coded this year. That’s the whole scope of what this looks for.

Look at the sixth row. HCC108, peripheral arterial disease, evidence “PAD query, vascular review inconclusive”, status Dismissed. That’s the system working. The evidence didn’t support the code, a clinician said so, and the record of the dismissal stays on the row. Dismissals are kept. They’re part of the defence if anyone asks later why a category the panel might have claimed was left alone.

The platform won’t suggest a code the record doesn’t support. A suggestion comes from a documented finding and travels with that finding attached. If there’s nothing in the record to display, there’s nothing to put in front of a clinician. What the platform doesn’t do is verify the evidence on the clinician’s behalf. It shows the line from the record and the clinician judges whether it supports the code. That judgement is where a code becomes defensible, and it belongs to a person.

Coding a row opens a small form on the row itself. The clinician confirms or changes the ICD-10 code and writes the encounter note that supports it. Both are stored against the gap with the username of the person who did it. There’s no bulk accept. There’s no button that codes the panel.

The RAF Recapture surface goes a step further and shows the extracted note passage alongside the documentation language the code would need. This is where a clinician can see, side by side, what the note said and what a coder would need it to say.

RAF Recapture detail panel. On the left, AI-Extracted Clinical Note Snippet, dated 2025-11-10, attributed to Dr James Okafor, with highlighted text reading BNP 480, EF 38 per cent on echo from September, patient on carvedilol and lisinopril for decompensated heart failure, Class II NYHA. On the right, Suggested Documentation Language reading: document Chronic systolic congestive heart failure, unspecified, with EF per cent documented and NYHA classification to support I50.20. Below it, HCC Category Heart Failure and Est. Annual Revenue 4,416 dollars, then three buttons: Accept, add to coding queue; Already Coded; Reject.
RAF Recapture · note extract and documentation languageDemonstrated surface, seeded content · the dollar figure is illustrative

The dollar figure on that panel and on the recapture tiles is illustrative demonstration content. It exists because a coding lead asks what a documentation gap is worth, and the honest answer is a number. It’s a consequence of coding the panel accurately. It isn’t what the work is for, and the platform doesn’t rank a clinician’s queue by it.

4 The annual recapture cycle

Because the model resets each year, a condition coded in January 2025 and not recoded in 2026 simply stops counting at the next reconciliation. The patient still has it. The payment stops reflecting it. This is the failure mode that quietly costs an accountable care organisation the most, and it’s entirely a calendar problem.

RAF Decay Monitor panel headed Conditions at Risk of Drop-off, with the note that chronic conditions not recoded in the current year will drop off the RAF score at the next CMS reconciliation on 1 January and these patients require a coding encounter before year-end. Five rows listing patient, condition at risk, HCC number, category weight, month last coded and revenue at risk: CHF systolic HCC 85 weight 0.368 last coded January 2025; COPD HCC 111 weight 0.335 last coded February 2025; major depression recurrent HCC 59 weight 0.395 last coded December 2024; protein-calorie malnutrition HCC 21 weight 0.516 last coded March 2025; diabetic nephropathy HCC 18 weight 0.318 last coded January 2025.
RAF Recapture · conditions at risk of drop-offDemonstrated surface, seeded content · the dollar figures are illustrative

The decay list is sorted by when the condition was last coded, so it reads as a work queue with a deadline instead of a report. The right response to a row on it’s usually an appointment. An annual wellness visit is the natural place to review a chronic problem list, examine the patient and document what is still true, and the platform’s wellness visit and chronic care management surfaces are where that encounter gets recorded.

Be clear what this list is. It prompts you to see a patient and assess them. It doesn’t prompt you to re-enter last year’s codes. A condition that has resolved should drop off, and the encounter is how you find out which is which.

5 Watching the score move, per patient and per panel

A single score tells you little. Movement tells you a lot. The registry holds last period’s score and this period’s side by side for every attributed patient, with the direction of travel and the categories currently uncoded.

RAF Score Monitor patient registry. A RAF Score Distribution panel shows four bars: Low under 1.0 with 5 patients, Medium 1.0 to 1.5 with 5, High 1.5 to 2.0 with 6, Very High above 2.0 with 4. Filter pills for tier and for payer, All Payers, Medicare Advantage and MSSP. The table lists patient, payer, last RAF, current RAF, a trend arrow, a sparkline, uncoded HCCs and risk tier. Rows include Walter Nuttall, Medicare Advantage, 2.20 to 2.40, trend up, no uncoded HCCs, Very High; Archibald Marsden, 1.80 down to 1.75, 3 gaps, Very High; Margaret Hollis, MSSP, 1.85 down to 1.72, 2 gaps, Very High. Each row carries an Add Note action.
RAF Score Monitor · patient registry and score movementCaptured from the running system, build B-591 · seeded data

The pattern to look for is a score falling while the patient gets no better. Two rows above do that, and both carry uncoded categories. It’s a documentation problem presenting as a payment problem, visible months before a reconciliation would surface it.

The undercoding view turns the same data into cards, one per patient, listing the uncoded categories by name and offering a Document HCC action instead of a code-it action. The wording is chosen on purpose. What is missing is the documentation, and the code follows it.

A clinician can attach a note to any patient’s risk record, which is where a “reviewed, condition resolved, do not recapture” belongs. Tier and payer filters run on the server, so a panel can be cut to one contract before anyone works it.

6 What survives an audit

If a payer or an auditor asks how a code got onto a claim, the answer has to be a record instead of a recollection. Everything this route can do to a code is written down.

The suggestion. The category, the category weight, the suggested ICD-10 code and the evidence line from the record, stored on the gap before anyone touches it.
The decision. Coded or dismissed, held as a status on the same row. A dismissal is a stored outcome and stays visible under the Dismissed filter.
The person. The username of the clinician who coded it, written by the endpoint from the authenticated session and not typed into a field.
The clinical justification. The encounter note the clinician wrote at the point of coding, stored against the gap alongside the code they confirmed.
The role gate. Coding and dismissing require a clinician role or above. A read-only user can see the worklist and change nothing on it.

Where a model scores a patient anywhere in the platform, that model sits on a governance register with its version, the dataset it was trained against, its area under the curve, sensitivity, specificity, operating threshold, retrain due date, current drift against an alert threshold, and a named clinical sign-off with a date. An unsigned model is counted and shown as unsigned.

Two ceilings, stated plainly. First, the platform doesn’t submit a risk-adjustment encounter to a payer. That path isn’t built, and the endpoint that would have done it refuses and names what is absent instead of returning a success nobody can distinguish from a real one. Second, the Recapture Engine’s five tabs are a demonstrated surface reading seeded content, and the page says so in a banner on itself. The gap worklist, the registry, the undercoding alerts and the coding and dismissal actions are API-backed.

Where it lives in commvita

CapabilityRouteModel / APIStatus
HCC gap worklist with evidence/hcc-risk-codingAPI GET /hcc/gaps · /hcc/summary · CMS-HCC v28● Live
Code a gap (ICD-10 plus encounter note, coder recorded)/hcc-risk-codingAPI POST /hcc/gaps/{id}/code● Live
Dismiss a gap (outcome retained)/hcc-risk-codingAPI POST /hcc/gaps/{id}/dismiss● Live
Panel RAF trend against the 1.0 average/hcc-risk-codingAPI GET /hcc/raf-trend · 12 months● Live
Patient registry and score movement/raf-score-monitorAPI GET /raf/patients · /raf/summary · tier and payer filters● Live
Undercoding alerts per patient/raf-score-monitorAPI GET /raf/undercoding-alerts● Live
Clinical note on a risk record/raf-score-monitorAPI POST /raf/patients/{id}/add-note● Live
Model governance register and sign-off/predictive-analyticsAPI /analytics/model-governance · version, metrics, drift, named sign-off● Live
Note mining queue and coding queue/raf-recapturePage holds seeded content; /raf-recapture/summary returns fixed figures☉ Demonstrated
Provider coding performance/raf-recaptureSeeded panel · expected against actual average score by provider☉ Demonstrated
Decay monitor and category catalogue/raf-recaptureSeeded panels · documentation requirements per category☉ Demonstrated
It doesn’t code. It isn’t a coding engine and it doesn’t code. Every code that reaches a claim through this route was confirmed by a named clinician who saw the evidence and wrote a note. It carries no diagnostic claim and isn’t a medical device; it surfaces what is already in the record and a clinician decides. It doesn’t submit encounters or claims to a payer. It won’t put a category in front of anybody without the line from the record that raised it, and a dismissal is an answer the platform keeps.
© 2026 Commvita Digital Health Solutions Ltd. All rights reserved. CMS-HCC v28 risk adjustment modelICD-10-CMMedicare Shared Savings Program Medicare AdvantageHIPAA minimum necessaryRole-based access control Non-SaMD