Repository navigation
Update CMS out-of-pocket per-capita uprater to NHE projections 2025-2034 - #10084
Conversation
Replace calibration.gov.hhs.cms.moop_per_capita with Table 3 of the 2025-2034 NHE projections (2018-2024 historical estimates, 2025-2034 projections), derive 2015-2017 from the historical accounts by the rule that reproduces Table 3's 2018-2024 values, drop the hand-extended 2033-2035 values, and extend from 2034 at the 2033-2034 growth rate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hand-off to the US + core hub. Only CI and the merge remain.
|
Aggregate impact: full-population microsimulation, 2025 and 2026Informational; it doesn't hold the merge. Four full-population runs back these numbers (base and PR, for 2025 and 2026), on the default dataset
Headline
SPM resources subtract medical out-of-pocket expenses ( Uprated inputs ($ billions, weighted)Every populated input moves by exactly the ratio of the two series' factors from 2024: 1.05453 / 1.03088 = +2.29% for 2025 and 1.11887 / 1.06238 = +5.32% for 2026, matching the per-person table in the PR body.
The other 12 inputs on this uprater are zero for every record in this dataset, on both sides: physician services, inpatient, outpatient, emergency room, urgent care, ambulance, imaging, lab and prescription expenses; long-term health insurance premiums; reported Medicare Part B premiums; and HSA payroll contributions. This PR changes none of them in a default-dataset simulation. Of the 2026 change in SPM medical out-of-pocket expenses, $21.21 billion is the non-premium part ( Other outputs, 2026 ($ billions)
Unchanged in both years: Checks
Evidence (local): |
#10097 moved health_savings_account_payroll_contributions to the family HSA contribution limit, so it no longer uprates by moop_per_capita. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
US + core hub merge audit, us#10084 at
|
Summary
calibration.gov.hhs.cms.moop_per_capitais the uprater for the model's health expense inputs. It held CMS's 2023-2032 National Health Expenditure (NHE) projections (retrieved 2025-02-17), with 2033-2035 extended by hand in the YAML. This PR replaces it with the current 2025-2034 release:uprating_extensions.pyextends fromlast_projected_year=2034. Each year from 2035 to 2100 grows at CMS's 2033-2034 rate (2,512 / 2,412, 4.1% a year), and later years hold the 2100 value. That is whatextend_parameter_valuesdoes; the call site and the YAML now say so.Source verification
Downloaded and re-verified on 2026-10-11:
264f822618a5e1829138aea57cc6c8bf45bbaf072a72898fef5547f7ece6cd70b6a9e26774ca36931d42add46204947d6335fc4898011780563196898f964746Every value was read programmatically from
Table03 National Health Expenditures by Sources of Funds.xlsx(cells C24:C41), not retyped from the brief. The brief's figures for 2018-2031 match the file.2015-2017: derived, not dropped or kept
The new Table 3 starts in 2018. No historical NHE table publishes an out-of-pocket per-capita row either: historical Table 3 has out-of-pocket spending only in billions, and Tables 1 and 2 give per-capita figures for spending categories, not for sources of funds. Three options:
Keep the old 2016-2017 values (1,130 and 1,139). They are on the old vintage. Every year from 2018 to 2032, which both vintages report, moved: 2018 went from 1,181 to 1,223, 2022 from 1,425 to 1,468. Keeping them would splice two vintages and put a spurious 7.4% jump into 2017-2018, where the current vintage has 3.9%. CMS's summary of the 2024 comprehensive revision says the entire NHEA time series is opened for revision, and that 2022 out-of-pocket spending was revised up $20.4 billion.
Drop them.
backdate_parameters(tools/parameters.py) copies a parameter's earliest value back toFIRST_MODELED_YEAR(2015). The 2018 value would then apply to 2015-2017, and an input reported for 2015, 2016 or 2017 would get no health-cost growth to 2018 instead of 9.3%, 5.9% or 3.9%.Derive them on the current vintage (chosen). Each year's value is per-capita NHE (Table 1 of the same projections ZIP, which runs from 2013) times out-of-pocket spending's share of NHE in the historical accounts (
NHE2024.csv, rows "Out of pocket" and "Total National Health Expenditures", in millions), rounded to the dollar.2015 is added because it is the first modeled year: without it, 2015 took 2016's value and 2015-2016 health-cost growth was zero.
Per-person uprating change
A health expense input reported for 2024 is carried to later years by the ratio of this series. Values are the model's
system.parametersonmainand on this branch:From 2024 to 2034, per-person health expense uprating goes from +41.3% (factor 1.4126, 3.51% a year) to +53.9% (factor 1.5392, 4.41% a year). A 2024 input's 2034 value is 9.0% higher than before; for 2025 simulations it is 2.3% higher. After the source ends, the long-run rate goes from 3.59% to 4.15% a year.
These factors are parameter ratios, not microsimulation output. Weighted totals of these inputs also grow with population, through the household weights.
What uses this series
The inputs listed in
docs-quarto/methodology/spm-poverty.qmd: other medical expenses, over-the-counter health expenses, other health insurance premiums; physician services, inpatient, outpatient, emergency room, urgent care, ambulance, imaging, lab and prescription expenses; health insurance premiums in total, pre-tax, long-term and excluding Medicare Part B; and reported Medicare Part B premiums. Health savings account payroll contributions also used it until #10097 moved them to the family HSA contribution limit. #10083 movespre_tax_health_insurance_premiumsandemployer_sponsored_insurance_premiumstocalibration.gov.hhs.cms.esi_premium_per_enrollee; this PR leaves both alone. The docs page names the series without numbers, so it needs no edit (and editing its line 53 would conflict with #10083).Invariants
Tests
policyengine_us/tests/core/test_cms_moop_uprating.py(invariants 1-5, plus the set of inputs on this uprater).test_uprating_extensions.py::test_cms_moop_per_capita_extends_to_2100: 2034 is 2,512, 2035-2100 grow at the 2033-2034 rate, and 2150 equals 2100.main's YAML and extension call restored, 32 of these tests fail (transcription, historical rule, markers, monotonicity on the flat 2015-2016, extension rate).test_per_capita_uprating.py,test_uprating_series.py,test_pre_first_modeled_year_uprated_inputs.py,test_uprating_extensions.py): pass.tests/code_health: 266 passed.git merge-tree), and on the merged tree both PRs' uprating tests pass (287 passed).Review
4ea78e2: APPROVE, two wording nits.main's values), recomputed every row of the factor table, and checked that the merge with Uprate ESI premium inputs by CMS ESI premium per enrollee #10083 is clean.9d48c6e.9d48c6e: APPROVE, no findings. The delta is the docstring only; an AST comparison excluding docstrings is identical.Reports:
~/reviews/moop-nhe-2025-2034/review/(review-10084.md,delta-review-9d48c6e.md,evidence/).Microsimulation impact (full population, 2025 and 2026)
Four full-population runs back these numbers (base and PR, for 2025 and 2026), on the default dataset
populace_us_2024(buildpopulace-us-2024-spm-20260909), through the hub's heavy lock.mainat7dc07567eb.9d48c6e926(tree8871f01b19). The two snapshots differ only inmoop_per_capita.yaml,uprating_extensions.pyand tests.main, not this PR's merge-base, because Uprate ESI premium inputs by CMS ESI premium per enrollee #10083 has since merged and moved the employer-premium inputs off this uprater.Headline
SPM resources subtract medical out-of-pocket expenses (
spm_unit_net_incomesubtractsspm_unit_spm_expenses), so the higher series lowers SPM resources by $17.69 billion in 2025 and $42.65 billion in 2026 and raises measured SPM poverty. The rise in household net income matches, to rounding, the fall in household taxes plus the rise in SNAP (2026: $1.82 billion + $0.30 billion; 2025: $0.76 billion + $0.16 billion).Uprated inputs ($ billions, weighted)
Every populated input moves by exactly the ratio of the two series' factors from 2024: 1.05453 / 1.03088 = +2.29% for 2025 and 1.11887 / 1.06238 = +5.32% for 2026, matching the per-person table in the PR body.
other_medical_expensesover_the_counter_health_expensesother_health_insurance_premiumshealth_insurance_premiums_without_medicare_part_bhealth_insurance_premiumsThe other 11 inputs on this uprater are zero for every record in this dataset, on both sides: physician services, inpatient, outpatient, emergency room, urgent care, ambulance, imaging, lab and prescription expenses; long-term health insurance premiums; and reported Medicare Part B premiums. This PR changes none of them in a default-dataset simulation. (The runs predate #10097, so HSA payroll contributions, then a 12th zero input on this uprater, now follow the family HSA limit instead; the dataset has no such column.)
Of the 2026 change in SPM medical out-of-pocket expenses, $21.21 billion is the non-premium part (
other_medical_expensesplusover_the_counter_health_expenses) and $23.57 billion isother_health_insurance_premiums. #10085 (open) moves the five premium inputs on this uprater, including the three populated ones above, to premium series; if it merges, only the non-premium part stays attributable to this PR.Other outputs, 2026 ($ billions)
itemized_medical_expensesitemized_taxable_income_deductionsself_employed_health_insurance_aldadjusted_gross_incometaxable_incomehousehold_taxUnchanged in both years:
employee_payroll_tax,ssiandmsp(zero records changed).medicaidtotals $880.02 billion on both sides. Its record values shift (2026: 9 records up, 4,159 down, about $1.12 billion each way) becausemedicaid_cost_if_enrolledsplits each state's fixed spending total across that state's enrollees.spm_unit_capped_housing_subsidyrises by $2.8 million in 2026.Checks
pre_tax_health_insurance_premiumsandemployer_sponsored_insurance_premiumswere included as controls. They are zero in this dataset, so the microsimulation can't show they stay put; a separate check of both snapshots confirms they uprate byesi_premium_per_enrolleeon both sides.264f8226…cd70), equal this PR's YAML in every year.Evidence (local):
~/reviews/moop-nhe-2025-2034-aggregates-2026-10/holds the snapshots' SHAs, the driver, per-record outputs,compare.2025.json,compare.2026.jsonand the full 45-variable tables inimpact/summary.2025.mdandimpact/summary.2026.md.axiom: n/a: calibration uprating data, not a policy rule
🤖 Generated with Claude Code