CMS HCCs
Overview
The CMS HCCs data mart package implements Medicare Advantage risk adjustment workflows on top of the Tuva Core Data Model. It converts CMS-HCC model software, diagnosis mappings, coefficient files, hierarchy files, normalization factors, and coding pattern adjustment factors into dbt models that run inside the data warehouse.
The package is organized into three sections: Models, Recapture, and Suspecting. CMS publishes the source risk adjustment material on the CMS Risk Adjustment page.
Models
The Models section calculates patient-level CMS-HCC risk factors and risk scores for a selected payment year. It maps risk-adjustable diagnoses to HCCs, applies CMS hierarchy rules, adds demographic and enrollment factors, and calculates V24, V28, blended, normalized, and payment risk scores.
CMS finalized the 2024 CMS-HCC model, commonly called V28, for a three-year phase-in beginning in calendar year 2024. Tuva calculates V24, V28, and blended risk scores where the payment year requires blending.
| Payment Year | Blending Approach |
|---|---|
| 2024 | 67% V24 and 33% V28 |
| 2025 | 33% V24 and 67% V28 |
| 2026 | 100% V28 |
Required Inputs
The Models workflow runs when claims data is enabled and uses the following Core Data Model tables:
| Core Table | Required Content |
|---|---|
core.patient | person_id, sex, birth date, death date, and patient demographic fields. |
core.eligibility | Enrollment spans, payer, plan, original reason for Medicare entitlement, dual status, and Medicare status. |
core.member_month | Monthly eligibility rows used to weight risk scores by member months. |
core.condition | Diagnosis records used to identify risk-adjustable conditions. |
core.medical_claim | Claim-level and line-level diagnosis and procedure fields used in CMS-HCC logic. |
At the input layer, medical claims can include up to 25 diagnosis code fields, but diagnosis_code_1 is the minimum diagnosis field required by the package.
An eligibility row with a null enrollment_end_date is treated as open for
CMS-HCC collection-period overlap and is capped at the selected payment-year
end when coverage months are calculated.
Vars
| Variable | Default | When To Set |
|---|---|---|
claims_enabled | Project-level Tuva var | Must be true for CMS-HCC model scoring, because the model scoring workflow runs on claims-derived core tables. |
cms_hcc_payment_year | Year of the dbt run | Set this when you need to calculate a specific payment year instead of using the current run year. |
tuva_schema_prefix | null | Optional. Set this only if your project uses prefixed Tuva schemas. |
Example:
vars:
claims_enabled: true
cms_hcc_payment_year: 2026
Run Commands
Run the Models workflow with the default payment year:
dbt build --select tag:cms_hcc
Run the Models workflow for a specific payment year:
dbt build --select tag:cms_hcc --vars '{cms_hcc_payment_year: 2026}'
If this package is installed inside another dbt project, run dbt deps before building so dbt installs the CMS HCC package and its dependencies.
Score Fields
| Field | Description |
|---|---|
v24_risk_score | Sum of patient risk factors under the CMS-HCC V24 model. |
v28_risk_score | Sum of patient risk factors under the CMS-HCC V28 model. |
blended_risk_score | Payment-year blend of V24 and V28 risk scores when CMS phase-in rules apply. |
normalized_risk_score | Blended score divided by the CMS normalization factor for the payment year and model. |
payment_risk_score | Normalized score multiplied by the CMS MA coding pattern adjustment factor. |
payment_risk_score_weighted_by_months | Payment risk score multiplied by the member months available for the member. |
Outputs
| Model | Description |
|---|---|
cms_hcc.patient_risk_factors | Patient-level demographic, disease, interaction, and enrollment factors used in CMS-HCC risk scoring. |
cms_hcc.patient_risk_factors_monthly | Monthly patient risk factors for collection-period tracking. |
cms_hcc.patient_risk_scores | Patient-level CMS-HCC risk score output for the selected payment year. |
cms_hcc.patient_risk_scores_monthly | Monthly patient risk scores for trend analysis. |
cms_hcc.patient_risk_scores_monthly_by_factor_type | Monthly patient risk scores split by factor type. |
Example SQL
Average CMS-HCC Risk Scores
select
count(distinct person_id) as patient_count
, avg(blended_risk_score) as average_blended_risk_score
, avg(normalized_risk_score) as average_normalized_risk_score
, avg(payment_risk_score) as average_payment_risk_score
from cms_hcc.patient_risk_scores;
Average CMS-HCC Risk Scores by Patient Location
select
patient.state
, patient.city
, patient.zip_code
, avg(risk.payment_risk_score) as average_payment_risk_score
from cms_hcc.patient_risk_scores as risk
inner join core.patient as patient
on risk.person_id = patient.person_id
and risk.data_source = patient.data_source
group by
patient.state
, patient.city
, patient.zip_code
order by average_payment_risk_score desc;
Monthly Average CMS-HCC Risk Scores
select
collection_end_date
, payment_year
, avg(payment_risk_score) as average_payment_risk_score
from cms_hcc.patient_risk_scores_monthly
group by
collection_end_date
, payment_year
order by
collection_end_date
, payment_year;
Distribution of CMS-HCC Risk Factors
select
risk_factor_description
, count(*) as patient_factor_count
, cast(
100.0 * count(*) / nullif(sum(count(*)) over (), 0)
as numeric(38, 1)
) as percent
from cms_hcc.patient_risk_factors
group by risk_factor_description
order by patient_factor_count desc;
Risk Weighted by Member Months
select
sum(payment_risk_score_weighted_by_months)
/ nullif(sum(member_months), 0) as weighted_payment_risk_score
from cms_hcc.patient_risk_scores;
Risk Score Stratification
select
sum(case when payment_risk_score < 1.00 then 1 else 0 end) as lower_than_average_risk
, sum(case when payment_risk_score = 1.00 then 1 else 0 end) as average_risk
, sum(case when payment_risk_score > 1.00 then 1 else 0 end) as higher_than_average_risk
, avg(payment_risk_score) as total_population_average
from cms_hcc.patient_risk_scores;
Total HCC Conditions
select
risk_factor_description
, count(*) as patient_count
from cms_hcc.patient_risk_factors
where factor_type = 'Disease'
group by risk_factor_description
order by patient_count desc;
Recapture
Recapture evaluates HCCs coded or suspected in a prior collection year and determines whether those HCCs were captured again in the current collection year. This matters because chronic conditions often need to be documented again to support complete risk adjustment and value-based care reimbursement.
The Recapture workflow combines previously coded HCCs with suspected HCCs and assigns a gap_status to each patient-HCC record. It also produces annual rates and monthly year-to-date recapture curves.
Vars
| Variable | Default | When To Set |
|---|---|---|
claims_enabled | Project-level Tuva var | Must be true for recapture, because recapture uses claims-derived HCC history. |
cms_hcc_payment_year | Year of the dbt run | Set this when recapture should run for a specific payment year. |
hcc_recapture_suspect_list | false | Set to true when you want to provide your own suspect_hccs model from a payer, clinical source, or internal review workflow. |
hcc_recapture_chronic_hccs | false | Set to true when you want to provide your own chronic_hccs model instead of Tuva's default chronic HCC definitions. |
tuva_schema_prefix | null | Optional. Set this only if your project uses prefixed Tuva schemas. |
If hcc_recapture_suspect_list is true, your project must define a model named suspect_hccs with these fields: person_id, payer, data_source, recorded_date, model_version, claim_id, hcc_code, hcc_description, suspect_hcc_flag, eligible_claim_flag, reason, hcc_type, and hcc_source. Preserve a distinct reason for each independent finding; the same person/HCC can have more than one reason.
If hcc_recapture_chronic_hccs is true, your project must define a model named chronic_hccs with these fields: hcc_code, model_version, and chronic_flag.
Example:
vars:
claims_enabled: true
cms_hcc_payment_year: 2026
hcc_recapture_suspect_list: false
hcc_recapture_chronic_hccs: false
Run Commands
Run Recapture with the default package definitions:
dbt build --select tag:hcc_recapture
Run Recapture for a specific payment year:
dbt build --select tag:hcc_recapture --vars '{cms_hcc_payment_year: 2026}'
Run Recapture with custom suspect and chronic HCC inputs:
dbt build --select tag:hcc_recapture --vars '{hcc_recapture_suspect_list: true, hcc_recapture_chronic_hccs: true}'
Gap Status
| Gap Status | Definition |
|---|---|
closed | The specific HCC was observed in a risk-adjustable claim during the collection year. |
closed - higher coefficient hcc in hierarchy group | An HCC in the same hierarchy group was closed and has a higher coefficient than the prior-year HCC. |
closed - lower coefficient hcc in hierarchy group | An HCC in the same hierarchy group was closed and has a lower coefficient than the prior-year HCC. |
new | The HCC has not been coded in the prior two years. |
open | The HCC is chronic and appropriate for recapture but has not been documented in the current collection year. |
ineligible for recapture | The HCC is open but is not appropriate for risk adjustment because it is not considered a chronic diagnosis for recapture. |
Outputs
| Model | Description |
|---|---|
hcc_recapture.gap_status | One row per patient, HCC, payer, data source, model version, payment year, HCC type, and HCC source with the resulting gap status. |
hcc_recapture.hcc_status | Claim-level and source-level HCC status detail used to evaluate coded, captured, suspected, and recaptured HCCs. |
hcc_recapture.recapture_rates | Recapture rate summary by data source, payer, and payment year. |
hcc_recapture.recapture_rates_monthly | Monthly recapture rate summary by data source, payer, payment year, and payment year month. |
hcc_recapture.recapture_rates_monthly_ytd | Year-to-date recapture curves by data source, payer, payment year, and payment year month. |
Example SQL
Open HCC Recapture Gaps
select
hcc_code
, hcc_description
, count(*) as open_gap_count
from hcc_recapture.gap_status
where gap_status = 'open'
group by
hcc_code
, hcc_description
order by open_gap_count desc;
Monthly Recapture Curve
select
payer
, payment_year
, payment_year_month
, ytd_closed_hccs
, ytd_open_hccs
, yearly_total_hccs
, ytd_recapture_rate
from hcc_recapture.recapture_rates_monthly_ytd
order by
payer
, payment_year
, payment_year_month;
Suspecting
Suspecting identifies patients who may have an uncoded HCC during the current payment year. This workflow is intended for prospective coding review and care management workflows, not for final CMS-HCC payment risk score calculation.
The Suspecting workflow can use claims and clinical evidence, including conditions, medications, lab results, observations, and pharmacy claims.
Vars
| Variable | Default | When To Set |
|---|---|---|
claims_enabled | Project-level Tuva var | Set to true when you want suspecting to use claims-derived core tables. |
clinical_enabled | Project-level Tuva var | Set to true when you want suspecting to use clinical core tables such as conditions, lab results, medications, and observations. |
tuva_schema_prefix | null | Optional. Set this only if your project uses prefixed Tuva schemas. |
At least one of claims_enabled or clinical_enabled must be true for Suspecting to run. Claims data provides diagnosis and pharmacy claim evidence. Clinical data adds evidence from EHR-derived conditions, labs, medications, and observations.
Example:
vars:
claims_enabled: true
clinical_enabled: true
Run Commands
Run Suspecting:
dbt build --select tag:hcc_suspecting
Run Suspecting with both claims and clinical evidence enabled:
dbt build --select tag:hcc_suspecting --vars '{claims_enabled: true, clinical_enabled: true}'
Methods
The workflow uses several evidence sources:
| Method | Description |
|---|---|
| Recapture history | Uses billed claims history to evaluate whether recurring diagnoses from prior years were captured during the current payment year. |
| Clinical discovery | Uses available clinical and claims data, including problem lists, conditions, medications, observations, and lab results, to identify possible new HCCs. |
| Coding system mapping | Uses SNOMED-CT to ICD-10-CM mappings to identify suspecting opportunities when source diagnoses are not already coded in a CMS-HCC-supported code system. |
The package currently includes condition-specific suspecting logic for:
| Suspecting Area | Evidence Used |
|---|---|
| Chronic kidney disease | eGFR lab results and CKD-relevant conditions. |
| Depression | Medications and PHQ-9 assessments. |
| Diabetes | Diabetes with comorbidity evidence such as CKD stage 1 or 2. |
| Morbid obesity | BMI and vital-sign evidence combined with comorbidities such as diabetes, hypertension, or obstructive sleep apnea. |
Outputs
| Model | Description |
|---|---|
hcc_suspecting.list | Patient-level suspected HCC records with HCC, reason, contributing factor, and suspect date. Excludes HCCs already billed in the current payment year. |
hcc_suspecting.list_all | Patient-level suspected HCC records before filtering out current-year billed HCCs. |
hcc_suspecting.list_rollup | Patient-HCC rollup with the latest contributing factor. |
hcc_suspecting.summary | Patient-level summary of suspecting gaps. |
Example SQL
Total Suspected HCCs
select
hcc_code
, hcc_description
, count(*) as suspected_hcc_count
from hcc_suspecting.list
group by
hcc_code
, hcc_description
order by suspected_hcc_count desc;
Suspected HCCs by Reason
select
reason
, count(*) as suspected_hcc_count
from hcc_suspecting.list
group by reason
order by suspected_hcc_count desc;
Actionable Suspecting Patient List
select
person_id
, payer
, patient_birth_date
, patient_age
, patient_sex
, suspecting_gaps
from hcc_suspecting.summary
where suspecting_gaps > 0
order by suspecting_gaps desc;