diff --git a/changelog.d/ssi-supplement-couple-spouse-eligibility.fixed.md b/changelog.d/ssi-supplement-couple-spouse-eligibility.fixed.md new file mode 100644 index 00000000000..82a22b68683 --- /dev/null +++ b/changelog.d/ssi-supplement-couple-spouse-eligibility.fixed.md @@ -0,0 +1 @@ +Pay the Colorado AND-CS, Texas SSI facility and New Mexico residential care supplements to SSI recipients, so both members of an SSI couple qualify instead of only the one labelled the eligible individual. Colorado AND-CS now counts each spouse's own income (9 CCR 2503-5 3.549), and Texas keeps a facility resident whose countable income equals the $30 reduced standard. diff --git a/policyengine_us/parameters/gov/states/co/ssa/state_supplement/grant_standard.yaml b/policyengine_us/parameters/gov/states/co/ssa/state_supplement/grant_standard.yaml index 9d104731d97..d35eed18446 100644 --- a/policyengine_us/parameters/gov/states/co/ssa/state_supplement/grant_standard.yaml +++ b/policyengine_us/parameters/gov/states/co/ssa/state_supplement/grant_standard.yaml @@ -38,4 +38,4 @@ metadata: - title: 9 CCR 2503-5, Section 3.546, AND-CS Program (effective 2023) href: https://www.coloradosos.gov/CCR/GenerateRulePdf.do?ruleVersionId=10694#page=73 - title: 9 CCR 2503-5, Section 3.546, AND-CS Program - href: https://www.sos.state.co.us/CCR/GenerateRulePdf.do?fileName=9+CCR+2503-5&ruleVersionId=12428#page=99 + href: https://www.sos.state.co.us/CCR/GenerateRulePdf.do?fileName=9+CCR+2503-5&ruleVersionId=12428#page=91 diff --git a/policyengine_us/tests/core/test_ssi_state_supplement_couple_invariants.py b/policyengine_us/tests/core/test_ssi_state_supplement_couple_invariants.py new file mode 100644 index 00000000000..cdecc40f80c --- /dev/null +++ b/policyengine_us/tests/core/test_ssi_state_supplement_couple_invariants.py @@ -0,0 +1,197 @@ +"""Invariants for the CO, TX and NM SSI supplements over married couples. + +Each state pays every SSI recipient on their own (9 CCR 2503-5 3.546-3.549; +HHSC MEPD Handbook H-1500 and H-6000; 8.106.400.10(C) and 8.106.500.10 NMAC), +so a spouse's supplement must not depend on which spouse holds the tax-unit +head role. The grid crosses state, role assignment, the second spouse's +citizenship, the first spouse's resources and the two spouses' monthly +pensions (none, $300 each, or $400 and $200): 72 married couples (144 people) +in one vectorized simulation. + +Checked for every person in the grid: + +1. Receipt: anyone paid SSI is eligible, and no one is eligible without being + eligible for SSI with countable income not over the payment standard (no + one in the grid reports SSI receipt, and every other program condition is + met by construction). In Colorado and New Mexico eligibility is exactly a + positive SSI payment. +2. Role invariance: eligibility and the supplement are identical when the + head and spouse roles are swapped. +3. Couples: two citizen spouses with the same income have the same + eligibility and the same supplement. +4. Citizenship: a spouse who fails the SSI citizenship condition is never + eligible. +5. Colorado couple total: when both spouses of a joint SSI claim receive + AND-CS and have only unearned income, the two grants sum to twice the + grant standard less the couple's federal SSI and pooled countable income, + as in SSA's Colorado couple payment level (1,398 = 2 x 699 in January + 2011), however 3.549(A) divides their own income between them. (Earnings + break the identity: 3.549(A)(1) deducts $65 for each client, where SSI + deducts $65 once for the couple.) + +YAML covers the source examples and their amounts. Python is needed here to +compare each person across role assignments and spouses in one simulation. +""" + +from itertools import product + +import numpy as np +import pytest + +from policyengine_us import Simulation + + +YEAR = 2026 +PERIOD = "2026-01" +STATES = ("CO", "TX", "NM") +ROLE_ORDERS = ("first_is_head", "second_is_head") +SECOND_CITIZENSHIP = ("CITIZEN", "UNDOCUMENTED") +FIRST_RESOURCES = (0, 4_000) +# Monthly pensions of the first and second spouse. +PENSIONS = ((0, 0), (300, 300), (400, 200)) +GRID = tuple( + product(STATES, ROLE_ORDERS, SECOND_CITIZENSHIP, FIRST_RESOURCES, PENSIONS) +) +PROGRAMS = { + "CO": ("co_state_supplement_eligible", "co_state_supplement"), + "TX": ("tx_ssi_state_supplement_eligible", "tx_ssi_state_supplement"), + "NM": ("nm_ssi_state_supplement_eligible", "nm_ssi_state_supplement"), +} +# Each state's program conditions other than SSI. +STATE_INPUTS = { + # AND-CS: blind or disabled, ages 0-59. + "CO": dict( + ages=(50, 52), + is_disabled=True, + meets_ssi_disability_criteria=True, + ), + # SSI recipient in a Medicaid facility on the $30 reduced benefit. + "TX": dict( + ages=(72, 70), + is_in_medicaid_facility=True, + ssi_lives_in_medical_treatment_facility=True, + ssi_medicaid_pays_majority_of_care=True, + ), + # SSI recipient aged 18 or over in a licensed ARSCH home. + "NM": dict(ages=(68, 66), is_in_adult_residential_care=True), +} + + +def _situation(): + groups = ("tax_units", "marital_units", "spm_units", "families", "households") + situation = {"people": {}, **{group: {} for group in groups}} + for index, (state, order, citizenship, resources, pensions) in enumerate(GRID): + conditions = dict(STATE_INPUTS[state]) + ages = conditions.pop("ages") + members = [f"couple{index}_first", f"couple{index}_second"] + head = 0 if order == "first_is_head" else 1 + for position, member in enumerate(members): + person = { + "age": {YEAR: ages[position]}, + "is_tax_unit_head": {YEAR: position == head}, + "is_tax_unit_spouse": {YEAR: position != head}, + "pension_income": {YEAR: 12 * pensions[position]}, + "ssi_countable_resources": {YEAR: resources if position == 0 else 0}, + "immigration_status_str": { + YEAR: citizenship if position == 1 else "CITIZEN" + }, + } + person.update({name: {YEAR: value} for name, value in conditions.items()}) + situation["people"][member] = person + for group in groups: + situation[group][f"{group}_{index}"] = {"members": members} + situation["households"][f"households_{index}"]["state_code"] = {YEAR: state} + return situation + + +@pytest.fixture(scope="module") +def results(): + simulation = Simulation(situation=_situation()) + + def couples(variable, period=PERIOD): + return simulation.calculate(variable, period).reshape(len(GRID), 2) + + eligible = np.zeros((len(GRID), 2), dtype=bool) + supplement = np.zeros((len(GRID), 2)) + for state, (eligible_variable, amount_variable) in PROGRAMS.items(): + rows = [index for index, case in enumerate(GRID) if case[0] == state] + eligible[rows] = couples(eligible_variable)[rows] + supplement[rows] = couples(amount_variable)[rows] + parameters = simulation.tax_benefit_system.parameters(PERIOD) + return dict( + grant_standard=parameters.gov.states.co.ssa.state_supplement.grant_standard, + ssi=couples("ssi"), + ssi_eligible=couples("is_ssi_eligible"), + uncapped_ssi=couples("uncapped_ssi"), + joint=couples("ssi_claim_is_joint", YEAR), + federal_countable=couples("ssi_countable_income", YEAR) / 12, + eligible=eligible, + supplement=supplement, + ) + + +def _rows(**fixed): + names = ("state", "order", "citizenship", "resources", "pensions") + return [ + index + for index, case in enumerate(GRID) + if all(case[names.index(name)] == value for name, value in fixed.items()) + ] + + +def test_eligibility_follows_ssi_eligibility(results): + paid = results["ssi"] > 0 + within_limit = results["ssi_eligible"] & (results["uncapped_ssi"] >= 0) + eligible = results["eligible"] + assert not (paid & ~eligible).any() + assert not (eligible & ~within_limit).any() + for state in ("CO", "NM"): + rows = _rows(state=state) + np.testing.assert_array_equal(eligible[rows], paid[rows]) + + +def test_supplement_does_not_depend_on_tax_unit_roles(results): + for state, citizenship, resources, pensions in product( + STATES, SECOND_CITIZENSHIP, FIRST_RESOURCES, PENSIONS + ): + first, second = ( + GRID.index((state, order, citizenship, resources, pensions)) + for order in ROLE_ORDERS + ) + for name in ("eligible", "supplement"): + np.testing.assert_allclose(results[name][first], results[name][second]) + + +def test_citizen_spouses_with_equal_income_are_treated_alike(results): + for index, (_, _, citizenship, _, pensions) in enumerate(GRID): + if citizenship == "CITIZEN" and pensions[0] == pensions[1]: + for name in ("eligible", "supplement"): + assert results[name][index, 0] == pytest.approx(results[name][index, 1]) + + +def test_spouse_failing_citizenship_condition_is_never_eligible(results): + rows = _rows(citizenship="UNDOCUMENTED") + assert not results["eligible"][rows, 1].any() + assert not results["supplement"][rows, 1].any() + + +def test_colorado_couple_total_matches_pooled_computation(results): + rows = [ + index + for index in _rows(state="CO") + if results["joint"][index].all() and results["eligible"][index].all() + ] + assert rows + pooled = ( + 2 * results["grant_standard"] + - results["ssi"][rows].sum(axis=1) + - results["federal_countable"][rows].sum(axis=1) + ) + np.testing.assert_allclose(results["supplement"][rows].sum(axis=1), pooled) + + +def test_grid_reaches_both_outcomes_for_each_state(results): + for state in STATES: + rows = _rows(state=state) + assert results["eligible"][rows].any() + assert not results["eligible"][rows].all() diff --git a/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement.yaml b/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement.yaml index 31fd3ee0804..dd50f2b0fc2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement.yaml @@ -127,3 +127,212 @@ ssi: 0 output: co_state_supplement: 11_928 + +- name: Case 14, both members of a disabled SSI couple receive the supplement in 2026. + # SSA 2026 SSI couple rate: $1,491/month, or $745.50 for each spouse of a + # joint claim. 9 CCR 2503-5 3.546, 3.548(A)-(B): each spouse is an AND-CS + # client whose grant is the $994 standard less their own countable income, + # which includes their SSI (3.549(A)(2)(d)): 994 - 745.50 = 248.50/month, + # or 2,982/year. SSA's January 2011 Colorado table pays a couple the same + # way: combined standard $1,398 (2 x $699), state supplement $387 + # (1,398 - 1,011 federal couple rate). + absolute_error_margin: 0.1 + period: 2026 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + ssi: [8_946, 8_946] + co_state_supplement: [2_982, 2_982] + +- name: Case 15, a disabled SSI couple with equal pensions each receive the supplement. + # Each spouse has a $300/month pension. Federal SSI: couple unearned income + # 600 - 20 general exclusion = 580; couple payment 1,491 - 580 = 911, or + # 455.50 each. 3.549(A)(2): each client's countable unearned income is + # 300 - 10 (the $20 disregard split between spouses) + 455.50 SSI added back + # = 745.50, so each grant is 994 - 745.50 = 248.50/month, or 2,982/year. + absolute_error_margin: 0.1 + period: 2026 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + pension_income: 3_600 + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + pension_income: 3_600 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + ssi: [5_466, 5_466] + co_state_supplement: [2_982, 2_982] + +- name: Case 16, a disabled adult above the SSI resource limit receives nothing. + # $3,000 of countable resources exceeds the $2,000 SSI limit, so no SSI is + # paid. 3.546 limits AND-CS to clients receiving SSI, and 3.547(D) ends + # AND-CS when SSI ends, so the grant is 0 rather than the $994 standard. + absolute_error_margin: 0.1 + period: 2026 + input: + people: + person: + age: 45 + is_disabled: true + meets_ssi_disability_criteria: true + ssi_countable_resources: 3_000 + households: + household: + members: [person] + state_code: CO + output: + ssi: 0 + co_state_supplement: 0 + +- name: Case 17, a disabled SSI couple with unequal pensions each count their own income. + # Pensions of $400 and $200 a month. Federal SSI pools them: 600 - 20 = 580 + # countable, so the couple payment is 1,491 - 580 = 911, or 455.50 each. + # 3.549(A)(2) counts each client's own income with the $20 disregard split + # between the spouses: head 400 - 10 = 390, spouse 200 - 10 = 190. Grants: + # head 994 - 455.50 - 390 = 148.50/month (1,782/year); spouse + # 994 - 455.50 - 190 = 348.50/month (4,182/year). The couple total is the + # same 497/month as with equal pensions. + absolute_error_margin: 0.1 + period: 2026 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + pension_income: 4_800 + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + pension_income: 2_400 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + ssi: [5_466, 5_466] + co_state_supplement_countable_income: [4_680, 2_280] + co_state_supplement: [1_782, 4_182] + +- name: Case 18, a disabled SSI couple where only the head has earnings. + # The head earns $500/month and the spouse has no income. Federal SSI pools + # earnings: (500 - 20 - 65) / 2 = 207.50 countable, so the couple payment is + # 1,491 - 207.50 = 1,283.50, or 641.75 each. 3.549(A): the head's only + # unearned income is SSI, so no unearned disregard applies (3.549(A)(2)(c)), + # and their gross unearned income is not under $20, so none reaches earned + # income (3.549(A)(2)(f)); 3.549(A)(1) gives (500 - 65) / 2 = 217.50. Head + # grant 994 - 641.75 - 217.50 = 134.75/month (1,617/year); spouse + # 994 - 641.75 = 352.25/month (4,227/year). + absolute_error_margin: 0.1 + period: 2026 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + employment_income: 6_000 + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + ssi: [7_701, 7_701] + co_state_supplement_countable_income: [2_610, 0] + co_state_supplement: [1_617, 4_227] + +- name: Case 19, a disabled SSI couple receiving outside shelter support. + # No cash income. In-kind support and maintenance for a couple is one + # presumed maximum value: 1,491 / 3 + 20 = 517/month (20 CFR 416.1140), so + # couple countable income is 517 - 20 = 497 and the couple payment is + # 1,491 - 497 = 994, or 497 each. Each spouse counts half the couple's + # in-kind support, 258.50, less their 10 share of the disregard: 248.50. + # Grant 994 - 497 - 248.50 = 248.50/month (2,982/year) each. + absolute_error_margin: 0.1 + period: 2026 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + ssi_receives_outside_shelter_support: true + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + ssi_receives_outside_shelter_support: true + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + ssi: [5_964, 5_964] + co_state_supplement_countable_income: [2_982, 2_982] + co_state_supplement: [2_982, 2_982] diff --git a/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement_countable_income.yaml new file mode 100644 index 00000000000..774f71cc0cb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement_countable_income.yaml @@ -0,0 +1,75 @@ +- name: Case 1, outside an SSI couple computation, countable income is SSI countable income. + period: 2026 + input: + ssi_countable_income: 3_000 + state_code: CO + output: + co_state_supplement_countable_income: 3_000 + +- name: Case 2, spouses of a joint SSI claim each count their own income. + # 9 CCR 2503-5 3.549(A)(2): own unearned income other than SSI, less the + # client's half of the $20 disregard. Pensions of $400 and $200 a month give 390 and 190 + # a month, or 4,680 and 2,280 a year. Federal SSI would give each half of + # the pooled 580, or 290 a month. + period: 2026 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + pension_income: 4_800 + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + pension_income: 2_400 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + ssi_countable_income: [3_480, 3_480] + co_state_supplement_countable_income: [4_680, 2_280] + +- name: Case 3, an SSI recipient's earnings get no share of the unearned income disregard. + # The spouse has $5/month of interest and $200/month of earnings. Their $10 + # share of the $20 disregard covers the $5 of interest (3.549(A)(2)(c)). Their + # gross unearned income, SSI included, is not under $20, so nothing reaches + # earned income (3.549(A)(2)(f)): (200 - 65) / 2 = 67.50 a month, or 810 a + # year. + period: 2026 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + interest_income: 60 + employment_income: 2_400 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + co_state_supplement_countable_income: [0, 810] diff --git a/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.yaml index c9f2703f30f..6a42a8fd629 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.yaml @@ -1,7 +1,7 @@ - name: Case 1, ineligible senior over 60. period: 2023 input: - is_ssi_eligible_individual: true + ssi: 1_200 age: 60 is_blind: true is_ssi_disabled: true @@ -12,7 +12,7 @@ - name: Case 2, not blind or disabled. period: 2023 input: - is_ssi_eligible_individual: true + ssi: 1_200 age: 30 is_blind: false is_ssi_disabled: false @@ -20,10 +20,10 @@ output: co_state_supplement_eligible: false -- name: Case 3, not SSI eligible. +- name: Case 3, not receiving SSI. period: 2023 input: - is_ssi_eligible_individual: false + ssi: 0 age: 19 is_blind: true is_ssi_disabled: true @@ -31,10 +31,10 @@ output: co_state_supplement_eligible: false -- name: Case 4, SSI eligible and blind under 60. +- name: Case 4, receives SSI and blind under 60. period: 2023 input: - is_ssi_eligible_individual: true + ssi: 1_200 age: 59 is_blind: true is_ssi_disabled: false @@ -42,10 +42,10 @@ output: co_state_supplement_eligible: true -- name: Case 5, SSI eligible and disabled child. +- name: Case 5, receives SSI and disabled child. period: 2023 input: - is_ssi_eligible_individual: true + ssi: 1_200 age: 5 is_blind: false is_ssi_disabled: true @@ -56,7 +56,7 @@ - name: Case 6, historical eligibility in 2005. period: 2005 input: - is_ssi_eligible_individual: true + ssi: 1_200 age: 40 is_blind: false is_ssi_disabled: true @@ -67,10 +67,105 @@ - name: Case 7, age boundary at exactly 59. period: 2023 input: - is_ssi_eligible_individual: true + ssi: 1_200 age: 59 is_blind: false is_ssi_disabled: true state_code: CO output: co_state_supplement_eligible: true + +- name: Case 8, reported SSI receipt qualifies with zero computed SSI. + period: 2026-01 + input: + ssi: 0 + receives_ssi: true + age: 40 + is_blind: false + is_ssi_disabled: true + state_code: CO + output: + co_state_supplement_eligible: true + +- name: Case 9, both members of a disabled SSI couple are eligible. + # 9 CCR 2503-5 3.546: AND-CS is for clients "receiving SSI due to a + # disability or blindness"; 3.548(A): grants are "calculated on an + # individual basis with just one client per case". Each spouse of a joint + # SSI claim receives SSI, so each is an AND-CS client. + period: 2026-01 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + co_state_supplement_eligible: [true, true] + +- name: Case 10, a disabled spouse who fails the SSI citizenship condition is not eligible. + # The tax-unit spouse is undocumented, so receives no SSI (8 USC 1611, + # 1612) and is not an AND-CS client. + period: 2026-01 + input: + people: + head: + age: 50 + is_disabled: true + meets_ssi_disability_criteria: true + is_tax_unit_head: true + spouse: + age: 52 + is_disabled: true + meets_ssi_disability_criteria: true + immigration_status_str: UNDOCUMENTED + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + marital_units: + marital_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: CO + output: + people: + spouse: + ssi: 0 + co_state_supplement_eligible: false + +- name: Case 11, a disabled adult above the SSI resource limit is not eligible. + # $3,000 of countable resources exceeds the $2,000 SSI limit (20 CFR + # 416.1205), so no SSI is paid and 3.547(D) bars AND-CS. + period: 2026-01 + input: + people: + person: + age: 45 + is_disabled: true + meets_ssi_disability_criteria: true + ssi_countable_resources: 3_000 + households: + household: + members: [person] + state_code: CO + output: + ssi: 0 + co_state_supplement_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/integration.yaml index 387916d45ac..eba4e110bd0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/integration.yaml @@ -2,6 +2,8 @@ # Tests the full eligibility and benefit calculation pipeline # Source: 8.106.500.10 NMAC - Payments to Adults in Residential Care # Program: $100/month flat payment for SSI recipients in licensed ARSCH facilities +# 8.106.400.10(C) NMAC: two SSI recipients who would be a family at home are +# two separate benefit groups in an ARSCH facility, so each spouse is paid. - name: Case 1, elderly SSI recipient in ARSCH facility receives supplement. period: 2025 @@ -10,7 +12,6 @@ people: person1: age: 70 - is_ssi_eligible_individual: true is_in_adult_residential_care: true households: household: @@ -19,7 +20,7 @@ output: people: person1: - # Eligibility: SSI-eligible (true) AND age >= 18 (70 >= 18) AND in ARSCH (true) + # Eligibility: SSI recipient (aged) AND age >= 18 (70 >= 18) AND in ARSCH (true) nm_ssi_state_supplement_eligible: true # Benefit: $100/month * 12 = $1,200/year (flat payment) nm_ssi_state_supplement: 1_200 @@ -31,7 +32,8 @@ people: person1: age: 35 - is_ssi_eligible_individual: true + is_disabled: true + meets_ssi_disability_criteria: true is_in_adult_residential_care: true households: household: @@ -40,24 +42,35 @@ output: people: person1: - # Eligibility: SSI-eligible (true) AND age >= 18 (35 >= 18) AND in ARSCH (true) + # Eligibility: SSI recipient (disabled) AND age >= 18 (35 >= 18) AND in ARSCH (true) nm_ssi_state_supplement_eligible: true # Benefit: $100/month * 12 = $1,200/year nm_ssi_state_supplement: 1_200 -- name: Case 3, SSI couple both in ARSCH facility each receive supplement. +- name: Case 3, married SSI couple both in ARSCH facility each receive supplement. + # Both spouses of a joint SSI claim. 2025 SSI couple rate: $1,450/month, or + # $725 for each spouse. 8.106.400.10(C) NMAC: two SSI recipients who would + # be a family at home are "two separate benefit groups" in an ARSCH + # facility, and 8.106.500.10(C)(2) NMAC pays each $100/month. SSA's January + # 2011 New Mexico table shows the couple supplement as $200 (2 x $100). period: 2025 absolute_error_margin: 0.01 input: people: person1: age: 68 - is_ssi_eligible_individual: true + is_tax_unit_head: true is_in_adult_residential_care: true person2: age: 66 - is_ssi_eligible_individual: true + is_tax_unit_spouse: true is_in_adult_residential_care: true + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] households: household: members: [person1, person2] @@ -65,13 +78,17 @@ output: people: person1: - # Person 1: SSI-eligible, age 68 >= 18, in ARSCH + ssi_claim_is_joint: true + # $725/month * 12 = $8,700/year + ssi: 8_700 + # Person 1: SSI recipient, age 68 >= 18, in ARSCH nm_ssi_state_supplement_eligible: true # $100/month * 12 = $1,200/year per person nm_ssi_state_supplement: 1_200 person2: - # Person 2: SSI-eligible, age 66 >= 18, in ARSCH - # Per 8.106.400.10 NMAC: couples in ARSCH are two separate benefit groups + ssi_claim_is_joint: true + ssi: 8_700 + # Person 2: SSI recipient, age 66 >= 18, in ARSCH nm_ssi_state_supplement_eligible: true # $100/month * 12 = $1,200/year per person nm_ssi_state_supplement: 1_200 @@ -83,7 +100,6 @@ people: person1: age: 72 - is_ssi_eligible_individual: true is_in_adult_residential_care: false households: household: @@ -92,7 +108,7 @@ output: people: person1: - # Not in ARSCH facility: ineligible regardless of SSI status + # Not in ARSCH facility: ineligible regardless of SSI receipt nm_ssi_state_supplement_eligible: false nm_ssi_state_supplement: 0 @@ -103,7 +119,8 @@ people: person1: age: 18 - is_ssi_eligible_individual: true + is_disabled: true + meets_ssi_disability_criteria: true is_in_adult_residential_care: true households: household: @@ -124,11 +141,11 @@ people: person1: age: 60 - is_ssi_eligible_individual: true + is_disabled: true + meets_ssi_disability_criteria: true is_in_adult_residential_care: true person2: age: 45 - is_ssi_eligible_individual: false is_in_adult_residential_care: true households: household: @@ -137,11 +154,11 @@ output: people: person1: - # Person 1: SSI-eligible, age 60 >= 18, in ARSCH = eligible + # Person 1: SSI recipient (disabled), age 60 >= 18, in ARSCH = eligible nm_ssi_state_supplement_eligible: true nm_ssi_state_supplement: 1_200 person2: - # Person 2: NOT SSI-eligible = ineligible even though in ARSCH + # Person 2: not aged, blind or disabled, so no SSI = ineligible even though in ARSCH nm_ssi_state_supplement_eligible: false nm_ssi_state_supplement: 0 @@ -152,7 +169,6 @@ people: person1: age: 65 - is_ssi_eligible_individual: true is_in_adult_residential_care: true households: household: @@ -164,3 +180,62 @@ # Wrong state: defined_for = StateCode.NM excludes non-NM residents nm_ssi_state_supplement_eligible: false nm_ssi_state_supplement: 0 + +- name: Case 8, ARSCH resident whose spouse fails the SSI citizenship condition. + # The undocumented tax-unit spouse receives no SSI (8 USC 1611, 1612), so + # is not "a recipient of supplemental security income" under + # 8.106.500.10(A) NMAC. The citizen head still receives the supplement. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + is_tax_unit_head: true + is_in_adult_residential_care: true + person2: + age: 66 + immigration_status_str: UNDOCUMENTED + is_tax_unit_spouse: true + is_in_adult_residential_care: true + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + people: + person1: + nm_ssi_state_supplement_eligible: true + nm_ssi_state_supplement: 1_200 + person2: + ssi: 0 + nm_ssi_state_supplement_eligible: false + nm_ssi_state_supplement: 0 + +- name: Case 9, ARSCH resident above the SSI resource limit receives nothing. + # $3,000 of countable resources exceeds the $2,000 SSI limit, so no SSI is + # paid and 8.106.500.10(A) NMAC bars the supplement. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + ssi_countable_resources: 3_000 + is_in_adult_residential_care: true + households: + household: + members: [person1] + state_code: NM + output: + people: + person1: + ssi: 0 + nm_ssi_state_supplement_eligible: false + nm_ssi_state_supplement: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement.yaml index d101679d948..3d7d28619ee 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement.yaml @@ -9,7 +9,7 @@ people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -21,14 +21,14 @@ # $100/month * 12 months = $1,200/year nm_ssi_state_supplement: 1_200 -- name: Case 2, not SSI-eligible receives zero. +- name: Case 2, not an SSI recipient receives zero. period: 2025 absolute_error_margin: 0.01 input: people: person1: age: 65 - is_ssi_eligible_individual: false + ssi: 0 is_in_adult_residential_care: true households: household: @@ -46,7 +46,7 @@ people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: false households: household: @@ -64,7 +64,7 @@ people: person1: age: 17 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.yaml index 44eb3aa7c43..6a6840b34fd 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.yaml @@ -9,7 +9,7 @@ people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -27,7 +27,7 @@ people: person1: age: 30 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -38,14 +38,14 @@ person1: nm_ssi_state_supplement_eligible: true -- name: Case 3, not SSI-eligible person in ARSCH facility in NM is ineligible. +- name: Case 3, person in ARSCH facility in NM who receives no SSI is ineligible. period: 2025 absolute_error_margin: 0.01 input: people: person1: age: 65 - is_ssi_eligible_individual: false + ssi: 0 is_in_adult_residential_care: true households: household: @@ -56,14 +56,14 @@ person1: nm_ssi_state_supplement_eligible: false -- name: Case 4, underage person is ineligible even if SSI-eligible and in ARSCH. +- name: Case 4, underage person is ineligible even if SSI recipient and in ARSCH. period: 2025 absolute_error_margin: 0.01 input: people: person1: age: 17 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -81,7 +81,7 @@ people: person1: age: 18 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -92,14 +92,14 @@ person1: nm_ssi_state_supplement_eligible: true -- name: Case 6, SSI-eligible adult NOT in ARSCH facility is ineligible. +- name: Case 6, SSI recipient adult NOT in ARSCH facility is ineligible. period: 2025 absolute_error_margin: 0.01 input: people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: false households: household: @@ -110,14 +110,14 @@ person1: nm_ssi_state_supplement_eligible: false -- name: Case 7, SSI-eligible adult in ARSCH but wrong state is ineligible. +- name: Case 7, SSI recipient adult in ARSCH but wrong state is ineligible. period: 2025 absolute_error_margin: 0.01 input: people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -127,3 +127,21 @@ people: person1: nm_ssi_state_supplement_eligible: false + +- name: Case 8, reported SSI receipt qualifies a resident with zero computed SSI. + period: 2025-01 + input: + people: + person1: + age: 65 + ssi: 0 + receives_ssi: true + is_in_adult_residential_care: true + households: + household: + members: [person1] + state_code: NM + output: + people: + person1: + nm_ssi_state_supplement_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_historical.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_historical.yaml index 0724d4aaa8a..99246699f84 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_historical.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_historical.yaml @@ -1,5 +1,5 @@ # Historical (2017-2019) New Mexico SSI state supplement amount. -# The optional state supplement for an SSI-eligible adult residing in a +# The optional state supplement for an SSI recipient adult residing in a # licensed adult residential care home has been a flat $100.00/month # ($1,200/year) continuously since July 2004 through at least 2025 (verified # against the SSA annual "State Assistance Programs for SSI Recipients" reports @@ -22,7 +22,7 @@ people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -40,7 +40,7 @@ people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: @@ -58,7 +58,7 @@ people: person1: age: 65 - is_ssi_eligible_individual: true + ssi: 9_000 is_in_adult_residential_care: true households: household: diff --git a/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/integration.yaml index 014f8e1eb49..5bc7929b311 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/integration.yaml @@ -7,19 +7,23 @@ # - 2024 PNA: $75/month, Federal reduced SSI: $30/month individual # - Individual supplement: $45/month = $540/year # - No additional state income rules beyond federal SSI +# - Each spouse of a couple in a facility receives the reduced benefit ($60 +# for the couple, H-6000), so each receives the supplement # # Reference: Texas Human Resources Code Section 32.024(w) +# Reference: HHSC MEPD Handbook H-1500 and H-6000 # Reference: SSA State Assistance Programs for SSI Recipients - Texas -- name: Scenario 1, SSI-eligible elderly individual in Texas Medicaid facility. +- name: Scenario 1, elderly SSI recipient in Texas Medicaid facility. # 70-year-old SSI recipient in a nursing facility receives state supplement period: 2024 input: people: person1: age: 70 - is_ssi_eligible_individual: true is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true tax_units: tax_unit: members: [person1] @@ -31,20 +35,25 @@ members: [person1] state_code: TX output: - # Eligibility: SSI eligible + in Medicaid facility + TX = eligible + # Federal reduced SSI: $30/month * 12 = $360/year + ssi: 360 + # Eligibility: SSI recipient + in Medicaid facility + TX = eligible tx_ssi_state_supplement_eligible: true # Supplement: ($75 PNA - $30 federal reduced SSI) * 12 = $540/year tx_ssi_state_supplement: 540 -- name: Scenario 2, SSI-eligible disabled individual in Texas Medicaid facility. +- name: Scenario 2, disabled SSI recipient in Texas Medicaid facility. # 45-year-old disabled SSI recipient in ICF/IID period: 2024 input: people: person1: age: 45 - is_ssi_eligible_individual: true + is_disabled: true + meets_ssi_disability_criteria: true is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true tax_units: tax_unit: members: [person1] @@ -56,19 +65,19 @@ members: [person1] state_code: TX output: - # Eligibility: SSI eligible + in Medicaid facility + TX = eligible + ssi: 360 + # Eligibility: SSI recipient + in Medicaid facility + TX = eligible tx_ssi_state_supplement_eligible: true # Supplement: ($75 - $30) * 12 = $540/year tx_ssi_state_supplement: 540 -- name: Scenario 3, SSI-eligible individual NOT in Medicaid facility. +- name: Scenario 3, SSI recipient NOT in Medicaid facility. # SSI recipient living in community - no supplement period: 2024 input: people: person1: age: 70 - is_ssi_eligible_individual: true is_in_medicaid_facility: false tax_units: tax_unit: @@ -85,15 +94,16 @@ tx_ssi_state_supplement_eligible: false tx_ssi_state_supplement: 0 -- name: Scenario 4, person in Medicaid facility but NOT SSI eligible. - # Non-SSI recipient in nursing facility - no supplement +- name: Scenario 4, person in Medicaid facility but NOT an SSI recipient. + # 50-year-old who is neither aged, blind nor disabled receives no SSI period: 2024 input: people: person1: age: 50 - is_ssi_eligible_individual: false is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true tax_units: tax_unit: members: [person1] @@ -105,19 +115,21 @@ members: [person1] state_code: TX output: - # Not SSI eligible = not eligible for supplement + # No SSI = not eligible for supplement + ssi: 0 tx_ssi_state_supplement_eligible: false tx_ssi_state_supplement: 0 -- name: Scenario 5, SSI-eligible individual in Medicaid facility in another state. +- name: Scenario 5, SSI recipient in Medicaid facility in another state. # SSI recipient in facility but not in Texas period: 2024 input: people: person1: age: 68 - is_ssi_eligible_individual: true is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true tax_units: tax_unit: members: [person1] @@ -133,22 +145,35 @@ tx_ssi_state_supplement_eligible: false tx_ssi_state_supplement: 0 -- name: Scenario 6, couple both SSI-eligible in Texas Medicaid facility. - # Both members of a couple in a nursing facility +- name: Scenario 6, married SSI couple both in a Texas Medicaid facility. + # Both spouses of a joint SSI claim live in a nursing facility. H-6000: + # "SSA lowers the SSI payment standard to the reduced standard for a couple + # ($60)", i.e. $30 for each spouse, and "HHSC supplements the reduced SSI + # payment standard by $45 per month to ensure SSI recipients also have a $75 + # personal needs allowance." SSA's January 2011 Texas table: "Couples + # residing in this living arrangement for more than 30 days are treated as + # two individuals." period: 2024 input: people: person1: age: 72 - is_ssi_eligible_individual: true + is_tax_unit_head: true is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true person2: age: 70 - is_ssi_eligible_individual: true + is_tax_unit_spouse: true is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true tax_units: tax_unit: members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] spm_units: spm_unit: members: [person1, person2] @@ -157,7 +182,10 @@ members: [person1, person2] state_code: TX output: - # Both persons are eligible + ssi_claim_is_joint: [true, true] + # Each spouse: $30/month * 12 = $360/year + ssi: [360, 360] + # Both spouses are eligible tx_ssi_state_supplement_eligible: [true, true] # Each person: ($75 - $30) * 12 = $540/year tx_ssi_state_supplement: [540, 540] @@ -169,8 +197,9 @@ people: person1: age: 75 - is_ssi_eligible_individual: true is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true tax_units: tax_unit: members: [person1] @@ -194,8 +223,9 @@ people: person1: age: 80 - is_ssi_eligible_individual: true is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true tax_units: tax_unit: members: [person1] @@ -211,3 +241,151 @@ # 2005 PNA: $45/month (set 2003-09-01), Federal reduced SSI: $30/month # Supplement: ($45 - $30) * 12 = $180/year tx_ssi_state_supplement: 180 + +- name: Scenario 9, facility resident whose spouse fails the SSI citizenship condition. + # The undocumented tax-unit spouse receives no SSI (8 USC 1611, 1612), so + # receives no Texas supplement. The citizen head still does. + period: 2024 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + person2: + age: 70 + immigration_status_str: UNDOCUMENTED + is_tax_unit_spouse: true + is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: TX + output: + ssi: [360, 0] + tx_ssi_state_supplement_eligible: [true, false] + tx_ssi_state_supplement: [540, 0] + +- name: Scenario 10, facility resident above the SSI resource limit. + # $3,000 of countable resources exceeds the $2,000 SSI limit, so the + # person is not an SSI recipient and H-1500 gives no state supplement. + period: 2024 + input: + people: + person1: + age: 80 + ssi_countable_resources: 3_000 + is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: TX + output: + ssi: 0 + tx_ssi_state_supplement_eligible: false + tx_ssi_state_supplement: 0 + +- name: Scenario 11, facility resident whose countable income equals the $30 reduced standard. + # A $50/month pension less the $20 general exclusion is $30 of countable + # income, so the federal payment is $30 - $30 = $0. H-6000: the resident + # "remains eligible for SSI if their countable income does not exceed the + # SSI reduced standard payment amount", and HHSC pays the $45 supplement. + period: 2024 + input: + people: + person1: + age: 80 + pension_income: 600 + is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: TX + output: + ssi: 0 + tx_ssi_state_supplement_eligible: true + # ($75 - $30) * 12 = $540/year + tx_ssi_state_supplement: 540 + +- name: Scenario 12, facility resident whose countable income exceeds the $30 reduced standard. + # A $51/month pension gives $31 of countable income, above the reduced + # standard, so the resident is not eligible for SSI or the supplement. + period: 2024 + input: + people: + person1: + age: 80 + pension_income: 612 + is_in_medicaid_facility: true + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: TX + output: + ssi: 0 + tx_ssi_state_supplement_eligible: false + tx_ssi_state_supplement: 0 + +- name: Scenario 13, facility resident outside the SSI facility living arrangement with income at the full federal rate. + # Only is_in_medicaid_facility is set, so SSI uses the $943 own-household + # rate. A $963/month pension gives $943 of countable income: SSI is $0, and + # the income is far above the $30 reduced standard that H-6000 applies to a + # facility resident, so there is no supplement. + period: 2024 + input: + people: + person1: + age: 80 + pension_income: 11_556 + is_in_medicaid_facility: true + tax_units: + tax_unit: + members: [person1] + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: TX + output: + ssi: 0 + tx_ssi_state_supplement_eligible: false + tx_ssi_state_supplement: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.yaml index dd95373cc66..d5d5fb0042e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.yaml @@ -1,21 +1,29 @@ # Unit tests for Texas SSI State Supplement eligibility -# Eligible if: SSI eligible individual AND residing in a Medicaid-funded facility -# AND in Texas -# Reference: Texas Human Resources Code Section 32.024(w) +# Eligible if: eligible for SSI with countable income not over the $30 reduced +# standard (a $0 federal payment at the limit included) and takes up SSI, or +# reported to receive SSI; AND residing in a Medicaid-funded facility; AND in +# Texas +# Reference: Texas Human Resources Code Section 32.024(w); HHSC MEPD Handbook +# H-1500 ("SSI recipients who live in an institutional setting and receive the +# $30 reduced federal benefit receive a state supplement") and H-6000 (an SSI +# recipient in a facility "remains eligible for SSI if their countable income +# does not exceed the SSI reduced standard payment amount") -- name: Case 1, SSI eligible and in Medicaid facility in Texas. +- name: Case 1, SSI-eligible facility resident with no countable income. period: 2024 input: - is_ssi_eligible_individual: true + is_ssi_eligible: true + ssi_countable_income: 0 is_in_medicaid_facility: true state_code: TX output: tx_ssi_state_supplement_eligible: true -- name: Case 2, SSI eligible but not in Medicaid facility. +- name: Case 2, SSI-eligible but not in Medicaid facility. period: 2024 input: - is_ssi_eligible_individual: true + is_ssi_eligible: true + ssi_countable_income: 0 is_in_medicaid_facility: false state_code: TX output: @@ -24,7 +32,7 @@ - name: Case 3, not SSI eligible but in Medicaid facility. period: 2024 input: - is_ssi_eligible_individual: false + is_ssi_eligible: false is_in_medicaid_facility: true state_code: TX output: @@ -33,8 +41,62 @@ - name: Case 4, neither SSI eligible nor in Medicaid facility. period: 2024 input: - is_ssi_eligible_individual: false + is_ssi_eligible: false is_in_medicaid_facility: false state_code: TX output: tx_ssi_state_supplement_eligible: false + +- name: Case 5, reported SSI receipt qualifies a facility resident. + period: 2024-01 + input: + is_ssi_eligible: false + receives_ssi: true + is_in_medicaid_facility: true + state_code: TX + output: + tx_ssi_state_supplement_eligible: true + +- name: Case 6, countable income equal to the $30 reduced standard stays eligible. + # $360/year = $30/month, so the federal payment is $0 (H-6000). + period: 2024 + input: + is_ssi_eligible: true + ssi_countable_income: 360 + is_in_medicaid_facility: true + state_code: TX + output: + tx_ssi_state_supplement_eligible: true + +- name: Case 7, countable income above the $30 reduced standard is not eligible. + # $372/year = $31/month. + period: 2024 + input: + is_ssi_eligible: true + ssi_countable_income: 372 + is_in_medicaid_facility: true + state_code: TX + output: + tx_ssi_state_supplement_eligible: false + +- name: Case 8, a facility resident who does not take up SSI is not eligible. + period: 2024 + input: + is_ssi_eligible: true + ssi_countable_income: 0 + takes_up_ssi_if_eligible: false + is_in_medicaid_facility: true + state_code: TX + output: + tx_ssi_state_supplement_eligible: false + +- name: Case 9, no supplement for SSI recipients once SSI is abolished. + period: 2024 + input: + gov.ssa.ssi.abolish_ssi: true + is_ssi_eligible: true + ssi_countable_income: 0 + is_in_medicaid_facility: true + state_code: TX + output: + tx_ssi_state_supplement_eligible: false diff --git a/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement.py b/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement.py index da55e8d65e7..dac180acbd4 100644 --- a/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement.py +++ b/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement.py @@ -9,7 +9,7 @@ class co_state_supplement(Variable): defined_for = "co_state_supplement_eligible" def formula(person, period, parameters): - income = person("ssi_countable_income", period) + income = person("co_state_supplement_countable_income", period) ssi = person("ssi", period) total_countable_income = ssi + income p = parameters(period).gov.states.co.ssa.state_supplement diff --git a/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement_countable_income.py b/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement_countable_income.py new file mode 100644 index 00000000000..7c715bc5a79 --- /dev/null +++ b/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement_countable_income.py @@ -0,0 +1,48 @@ +from policyengine_us.model_api import * + + +class co_state_supplement_countable_income(Variable): + value_type = float + entity = Person + label = "Colorado State Supplement countable income other than SSI" + unit = USD + definition_period = MONTH + # PDF pages 93-94 + reference = "https://www.sos.state.co.us/CCR/GenerateRulePdf.do?fileName=9+CCR+2503-5&ruleVersionId=12428#page=93" + + def formula(person, period, parameters): + # 9 CCR 2503-5 3.549(A) counts each AND-CS client's own income. Where + # SSI's couple computation applies, ssi_countable_income instead gives + # each spouse half of the couple's pooled countable income. Both + # spouses then receive SSI, so 3.549(F) deems neither spouse's income + # to the other, and the client's own income is counted as follows. + couple_computation = person("ssi_couple_computation_applies", period) + p = parameters(period).gov.ssa.ssi.income.exclusions + earned = max_( + person("ssi_earned_income", period) + - person("ssi_blind_or_disabled_working_student_exclusion", period), + 0, + ) + # A joint couple's in-kind support and maintenance is one presumed + # maximum value for the couple (ssi_pmv_amount), which SSI splits + # equally between the spouses. + ism_share = person("ssi_in_kind_support_and_maintenance", period) / 2 + unearned = person("ssi_unearned_income", period) + ism_share + ssi = person("ssi", period) + # 3.549(A)(2)(c): $20 is deducted from unearned income other than SSI, + # split between married spouses; a client whose only unearned income + # is SSI gets no unearned income disregard. + unearned_disregard = min_(p.general / 2, unearned) + # 3.549(A)(2)(f): only when the client's gross unearned income, SSI + # included, is under $20 does the difference reduce earned income. + earned_disregard = where(unearned > 0, max_(0, p.general - unearned - ssi), 0) + # 3.549(A)(1): deduct $65 from gross earned income and halve the rest. + countable_earned = max_(0, earned - p.earned - earned_disregard) * ( + 1 - p.earned_share + ) + own_countable = unearned - unearned_disregard + countable_earned + return where( + couple_computation, + own_countable, + person("ssi_countable_income", period), + ) diff --git a/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.py b/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.py index f9c624c8887..24e9ea2c409 100644 --- a/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.py +++ b/policyengine_us/variables/gov/states/co/ssa/state_supplement/co_state_supplement_eligible.py @@ -7,13 +7,19 @@ class co_state_supplement_eligible(Variable): label = "Colorado State Supplement Eligible" definition_period = MONTH defined_for = StateCode.CO + # PDF pages 91-92 + reference = "https://www.sos.state.co.us/CCR/GenerateRulePdf.do?fileName=9+CCR+2503-5&ruleVersionId=12428#page=91" def formula(person, period, parameters): - ssi_eligible = person("is_ssi_eligible_individual", period.this_year) + # 9 CCR 2503-5 3.546 and 3.547(A), (D): AND-CS is for clients + # "receiving SSI due to a disability or blindness". 3.548(A) + # calculates grants "on an individual basis with just one client per + # case", so each member of an SSI couple qualifies on their own. + receives_ssi = (person("ssi", period) > 0) | person("receives_ssi", period) is_disabled = person("is_ssi_disabled", period.this_year) is_blind = person("is_blind", period.this_year) disabled_or_blind = is_disabled | is_blind age = person("age", period.this_year) p = parameters(period).gov.states.co.ssa.state_supplement in_age_range = p.age_range.calc(age) - return disabled_or_blind & ssi_eligible & in_age_range + return disabled_or_blind & receives_ssi & in_age_range diff --git a/policyengine_us/variables/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.py b/policyengine_us/variables/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.py index 7129f51da12..3e73c285359 100644 --- a/policyengine_us/variables/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.py +++ b/policyengine_us/variables/gov/states/nm/hca/ssi_supplement/nm_ssi_state_supplement_eligible.py @@ -9,13 +9,18 @@ class nm_ssi_state_supplement_eligible(Variable): defined_for = StateCode.NM reference = ( "https://srca.nm.gov/parts/title08/08.106.0500.html", + "https://srca.nm.gov/parts/title08/08.106.0400.html", "https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/2011/nm.html", ) def formula(person, period, parameters): - ssi_eligible = person("is_ssi_eligible_individual", period.this_year) + # 8.106.500.10(A) NMAC: "The individual must be a recipient of + # supplemental security income (SSI)". 8.106.400.10(C) NMAC: two SSI + # recipients who would be a family at home are two separate benefit + # groups in residential care, so each spouse receives the payment. + receives_ssi = (person("ssi", period) > 0) | person("receives_ssi", period) age = person("age", period.this_year) p = parameters(period).gov.states.nm.hca.ssi_supplement meets_age = age >= p.min_age in_residential_care = person("is_in_adult_residential_care", period) - return ssi_eligible & meets_age & in_residential_care + return receives_ssi & meets_age & in_residential_care diff --git a/policyengine_us/variables/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.py b/policyengine_us/variables/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.py index 2bcbdb97b9a..2dda8005e13 100644 --- a/policyengine_us/variables/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.py +++ b/policyengine_us/variables/gov/states/tx/hhsc/ssi_state_supplement/tx_ssi_state_supplement_eligible.py @@ -10,9 +10,30 @@ class tx_ssi_state_supplement_eligible(Variable): reference = ( "https://statutes.capitol.texas.gov/Docs/HR/htm/HR.32.htm", "https://www.hhs.texas.gov/handbooks/medicaid-elderly-people-disabilities-handbook/h-6000-co-payment-ssi-cases", + "https://www.hhs.texas.gov/handbooks/medicaid-elderly-people-disabilities-handbook/h-1500-personal-needs-allowance", ) def formula(person, period, parameters): - ssi_eligible = person("is_ssi_eligible_individual", period.this_year) + # MEPD Handbook H-1500: "SSI recipients who live in an institutional + # setting and receive the $30 reduced federal benefit receive a state + # supplement." H-6000: such a resident "remains eligible for SSI if + # their countable income does not exceed the SSI reduced standard + # payment amount", so countable income equal to it, with a $0 federal + # payment, still qualifies. The test is against the reduced standard + # itself, since this program identifies residents through + # is_in_medicaid_facility rather than the SSI living arrangement. For + # a couple in a facility, SSI's couple computation gives each spouse + # half the couple's countable income, held to their $30 half of the + # $60 couple standard (H-6000). + p = parameters(period).gov.ssa.ssi + countable_income = person("ssi_countable_income", period) + within_reduced_standard = countable_income <= p.amount.institutional.individual + eligible_for_ssi = ( + person("is_ssi_eligible", period) + & person("takes_up_ssi_if_eligible", period.this_year) + & within_reduced_standard + & ~p.abolish_ssi + ) + receives_ssi = person("receives_ssi", period) in_facility = person("is_in_medicaid_facility", period) - return ssi_eligible & in_facility + return (eligible_for_ssi | receives_ssi) & in_facility