Skip to content

MOOP should use computed premiums instead of fully imputed, so reforms propagate to SPM #8089

@MaxGhenis

Description

@MaxGhenis

Follow-up from #8086 and #8088.

Problem

Medical out-of-pocket expenses (MOOP) are used to compute SPM resources:

spm_unit_net_income = market_income + benefits − taxes − spm_expenses
spm_expenses         = child_support + medical_out_of_pocket_expenses + capped_childcare
medical_out_of_pocket_expenses = health_insurance_premiums + other_medical_expenses

health_insurance_premiums (and its Medicare-Part-B split) are pure CPS-imputed inputs — no formula, just survey data uprated via calibration.gov.hhs.cms.moop_per_capita:

  • policyengine_us/variables/household/expense/health/health_insurance_premiums_without_medicare_part_b.py
  • policyengine_us/variables/household/expense/health/medicare_part_b_premiums.py

This means:

  • Baseline SPM is fine: imputed MOOP already includes whatever CHIP / Medicare / Marketplace premiums CPS respondents reported.
  • Reforms break: if a reform eliminates CHIP premiums, simulated chip_premium drops to zero, but MOOP (survey-imputed) doesn't change, so SPM resources don't respond. Same for Medicare Part B IRMAA reforms, Marketplace benchmark changes, etc.

Proposed architecture

Whatever we compute from policy rules should replace (not add to) the corresponding slice of imputed MOOP:

medical_out_of_pocket_expenses = imputed_moop_residual
                                + computed_chip_premium
                                + computed_medicare_part_b_premium
                                + computed_marketplace_net_premium
                                + other_computed_premiums...

where

imputed_moop_residual = imputed_moop_total - baseline_computed_premium_sum

baseline_computed_premium_sum is pre-computed per CPS record during data construction using the rules that were in effect during the CPS reference year (currently 2024). In baseline simulations the two cancel; in reforms the computed piece moves and SPM adjusts correctly.

What's computable today

Program Can we compute it from rules? Status
CHIP premiums Yes — #8086 chip_premium (17 states)
Medicare Part B Yes — statutory base + IRMAA tiers by MAGI Not computed
Marketplace net premium Yes — silver benchmark × applicable-fig percent of income − PTC premium_tax_credit computed; net premium not assembled
Medicaid cost-sharing Partial — varies widely by state Out of scope
Copays / deductibles No — not rule-driven Stay in imputed residual

Staging

  1. us-model (this issue / follow-up PR) — add chip_premium to the MOOP chain so reforms to CHIP premiums propagate to SPM. Accepts a small baseline double-count until step 2 lands.
  2. us-data — during data construction, compute each CPS record's CHIP premium under 2024 rules (the reference year) and subtract it from the imputed health_insurance_premiums_without_medicare_part_b component. After this, baseline reconciles exactly.
  3. us-model (later) — rules-based Medicare Part B (standard premium + IRMAA by MAGI tier), plug into same MOOP chain.
  4. us-data (later) — strip Medicare Part B from imputed MOOP using 2024 rules.
  5. us-model / us-data (later) — rules-based Marketplace net premium using existing premium_tax_credit plus benchmark × affordability percent.

Notes

  • The "2024 rules" requirement for step 2 comes from the CPS reference year. As the dataset updates (CPS ASEC 2026 → reference year 2025 etc.), the anchor year updates too.
  • Entity-mismatch caveat: chip_premium is TaxUnit-level, medical_out_of_pocket_expenses is Person-level. Aggregation goes through add() at the SPM unit level (existing precedent: spm_unit_benefits adds TaxUnit-level premium_tax_credit). Architecturally clean at the SPM-unit boundary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions