From 1019509852bfacf90c0f95529116c3f9864dd3b2 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:31:48 -0400 Subject: [PATCH 1/2] Retire legacy marketplace coverage input --- changelog.d/fixed/8674.md | 1 + .../household/household_health_benefits.yaml | 8 +-- .../core/test_input_variable_definitions.py | 12 +++++ .../gov/aca/ptc/premium_tax_credit.yaml | 7 +++ .../has_marketplace_health_coverage.yaml | 13 +++++ .../household/healthcare_benefit_value.yaml | 14 ++++++ .../household/household_health_benefits.yaml | 49 ++++++++++++++----- .../health/has_marketplace_health_coverage.py | 11 +++-- .../household/healthcare_benefit_value.py | 5 ++ .../household/household_health_benefits.py | 6 +++ 10 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 changelog.d/fixed/8674.md create mode 100644 policyengine_us/tests/policy/baseline/gov/aca/ptc/premium_tax_credit.yaml create mode 100644 policyengine_us/tests/policy/baseline/household/expense/health/has_marketplace_health_coverage.yaml diff --git a/changelog.d/fixed/8674.md b/changelog.d/fixed/8674.md new file mode 100644 index 00000000000..645a7ca4c1a --- /dev/null +++ b/changelog.d/fixed/8674.md @@ -0,0 +1 @@ +Retired `has_marketplace_health_coverage` from active input discovery by making it a compatibility alias, and canonicalized household health benefit accounting on annual health-value variables such as `assigned_aca_ptc`. diff --git a/policyengine_us/parameters/gov/household/household_health_benefits.yaml b/policyengine_us/parameters/gov/household/household_health_benefits.yaml index be4f005eb05..7ef50fb4864 100644 --- a/policyengine_us/parameters/gov/household/household_health_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_health_benefits.yaml @@ -1,10 +1,12 @@ description: The government counts these sources as household benefits. values: 2022-01-01: - - medicaid + - medicaid_cost - msp_cost - - chip - - premium_tax_credit + - per_capita_chip + - assigned_aca_ptc + - co_omnisalud + - or_healthier_oregon_cost metadata: unit: list diff --git a/policyengine_us/tests/core/test_input_variable_definitions.py b/policyengine_us/tests/core/test_input_variable_definitions.py index 02883e15b7c..ced20379cc0 100644 --- a/policyengine_us/tests/core/test_input_variable_definitions.py +++ b/policyengine_us/tests/core/test_input_variable_definitions.py @@ -48,6 +48,18 @@ def test_input_variables_do_not_use_formulas_adds_or_subtracts(): assert invalid == {} +def test_legacy_marketplace_coverage_is_not_active_input_variable(): + system = CountryTaxBenefitSystem() + + legacy_variable = system.variables["has_marketplace_health_coverage"] + assert not legacy_variable.is_input_variable() + assert legacy_variable.formulas + assert system.variables[ + "has_marketplace_health_coverage_at_interview" + ].is_input_variable() + assert system.variables["takes_up_aca_if_eligible"].is_input_variable() + + def test_state_input_variables_match_state_defined_for(): system = CountryTaxBenefitSystem() diff --git a/policyengine_us/tests/policy/baseline/gov/aca/ptc/premium_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/aca/ptc/premium_tax_credit.yaml new file mode 100644 index 00000000000..f82f36e390f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/aca/ptc/premium_tax_credit.yaml @@ -0,0 +1,7 @@ +- name: Case 1, monthly Premium Tax Credit is one twelfth of assigned annual ACA PTC. + period: 2026-01 + absolute_error_margin: 0.01 + input: + assigned_aca_ptc: 1_200 + output: + premium_tax_credit: 100 diff --git a/policyengine_us/tests/policy/baseline/household/expense/health/has_marketplace_health_coverage.yaml b/policyengine_us/tests/policy/baseline/household/expense/health/has_marketplace_health_coverage.yaml new file mode 100644 index 00000000000..9ec02d74c65 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/household/expense/health/has_marketplace_health_coverage.yaml @@ -0,0 +1,13 @@ +- name: Case 1, legacy Marketplace coverage follows reported interview coverage. + period: 2026 + input: + has_marketplace_health_coverage_at_interview: true + output: + has_marketplace_health_coverage: true + +- name: Case 2, legacy Marketplace coverage defaults false without reported interview coverage. + period: 2026 + input: + has_marketplace_health_coverage_at_interview: false + output: + has_marketplace_health_coverage: false diff --git a/policyengine_us/tests/policy/baseline/household/healthcare_benefit_value.yaml b/policyengine_us/tests/policy/baseline/household/healthcare_benefit_value.yaml index 62a61731f5a..af34fa029f1 100644 --- a/policyengine_us/tests/policy/baseline/household/healthcare_benefit_value.yaml +++ b/policyengine_us/tests/policy/baseline/household/healthcare_benefit_value.yaml @@ -22,3 +22,17 @@ msp_cost: 2_434.8 output: healthcare_benefit_value: 2_434.8 + +- name: Case 3, annual assigned ACA PTC is the canonical ACA health benefit value. + period: 2026 + absolute_error_margin: 0.01 + input: + medicaid_cost: 0 + msp_cost: 0 + per_capita_chip: 0 + assigned_aca_ptc: 1_200 + premium_tax_credit: 99 + co_omnisalud: 0 + or_healthier_oregon_cost: 0 + output: + healthcare_benefit_value: 1_200 diff --git a/policyengine_us/tests/policy/baseline/household/household_health_benefits.yaml b/policyengine_us/tests/policy/baseline/household/household_health_benefits.yaml index 3fe73b67b11..622def5369b 100644 --- a/policyengine_us/tests/policy/baseline/household/household_health_benefits.yaml +++ b/policyengine_us/tests/policy/baseline/household/household_health_benefits.yaml @@ -1,33 +1,56 @@ -- name: flag off +- name: Case 1, flag off excludes canonical and legacy health values. period: 2026 + absolute_error_margin: 0.01 input: - gov.simulation.include_health_benefits_in_net_income: false - premium_tax_credit: 1_000 - medicaid: 500 + gov.simulation.include_health_benefits_in_net_income: false + assigned_aca_ptc: 1_000 + premium_tax_credit: 999 + medicaid_cost: 500 + medicaid: 777 snap: 0 output: household_health_benefits: 0 household_benefits: 0 -- name: flag on +- name: Case 2, flag on includes annual canonical ACA PTC and Medicaid value. period: 2026 - input: + absolute_error_margin: 0.01 + input: gov.simulation.include_health_benefits_in_net_income: true - premium_tax_credit: 1_000 - medicaid: 500 + assigned_aca_ptc: 1_000 + medicaid_cost: 500 snap: 0 output: household_health_benefits: 1_500 household_benefits: 1_500 -- name: flag on includes MSP limited-benefit cost +- name: Case 3, flag on includes annual MSP and CHIP values. + period: 2026 + absolute_error_margin: 0.01 + input: + gov.simulation.include_health_benefits_in_net_income: true + assigned_aca_ptc: 1_000 + medicaid_cost: 500 + msp_cost: 2_434.8 + per_capita_chip: 300 + snap: 0 + output: + household_health_benefits: 4_234.8 + household_benefits: 4_234.8 + +- name: Case 4, legacy wrappers do not double count canonical health values. period: 2026 + absolute_error_margin: 0.01 input: gov.simulation.include_health_benefits_in_net_income: true - premium_tax_credit: 1_000 - medicaid: 500 + assigned_aca_ptc: 1_000 + premium_tax_credit: 999 + medicaid_cost: 500 + medicaid: 777 + per_capita_chip: 300 + chip: 888 msp_cost: 2_434.8 snap: 0 output: - household_health_benefits: 3_934.8 - household_benefits: 3_934.8 + household_health_benefits: 4_234.8 + household_benefits: 4_234.8 diff --git a/policyengine_us/variables/household/expense/health/has_marketplace_health_coverage.py b/policyengine_us/variables/household/expense/health/has_marketplace_health_coverage.py index 3df2ba653a4..ddd0482b825 100644 --- a/policyengine_us/variables/household/expense/health/has_marketplace_health_coverage.py +++ b/policyengine_us/variables/household/expense/health/has_marketplace_health_coverage.py @@ -4,13 +4,16 @@ class has_marketplace_health_coverage(Variable): value_type = bool entity = Person - label = "Deprecated legacy modeled Marketplace health coverage input" + label = "Deprecated legacy Marketplace health coverage compatibility alias" definition_period = YEAR - default_value = True documentation = """ - Deprecated legacy modeled Marketplace coverage status. + Deprecated legacy Marketplace coverage status kept for compatibility. Use has_marketplace_health_coverage_at_interview for reported Marketplace coverage from survey data, and takes_up_aca_if_eligible for modeled ACA - Marketplace take-up. ACA PTC eligibility does not depend on this variable. + Marketplace take-up. ACA PTC eligibility and health benefit accounting do + not depend on this variable. """ + + def formula(person, period, parameters): + return person("has_marketplace_health_coverage_at_interview", period) diff --git a/policyengine_us/variables/household/healthcare_benefit_value.py b/policyengine_us/variables/household/healthcare_benefit_value.py index 4e0dd9b646d..3213b3e87e6 100644 --- a/policyengine_us/variables/household/healthcare_benefit_value.py +++ b/policyengine_us/variables/household/healthcare_benefit_value.py @@ -7,6 +7,11 @@ class healthcare_benefit_value(Variable): entity = Household definition_period = YEAR unit = USD + documentation = ( + "Annual canonical household resource value of health coverage. This " + "uses annual health-value and government-cost proxy variables directly, " + "including assigned_aca_ptc for ACA premium tax credits." + ) adds = [ "medicaid_cost", "msp_cost", diff --git a/policyengine_us/variables/household/income/household/household_health_benefits.py b/policyengine_us/variables/household/income/household/household_health_benefits.py index 7fc740df6e1..e02f2456c26 100644 --- a/policyengine_us/variables/household/income/household/household_health_benefits.py +++ b/policyengine_us/variables/household/income/household/household_health_benefits.py @@ -7,6 +7,12 @@ class household_health_benefits(Variable): label = "Household health benefits" unit = USD definition_period = YEAR + documentation = ( + "Annual household health coverage value included in household_benefits " + "only when gov.simulation.include_health_benefits_in_net_income is " + "enabled. Uses annual canonical health-value variables to avoid " + "double-counting monthly compatibility wrappers." + ) def formula(household, period, parameters): p = parameters(period) From 7c511ae8b2f37b55a69efa2bd4ce2c880de5b049 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:33:51 -0400 Subject: [PATCH 2/2] Fix changelog fragment path --- changelog.d/{fixed/8674.md => 8674.fixed.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{fixed/8674.md => 8674.fixed.md} (100%) diff --git a/changelog.d/fixed/8674.md b/changelog.d/8674.fixed.md similarity index 100% rename from changelog.d/fixed/8674.md rename to changelog.d/8674.fixed.md