From 3ae1258b929374d9dac5dd5856d386f840e97ed4 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 12 Oct 2026 14:34:05 -0400 Subject: [PATCH 1/7] Add Utah state supplementation for 2026 --- changelog.d/ut-ssp-2026.added.md | 1 + .../household/household_state_benefits.yaml | 4 + .../hud/annual_income/sources/unearned.yaml | 1 + .../gov/states/ut/dhhs/ssp/amount.yaml | 10 ++ .../ut/dhhs/ssp/minimum_ssi_payment.yaml | 10 ++ .../usda/snap/income/sources/unearned.yaml | 7 +- policyengine_us/programs.yaml | 8 ++ ...si_state_supplement_medicaid_dependency.py | 21 +++- .../gov/states/ut/dhhs/ssp/integration.yaml | 23 ++++ .../gov/states/ut/dhhs/ssp/ut_ssp.yaml | 117 ++++++++++++++++++ ...icaid_enrolled_for_ssi_state_supplement.py | 35 +++--- .../gov/states/ut/dhhs/ssp/ut_ssp.py | 12 ++ .../gov/states/ut/dhhs/ssp/ut_ssp_eligible.py | 29 +++++ .../income/spm_unit/spm_unit_benefits.py | 1 + 14 files changed, 256 insertions(+), 23 deletions(-) create mode 100644 changelog.d/ut-ssp-2026.added.md create mode 100644 policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml create mode 100644 policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py create mode 100644 policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py diff --git a/changelog.d/ut-ssp-2026.added.md b/changelog.d/ut-ssp-2026.added.md new file mode 100644 index 00000000000..5c51948e9ba --- /dev/null +++ b/changelog.d/ut-ssp-2026.added.md @@ -0,0 +1 @@ +Add Utah's State Supplemental Payment for qualifying Medicaid institution residents, verified for 2026. diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index d2cbd6ba2d4..7574166c0cf 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -78,6 +78,7 @@ values: # DC benefits - dc_ossp # Kansas benefits + - ut_ssp - ks_sspp # Hawaii benefits - hi_oss @@ -176,6 +177,7 @@ values: # DC benefits - dc_ossp # Kansas benefits + - ut_ssp - ks_sspp # Hawaii benefits - hi_oss @@ -279,6 +281,7 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits + - ut_ssp - ks_sspp # Hawaii benefits - hi_oss @@ -382,6 +385,7 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits + - ut_ssp - ks_sspp # Hawaii benefits - hi_oss diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index d2b2bbd8675..dd9a8ead3ad 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -19,6 +19,7 @@ values: - strike_benefits - social_security - ssi + - ut_ssp - general_assistance - unemployment_compensation - child_support_received diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml new file mode 100644 index 00000000000..620bcd4ffa5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml @@ -0,0 +1,10 @@ +description: Utah provides this monthly State Supplemental Payment to qualifying Medicaid institution residents. +values: + 2008-02-01: 15 +metadata: + unit: currency-USD + period: month + label: Utah SSP amount + reference: + - title: Utah Medicaid Manual 661, Eligibility for the Supplemental Payment + href: https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml new file mode 100644 index 00000000000..be115c156c2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml @@ -0,0 +1,10 @@ +description: Utah requires at least this monthly federal SSI payment for the State Supplemental Payment. +values: + 2008-02-01: 1 +metadata: + unit: currency-USD + period: month + label: Utah SSP minimum federal SSI payment + reference: + - title: Utah Medicaid Manual 661, Eligibility for the Supplemental Payment + href: https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm diff --git a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml index 6f94d3d09b2..567336634dd 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -36,6 +36,7 @@ values: - hi_oss - id_aabd - in_ssp + - ut_ssp - ks_sspp - ky_ssp - la_oss @@ -95,9 +96,7 @@ values: metadata: reference: - - title: 7 CFR 273.9(b)(2) - href: https://www.law.cornell.edu/cfr/text/7/273.9#b_2 - - title: 7 CFR 273.9(c)(1) - href: https://www.law.cornell.edu/cfr/text/7/273.9#c_1 + - title: 7 CFR 273.9(b)(2) and (c)(1), (5) + href: https://www.law.cornell.edu/cfr/text/7/273.9 - title: POMS SI 01401.001 General Information about State Supplementation href: https://secure.ssa.gov/poms.nsf/lnx/0501401001 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 05cb1d13747..796d9783d1f 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1090,6 +1090,14 @@ programs: tracks. Unmodeled paths: grandfathered medically-needy-in-medical- institution recipients per WAC 388-478-0055(2)(b); DDA-determined / PVL track per (2)(f); and foster child in BRS per (2)(g). + - state: UT + status: complete + name: Utah SSP + full_name: Utah State Supplemental Payment + variable: ut_ssp + parameter_prefix: gov.states.ut.dhhs.ssp + verified_years: "2026" + notes: Models the fixed payment to qualifying Medicaid institution residents. - id: social_security name: Social Security diff --git a/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py b/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py index a64c80a17a7..397df101d71 100644 --- a/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py +++ b/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py @@ -35,11 +35,14 @@ def situation(year, state="IN"): } -@pytest.mark.parametrize("year", [2027, 2030, 2035]) -@pytest.mark.parametrize("state,benefit", [("IN", "in_ssp"), ("KS", "ks_sspp")]) +@pytest.mark.parametrize("year", [2026, 2027, 2030, 2035]) +@pytest.mark.parametrize( + "state,benefit", + [("IN", "in_ssp"), ("KS", "ks_sspp"), ("UT", "ut_ssp")], +) def test_ssp_snap_medicaid_calculation_order(year, state, benefit): """YAML cannot express repeated calculations in different orders.""" - variables = (benefit, "snap", "medicaid_enrolled") + variables = (benefit, "snap", "medicaid_enrolled", "hud_unearned_income") results = [] for order in (variables, variables[::-1]): simulation = Simulation(situation=situation(year, state)) @@ -54,7 +57,10 @@ def test_ssp_snap_medicaid_calculation_order(year, state, benefit): assert results[0]["snap"][1] > 0 # Kansas does not cover this childless adult through Medicaid expansion; # SNAP pass-through does not replace Medicaid's category requirement. - assert results[0]["medicaid_enrolled"].tolist() == [True, state == "IN"] + assert results[0]["medicaid_enrolled"].tolist() == [ + True, + state in {"IN", "OH", "UT"}, + ] @pytest.mark.parametrize( @@ -62,7 +68,12 @@ def test_ssp_snap_medicaid_calculation_order(year, state, benefit): ["medicaid_enrolled", "is_medicaid_eligible", "takes_up_medicaid_if_eligible"], ) @pytest.mark.parametrize( - "state,eligibility", [("IN", "in_ssp_sapn_eligible"), ("KS", "ks_sspp_eligible")] + "state,eligibility", + [ + ("IN", "in_ssp_sapn_eligible"), + ("KS", "ks_sspp_eligible"), + ("UT", "ut_ssp_eligible"), + ], ) def test_ssp_preserves_medicaid_inputs_set_after_initialization( variable, state, eligibility diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml new file mode 100644 index 00000000000..87411bc3281 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml @@ -0,0 +1,23 @@ +- name: Case 1, Utah supplement enters state benefit and SNAP income totals. + period: 2026 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ut_ssp: 180 + snap_unearned_income: 540 + household_state_benefits: 180 + hud_unearned_income: 540 +- name: Case 2, endogenous Medicaid eligibility does not create a SNAP dependency cycle. + period: 2026-01 + input: + state_code: UT + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ut_ssp: 15 + snap_unearned_income: 45 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml new file mode 100644 index 00000000000..bc3346c887c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml @@ -0,0 +1,117 @@ +# Utah Medicaid Manual 661: $15 when institutional SSI is $1 through $30. +- name: Case 1, Medicaid institutional recipient receives the fixed supplement. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ssi: 30 + ut_ssp: 15 + +- name: Case 2, one dollar institutional SSI still qualifies for the full payment. + # $49 other income less $20 = $29 countable; $30 - $29 = $1 SSI. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + social_security_retirement: 588 + output: + ssi: 1 + ut_ssp: 15 + +- name: Case 3, no federal SSI means no state payment. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + social_security_retirement: 600 + output: + ssi: 0 + ut_ssp: 0 + +- name: Case 4, Medicaid approval is required. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: false + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ut_ssp: 0 + +- name: Case 5, independent living does not receive an institutional supplement. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + output: + ssi: 994 + ut_ssp: 0 + +- name: Case 6, Utah supplement is not payable outside Utah. + period: 2026-01 + input: + state_code: WY + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ut_ssp: 0 + +- name: Case 7, medical care without majority Medicaid funding does not qualify. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: false + output: + ut_ssp: 0 + +- name: Case 8, declining SSI leaves no qualifying receipt. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + takes_up_ssi_if_eligible: false + output: + ut_ssp: 0 + +- name: Case 9, negative earnings cannot increase the fixed supplement. + period: 2026-01 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + self_employment_income: -12_000 + output: + ut_ssp: 15 + +- name: Case 10, year total includes twelve monthly payments. + period: 2026 + input: + state_code: UT + age: 65 + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ut_ssp: 180 diff --git a/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py b/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py index d02f1625c4e..3840cb737a1 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py +++ b/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py @@ -14,7 +14,7 @@ class medicaid_enrolled_for_ssi_state_supplement(Variable): ) documentation = ( "Medicaid enrollment condition for SSI/aged/blind/disabled state " - "supplement candidates only (Indiana SAPN/RCAP and Kansas SSPP). " + "supplement candidates only (Indiana, Kansas and Utah). " "SSI recipients and aged, blind, or disabled RCAP candidates do not " "need the SNAP/TANF community-engagement exclusion. Other consumers " "must use medicaid_enrolled, which retains that exclusion." @@ -22,30 +22,37 @@ class medicaid_enrolled_for_ssi_state_supplement(Variable): def formula(person, period, parameters): p = parameters(period).gov.hhs.medicaid.eligibility.work_requirements - if not p.applies: - return person("medicaid_enrolled", period) - simulation = person.simulation enrolled = simulation.get_array("medicaid_enrolled", period) if enrolled is not None: return enrolled - # SNAP counts these state supplements as income, so asking for receipt - # status here would recurse. SSP candidates qualify through SSI or - # age/blindness/disability independently of SNAP/TANF. Keep all other - # Medicaid conditions, take-up and supplied inputs in a private branch. + # SNAP counts supplements as income, so its work-requirement + # exemption cannot determine Medicaid for SSI/ABD supplement candidates. + # HUD also counts supplements. Medicaid's optional tax-filing check can + # reach HUD through rent-related tax deductions. While determining + # enrollment, withhold the supplements that require that enrollment; + # evaluate their actual grants only in the original simulation. SSI/ABD + # Medicaid eligibility does not depend on those housing tax deductions. + # Preserve all other Medicaid conditions, take-up and supplied inputs. branch_name = f"{simulation.branch_name}_ssi_state_supplement_medicaid_{period}" + overrides = { + "medicaid_enrolled_for_ssi_state_supplement": ( + period, + np.zeros(person.count, dtype=bool), + ) + } + if p.applies: + overrides["medicaid_community_engagement_pass_through_eligible"] = ( + period.first_month, + np.zeros(person.count, dtype=bool), + ) try: branch = get_override_branch( simulation, branch_name, period, - { - "medicaid_community_engagement_pass_through_eligible": ( - period.first_month, - np.zeros(person.count, dtype=bool), - ) - }, + overrides, ) return branch.calculate("medicaid_enrolled", period) finally: diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py new file mode 100644 index 00000000000..d42cca693e5 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class ut_ssp(Variable): + value_type = float + entity = Person + label = "Utah State Supplemental Payment" + definition_period = MONTH + unit = USD + defined_for = "ut_ssp_eligible" + reference = "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm" + adds = ["gov.states.ut.dhhs.ssp.amount"] diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py new file mode 100644 index 00000000000..03bb6d26327 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.status.ssi_federal_living_arrangement import ( + SSIFederalLivingArrangement, +) + + +class ut_ssp_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible for Utah State Supplemental Payment" + definition_period = MONTH + defined_for = StateCode.UT + reference = "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm" + + def formula(person, period, parameters): + p = parameters(period).gov.states.ut.dhhs.ssp + federal = parameters(period).gov.ssa.ssi.amount + ssi = person("ssi", period) + arrangement = person("ssi_federal_living_arrangement", period) + medical = arrangement == SSIFederalLivingArrangement.MEDICAL_TREATMENT_FACILITY + medicaid = person( + "medicaid_enrolled_for_ssi_state_supplement", period.this_year + ) + return ( + medical + & medicaid + & (ssi >= p.minimum_ssi_payment) + & (ssi <= federal.medical_facility) + ) diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py index 41ead044f46..4196edf186a 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py @@ -22,6 +22,7 @@ def formula(spm_unit, period, parameters): "ky_ssp", # Kentucky benefits "de_ssp", # Delaware benefits "fl_oss", + "ut_ssp", "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits From 1dad73a9b940eec3bd65ccdaf107f22045074282 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 13 Oct 2026 01:04:36 -0400 Subject: [PATCH 2/7] Normalize Utah SSP parameter and test formatting --- .../parameters/gov/household/household_state_benefits.yaml | 1 + .../parameters/gov/hud/annual_income/sources/unearned.yaml | 1 + policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml | 1 + .../parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml | 1 + .../policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml | 1 + .../tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml | 2 +- 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index 7574166c0cf..6e974da9a70 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -405,6 +405,7 @@ values: - nj_property_tax_relief # New York benefits - ny_child_care_subsidies + metadata: unit: list period: year diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index dd9a8ead3ad..41ff9bdde3f 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -30,6 +30,7 @@ values: - disability_benefits - survivor_benefits - financial_assistance + metadata: unit: list period: year diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml index 620bcd4ffa5..04065553a38 100644 --- a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml @@ -1,6 +1,7 @@ description: Utah provides this monthly State Supplemental Payment to qualifying Medicaid institution residents. values: 2008-02-01: 15 + metadata: unit: currency-USD period: month diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml index be115c156c2..91a046fd64c 100644 --- a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml @@ -1,6 +1,7 @@ description: Utah requires at least this monthly federal SSI payment for the State Supplemental Payment. values: 2008-02-01: 1 + metadata: unit: currency-USD period: month diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml index 87411bc3281..1ab4d40e8b2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml @@ -11,6 +11,7 @@ snap_unearned_income: 540 household_state_benefits: 180 hud_unearned_income: 540 + - name: Case 2, endogenous Medicaid eligibility does not create a SNAP dependency cycle. period: 2026-01 input: diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml index bc3346c887c..7e52b087d7f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml @@ -12,7 +12,7 @@ ut_ssp: 15 - name: Case 2, one dollar institutional SSI still qualifies for the full payment. - # $49 other income less $20 = $29 countable; $30 - $29 = $1 SSI. +# $49 other income less $20 = $29 countable; $30 - $29 = $1 SSI. period: 2026-01 input: state_code: UT From f39f92dd7d2d164b0e2704f959c18fb5a7351c37 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 13 Oct 2026 02:33:14 -0400 Subject: [PATCH 3/7] Fix issues from review: Utah SSP receipt gate, references and tests - Accept reported SSI receipt alongside the $1 computed-SSI floor; drop the redundant $30 bound - Cite Utah Admin. Code R414-306-6 and note state administration - State-neutral wording in the shared Medicaid helper documentation (same as OH) - Registry placement and comments, SNAP reference title, programs.yaml note - Floor cases with direct SSI inputs; reported-receipt and couple cases Co-Authored-By: Claude Opus 5.5 --- .../household/household_state_benefits.yaml | 12 ++- .../gov/states/ut/dhhs/ssp/amount.yaml | 2 + .../ut/dhhs/ssp/minimum_ssi_payment.yaml | 2 + .../usda/snap/income/sources/unearned.yaml | 4 +- policyengine_us/programs.yaml | 2 +- .../gov/states/ut/dhhs/ssp/integration.yaml | 4 +- .../gov/states/ut/dhhs/ssp/ut_ssp.yaml | 93 +++++++++++++++++-- ...icaid_enrolled_for_ssi_state_supplement.py | 2 +- .../gov/states/ut/dhhs/ssp/ut_ssp.py | 7 +- .../gov/states/ut/dhhs/ssp/ut_ssp_eligible.py | 17 ++-- .../income/spm_unit/spm_unit_benefits.py | 2 +- 11 files changed, 121 insertions(+), 26 deletions(-) diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index 6e974da9a70..562e7d2ba09 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -71,6 +71,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Utah benefits + - ut_ssp # Virginia benefits - va_child_care_subsidies # Massachusetts benefits @@ -78,7 +80,6 @@ values: # DC benefits - dc_ossp # Kansas benefits - - ut_ssp - ks_sspp # Hawaii benefits - hi_oss @@ -164,6 +165,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Utah benefits + - ut_ssp # Virginia benefits - va_child_care_subsidies # West Virginia benefits @@ -177,7 +180,6 @@ values: # DC benefits - dc_ossp # Kansas benefits - - ut_ssp - ks_sspp # Hawaii benefits - hi_oss @@ -267,6 +269,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Utah benefits + - ut_ssp # Virginia benefits - va_child_care_subsidies # West Virginia benefits @@ -281,7 +285,6 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits - - ut_ssp - ks_sspp # Hawaii benefits - hi_oss @@ -371,6 +374,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Utah benefits + - ut_ssp # Virginia benefits - va_child_care_subsidies # West Virginia benefits @@ -385,7 +390,6 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits - - ut_ssp - ks_sspp # Hawaii benefits - hi_oss diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml index 04065553a38..a0bb572b51d 100644 --- a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml @@ -7,5 +7,7 @@ metadata: period: month label: Utah SSP amount reference: + - title: Utah Admin. Code R414-306-6(2) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6 - title: Utah Medicaid Manual 661, Eligibility for the Supplemental Payment href: https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml index 91a046fd64c..feb6cdade09 100644 --- a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml @@ -7,5 +7,7 @@ metadata: period: month label: Utah SSP minimum federal SSI payment reference: + - title: Utah Admin. Code R414-306-6(2) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6 - title: Utah Medicaid Manual 661, Eligibility for the Supplemental Payment href: https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm diff --git a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml index 567336634dd..e8d2accec6a 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -36,7 +36,6 @@ values: - hi_oss - id_aabd - in_ssp - - ut_ssp - ks_sspp - ky_ssp - la_oss @@ -50,6 +49,7 @@ values: - nm_ssi_state_supplement - sc_ssi_state_supplement - tx_ssi_state_supplement + - ut_ssp - wa_ssp # Listed elsewhere: ca_state_supplement is an SPM unit variable with no # person-level counterpart. policyengine-core projects a group value onto @@ -96,7 +96,7 @@ values: metadata: reference: - - title: 7 CFR 273.9(b)(2) and (c)(1), (5) + - title: 7 CFR 273.9(b)(2) and (c)(1) href: https://www.law.cornell.edu/cfr/text/7/273.9 - title: POMS SI 01401.001 General Information about State Supplementation href: https://secure.ssa.gov/poms.nsf/lnx/0501401001 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 796d9783d1f..cc6321bf695 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1097,7 +1097,7 @@ programs: variable: ut_ssp parameter_prefix: gov.states.ut.dhhs.ssp verified_years: "2026" - notes: Models the fixed payment to qualifying Medicaid institution residents. + notes: Models the 2026 $15 monthly payment to SSI recipients in Medicaid-funded medical institutions. Utah's former federally administered optional supplement is not modeled. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml index 1ab4d40e8b2..6f35f1318ec 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml @@ -12,7 +12,7 @@ household_state_benefits: 180 hud_unearned_income: 540 -- name: Case 2, endogenous Medicaid eligibility does not create a SNAP dependency cycle. +- name: Case 2, endogenous Medicaid enrollment counts the supplement in HUD and SNAP income without a dependency cycle. period: 2026-01 input: state_code: UT @@ -22,3 +22,5 @@ output: ut_ssp: 15 snap_unearned_income: 45 + # Annual $360 SSI + $180 supplement = $540; $540 / 12 = $45 per month. + hud_unearned_income: 45 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml index 7e52b087d7f..81e068131ef 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml @@ -12,7 +12,6 @@ ut_ssp: 15 - name: Case 2, one dollar institutional SSI still qualifies for the full payment. -# $49 other income less $20 = $29 countable; $30 - $29 = $1 SSI. period: 2026-01 input: state_code: UT @@ -20,12 +19,13 @@ medicaid_enrolled: true ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true - social_security_retirement: 588 - output: ssi: 1 + output: + # $1 SSI >= $1 minimum federal SSI payment, so the $15 payment applies. + ut_ssp_eligible: true ut_ssp: 15 -- name: Case 3, no federal SSI means no state payment. +- name: Case 3, institutional SSI below one dollar does not qualify. period: 2026-01 input: state_code: UT @@ -33,9 +33,10 @@ medicaid_enrolled: true ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true - social_security_retirement: 600 + ssi: 0.50 output: - ssi: 0 + # $0.50 SSI < $1 minimum federal SSI payment and no reported receipt. + ut_ssp_eligible: false ut_ssp: 0 - name: Case 4, Medicaid approval is required. @@ -115,3 +116,83 @@ ssi_medicaid_pays_majority_of_care: true output: ut_ssp: 180 + +- name: Case 11, reported SSI receipt qualifies without a computed SSI payment. + period: 2026-01 + input: + state_code: UT + age: 50 + receives_ssi: true + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + # Age 50 with no disability inputs is not aged, blind or disabled: SSI $0. + ssi: 0 + # Reported SSI receipt meets the SSI condition: $15. + ut_ssp: 15 + +- name: Case 12, couple both in a Medicaid facility each receive the supplement. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + person2: + age: 70 + is_tax_unit_spouse: true + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Both in a facility: couple computation, $60 / 2 = $30 each with + # no income (20 CFR 416.414(b)(2)). + ssi: [30, 30] + # $30 SSI >= $1 minimum for each spouse: $15 each. + ut_ssp: [15, 15] + +- name: Case 13, couple with one spouse in a Medicaid facility pays only that spouse. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + medicaid_enrolled: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + person2: + age: 70 + is_tax_unit_spouse: true + medicaid_enrolled: true + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # One spouse in a facility: separate computation (20 CFR 416.414(b)(3)). + # person1 gets the $30 facility rate; person2 at home gets the $994 + # individual FBR. Both are eligible, so no deeming; no income. + ssi: [30, 994] + # Only person1 lives in a medical treatment facility: [$15, $0]. + ut_ssp: [15, 0] diff --git a/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py b/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py index 3840cb737a1..e5e6cf14aef 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py +++ b/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py @@ -14,7 +14,7 @@ class medicaid_enrolled_for_ssi_state_supplement(Variable): ) documentation = ( "Medicaid enrollment condition for SSI/aged/blind/disabled state " - "supplement candidates only (Indiana, Kansas and Utah). " + "supplement candidates only (state supplements that require Medicaid enrollment). " "SSI recipients and aged, blind, or disabled RCAP candidates do not " "need the SNAP/TANF community-engagement exclusion. Other consumers " "must use medicaid_enrolled, which retains that exclusion." diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py index d42cca693e5..9e2864cdcd5 100644 --- a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py @@ -8,5 +8,10 @@ class ut_ssp(Variable): definition_period = MONTH unit = USD defined_for = "ut_ssp_eligible" - reference = "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm" + # Utah administers and issues this payment itself, not through SSA + # (Manual 661, "The Payment Process"). + reference = ( + "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6", + "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm", + ) adds = ["gov.states.ut.dhhs.ssp.amount"] diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py index 03bb6d26327..cffd13e1948 100644 --- a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py @@ -10,20 +10,19 @@ class ut_ssp_eligible(Variable): label = "Eligible for Utah State Supplemental Payment" definition_period = MONTH defined_for = StateCode.UT - reference = "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm" + reference = ( + "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6", + "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm", + ) def formula(person, period, parameters): p = parameters(period).gov.states.ut.dhhs.ssp - federal = parameters(period).gov.ssa.ssi.amount - ssi = person("ssi", period) + receives_ssi = (person("ssi", period) >= p.minimum_ssi_payment) | person( + "receives_ssi", period + ) arrangement = person("ssi_federal_living_arrangement", period) medical = arrangement == SSIFederalLivingArrangement.MEDICAL_TREATMENT_FACILITY medicaid = person( "medicaid_enrolled_for_ssi_state_supplement", period.this_year ) - return ( - medical - & medicaid - & (ssi >= p.minimum_ssi_payment) - & (ssi <= federal.medical_facility) - ) + return receives_ssi & medical & medicaid diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py index 4196edf186a..31323857399 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py @@ -22,7 +22,7 @@ def formula(spm_unit, period, parameters): "ky_ssp", # Kentucky benefits "de_ssp", # Delaware benefits "fl_oss", - "ut_ssp", + "ut_ssp", # Utah benefits "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits From 0cdb5a50abb304ada142276902685bd13da075e6 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 13 Oct 2026 15:12:23 -0400 Subject: [PATCH 4/7] Leave Utah SSP out of HUD income to avoid a Medicaid cycle Counting ut_ssp as HUD income made Medicaid enrollment, rent-related tax deductions and HUD income circular, so the shared SSP Medicaid helper had to run a full-population branch in every year and the microsimulation job ran out of time and memory. Recipients live in Medicaid-funded medical institutions, so the supplement stays out of HUD income, and the helper and its core test return to main's version (only the docstring wording differs). Integration Case 2 drops its HUD check, which depended on calculation order for a January-only facility input. Co-Authored-By: Claude Opus 5.5 --- .../hud/annual_income/sources/unearned.yaml | 1 - ...si_state_supplement_medicaid_dependency.py | 21 +++--------- .../gov/states/ut/dhhs/ssp/integration.yaml | 8 ++--- ...icaid_enrolled_for_ssi_state_supplement.py | 33 ++++++++----------- .../gov/states/ut/dhhs/ssp/ut_ssp.py | 3 ++ 5 files changed, 25 insertions(+), 41 deletions(-) diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index 41ff9bdde3f..9224ea96b39 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -19,7 +19,6 @@ values: - strike_benefits - social_security - ssi - - ut_ssp - general_assistance - unemployment_compensation - child_support_received diff --git a/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py b/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py index 397df101d71..a64c80a17a7 100644 --- a/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py +++ b/policyengine_us/tests/core/test_ssi_state_supplement_medicaid_dependency.py @@ -35,14 +35,11 @@ def situation(year, state="IN"): } -@pytest.mark.parametrize("year", [2026, 2027, 2030, 2035]) -@pytest.mark.parametrize( - "state,benefit", - [("IN", "in_ssp"), ("KS", "ks_sspp"), ("UT", "ut_ssp")], -) +@pytest.mark.parametrize("year", [2027, 2030, 2035]) +@pytest.mark.parametrize("state,benefit", [("IN", "in_ssp"), ("KS", "ks_sspp")]) def test_ssp_snap_medicaid_calculation_order(year, state, benefit): """YAML cannot express repeated calculations in different orders.""" - variables = (benefit, "snap", "medicaid_enrolled", "hud_unearned_income") + variables = (benefit, "snap", "medicaid_enrolled") results = [] for order in (variables, variables[::-1]): simulation = Simulation(situation=situation(year, state)) @@ -57,10 +54,7 @@ def test_ssp_snap_medicaid_calculation_order(year, state, benefit): assert results[0]["snap"][1] > 0 # Kansas does not cover this childless adult through Medicaid expansion; # SNAP pass-through does not replace Medicaid's category requirement. - assert results[0]["medicaid_enrolled"].tolist() == [ - True, - state in {"IN", "OH", "UT"}, - ] + assert results[0]["medicaid_enrolled"].tolist() == [True, state == "IN"] @pytest.mark.parametrize( @@ -68,12 +62,7 @@ def test_ssp_snap_medicaid_calculation_order(year, state, benefit): ["medicaid_enrolled", "is_medicaid_eligible", "takes_up_medicaid_if_eligible"], ) @pytest.mark.parametrize( - "state,eligibility", - [ - ("IN", "in_ssp_sapn_eligible"), - ("KS", "ks_sspp_eligible"), - ("UT", "ut_ssp_eligible"), - ], + "state,eligibility", [("IN", "in_ssp_sapn_eligible"), ("KS", "ks_sspp_eligible")] ) def test_ssp_preserves_medicaid_inputs_set_after_initialization( variable, state, eligibility diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml index 6f35f1318ec..8aba3a8be0c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml @@ -10,9 +10,10 @@ ut_ssp: 180 snap_unearned_income: 540 household_state_benefits: 180 - hud_unearned_income: 540 + # HUD income excludes the supplement (see ut_ssp): SSI 30 * 12 = 360. + hud_unearned_income: 360 -- name: Case 2, endogenous Medicaid enrollment counts the supplement in HUD and SNAP income without a dependency cycle. +- name: Case 2, endogenous Medicaid enrollment counts the supplement in SNAP income without a dependency cycle. period: 2026-01 input: state_code: UT @@ -21,6 +22,5 @@ ssi_medicaid_pays_majority_of_care: true output: ut_ssp: 15 + # $30 SSI + $15 supplement = $45 for the month. snap_unearned_income: 45 - # Annual $360 SSI + $180 supplement = $540; $540 / 12 = $45 per month. - hud_unearned_income: 45 diff --git a/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py b/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py index e5e6cf14aef..aadcfc81799 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py +++ b/policyengine_us/variables/gov/hhs/medicaid/medicaid_enrolled_for_ssi_state_supplement.py @@ -22,37 +22,30 @@ class medicaid_enrolled_for_ssi_state_supplement(Variable): def formula(person, period, parameters): p = parameters(period).gov.hhs.medicaid.eligibility.work_requirements + if not p.applies: + return person("medicaid_enrolled", period) + simulation = person.simulation enrolled = simulation.get_array("medicaid_enrolled", period) if enrolled is not None: return enrolled - # SNAP counts supplements as income, so its work-requirement - # exemption cannot determine Medicaid for SSI/ABD supplement candidates. - # HUD also counts supplements. Medicaid's optional tax-filing check can - # reach HUD through rent-related tax deductions. While determining - # enrollment, withhold the supplements that require that enrollment; - # evaluate their actual grants only in the original simulation. SSI/ABD - # Medicaid eligibility does not depend on those housing tax deductions. - # Preserve all other Medicaid conditions, take-up and supplied inputs. + # SNAP counts these state supplements as income, so asking for receipt + # status here would recurse. SSP candidates qualify through SSI or + # age/blindness/disability independently of SNAP/TANF. Keep all other + # Medicaid conditions, take-up and supplied inputs in a private branch. branch_name = f"{simulation.branch_name}_ssi_state_supplement_medicaid_{period}" - overrides = { - "medicaid_enrolled_for_ssi_state_supplement": ( - period, - np.zeros(person.count, dtype=bool), - ) - } - if p.applies: - overrides["medicaid_community_engagement_pass_through_eligible"] = ( - period.first_month, - np.zeros(person.count, dtype=bool), - ) try: branch = get_override_branch( simulation, branch_name, period, - overrides, + { + "medicaid_community_engagement_pass_through_eligible": ( + period.first_month, + np.zeros(person.count, dtype=bool), + ) + }, ) return branch.calculate("medicaid_enrolled", period) finally: diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py index 9e2864cdcd5..fb8a6146488 100644 --- a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py @@ -10,6 +10,9 @@ class ut_ssp(Variable): defined_for = "ut_ssp_eligible" # Utah administers and issues this payment itself, not through SSA # (Manual 661, "The Payment Process"). + # NOTE: Not in the HUD income list. Recipients live in a Medicaid-funded medical + # institution (Manual 661), not HUD-assisted housing, and HUD income would make + # the Medicaid condition circular via rent tax deductions. reference = ( "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6", "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm", From 0b20d5f5435a5bb61256221cc09bd669190e8f50 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 20 Oct 2026 05:04:28 -0400 Subject: [PATCH 5/7] Add Utah's DWS state supplement and address review findings Add the Department of Workforce Services quarterly supplement (DWS Eligibility Manual 205-10) alongside the $15 DHHS payment, with SNAP excluding it (425-11) and HUD counting it; mark the registry entry partial, update descriptions and add SPM benefit and 2027 cases. Co-Authored-By: Claude Opus 5.5 --- changelog.d/ut-ssp-2026.added.md | 2 +- .../hud/annual_income/sources/unearned.yaml | 1 + .../gov/states/ut/dhhs/ssp/amount.yaml | 4 +- .../ut/dhhs/ssp/minimum_ssi_payment.yaml | 8 +- .../ssp/amount/couple/another_household.yaml | 12 + .../dws/ssp/amount/couple/own_household.yaml | 12 + .../states/ut/dws/ssp/amount/individual.yaml | 12 + .../usda/snap/income/sources/unearned.yaml | 5 +- policyengine_us/programs.yaml | 8 +- .../gov/states/ut/dhhs/ssp/integration.yaml | 153 ++++++++ .../gov/states/ut/dhhs/ssp/ut_ssp.yaml | 102 +++++- .../gov/states/ut/dws/ssp/ut_dws_ssp.yaml | 266 ++++++++++++++ .../ut/dws/ssp/ut_dws_ssp_eligible.yaml | 339 ++++++++++++++++++ .../gov/states/ut/dhhs/ssp/ut_dhhs_ssp.py | 20 ++ ...sp_eligible.py => ut_dhhs_ssp_eligible.py} | 20 +- .../gov/states/ut/dhhs/ssp/ut_ssp.py | 17 +- .../gov/states/ut/dws/ssp/ut_dws_ssp.py | 48 +++ .../states/ut/dws/ssp/ut_dws_ssp_eligible.py | 71 ++++ 18 files changed, 1079 insertions(+), 21 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/another_household.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/own_household.yaml create mode 100644 policyengine_us/parameters/gov/states/ut/dws/ssp/amount/individual.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.yaml create mode 100644 policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_dhhs_ssp.py rename policyengine_us/variables/gov/states/ut/dhhs/ssp/{ut_ssp_eligible.py => ut_dhhs_ssp_eligible.py} (50%) create mode 100644 policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py create mode 100644 policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.py diff --git a/changelog.d/ut-ssp-2026.added.md b/changelog.d/ut-ssp-2026.added.md index 5c51948e9ba..0157c1cba44 100644 --- a/changelog.d/ut-ssp-2026.added.md +++ b/changelog.d/ut-ssp-2026.added.md @@ -1 +1 @@ -Add Utah's State Supplemental Payment for qualifying Medicaid institution residents, verified for 2026. +Add Utah's state supplements to SSI recipients for 2026: the Department of Workforce Services supplement and the $15 payment to Medicaid institution residents. diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index 9b22e1cc3a7..00281846963 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -24,6 +24,7 @@ values: - wy_ssp - nc_sa_countable_for_hud - nv_oss + - ut_dws_ssp - general_assistance - total_unemployment_compensation - child_support_received diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml index a0bb572b51d..b5a945dd245 100644 --- a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/amount.yaml @@ -1,11 +1,11 @@ -description: Utah provides this monthly State Supplemental Payment to qualifying Medicaid institution residents. +description: Utah provides this amount as the monthly payment to Medicaid institution residents under the State Supplemental Payment program. values: 2008-02-01: 15 metadata: unit: currency-USD period: month - label: Utah SSP amount + label: Utah DHHS SSP amount reference: - title: Utah Admin. Code R414-306-6(2) href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6 diff --git a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml index feb6cdade09..52c533a81e7 100644 --- a/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml +++ b/policyengine_us/parameters/gov/states/ut/dhhs/ssp/minimum_ssi_payment.yaml @@ -1,13 +1,13 @@ -description: Utah requires at least this monthly federal SSI payment for the State Supplemental Payment. +description: Utah sets this amount as the minimum monthly federal Supplemental Security Income payment under the State Supplemental Payment program. values: 2008-02-01: 1 metadata: unit: currency-USD period: month - label: Utah SSP minimum federal SSI payment + label: Utah DHHS SSP minimum federal SSI payment reference: - - title: Utah Admin. Code R414-306-6(2) - href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6 - title: Utah Medicaid Manual 661, Eligibility for the Supplemental Payment href: https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm + - title: Utah Admin. Code R414-306-6(2) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6 diff --git a/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/another_household.yaml b/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/another_household.yaml new file mode 100644 index 00000000000..26b1720848a --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/another_household.yaml @@ -0,0 +1,12 @@ +description: Utah provides this amount as the monthly supplement to a couple living in the household of another under the State Supplemental Payments to Supplemental Security Income Recipients program. +values: + # DWS has republished the amounts each January since 2024; no indexing rule is published. + 2026-01-01: 12.19 + +metadata: + unit: currency-USD + period: month + label: Utah DWS SSP couple amount in the household of another + reference: + - title: Utah DWS Eligibility Manual 205-10, State Supplemental Payments to SSI Recipients (effective January 1, 2026) + href: https://jobs.utah.gov/infosource/eligibilitymanual/200_Program_Eligibility_Requirements/205-10_State_Supplemental_Payments_to_SSI_Recipients_-_General_Information.htm diff --git a/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/own_household.yaml b/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/own_household.yaml new file mode 100644 index 00000000000..efafb8a865e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/couple/own_household.yaml @@ -0,0 +1,12 @@ +description: Utah provides this amount as the monthly supplement to a couple living alone or with others in their own household under the State Supplemental Payments to Supplemental Security Income Recipients program. +values: + # DWS has republished the amounts each January since 2024; no indexing rule is published. + 2026-01-01: 5.75 + +metadata: + unit: currency-USD + period: month + label: Utah DWS SSP couple amount in their own household + reference: + - title: Utah DWS Eligibility Manual 205-10, State Supplemental Payments to SSI Recipients (effective January 1, 2026) + href: https://jobs.utah.gov/infosource/eligibilitymanual/200_Program_Eligibility_Requirements/205-10_State_Supplemental_Payments_to_SSI_Recipients_-_General_Information.htm diff --git a/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/individual.yaml b/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/individual.yaml new file mode 100644 index 00000000000..a41ea3401b5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dws/ssp/amount/individual.yaml @@ -0,0 +1,12 @@ +description: Utah provides this amount as the monthly supplement to a single person under the State Supplemental Payments to Supplemental Security Income Recipients program. +values: + # DWS has republished the amounts each January since 2024; no indexing rule is published. + 2026-01-01: 3.91 + +metadata: + unit: currency-USD + period: month + label: Utah DWS SSP single person amount + reference: + - title: Utah DWS Eligibility Manual 205-10, State Supplemental Payments to SSI Recipients (effective January 1, 2026) + href: https://jobs.utah.gov/infosource/eligibilitymanual/200_Program_Eligibility_Requirements/205-10_State_Supplemental_Payments_to_SSI_Recipients_-_General_Information.htm diff --git a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml index 07d43b5d3f1..71b5fe9abff 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -53,7 +53,10 @@ values: - pa_ssp - sc_ssi_state_supplement - tx_ssi_state_supplement - - ut_ssp + # Utah exempts its Department of Workforce Services supplement + # (ut_dws_ssp) from SNAP income (DWS Eligibility Manual 425-11). + # The model follows that exemption, which cites no 273.9(c) exclusion. + - ut_dhhs_ssp - wa_ssp - wy_ssp # Listed elsewhere: ca_state_supplement is an SPM unit variable with no diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index f90f9596c8a..e4b43876b7d 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1149,13 +1149,17 @@ programs: notes: Models 2026 basic and enhanced facility and in-home payments, including lower contracted rates and first-month proration. Open/shut and discharge payments are not modeled. - state: UT - status: complete + status: partial name: Utah SSP full_name: Utah State Supplemental Payment variable: ut_ssp parameter_prefix: gov.states.ut.dhhs.ssp verified_years: "2026" - notes: Models the 2026 $15 monthly payment to SSI recipients in Medicaid-funded medical institutions. Utah's former federally administered optional supplement is not modeled. + notes: >- + Models the 2026 Department of Workforce Services supplement, paid + quarterly to SSI recipients and over-income applicants other than + single individuals living alone, and the $15 monthly payment to SSI + recipients in Medicaid-funded medical institutions. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml index 8aba3a8be0c..18c99456130 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/integration.yaml @@ -6,12 +6,16 @@ medicaid_enrolled: true ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true + # SNAP take-up off keeps projected SNAP out of spm_unit_benefits. + takes_up_snap_if_eligible: false output: ut_ssp: 180 snap_unearned_income: 540 household_state_benefits: 180 # HUD income excludes the supplement (see ut_ssp): SSI 30 * 12 = 360. hud_unearned_income: 360 + # SSI 30 * 12 = 360 + Utah SSP 15 * 12 = 180 = 540 (SNAP take-up off). + spm_unit_benefits: 540 - name: Case 2, endogenous Medicaid enrollment counts the supplement in SNAP income without a dependency cycle. period: 2026-01 @@ -24,3 +28,152 @@ ut_ssp: 15 # $30 SSI + $15 supplement = $45 for the month. snap_unearned_income: 45 + +- name: Case 3, 2027 facility resident with endogenous Medicaid keeps the fixed supplement. + period: 2027-01 + input: + state_code: UT + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + # The federal $30 medical treatment facility rate has no COLA. + ssi: 30 + # Medicaid work requirements apply from 2027, so enrollment comes from the + # cycle-breaking Medicaid branch; the $15 supplement is not indexed. + ut_ssp: 15 + # $30 SSI + $15 supplement = $45 for the month. + snap_unearned_income: 45 + +- name: Case 4, DWS supplement enters state benefit and HUD totals but not SNAP income. + period: 2026 + input: + people: + person1: + age: 72 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 45 + # Utah minimum wage (the federal $7.25, Utah Code 34-40-103) full time: + # 7.25 * 2,080 = 15,080. + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # One-third reduction: 994 * 2 / 3 * 12 = 7,952. + ssi: [7_952, 0] + # Single person in the household of another: 3.91 * 12 = 46.92. + ut_dws_ssp: [46.92, 0] + ut_dhhs_ssp: [0, 0] + ut_ssp: [46.92, 0] + household_state_benefits: 46.92 + # Utah exempts the DWS supplement from SNAP income (DWS Manual 425-11): + # SSI only. + snap_unearned_income: 7_952 + # SSI 7,952 + DWS supplement 46.92 = 7,998.92. + hud_unearned_income: [7_998.92, 0] + +- name: Case 5, 2027 couple in the household of another keeps the 2026 DWS amount. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 70 + is_tax_unit_spouse: true + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person3: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1, person2] + tax_unit2: + members: [person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + # 2027 couple rate 1,544 / 2 * 2 / 3 = 514.67 each. + ssi: [514.67, 514.67, 0] + # DWS publishes no indexing rule, so the 2026 $12.19 carries forward: + # 12.19 / 2 = 6.095 each. + ut_dws_ssp: [6.095, 6.095, 0] + ut_ssp: [6.095, 6.095, 0] + # SSI 514.67 * 2 = 1,029.33; the DWS supplement is exempt. + snap_unearned_income: 1_029.33 + +- name: Case 6, over-income DWS recipient counts Social Security but not the supplement for SNAP. + period: 2026 + input: + people: + person1: + age: 72 + # SSA 2026 COLA fact sheet: average retired-worker benefit $2,071 a + # month, 2,071 * 12 = 24,852. + social_security_retirement: 24_852 + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Countable income 2,071 - 20 = 2,051 > $994: no SSI. + ssi: [0, 0] + # Meets SSI criteria other than income and lives with others: + # 3.91 * 12 = 46.92. + ut_ssp: [46.92, 0] + household_state_benefits: 46.92 + # Social Security 24,852; the DWS supplement is exempt. + snap_unearned_income: 24_852 + # Social Security 24,852 + DWS supplement 46.92 = 24,898.92. + hud_unearned_income: [24_898.92, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml index 81e068131ef..1a9f7e0d1dd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dhhs/ssp/ut_ssp.yaml @@ -22,7 +22,7 @@ ssi: 1 output: # $1 SSI >= $1 minimum federal SSI payment, so the $15 payment applies. - ut_ssp_eligible: true + ut_dhhs_ssp_eligible: true ut_ssp: 15 - name: Case 3, institutional SSI below one dollar does not qualify. @@ -36,7 +36,7 @@ ssi: 0.50 output: # $0.50 SSI < $1 minimum federal SSI payment and no reported receipt. - ut_ssp_eligible: false + ut_dhhs_ssp_eligible: false ut_ssp: 0 - name: Case 4, Medicaid approval is required. @@ -196,3 +196,101 @@ ssi: [30, 994] # Only person1 lives in a medical treatment facility: [$15, $0]. ut_ssp: [15, 0] + +- name: Case 14, Medicaid facility spouse receives the DHHS payment and the spouse at home with a son receives the DWS supplement. + period: 2026-01 + input: + people: + person1: + age: 80 + is_tax_unit_head: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + person2: + age: 78 + is_tax_unit_spouse: true + person3: + age: 50 + # Utah minimum wage (the federal $7.25, Utah Code 34-40-103) full time: + # 7.25 * 2,080 = 15,080. + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1, person2] + tax_unit2: + members: [person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + # One spouse in a facility: separate computation, $30 and $994. + ssi: [30, 994, 0] + # person1: $30 SSI >= $1 in a Medicaid facility: $15. + ut_dhhs_ssp: [15, 0, 0] + # person2 is a single individual living with person3: $3.91. + ut_dws_ssp: [0, 3.91, 0] + ut_ssp: [15, 3.91, 0] + +- name: Case 15, Utah recipient is paid beside a Massachusetts recipient in the same simulation. + period: 2026-01 + input: + people: + person1: + age: 72 + person2: + age: 45 + employment_income: 15_080 + person3: + age: 72 + person4: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + tax_unit3: + members: [person3] + tax_unit4: + members: [person4] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + marital_unit3: + members: [person3] + marital_unit4: + members: [person4] + families: + family1: + members: [person1, person2] + family2: + members: [person3, person4] + spm_units: + spm_unit1: + members: [person1, person2] + spm_unit2: + members: [person3, person4] + households: + household1: + members: [person1, person2] + state_code: UT + household2: + members: [person3, person4] + state_code: MA + output: + ssi: [994, 0, 994, 0] + # Only the Utah recipient, who lives with others, receives $3.91. + ut_dws_ssp_eligible: [true, false, false, false] + ut_ssp: [3.91, 0, 0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml new file mode 100644 index 00000000000..16ee27e386a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml @@ -0,0 +1,266 @@ +# Utah DWS Eligibility Manual 205-10 (effective January 1, 2026): $3.91 a +# month for a single person, $12.19 for a couple in the household of another +# and $5.75 for a couple living alone or with others in their own household. +# Each spouse receives half of a couple amount. +- name: Case 1, single SSI recipient living with others in their own household. + period: 2026-01 + input: + people: + person1: + age: 72 + person2: + age: 45 + # Utah minimum wage (the federal $7.25, Utah Code 34-40-103) full time: + # 7.25 * 2,080 = 15,080. + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + ssi: [994, 0] + # Single person who does not live alone: $3.91. + ut_dws_ssp: [3.91, 0] + +- name: Case 2, single SSI recipient in the household of another. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # One-third reduction: 994 * 2 / 3 = 662.67. + ssi: [662.67, 0] + # A single person receives $3.91 in any arrangement other than alone. + ut_dws_ssp: [3.91, 0] + +- name: Case 3, SSI couple living alone splits the own-household couple amount. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + person2: + age: 70 + is_tax_unit_spouse: true + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Couple rate $1,491 / 2 = $745.50 each with no income. + ssi: [745.5, 745.5] + # $5.75 / 2 = $2.875 each; the couple receives $5.75. + ut_dws_ssp: [2.875, 2.875] + +- name: Case 4, SSI couple in the household of another splits the higher couple amount. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 70 + is_tax_unit_spouse: true + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person3: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1, person2] + tax_unit2: + members: [person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + # One-third reduction: 1,491 / 2 * 2 / 3 = 497 each. + ssi: [497, 497, 0] + # $12.19 / 2 = $6.095 each; the couple receives $12.19. + ut_dws_ssp: [6.095, 6.095, 0] + +- name: Case 5, SSI couple living with a grandson in their own household. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + person2: + age: 70 + is_tax_unit_spouse: true + person3: + age: 22 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1, person2] + tax_unit2: + members: [person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ssi: [745.5, 745.5, 0] + # Couple with others in their own household: $5.75 / 2 = $2.875 each. + ut_dws_ssp: [2.875, 2.875, 0] + +- name: Case 6, SSI recipient whose working spouse is not aged, blind or disabled receives the single amount. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + person2: + age: 60 + is_tax_unit_spouse: true + employment_income: 15_080 + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # person2 is not aged, blind or disabled, so person1 is an individual + # recipient who lives with a spouse: $3.91; person2 receives nothing. + ut_dws_ssp_eligible: [true, false] + ut_dws_ssp: [3.91, 0] + +- name: Case 7, aged couple over the SSI income limit splits the own-household couple amount. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + # SSA 2026 COLA fact sheet: average aged couple benefit $3,208 a + # month, with person1 at the $2,071 average retired-worker benefit: + # 2,071 * 12 = 24,852 and (3,208 - 2,071) * 12 = 13,644. + social_security_retirement: 24_852 + person2: + age: 70 + is_tax_unit_spouse: true + social_security_retirement: 13_644 + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Countable income 3,208 - 20 = 3,188 > $1,491 couple rate: no SSI. + ssi: [0, 0] + # Both spouses meet SSI criteria other than income: $5.75 / 2 each. + ut_dws_ssp: [2.875, 2.875] + +- name: Case 8, year total for a single recipient in the household of another. + period: 2026 + input: + people: + person1: + age: 72 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # $3.91 * 12 = $46.92, paid in four quarterly installments of $11.73. + ut_dws_ssp: [46.92, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.yaml new file mode 100644 index 00000000000..938958487c4 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.yaml @@ -0,0 +1,339 @@ +# Utah DWS Eligibility Manual 205-10 (effective January 1, 2026): SSI +# recipients and people who meet SSI criteria other than income qualify, +# except single individuals who live alone, Medicaid institution residents, +# inmates and people denied SSI for reasons other than income. +- name: Case 1, SSI recipient living with a working daughter is eligible. + period: 2026-01 + input: + people: + person1: + age: 72 + person2: + age: 45 + # Utah minimum wage (the federal $7.25, Utah Code 34-40-103) full time: + # 7.25 * 2,080 = 15,080. + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # person1: no income, own household: $994 SSI. + ssi: [994, 0] + # person1 receives SSI and lives with others; person2 is not aged, + # blind or disabled and receives no SSI. + ut_dws_ssp_eligible: [true, false] + +- name: Case 2, SSI recipient who lives alone is not eligible. + period: 2026-01 + input: + state_code: UT + age: 72 + output: + ssi: 994 + # "Single individuals who live alone" are not eligible. + ut_dws_ssp_eligible: false + +- name: Case 3, aged person over the SSI income limit living with a daughter is eligible. + period: 2026-01 + input: + people: + person1: + age: 72 + # SSA 2026 COLA fact sheet: average retired-worker benefit $2,071 a + # month, 2,071 * 12 = 24,852. + social_security_retirement: 24_852 + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Countable income 2,071 - 20 = 2,051 > $994: no SSI. + ssi: [0, 0] + # person1 meets SSI criteria other than income. + ut_dws_ssp_eligible: [true, false] + +- name: Case 4, person who declines SSI with qualifying income is not eligible. + period: 2026-01 + input: + people: + person1: + age: 72 + takes_up_ssi_if_eligible: false + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + ssi: [0, 0] + # Income would qualify for SSI, which the person must apply for (DWS + # Eligibility Manual 205), so the over-income path does not apply. + ut_dws_ssp_eligible: [false, false] + +- name: Case 5, person denied SSI for excess resources is not eligible. + period: 2026-01 + input: + people: + person1: + age: 72 + # Savings above the $2,000 SSI resource limit. + bank_account_assets: 15_000 + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + ssi: [0, 0] + # "Individuals who are denied or closed SSI for reasons other than + # exceeding the income" are not eligible. + ut_dws_ssp_eligible: [false, false] + +- name: Case 6, reported SSI receipt qualifies without a computed SSI payment. + period: 2026-01 + input: + people: + person1: + age: 50 + receives_ssi: true + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Age 50 with no disability inputs: no computed SSI. + ssi: [0, 0] + ut_dws_ssp_eligible: [true, false] + +- name: Case 7, incarcerated SSI recipient is not eligible. + period: 2026-01 + input: + people: + person1: + age: 72 + is_incarcerated: true + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Federal SSI does not model the inmate bar, so SSI is still paid. + ssi: [994, 0] + # "Individuals who are incarcerated" are not eligible. + ut_dws_ssp_eligible: [false, false] + +- name: Case 8, Medicaid institution resident is not eligible. + period: 2026-01 + input: + people: + person1: + age: 80 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + person2: + age: 50 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # $30 federal medical treatment facility rate. + ssi: [30, 0] + # Medicaid pays more than half the cost of care: not eligible. + ut_dws_ssp_eligible: [false, false] + +- name: Case 9, spouse at home alone while the other spouse is in a Medicaid facility is not eligible. + period: 2026-01 + input: + people: + person1: + age: 80 + is_tax_unit_head: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + person2: + age: 78 + is_tax_unit_spouse: true + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # One spouse in a facility: separate computation, $30 and $994. + ssi: [30, 994] + # person1 lives in a Medicaid institution. person2's only household + # member lives in the facility, so person2 lives alone as a single + # individual. + ut_dws_ssp_eligible: [false, false] + +- name: Case 10, supplement is not payable outside Utah. + period: 2026-01 + input: + people: + person1: + age: 72 + person2: + age: 45 + employment_income: 15_080 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WY + output: + ssi: [994, 0] + ut_dws_ssp_eligible: [false, false] + +- name: Case 11, spouse at home alone while the other spouse is incarcerated is not eligible. + period: 2026-01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + is_incarcerated: true + person2: + age: 70 + is_tax_unit_spouse: true + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Federal SSI does not model the inmate bar: $1,491 couple rate, half + # each. + ssi: [745.5, 745.5] + # person1 is incarcerated. As with a spouse in a facility (Case 9), + # person2's only household member is absent, so person2 lives alone as a + # single individual. + ut_dws_ssp_eligible: [false, false] diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_dhhs_ssp.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_dhhs_ssp.py new file mode 100644 index 00000000000..8aa2d448563 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_dhhs_ssp.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class ut_dhhs_ssp(Variable): + value_type = float + entity = Person + label = "Utah DHHS State Supplemental Payment" + definition_period = MONTH + unit = USD + defined_for = "ut_dhhs_ssp_eligible" + # Utah administers and issues this payment itself, not through SSA + # (Manual 661, "The Payment Process"). + # NOTE: Not in the HUD income list. Recipients live in a Medicaid-funded medical + # institution (Manual 661), not HUD-assisted housing, and HUD income would make + # the Medicaid condition circular via rent tax deductions. + reference = ( + "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6", + "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm", + ) + adds = ["gov.states.ut.dhhs.ssp.amount"] diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_dhhs_ssp_eligible.py similarity index 50% rename from policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py rename to policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_dhhs_ssp_eligible.py index cffd13e1948..96abbd92d01 100644 --- a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp_eligible.py +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_dhhs_ssp_eligible.py @@ -4,19 +4,35 @@ ) -class ut_ssp_eligible(Variable): +class ut_dhhs_ssp_eligible(Variable): value_type = bool entity = Person - label = "Eligible for Utah State Supplemental Payment" + label = "Eligible for Utah DHHS State Supplemental Payment" definition_period = MONTH defined_for = StateCode.UT reference = ( "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6", "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm", ) + documentation = """ + Set ssi_lives_in_medical_treatment_facility and + ssi_medicaid_pays_majority_of_care to true while the person lives in a + medical treatment facility where Medicaid pays more than half the cost of + care, which limits SSI to the federal facility rate. Utah Medicaid + enrollment is computed from Medicaid eligibility and take-up. Set + receives_ssi when the person reports an SSI payment that the model does + not compute. + """ + # NOTE: the microdata do not populate ssi_lives_in_medical_treatment_facility + # or ssi_medicaid_pays_majority_of_care, so this payment reaches household + # calculations only. def formula(person, period, parameters): p = parameters(period).gov.states.ut.dhhs.ssp + # NOTE: R414-306-6(2) requires that the resident "receives a + # Supplemental Security Income (SSI) payment"; Manual 661 sets the + # floor ("The SSI payment must be at least $1.00"), which the model + # applies through minimum_ssi_payment. receives_ssi = (person("ssi", period) >= p.minimum_ssi_payment) | person( "receives_ssi", period ) diff --git a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py index fb8a6146488..edcd8a84980 100644 --- a/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py +++ b/policyengine_us/variables/gov/states/ut/dhhs/ssp/ut_ssp.py @@ -7,14 +7,17 @@ class ut_ssp(Variable): label = "Utah State Supplemental Payment" definition_period = MONTH unit = USD - defined_for = "ut_ssp_eligible" - # Utah administers and issues this payment itself, not through SSA - # (Manual 661, "The Payment Process"). - # NOTE: Not in the HUD income list. Recipients live in a Medicaid-funded medical - # institution (Manual 661), not HUD-assisted housing, and HUD income would make - # the Medicaid condition circular via rent tax deductions. + defined_for = StateCode.UT + # The Department of Workforce Services supplement excludes residents of + # institutions where Medicaid pays more than half the cost of care + # (DWS Eligibility Manual 205-10), who may receive the DHHS payment + # instead. Both payments key on the federal MEDICAL_TREATMENT_FACILITY + # arrangement, so no one receives both. + # NOTE: Not in the HUD income list, because ut_dhhs_ssp depends on Medicaid + # enrollment. The HUD list carries ut_dws_ssp directly. reference = ( "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R414-306-6", "https://oepmanuals.dhhs.utah.gov/600_Program_Benefits/661_Fifteen_Dollar_State_Supplemental_Payment_%28SSP%29.htm", + "https://jobs.utah.gov/infosource/eligibilitymanual/200_Program_Eligibility_Requirements/205-10_State_Supplemental_Payments_to_SSI_Recipients_-_General_Information.htm", ) - adds = ["gov.states.ut.dhhs.ssp.amount"] + adds = ["ut_dhhs_ssp", "ut_dws_ssp"] diff --git a/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py b/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py new file mode 100644 index 00000000000..5f43a55d7f6 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py @@ -0,0 +1,48 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.status.ssi_federal_living_arrangement import ( + SSIFederalLivingArrangement, +) + + +class ut_dws_ssp(Variable): + value_type = float + entity = Person + label = "Utah DWS State Supplemental Payment" + definition_period = MONTH + unit = USD + defined_for = "ut_dws_ssp_eligible" + # The Department of Workforce Services pays this supplement "on a + # quarterly basis following the end of the quarter" (205-10). The model + # reports the monthly amount in the month it accrues. + reference = ( + "https://jobs.utah.gov/infosource/eligibilitymanual/200_Program_Eligibility_Requirements/205-10_State_Supplemental_Payments_to_SSI_Recipients_-_General_Information.htm", + # Statutory basis: Appropriation Act for the Department of Workforce + # Services. + "https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/2011/ut.html", + ) + documentation = """ + Spouses are the members of a marital unit. Set + ssi_lives_in_another_persons_household, + ssi_receives_shelter_from_others_in_household and ssi_others_pay_all_meals + for both spouses to place a couple in the household of another. + """ + + def formula(person, period, parameters): + p = parameters(period).gov.states.ut.dws.ssp.amount + # The couple amounts apply when both spouses qualify, and each spouse + # receives half. A person whose spouse does not qualify receives the + # single person amount. + eligible = person("ut_dws_ssp_eligible", period) + couple = person.marital_unit.sum(eligible) == 2 + # 205-10 pays couples "who live in the household of another" and + # couples "who live alone or with others in their own household". SSA + # paid the same rows by federal living arrangement codes B and A + # (205-10, 2004-2013 edition; SSA's January 2011 table). + arrangement = person("ssi_federal_living_arrangement", period) + another_household = ( + arrangement == SSIFederalLivingArrangement.ANOTHER_PERSONS_HOUSEHOLD + ) + couple_amount = where( + another_household, p.couple.another_household, p.couple.own_household + ) + return where(couple, couple_amount / 2, p.individual) diff --git a/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.py b/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.py new file mode 100644 index 00000000000..3db11ca4cab --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp_eligible.py @@ -0,0 +1,71 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.status.ssi_federal_living_arrangement import ( + SSIFederalLivingArrangement, +) + + +class ut_dws_ssp_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible for Utah DWS State Supplemental Payment" + definition_period = MONTH + defined_for = StateCode.UT + reference = ( + "https://jobs.utah.gov/infosource/eligibilitymanual/200_Program_Eligibility_Requirements/205-10_State_Supplemental_Payments_to_SSI_Recipients_-_General_Information.htm", + "https://jobs.utah.gov/infosource/eligibilitymanual/200_Program_Eligibility_Requirements/205_Financial_Assistance_General_Information.htm", + "https://jobs.utah.gov/infosource/eligibilitymanual/Obsolete_Policy/Obsolete_200_Program_Eligibility_Requirements/O205/O205-10_%284_1_04_to_12_31_13%29_State_Supp_Payments_SSI_Recipients_Gen_Info.htm", + "https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/2011/ut.html", + ) + documentation = """ + Living alone is read from household membership: a person with no other + household member who is outside a medical treatment facility and not + incarcerated lives alone. A resident of a medical facility where Medicaid + pays half or less of the cost is judged by household membership like + anyone else. Set receives_ssi when the person reports an SSI payment that + the model does not compute. + """ + + def formula(person, period, parameters): + # 205-10: "Customers who are receiving Supplemental Security Income + # (SSI) or who meet SSI criteria other than income are eligible". + receives_ssi = (person("ssi", period) > 0) | person("receives_ssi", period) + # is_ssi_eligible applies SSI's aged, blind or disabled, resource and + # immigration criteria, so an SSI denial on other grounds also denies + # the supplement ("Individuals who are denied or closed SSI for reasons + # other than exceeding the income"). Applicants for any financial + # assistance program must apply for other benefits they may be entitled + # to (205, "Application for Other Possible Benefits"), so a person whose + # income would qualify for SSI must take it up. + # NOTE: The over-income path has no take-up, so in microsimulation it + # reaches every eligible non-recipient who does not live alone, though + # 205-10 lets DWS reduce the amounts "to stay within budget". + over_income_for_ssi = person("is_ssi_eligible", period) & ( + person("uncapped_ssi", period) <= 0 + ) + # Not eligible: "Individuals who live in a public or private + # institution where Medicaid pays more than 50 percent of their cost of + # care" and "Individuals who are incarcerated". + arrangement = person("ssi_federal_living_arrangement", period) + medicaid_institution = ( + arrangement == SSIFederalLivingArrangement.MEDICAL_TREATMENT_FACILITY + ) + incarcerated = person("is_incarcerated", period) + # Not eligible: "Single individuals who live alone." Members living in + # a medical treatment facility or incarcerated do not share the home. + # The count leaves out the person themselves, and a spouse at home + # means the person does not live alone. + # NOTE: The 2004-2013 edition of 205-10, when SSA paid the supplement, + # paid "$3.13 for a single person living with others", and SSA's + # January 2011 table paid individuals only in the household of + # another (federal code B). The current edition pays "a single person" + # and excludes only "Single individuals who live alone", so the model + # also pays a single person living with others in their own household. + facility = person("ssi_lives_in_medical_treatment_facility", period) + housemate = ~facility & ~incarcerated + lives_alone = (person.household.sum(housemate) - housemate) == 0 + return ( + (receives_ssi | over_income_for_ssi) + & ~medicaid_institution + & ~incarcerated + & ~lives_alone + ) From 60014e2d33c7586c043ed1fe9b4fb711c07a8be7 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 20 Oct 2026 16:06:05 -0400 Subject: [PATCH 6/7] Document Utah's DWS take-up gap and pin the facility-spouse couple - programs.yaml notes that the over-income path has no take-up, so microsimulation pays far more people than the program reaches. - Pin a couple with one spouse in a facility where Medicaid pays half or less. - Note that each spouse's half follows their own living arrangement. Co-Authored-By: Claude Opus 5.5 --- policyengine_us/programs.yaml | 4 ++- .../gov/states/ut/dws/ssp/ut_dws_ssp.yaml | 34 +++++++++++++++++++ .../gov/states/ut/dws/ssp/ut_dws_ssp.py | 4 +++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index e4b43876b7d..ee595818352 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1159,7 +1159,9 @@ programs: Models the 2026 Department of Workforce Services supplement, paid quarterly to SSI recipients and over-income applicants other than single individuals living alone, and the $15 monthly payment to SSI - recipients in Medicaid-funded medical institutions. + recipients in Medicaid-funded medical institutions. The over-income + path has no take-up, so microsimulation pays far more people than + the program reaches. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml index 16ee27e386a..06cb2964b8d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dws/ssp/ut_dws_ssp.yaml @@ -264,3 +264,37 @@ output: # $3.91 * 12 = $46.92, paid in four quarterly installments of $11.73. ut_dws_ssp: [46.92, 0] + +- name: Case 9, aged couple with one spouse in a medical facility where Medicaid pays half or less of the cost. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 80 + is_tax_unit_head: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: false + person2: + age: 78 + is_tax_unit_spouse: true + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: UT + output: + # Medicaid does not pay most of person1's care, so both stay in their own + # household for SSI and receive the couple rate: 1,491 / 2 = 745.50. + ssi: [745.5, 745.5] + # 205-10 does not exclude this facility. Person1 has a household member + # outside a facility, so does not live alone; person2's only household + # member is in the facility, so person2 lives alone. Person1 receives the + # single person amount, since person2 does not qualify. + ut_dws_ssp_eligible: [true, false] + ut_dws_ssp: [3.91, 0] diff --git a/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py b/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py index 5f43a55d7f6..2f4d5ad757a 100644 --- a/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py +++ b/policyengine_us/variables/gov/states/ut/dws/ssp/ut_dws_ssp.py @@ -42,6 +42,10 @@ def formula(person, period, parameters): another_household = ( arrangement == SSIFederalLivingArrangement.ANOTHER_PERSONS_HOUSEHOLD ) + # NOTE: Each spouse's half follows that spouse's own living + # arrangement, as SSI's couple rate does. Household-of-another inputs + # set for only one spouse give a total that matches neither published + # couple amount. couple_amount = where( another_household, p.couple.another_household, p.couple.own_household ) From 769601aec1ba870b4a3da573a7cbbcc2f32d95cc Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 21 Oct 2026 21:19:27 -0400 Subject: [PATCH 7/7] Place shared-list entries apart from sibling SSP pull requests Each sibling SSP PR adds its line to the same unsorted lists, so the entries now sit at different anchors and the PRs merge without conflicts. Co-Authored-By: Claude Opus 5.5 --- .../household/household_state_benefits.yaml | 16 +++++++-------- .../hud/annual_income/sources/unearned.yaml | 2 +- policyengine_us/programs.yaml | 20 +++++++++---------- .../income/spm_unit/spm_unit_benefits.py | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index 8236a67cac8..d81996e0e8b 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -82,10 +82,10 @@ values: - sc_ssi_state_supplement # South Dakota benefits - sd_ssp - # Texas benefits - - tx_ssi_state_supplement # Utah benefits - ut_ssp + # Texas benefits + - tx_ssi_state_supplement # Virginia benefits - va_child_care_subsidies - va_ag @@ -191,10 +191,10 @@ values: - sc_ssi_state_supplement # South Dakota benefits - sd_ssp - # Texas benefits - - tx_ssi_state_supplement # Utah benefits - ut_ssp + # Texas benefits + - tx_ssi_state_supplement # Virginia benefits - va_child_care_subsidies - va_ag @@ -311,10 +311,10 @@ values: - sc_ssi_state_supplement # South Dakota benefits - sd_ssp - # Texas benefits - - tx_ssi_state_supplement # Utah benefits - ut_ssp + # Texas benefits + - tx_ssi_state_supplement # Virginia benefits - va_child_care_subsidies - va_ag @@ -432,10 +432,10 @@ values: - sc_ssi_state_supplement # South Dakota benefits - sd_ssp - # Texas benefits - - tx_ssi_state_supplement # Utah benefits - ut_ssp + # Texas benefits + - tx_ssi_state_supplement # Virginia benefits - va_child_care_subsidies - va_ag diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index 3777af419ba..79e1024b36a 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -28,9 +28,9 @@ values: - ok_ssp - ny_ssp - ri_ssp + - ut_dws_ssp - sd_ssp - va_ag - - ut_dws_ssp - general_assistance - total_unemployment_compensation - child_support_received diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 3fe768c4e4b..c00939bf9f1 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1247,16 +1247,6 @@ programs: notes: Models 2026 independent living and certified nonwaiver assisted living/adult foster care supplements. Out-of-state placements, historical mandatory supplements and claim administration are not modeled. - - state: VA - status: partial - name: Virginia Auxiliary Grant - full_name: Virginia Auxiliary Grant - variable: va_ag - parameter_prefix: gov.states.va.dars.ag - verified_years: '2026' - notes: Models 2026 locality rates and SSI and non-SSI budgets for certified assisted living, - adult foster care and supportive housing residents. Conditional resource benefits and - historical grandfathering are not modeled. - state: UT status: partial name: Utah SSP @@ -1271,6 +1261,16 @@ programs: recipients in Medicaid-funded medical institutions. The over-income path has no take-up, so microsimulation pays far more people than the program reaches. + - state: VA + status: partial + name: Virginia Auxiliary Grant + full_name: Virginia Auxiliary Grant + variable: va_ag + parameter_prefix: gov.states.va.dars.ag + verified_years: '2026' + notes: Models 2026 locality rates and SSI and non-SSI budgets for certified assisted living, + adult foster care and supportive housing residents. Conditional resource benefits and + historical grandfathering are not modeled. - id: social_security name: Social Security diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py index 5246b660807..203cdac1db3 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py @@ -30,9 +30,9 @@ def formula(spm_unit, period, parameters): "ok_ssp", # Oklahoma benefits "ny_ssp", # New York benefits "ri_ssp", # Rhode Island benefits + "ut_ssp", # Utah benefits "sd_ssp", # South Dakota benefits "va_ag", # Virginia benefits - "ut_ssp", # Utah benefits "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits