From 372e72caae73ca82a65d41d1f8449d536ef5ac05 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 07:41:05 -0400 Subject: [PATCH 1/4] Update CMS out-of-pocket per-capita uprater to NHE projections 2025-2034 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 --- .../moop-nhe-2025-2034-refresh.changed.md | 1 + .../gov/hhs/cms/moop_per_capita.yaml | 78 ++++-- .../parameters/uprating_extensions.py | 6 +- .../tests/core/test_cms_moop_uprating.py | 265 ++++++++++++++++++ .../parameters/test_uprating_extensions.py | 14 +- 5 files changed, 327 insertions(+), 37 deletions(-) create mode 100644 changelog.d/moop-nhe-2025-2034-refresh.changed.md create mode 100644 policyengine_us/tests/core/test_cms_moop_uprating.py diff --git a/changelog.d/moop-nhe-2025-2034-refresh.changed.md b/changelog.d/moop-nhe-2025-2034-refresh.changed.md new file mode 100644 index 00000000000..37cdde11b0f --- /dev/null +++ b/changelog.d/moop-nhe-2025-2034-refresh.changed.md @@ -0,0 +1 @@ +Update CMS out-of-pocket health spending per capita, the uprater for health expense inputs, to the NHE projections 2025-2034 release (2018-2034 from Table 3, 2015-2017 from the historical accounts), and extend it from 2034 at the 2033-2034 growth rate instead of hand-extended 2033-2035 values. diff --git a/policyengine_us/parameters/calibration/gov/hhs/cms/moop_per_capita.yaml b/policyengine_us/parameters/calibration/gov/hhs/cms/moop_per_capita.yaml index 57299d53f88..0b9aaac29c2 100644 --- a/policyengine_us/parameters/calibration/gov/hhs/cms/moop_per_capita.yaml +++ b/policyengine_us/parameters/calibration/gov/hhs/cms/moop_per_capita.yaml @@ -1,35 +1,51 @@ -description: The Centers for Medicare and Medicaid Services (CMS) projects these per-capita out-of-pocket health payments. +description: The Centers for Medicare and Medicaid Services (CMS) reports and projects this out-of-pocket health spending per capita. metadata: unit: currency-USD - label: Per-capita MOOP + label: CMS out-of-pocket health spending per capita reference: - # Data underlying figures: - # https://www.cms.gov/files/zip/nhe-projections-tables.zip - # Table03 National Health Expenditures by Sources of Funds - # Retrieved 2025-02-17. - - title: NHE Projections - href: https://www.cms.gov/data-research/statistics-trends-and-reports/national-health-expenditure-data/projected + # Table03 National Health Expenditures by Sources of Funds, "Per Capita + # Amount" block, "Out-of-Pocket Payments" column: historical estimates for + # 2018-2024 and projections for 2025-2034. ZIP Last-Modified 2026-09-03, + # sha256 264f822618a5e1829138aea57cc6c8bf45bbaf072a72898fef5547f7ece6cd70, + # retrieved 2026-10-11 from + # https://www.cms.gov/data-research/statistics-trends-and-reports/national-health-expenditure-data/projected + - title: CMS National Health Expenditure Projections 2025-2034, Table 3 + href: https://www.cms.gov/files/zip/nhe-projections-tables.zip + # 2015-2017 are before Table03's first year. Each is that year's per-capita + # national health expenditures (Table01 of the projections ZIP above) times + # out-of-pocket spending's share of national health expenditures (NHE2024.csv + # rows "Out of pocket" and "Total National Health Expenditures", millions), + # rounded to the dollar. The same rule reproduces every published 2018-2024 + # value. ZIP Last-Modified 2026-01-13, sha256 + # b6a9e26774ca36931d42add46204947d6335fc4898011780563196898f964746, + # retrieved 2026-10-11 from + # https://www.cms.gov/data-research/statistics-trends-and-reports/national-health-expenditure-data/historical + - title: CMS National Health Expenditures by Type of Service and Source of Funds, Calendar Years 1960-2024 + href: https://www.cms.gov/files/zip/national-health-expenditures-type-service-source-funds-cy-1960-2024.zip values: - # Historical. - 2016-01-01: 1_130 - 2017-01-01: 1_139 - 2018-01-01: 1_181 - 2019-01-01: 1_227 - 2020-01-01: 1_210 - 2021-01-01: 1_341 - 2022-01-01: 1_425 - # Projections. - 2023-01-01: 1_528 - 2024-01-01: 1_619 - 2025-01-01: 1_669 - 2026-01-01: 1_720 - 2027-01-01: 1_786 - 2028-01-01: 1_851 - 2029-01-01: 1_917 - 2030-01-01: 1_985 - 2031-01-01: 2_057 - 2032-01-01: 2_131 - # Applying the same growth rate as 2031-2032. - 2033-01-01: 2_208 # 2_131 * (2_131 / 2_057) - 2034-01-01: 2_287 # 2_131 * (2_131 / 2_057)^2 - 2035-01-01: 2_369 # 2_131 * (2_131 / 2_057)^3 + # Computed from CMS's historical accounts; see the second reference. + 2015-01-01: 1_119 + 2016-01-01: 1_155 + 2017-01-01: 1_177 + # Historical Estimates. + 2018-01-01: 1_223 + 2019-01-01: 1_269 + 2020-01-01: 1_239 + 2021-01-01: 1_372 + 2022-01-01: 1_468 + 2023-01-01: 1_555 + 2024-01-01: 1_632 + # Projected. + 2025-01-01: 1_721 + 2026-01-01: 1_826 + 2027-01-01: 1_892 + 2028-01-01: 1_974 + 2029-01-01: 2_053 + 2030-01-01: 2_139 + 2031-01-01: 2_223 + 2032-01-01: 2_314 + 2033-01-01: 2_412 + 2034-01-01: 2_512 + # 2035 to 2100 grow at the 2033-2034 rate (2_512 / 2_412, 4.1% a year) + # and later years hold the 2100 value; see set_all_uprating_parameters in + # uprating_extensions.py. diff --git a/policyengine_us/parameters/uprating_extensions.py b/policyengine_us/parameters/uprating_extensions.py index 037fa7898d2..f20f07f8ffb 100644 --- a/policyengine_us/parameters/uprating_extensions.py +++ b/policyengine_us/parameters/uprating_extensions.py @@ -840,10 +840,12 @@ def set_all_uprating_parameters(parameters: ParameterNode) -> ParameterNode: ) # CMS per-capita out-of-pocket medical spending (January values, last - # projection year 2035). Health expense inputs use this as their uprater. + # projection year 2034). Health expense inputs use this as their uprater. + # Each year from 2035 to 2100 grows at CMS's 2033-2034 rate, and later + # years hold the 2100 value. extend_parameter_values( parameters.calibration.gov.hhs.cms.moop_per_capita, - last_projected_year=2035, + last_projected_year=2034, end_year=END_YEAR, period_month=1, period_day=1, diff --git a/policyengine_us/tests/core/test_cms_moop_uprating.py b/policyengine_us/tests/core/test_cms_moop_uprating.py new file mode 100644 index 00000000000..da09a4ee358 --- /dev/null +++ b/policyengine_us/tests/core/test_cms_moop_uprating.py @@ -0,0 +1,265 @@ +"""The CMS out-of-pocket health spending per capita series that health +expense inputs uprate by. + +CMS's National Health Expenditure (NHE) projections (Table 3, 2025-2034 +release) report out-of-pocket spending per capita for 2018 to 2034: historical +estimates through 2024 and projections from 2025. The parameter holds that +column. 2015 to 2017 come from CMS's historical accounts by the rule that +reproduces Table 3's 2018-2024 values, and 2035 to 2100 grow at the 2033-2034 +rate. + +These tests read only the parameter tree and the parameter's YAML file. + +Invariants: + +1. Transcription: every 2018-2034 value is Table 3's published dollar figure, + and is consistent with the same release's out-of-pocket and national + health expenditure aggregates (Table 3) and per-capita national health + expenditures (Table 1) within rounding. +2. Historical rule: for 2015 to 2024, the value is per-capita national health + expenditures times out-of-pocket spending's share of national health + expenditures in the historical accounts, rounded to the dollar. For + 2018-2024 that reproduces Table 3, which is what licenses the rule for + 2015-2017. The historical accounts and the projections share their + historical years, so the two sources are one vintage. +3. Markers: the YAML marks 2018-2024 as historical estimates and 2025-2034 as + projected, as Table 3 does, and has no hand-extended years after 2034. +4. Bounds and order: the series is positive in every year. It is strictly + increasing over 2015-2019 and 2020-2100; its one decline, 2019 to 2020 + (1,269 to 1,239), is CMS's and is intended. +5. Extension rule: each year from 2035 to 2100 grows by 2,512 / 2,412, so the + value equals the closed form 2,512 * (2,512 / 2,412) ** (year - 2034); later + years hold the 2100 value. +""" + +import math +from pathlib import Path + +import pytest +import yaml +from hypothesis import given +from hypothesis import strategies as st +from policyengine_core.parameters.operations.get_parameter import get_parameter + +from policyengine_us.system import system + +MOOP = "calibration.gov.hhs.cms.moop_per_capita" +YAML_PATH = ( + Path(__file__).parents[2] + / "parameters" + / "calibration" + / "gov" + / "hhs" + / "cms" + / "moop_per_capita.yaml" +) +FIRST_YEAR, FIRST_TABLE_YEAR, FIRST_PROJECTED_YEAR = 2015, 2018, 2025 +LAST_PROJECTED_YEAR, END_YEAR = 2034, 2100 +TABLE_YEARS = range(FIRST_TABLE_YEAR, LAST_PROJECTED_YEAR + 1) +ACCOUNT_YEARS = range(FIRST_YEAR, FIRST_PROJECTED_YEAR) +# Health expense inputs that uprate by this series, as listed in +# docs-quarto/methodology/spm-poverty.qmd. Pre-tax health insurance premiums +# also use it today; PR #10083 moves them to the ESI premium series, so they +# are left out here. +HEALTH_INPUTS = { + "ambulance_expense", + "er_visit_expense", + "health_insurance_premiums", + "health_insurance_premiums_without_medicare_part_b", + "health_savings_account_contributions", + "imaging_expense", + "inpatient_expense", + "lab_expense", + "long_term_health_insurance_premiums", + "medicare_part_b_premiums_reported", + "other_health_insurance_premiums", + "other_medical_expenses", + "outpatient_expense", + "over_the_counter_health_expenses", + "physician_services_expense", + "prescription_expense", + "urgent_care_expense", +} + +# CMS NHE projections tables +# (https://www.cms.gov/files/zip/nhe-projections-tables.zip, Last-Modified +# 2026-09-03, sha256 264f8226...cd70). +# Table 3, "Per Capita Amount" block, "Out-of-Pocket Payments" column. +OOP_PER_CAPITA = dict( + zip( + TABLE_YEARS, + ( + *(1_223, 1_269, 1_239, 1_372, 1_468, 1_555, 1_632), + *(1_721, 1_826, 1_892, 1_974, 2_053, 2_139, 2_223, 2_314), + *(2_412, 2_512), + ), + ) +) +# Table 3, "Amount in Billions" block, "Out-of-Pocket Payments" and "Total". +OOP_BILLIONS = dict( + zip( + TABLE_YEARS, + ( + *(403.0, 420.4, 412.3, 457.2, 491.9, 525.4, 556.6, 591.1, 627.9), + *(651.8, 681.1, 710.0, 742.1, 773.6, 808.0, 845.1, 883.2), + ), + ) +) +NHE_BILLIONS = dict( + zip( + TABLE_YEARS, + ( + *(3637.7, 3805.1, 4204.3, 4376.9, 4586.6, 4925.3, 5278.6), + *(5661.7, 6017.4, 6301.6, 6627.1, 6966.6, 7316.0, 7689.0), + *(8074.7, 8510.9, 8970.3), + ), + ) +) +# Table 1, "Per Capita Amount" block, "National Health Expenditures" row. +NHE_PER_CAPITA = dict( + zip( + range(FIRST_YEAR, LAST_PROJECTED_YEAR + 1), + ( + *(9_860, 10_229, 10_582, 11_042, 11_487, 12_637, 13_137), + *(13_689, 14_580, 15_474, 16_486, 17_496, 18_295, 19_204), + *(20_141, 21_092, 22_095, 23_124, 24_289, 25_513), + ), + ) +) +# CMS historical accounts, NHE2024.csv rows "Out of pocket" and "Total +# National Health Expenditures", millions +# (https://www.cms.gov/files/zip/national-health-expenditures-type-service-source-funds-cy-1960-2024.zip, +# Last-Modified 2026-01-13, sha256 b6a9e267...4746). +OOP_MILLIONS = dict( + zip( + ACCOUNT_YEARS, + ( + *(360_681, 375_394, 385_333, 403_033, 420_412, 412_276), + *(457_160, 491_924, 525_424, 556_554), + ), + ) +) +NHE_MILLIONS = dict( + zip( + ACCOUNT_YEARS, + ( + *(3_177_216, 3_324_095, 3_464_208, 3_637_678, 3_805_121), + *(4_204_311, 4_376_932, 4_586_625, 4_925_324, 5_278_588), + ), + ) +) +EXTENSION_GROWTH = 2_512 / 2_412 + + +def _index(year): + return get_parameter(system.parameters, MOOP)(f"{year}-01-01") + + +def _round_half_up(value): + return math.floor(value + 0.5) + + +def _historical_rule(year, per_capita_nhe=None): + per_capita_nhe = NHE_PER_CAPITA[year] if per_capita_nhe is None else per_capita_nhe + return per_capita_nhe * OOP_MILLIONS[year] / NHE_MILLIONS[year] + + +@pytest.mark.parametrize("year", TABLE_YEARS) +def test_index_is_table_3_out_of_pocket_per_capita(year): + assert _index(year) == OOP_PER_CAPITA[year] + + +@pytest.mark.parametrize("year", TABLE_YEARS) +def test_published_values_match_aggregates_and_per_capita_nhe(year): + """Checks the transcribed rows against each other, so one mistyped + per-capita, aggregate or per-capita NHE figure fails.""" + # The aggregates are rounded to $0.1 billion, per-capita NHE to the + # dollar, and the published value to the dollar. + low = (NHE_PER_CAPITA[year] - 0.5) * (OOP_BILLIONS[year] - 0.05) + low = low / (NHE_BILLIONS[year] + 0.05) - 0.5 + high = (NHE_PER_CAPITA[year] + 0.5) * (OOP_BILLIONS[year] + 0.05) + high = high / (NHE_BILLIONS[year] - 0.05) + 0.5 + assert low <= OOP_PER_CAPITA[year] <= high + + +@pytest.mark.parametrize("year", range(FIRST_TABLE_YEAR, FIRST_PROJECTED_YEAR)) +def test_historical_accounts_share_the_projections_historical_years(year): + assert OOP_MILLIONS[year] / 1_000 == pytest.approx(OOP_BILLIONS[year], abs=0.05) + assert NHE_MILLIONS[year] / 1_000 == pytest.approx(NHE_BILLIONS[year], abs=0.05) + + +@pytest.mark.parametrize("year", ACCOUNT_YEARS) +def test_values_through_2024_follow_the_historical_rule(year): + computed = _historical_rule(year) + assert _index(year) == _round_half_up(computed) + # Per-capita NHE is rounded to the dollar; rounding the result is + # unambiguous anywhere in that range. + low = _historical_rule(year, NHE_PER_CAPITA[year] - 0.5) + high = _historical_rule(year, NHE_PER_CAPITA[year] + 0.5) + assert _round_half_up(low) == _round_half_up(high) + if year >= FIRST_TABLE_YEAR: + assert _round_half_up(computed) == OOP_PER_CAPITA[year] + + +def test_yaml_marks_historical_and_projected_years_as_table_3_does(): + lines = YAML_PATH.read_text().splitlines() + + def comment_before(date): + index = next( + i for i, line in enumerate(lines) if line.strip().startswith(f"{date}:") + ) + return lines[index - 1].strip() + + assert comment_before(f"{FIRST_TABLE_YEAR}-01-01") == "# Historical Estimates." + assert comment_before(f"{FIRST_PROJECTED_YEAR}-01-01") == "# Projected." + + values = yaml.safe_load(YAML_PATH.read_text())["values"] + years = sorted(date.year for date in values) + assert years == list(range(FIRST_YEAR, LAST_PROJECTED_YEAR + 1)) + + +@given(st.integers(FIRST_YEAR, END_YEAR + 100)) +def test_index_is_positive(year): + assert _index(year) > 0 + + +@given( + st.sampled_from([(FIRST_YEAR, 2019), (2020, END_YEAR)]), + st.integers(0, END_YEAR - FIRST_YEAR), + st.integers(1, END_YEAR - FIRST_YEAR), +) +def test_index_is_strictly_increasing_where_cms_is(segment, offset, gap): + start, end = segment + year = start + offset % (end - start) + later = min(year + gap, end) + assert _index(year) < _index(later) + + +def test_the_only_decline_is_cms_2019_to_2020(): + declines = [ + year + for year in range(FIRST_YEAR + 1, END_YEAR + 1) + if _index(year) < _index(year - 1) + ] + assert declines == [2020] + assert (_index(2019), _index(2020)) == (1_269, 1_239) + + +@given(st.integers(LAST_PROJECTED_YEAR + 1, END_YEAR)) +def test_extension_holds_the_last_projected_growth_rate(year): + growth = _index(year) / _index(year - 1) + assert growth == pytest.approx(EXTENSION_GROWTH, rel=1e-12) + closed_form = 2_512 * EXTENSION_GROWTH ** (year - LAST_PROJECTED_YEAR) + assert _index(year) == pytest.approx(closed_form, rel=1e-12) + + +@given(st.integers(END_YEAR, END_YEAR + 200)) +def test_index_holds_the_2100_value_after_2100(year): + assert _index(year) == _index(END_YEAR) + + +def test_health_inputs_uprate_by_the_cms_series(): + users = { + name for name, variable in system.variables.items() if variable.uprating == MOOP + } + assert users - {"pre_tax_health_insurance_premiums"} == HEALTH_INPUTS diff --git a/policyengine_us/tests/policy/baseline/parameters/test_uprating_extensions.py b/policyengine_us/tests/policy/baseline/parameters/test_uprating_extensions.py index 9049852d5a0..9c1af14d1bf 100644 --- a/policyengine_us/tests/policy/baseline/parameters/test_uprating_extensions.py +++ b/policyengine_us/tests/policy/baseline/parameters/test_uprating_extensions.py @@ -131,11 +131,17 @@ def test_social_security_benefit_inputs_use_gross_benefit_uprater(): def test_cms_moop_per_capita_extends_to_2100(): - """Health expense input upraters should not flatten after 2035.""" + """Health expense input upraters keep growing after CMS's 2034 + projection, at the 2033-2034 growth rate, then hold the 2100 value.""" parameter = PARAMETERS.calibration.gov.hhs.cms.moop_per_capita - - assert parameter("2036-01-01") > parameter("2035-01-01") - assert parameter("2100-01-01") > parameter("2036-01-01") + last_growth = parameter("2034-01-01") / parameter("2033-01-01") + + assert parameter("2034-01-01") == 2_512 + assert last_growth == pytest.approx(2_512 / 2_412, rel=1e-12) + for year in [2035, 2036, 2050, 2100]: + growth = parameter(f"{year}-01-01") / parameter(f"{year - 1}-01-01") + assert growth == pytest.approx(last_growth, rel=1e-12) + assert parameter("2150-01-01") == parameter("2100-01-01") def test_soi_income_upraters_extend_without_trustees_reform(): From 4ea78e28ce9dfcaedfe2a03d7b0620ef40535c27 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 07:45:11 -0400 Subject: [PATCH 2/4] Fix HSA variable name and limit rounding check to derived years Co-Authored-By: Claude Opus 5.5 --- .../tests/core/test_cms_moop_uprating.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/policyengine_us/tests/core/test_cms_moop_uprating.py b/policyengine_us/tests/core/test_cms_moop_uprating.py index da09a4ee358..4a4400b9dbd 100644 --- a/policyengine_us/tests/core/test_cms_moop_uprating.py +++ b/policyengine_us/tests/core/test_cms_moop_uprating.py @@ -66,7 +66,7 @@ "er_visit_expense", "health_insurance_premiums", "health_insurance_premiums_without_medicare_part_b", - "health_savings_account_contributions", + "health_savings_account_payroll_contributions", "imaging_expense", "inpatient_expense", "lab_expense", @@ -192,13 +192,15 @@ def test_historical_accounts_share_the_projections_historical_years(year): def test_values_through_2024_follow_the_historical_rule(year): computed = _historical_rule(year) assert _index(year) == _round_half_up(computed) - # Per-capita NHE is rounded to the dollar; rounding the result is - # unambiguous anywhere in that range. - low = _historical_rule(year, NHE_PER_CAPITA[year] - 0.5) - high = _historical_rule(year, NHE_PER_CAPITA[year] + 0.5) - assert _round_half_up(low) == _round_half_up(high) if year >= FIRST_TABLE_YEAR: assert _round_half_up(computed) == OOP_PER_CAPITA[year] + else: + # For the derived years, per-capita NHE is rounded to the dollar and + # the result rounds to the same dollar anywhere in that range. (Not + # so for 2024, whose range straddles 1,631.5; Table 3 settles it.) + low = _historical_rule(year, NHE_PER_CAPITA[year] - 0.5) + high = _historical_rule(year, NHE_PER_CAPITA[year] + 0.5) + assert _round_half_up(low) == _round_half_up(high) def test_yaml_marks_historical_and_projected_years_as_table_3_does(): From 9d48c6e926a8503817767e8614d94f7b22391d5d Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 11:31:47 -0400 Subject: [PATCH 3/4] Qualify the interval check's typo detection in its docstring Co-Authored-By: Claude Opus 5.5 --- policyengine_us/tests/core/test_cms_moop_uprating.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/policyengine_us/tests/core/test_cms_moop_uprating.py b/policyengine_us/tests/core/test_cms_moop_uprating.py index 4a4400b9dbd..1a9f91f50fa 100644 --- a/policyengine_us/tests/core/test_cms_moop_uprating.py +++ b/policyengine_us/tests/core/test_cms_moop_uprating.py @@ -171,8 +171,9 @@ def test_index_is_table_3_out_of_pocket_per_capita(year): @pytest.mark.parametrize("year", TABLE_YEARS) def test_published_values_match_aggregates_and_per_capita_nhe(year): - """Checks the transcribed rows against each other, so one mistyped - per-capita, aggregate or per-capita NHE figure fails.""" + """Checks three independently transcribed rows for consistency within + publication rounding. A mistyped figure fails unless it stays inside that + tolerance (883.3 for 2034's 883.2 would pass).""" # The aggregates are rounded to $0.1 billion, per-capita NHE to the # dollar, and the published value to the dollar. low = (NHE_PER_CAPITA[year] - 0.5) * (OOP_BILLIONS[year] - 0.05) From b54729f103cd6b8f9712cccc6b1ff22e5d82f9b9 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 12 Oct 2026 13:45:44 -0400 Subject: [PATCH 4/4] Leave HSA payroll contributions out of the CMS series' input list #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 --- policyengine_us/tests/core/test_cms_moop_uprating.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/policyengine_us/tests/core/test_cms_moop_uprating.py b/policyengine_us/tests/core/test_cms_moop_uprating.py index 1a9f91f50fa..ee6aabcb755 100644 --- a/policyengine_us/tests/core/test_cms_moop_uprating.py +++ b/policyengine_us/tests/core/test_cms_moop_uprating.py @@ -60,13 +60,13 @@ # Health expense inputs that uprate by this series, as listed in # docs-quarto/methodology/spm-poverty.qmd. Pre-tax health insurance premiums # also use it today; PR #10083 moves them to the ESI premium series, so they -# are left out here. +# are left out here. HSA payroll contributions follow the family HSA +# contribution limit since #10097. HEALTH_INPUTS = { "ambulance_expense", "er_visit_expense", "health_insurance_premiums", "health_insurance_premiums_without_medicare_part_b", - "health_savings_account_payroll_contributions", "imaging_expense", "inpatient_expense", "lab_expense",