Skip to content

Include Medicare Part A premiums and Part D IRMAA in MOOP#8532

Open
daphnehanse11 wants to merge 4 commits into
PolicyEngine:mainfrom
daphnehanse11:codex/medicare-premiums-moop
Open

Include Medicare Part A premiums and Part D IRMAA in MOOP#8532
daphnehanse11 wants to merge 4 commits into
PolicyEngine:mainfrom
daphnehanse11:codex/medicare-premiums-moop

Conversation

@daphnehanse11

Copy link
Copy Markdown
Collaborator

Summary

  • add a net medicare_part_a_premium variable for Part A premiums paid out of pocket
  • add msp_part_a_premium_coverage so QMB-covered Part A premiums do not count as household MOOP
  • include paid Part A premiums and Part D IRMAA in SPM health insurance premiums and medical out-of-pocket expenses

Fixes #8529.

Tests

uv run python -m policyengine_core.scripts.policyengine_command test -c policyengine_us policyengine_us/tests/policy/baseline/gov/hhs/medicare/eligibility/medicare_part_a_premium.yaml policyengine_us/tests/policy/baseline/gov/hhs/medicare/savings_programs/msp_part_a_premium_coverage.yaml policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_medical_out_of_pocket_expenses_medicare_part_b.yaml
uv run python -m policyengine_core.scripts.policyengine_command test -c policyengine_us policyengine_us/tests/policy/baseline/gov/hhs/medicare policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_medical_out_of_pocket_expenses_medicare_part_b.yaml

@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (7f028e9) to head (78b8288).
⚠️ Report is 479 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #8532   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            2         5    +3     
  Lines           30        58   +28     
  Branches         0         1    +1     
=========================================
+ Hits            30        58   +28     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@daphnehanse11 daphnehanse11 force-pushed the codex/medicare-premiums-moop branch from e3fb9eb to 3aff88b Compare May 29, 2026 18:52

@daphnehanse11 daphnehanse11 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope mismatch: this PR says it includes Medicare Part D premiums in MOOP, but spm_unit_health_insurance_premiums only adds income_adjusted_part_d_premium_surcharge. The surcharge variable documentation correctly says this is paid in addition to the beneficiary's underlying Part D plan premium, and I do not see a modeled base Part D premium or Part D enrollment variable in the PR. As written, ordinary Part D premiums remain omitted from MOOP, and high-income beneficiaries only get the IRMAA surcharge. Please add the base Part D premium path, or narrow the PR/docs/tests to say this only models Part D IRMAA.

@daphnehanse11 daphnehanse11 changed the title Include Medicare Part A and Part D premiums in MOOP Include Medicare Part A premiums and Part D IRMAA in MOOP May 29, 2026
@daphnehanse11 daphnehanse11 marked this pull request as ready for review June 19, 2026 14:42
@MaxGhenis

Copy link
Copy Markdown
Contributor

Reviewed in depth (agent-assisted). The Part A amounts check out against the CMS 2026 fact sheet ($565/$311, QMB-months proration correct), but three things block merge as-is:

  1. Double-count mechanism is unimplemented. spm_unit_health_insurance_premiums relies on the residual design in docs-quarto/methodology/moop-decomposition.qmd (other_health_insurance_premiums = reported non-Medicare premiums − baseline computed premiums), but nothing in policyengine-us-data writes other_health_insurance_premiums (the CPS build writes health_insurance_premiums_without_medicare_part_b from PHIP_VAL, which includes Part A/D amounts). Adding modeled Part A + Part D IRMAA on top will double-count once that input is populated. The data-side subtraction should land with (or before) this, and the methodology doc's component table should list the two new components.

  2. The May 29 self-review is still open: only the Part D IRMAA surcharge enters MOOP, not the base plan premium, so MOOP rises only for IRMAA-band (high-income) beneficiaries. Either add the base premium path or narrow all doc strings to IRMAA-only and note the gap.

  3. msp_part_a_premium_coverage gates on is_qmb_eligible, while msp_part_b_premium_coverage deliberately gates on msp_income_eligible & msp_asset_eligible to avoid the Medicaid → medically-needy → MOOP cycle. It appears cycle-safe today, but mirroring the Part B pattern (or documenting why the QMB gate is safe) would prevent a future cycle.

Also: draft #8721 duplicates the two new variables and the changelog fragment from this PR (same author, fewer tests) — they hard-conflict if both land, so one should be closed; this one looks canonical.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Include Medicare Part D IRMAA and paid Part A premiums in modeled MOOP/SPM premiums

2 participants