// data · dbt
TL;DR
cms_hcc v1.0.0 fixes a bug where members who switched payers during the collection year (think Medicare FFS → MA) silently lost every disease factor in their risk score. No error, no null — just a demographic-only score that looked completely normal.
What changed
Two models in cms_hcc made opposite assumptions about whether payer is part of a member’s grain.
int_members deduped eligibility down to one row per (person_id, collection_end_date). payer wasn’t in that dedupe key, so when a member had multiple payers in the same year, one won and the rest got discarded — silently.
int_disease_factors then joined demographics back to hcc_hierarchy on payer — except hcc_hierarchy’s payer comes from the claim, not from whichever payer won the eligibility dedupe upstream.
For a member with one payer all year, both sides always agree, so nobody noticed. For a member who switched payers, they can disagree, and the inner join drops every row on the disease-factor side. The member still gets scored — just on demographics alone.
int_members: dedupe by (person_id, collection_end_date)
int_disease_factors: join on payer ← comes from a different source entirely

What actually shipped
cms_hcc PR #37, merged 2026-09-01, part of the Core 1.0 restructuring that split cms_hcc out of the tuva-core monorepo. The fix adds payer and data_source to the member dedupe key in int_members, so its grain matches the join key int_disease_factors was already assuming.
New contract, cms_hcc v1.0.0+:
member grain: (person_id, payer, data_source, collection_end_date)
A person covered by two payers in the same collection year now gets two independent member rows and two independent scores. They’re not merged or deduped across payers.
Key takeaways
- A join key and a dedupe key are two separate contracts — nothing enforces that they agree, even when both live in the same package
- This class of bug doesn’t throw. It returns fewer rows than expected, and “fewer rows” reads as “fewer sick members,” not as “broken pipeline”
input_layer__eligibilitystill doesn’t document any uniqueness constraint onperson_id, so the grain is only recoverable by reverse-engineering two other models’ join keys — worth a docs PR on its own
15 Sep 2026 · #dbt #snowflake #dataengineering #healthcare
GLB_