# PBP cardiac pulmonary rehab (cleaned view)

`medicare_semantic.vw_pbp_cardiac_pulmonary_rehab` · Medicare Advantage, Part D, Medicaid · status live

Cleaned source-faithful PBP cardiac pulmonary rehab rows: era-normalized, CMS codes decoded, with offered_status/numeric_amount_observability/null_amount_reason/annualization_policy/combined_limit_policy/confidence_tier. The agent reasoning

**Grain.** One row per Medicare Advantage plan-segment, per quarterly PBP snapshot, per rehab sub-benefit. The minimal verified-unique key is (contract_id, plan_id, segment_id, report_year, quarter, rehab_sub_benefit) — 455,848 rows, all distinct on that key. Each plan-snapshot (contract+plan+segment+report_year+quarter = 113,962 of them) fans out into exactly 4 rows, one per rehab sub-benefit (cardiac_rehab_basic, intensive_cardiac_rehab, pulmonary_rehab, setpad). network_type is constant 'in_network' so it is not needed in the key.

**How to use it.** To get the in-network cardiac-rehab cost share for a plan in the current plan year, filter to one snapshot and one sub-benefit, e.g. SELECT contract_id, plan_id, segment_id, cost_share_string, copay_amount, coinsurance_pct, auth_required FROM vw_pbp_cardiac_pulmonary_rehab WHERE report_year=2026 AND quarter=1 AND rehab_sub_benefit='cardiac_rehab_basic'. This returns each plan's filed member copay/coinsurance and whether prior auth is needed for standard cardiac rehab. To compare the four rehab types for one plan, drop the sub_benefit filter and you get 4 rows.

**Traps.**
- No single ID column is unique. contract_id (1,231), plan_id (656), segment_id (24) are all repeated. The profiler's suggested candidate key (contract/plan/segment + limit_period_code + benefit_amount_period_code + confidence_tier) is WRONG — those three extra columns are 100% NULL or constant. The true key MUST include report_year, quarter, AND rehab_sub_benefit.
- Pick ONE snapshot or you will multiply rows. There are 16 (report_year, quarter) snapshots from 2019-2026; without a report_year+quarter filter a plan appears many times across years. 'quarter' is the CMS PUF release quarter, not a coverage period.
- Each plan-snapshot is fanned into 4 rows (one per rehab sub-benefit: cardiac_rehab_basic / intensive_cardiac_rehab / pulmonary_rehab / setpad). rehab_sub_benefit and source_pbp_section are 1:1 (B3_CRS/B3_ICRS/B3_PRS/B3_SETPAD). Filter on rehab_sub_benefit when you want a single benefit, else you 4x your aggregates.
- offered_status is a constant 'offered' scaffolding value and does NOT mean the plan offers that sub-benefit. ~20,880 rows are actually not-offered: detect them by cost_share_string IS NULL / auth_required IS NULL (these also have has_copay/has_coinsurance/has_deductible = NULL), not by offered_status.
- All benefit-amount and limit columns are 100% NULL (benefit_amount, benefit_amount_pmpm, benefit_amount_annualized, limit_text, limit_quantity, limit_period_code, normalization_status, aggregation_policy, etc.). They are shared-schema scaffolding; the gold metadata constants explain it: numeric_amount_observability='offered_without_numeric_amounts', null_amount_reason='unknown_requires_crosswalk', confidence_tier='source_faithful'. Use cost_share_string / copay_amount / coinsurance_pct for the actual cost share.
- source_url and sha256_content_hash are snapshot-level provenance (exactly 16 distinct, one per year+quarter), NOT row identifiers. has_deductible is never true. copay vs coinsurance are near-mutually-exclusive (plans file one or the other). The min/max copay & coinsurance columns just mirror the single value here.

| column | type | meaning |
|---|---|---|
| contract_id | string | Medicare Advantage contract ID, e.g. 'H0016' (H/R/S prefix). 1,231 distinct. Part of plan-identity key. |
| plan_id | string | Plan benefit package ID within the contract, e.g. '001','003' (3-char zero-padded). 656 distinct. NOT unique on its own. |
| segment_id | string | Plan segment ID, e.g. '0' (most plans are single-segment). 24 distinct values. Completes the CMS contract/plan/segment identity triple. |
| version | double | PBP submission/revision number for that plan-year (double, 1.0-26.0). The plan's filing revision; higher = later resubmission. One value per plan-snapshot here (no intra-snapshot duplicates), so it is informational, not a dedup key. |
| report_year | double | Plan/contract YEAR the PBP filing applies to (double: 2019-2026). THE real year dimension. 2023 is the largest cohort. |
| quarter | double | Quarter of the CMS PBP PUF release snapshot within report_year (double 1-4). Combined with report_year it identifies which of the 16 quarterly source files the row came from. NOT a benefit period or coverage quarter — it is the publication snapshot. |
| benefit_category | string | Constant 'cardiac_pulmonary_rehab' for every row — this view is the cardiac/pulmonary rehab slice of the PBP B3 rehab section. |
| cost_share_string | string | Human-readable member cost share as filed, e.g. '20.0%', '$0 copay', '$20.0 copay', '$0 copay + 20.0%'. The source-faithful display string; copay_amount/coinsurance_pct are parsed from it. NULL (~69K rows) means this sub-benefit is not offered/priced for that plan-snapshot. |
| copay_amount | double | Parsed flat-dollar copay (double, $0-$100, median ~$18). NULL when the cost share is coinsurance-only or the sub-benefit is not offered. ~244K rows populated. |
| coinsurance_pct | double | Parsed coinsurance percentage (double, 0-45, median 20 = the Medicare-standard 20%). NULL when cost share is copay-only or not offered. ~143K rows populated. Plans use copay XOR coinsurance ~ exclusively (only ~3.4K rows have both). |
| limit_text | string | 100% NULL in this view. Scaffolding column from the shared PBP gold schema; benefit limits are not populated for this rehab benefit. |
| auth_required | boolean | Boolean: prior authorization required (true ~276K, false ~157K, NULL ~22.7K). NULL coincides with the not-offered sub-benefit rows. |
| referral_required | boolean | Boolean: referral required (false ~331K, true ~102K, NULL ~22.7K). NULL = not-offered rows. |
| network_type | varchar(10) | Constant 'in_network' for all 455,848 rows. This view carries only the in-network cost share; do NOT include it in the grain key (it adds nothing). |
| max_oop_applies | boolean | Boolean, constant TRUE for all rows — this benefit accrues toward the plan MOOP. A fixed flag for this category, not a per-plan signal. |
| limit_quantity | double | 100% NULL. Unused gold-schema scaffolding column (visit/quantity caps not parsed for this benefit). |
| limit_unit | string | 100% NULL. Unused scaffolding. |
| limit_period_code | string | 100% NULL. Unused scaffolding (despite being listed as a profiler candidate key — it carries no information here). |
| limit_period_label | string | 100% NULL. Unused scaffolding. |
| limit_quantity_per_year | double | 100% NULL. Unused scaffolding. |
| benefit_amount | double | 100% NULL. This is a plan-PAYS/allowance column for supplemental cash-style benefits; not applicable to cardiac/pulmonary rehab, so always null. |
| benefit_amount_kind | string | 100% NULL. Unused scaffolding (would label benefit_amount type). |
| benefit_amount_period_code | string | 100% NULL. Unused scaffolding (profiler candidate key but carries no information). |
| benefit_amount_period_label | string | 100% NULL. Unused scaffolding. |
| benefit_amount_annualized | double | 100% NULL. Unused scaffolding (annualized benefit_amount). |
| benefit_amount_pmpm | double | 100% NULL. Unused scaffolding (per-member-per-month benefit_amount). |
| normalization_status | string | 100% NULL for this view. Gold-layer numeric-normalization status is not applied to this benefit (see numeric_amount_observability instead). |
| normalization_basis | string | 100% NULL. Gold-layer normalization basis not applied here. |
| aggregation_policy | string | 100% NULL. Gold-layer aggregation policy not applied here. |
| offered_status | varchar(15) | Constant 'offered' (varchar) for ALL rows — a row-level scaffolding constant, NOT a real per-plan offered flag. To tell whether a plan actually offers a sub-benefit, check whether cost_share_string/auth_required are non-null, not this column. |
| numeric_amount_observability | varchar(31) | Constant 'offered_without_numeric_amounts' — declares that this benefit is captured as offered + cost-share but without normalized dollar benefit amounts (explains why all benefit_amount_* are null). |
| null_amount_reason | varchar(30) | Constant 'unknown_requires_crosswalk' — the documented reason benefit amounts are null (would need a service-category crosswalk to populate). |
| annualization_policy | varchar(17) | Constant 'not_numeric' — annualization not performed because there is no numeric benefit amount. |
| combined_limit_policy | varchar(29) | Constant 'none_detected' — no shared/combined benefit limit detected for this category. |
| consumer_document_reconciliation_status | varchar(11) | Constant 'not_checked' — these rows have not been reconciled against consumer documents (EOC/SB). |
| confidence_tier | varchar(23) | Constant 'source_faithful' — values are taken as-filed from the PBP PUF without inference/enrichment. (Profiler candidate key but constant, so it adds nothing.) |
| cardiac_pulmonary_rehab_package_id | string |  |
| cardiac_pulmonary_rehab_package_match_basis | string |  |
| cardiac_pulmonary_rehab_package_name | string |  |
| cardiac_pulmonary_rehab_package_type_code | string |  |
| cardiac_pulmonary_rehab_package_type_label | string |  |
| cardiac_pulmonary_rehab_targeting | string |  |
| coinsurance_pct_max | double | Max coinsurance for the row; equals coinsurance_pct here (single-value range). Populated only where coinsurance_pct is. Exists for schema parity with multi-value benefits. |
| coinsurance_pct_min | double | Min coinsurance; equals coinsurance_pct here. Same fill (~143K). |
| copay_amount_max | double | Max copay for the row; equals copay_amount here (single-value range). Same fill (~244K). |
| copay_amount_min | double | Min copay; equals copay_amount here. Same fill. |
| has_coinsurance | boolean | Boolean derived flag: row has a coinsurance cost share. NULL (~20.8K) on not-offered rows. |
| has_copay | boolean | Boolean derived flag: row has a copay cost share. NULL on not-offered rows. ~248K true. |
| has_deductible | boolean | Boolean derived flag for a benefit-specific deductible. NEVER true in this view (always false, or NULL on not-offered rows) — cardiac/pulmonary rehab carries no separate deductible here. |
| max_plan_benefit_amount | double |  |
| max_plan_benefit_basis | string |  |
| max_plan_benefit_offered | boolean |  |
| max_plan_benefit_period_code | string |  |
| max_plan_benefit_period_label | string |  |
| max_plan_benefit_period_text | string |  |
| rehab_benefit_type_code | string |  |
| rehab_benefit_type_label | string |  |
| rehab_is_unlimited | boolean |  |
| rehab_sub_benefit | varchar(47) | The specific rehab sub-benefit the row prices. Exactly 4 values, each appearing 113,962 times: 'cardiac_rehab_basic' (standard cardiac rehab), 'intensive_cardiac_rehab', 'pulmonary_rehab', and 'setpad' (Supervised Exercise Therapy for symptomatic Peripheral Artery Disease). This is the column that fans each plan-snapshot into 4 rows and is REQUIRED in the grain key. |
| source_pbp_section | varchar(20) | CMS PBP B3 sub-section the row came from. 1:1 with rehab_sub_benefit: B3_CRS=cardiac_rehab_basic, B3_ICRS=intensive_cardiac_rehab, B3_PRS=pulmonary_rehab, B3_SETPAD=setpad. Redundant with rehab_sub_benefit. |
| source_silver_table | varchar(57) | Constant 'medicare_silver.pbp_section_b3_cardiac_rehab' — the silver lineage table all 4 sub-benefits are unpacked from. Provenance, not a dimension. |
| lmi_authorities | string | Constant URL to the CMS/LMI 'CY 2026 PBP Service Category Descriptions' PDF — the authoritative definition doc for these service categories. Reference link, same for every row. |
| source_url | string | URL of the CMS PBP PUF zip the snapshot was extracted from (e.g. '.../pbp-benefits-2024-quarter-4.zip'). Exactly 16 distinct values — one per (report_year, quarter) snapshot, NOT per row. Snapshot-level provenance. |
| sha256_content_hash | string | Content hash of the source snapshot file. Exactly 16 distinct values — one per snapshot, identical across all rows of the same (report_year, quarter). Snapshot-level provenance, NOT a row identifier. |

Tools that read it: get_pbp_benefit

Query it: `query_substrate` with `SELECT ... FROM medicare_semantic.vw_pbp_cardiac_pulmonary_rehab WHERE ... LIMIT 100`; read `describe_data_source("medicare_semantic.vw_pbp_cardiac_pulmonary_rehab")` first.
