diff --git a/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md new file mode 100644 index 00000000000..55f2c685ab7 --- /dev/null +++ b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md @@ -0,0 +1 @@ +Count the own income of aged, blind, or disabled people who fail SSI's noncitizen test in SSI-methodology countable income, so Medicaid's optional aged, blind, and disabled and medically needy income tests, CAPI, and other programs no longer treat it as zero; the California state supplement no longer counts the income of a member who fails SSI's noncitizen test unless that member is in an SSI couple computation, and Maryland PAA no longer deems spouse income to people SSI bars by alien status and imputes to them only the SSI that SSA pays when they report SSI receipt, with the one-third reduction on the couple rate under deeming. diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/is_optional_senior_or_disabled_for_medicaid.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/is_optional_senior_or_disabled_for_medicaid.yaml index 3702b579490..6e28ffe75fa 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/is_optional_senior_or_disabled_for_medicaid.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/is_optional_senior_or_disabled_for_medicaid.yaml @@ -61,8 +61,9 @@ # Emergency Medicaid covers noncitizens who meet the state plan's requirements # other than the receipt of SSI (42 U.S.C. 1396b(v)(2)(B); 42 CFR 435.406(b)). # In Alabama that leaves SSI's income test. Wages of $800 a month ($9,600 a -# year) are under the SSI rate ($11,928) before any disregard. Until #10240 -# merges, the pathway counts no income for this person; Cases 7 and 8 test it. +# year) are under the SSI rate ($11,928) before any disregard; the pathway +# counts that income (at most 4,290 a year after exclusions). Cases 7 and 8 +# test the income limit. - name: Case 6, undocumented aged Alabaman keeps the pathway, unlike the citizen in Case 3, and qualifies for emergency Medicaid. period: 2026 input: diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml index 5cf50414394..0d83bd5f24d 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml @@ -332,3 +332,79 @@ # 12,000 - 6,000 = 6,000 <= 6,264; resources 1,000 <= 2,000. is_in_medicaid_medically_needy_category: true is_medically_needy_for_medicaid: true + +- name: Case 11, aged permanent resident without 40 SSI quarters has pension counted. + period: 2026 + input: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 60_000 + is_in_medicaid_medically_needy_category: true + is_adult_for_medicaid: false + is_optional_senior_or_disabled_for_medicaid: false + medicaid_medically_needy_medical_expenses: 6_000 + ssi_countable_resources: 1_000 + state_code: MA + output: + # 60,000 - 20 x 12 = 59,760; 59,760 - 6,000 = 53,760 > 522 x 12 = 6,264. + is_medically_needy_for_medicaid: false + +- name: Case 12, aged permanent resident without 40 SSI quarters qualifies after medical spenddown. + period: 2026 + input: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 18_000 + is_in_medicaid_medically_needy_category: true + is_adult_for_medicaid: false + is_optional_senior_or_disabled_for_medicaid: false + medicaid_medically_needy_medical_expenses: 12_000 + ssi_countable_resources: 1_000 + state_code: MA + output: + # 18,000 - 20 x 12 = 17,760; 17,760 - 12,000 = 5,760 <= 522 x 12 = 6,264. + is_medically_needy_for_medicaid: true + +- name: Case 13, an aged noncitizen dependent parent's pension does not count against the head. + period: 2026 + input: + people: + head: + age: 70 + immigration_status: CITIZEN + pension_income: 20_000 + medicaid_medically_needy_medical_expenses: 15_000 + ssi_countable_resources: 1_000 + is_in_medicaid_medically_needy_category: true + is_optional_senior_or_disabled_for_medicaid: false + parent: + age: 90 + is_tax_unit_dependent: true + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 30_000 + ssi_countable_resources: 0 + tax_units: + tax_unit: + members: [head, parent] + marital_units: + head_unit: + members: [head] + parent_unit: + members: [parent] + households: + household: + members: [head, parent] + state_code: MA + output: + # The parent's 30,000 - 240 = 29,760 now counts (this PR), but a parent's + # income is never deemed to an adult child aged 70 (42 CFR + # 435.602(a)(2)(i)). The head: 20,000 - 240 - 15,000 = 4,760 <= 522 x 12 + # = 6,264. + ssi_countable_income: [19_760, 29_760] + is_medically_needy_for_medicaid: [true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/is_medicaid_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/is_medicaid_eligible.yaml index c48e39629ee..0defe6e70f6 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/is_medicaid_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/is_medicaid_eligible.yaml @@ -439,3 +439,48 @@ output: is_pregnant_for_medicaid: true is_medicaid_eligible: true + +- name: Case 21, aged permanent resident without 40 SSI quarters is over the Massachusetts income limit. + period: 2025 + input: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 60_000 + state_code: MA + output: + # The optional aged, blind, and disabled pathway counts 59,760 of + # income, above 100% of the poverty guideline, even though the person + # fails SSI's 40-quarter test. + is_medicaid_immigration_status_eligible: true + is_optional_senior_or_disabled_for_medicaid: false + is_medicaid_eligible: false + +- name: Case 22, aged permanent resident without 40 SSI quarters with a small pension is eligible. + period: 2025 + input: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 12_000 + state_code: MA + output: + # 12,000 - 20 x 12 = 11,760, under 100% of the poverty guideline. + is_optional_senior_or_disabled_for_medicaid: true + is_medicaid_eligible: true + +- name: Case 23, aged undocumented resident of the District of Columbia is over the income limit. + period: 2025 + input: + age: 70 + immigration_status: UNDOCUMENTED + pension_income: 60_000 + state_code: DC + output: + # The District covers undocumented residents, but the optional aged, + # blind, and disabled pathway still counts 59,760 of income. + is_medicaid_immigration_status_eligible: true + is_optional_senior_or_disabled_for_medicaid: false + is_medicaid_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.yaml index 1724495a64d..42218c4dfd6 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.yaml @@ -120,3 +120,36 @@ # (17,004 - 20 * 12 - 65 * 12) / 2 = 7,992 deemed and countable. medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse: [7_992, 0, 0] medicaid_optional_senior_or_disabled_countable_income: [7_992, 0, 0] + +- name: Spouse income is deemed to an aged permanent resident without 40 SSI quarters. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 6_000 + person2: + age: 55 + is_tax_unit_spouse: true + employment_income: 40_000 + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MA + output: + # SSI's noncitizen test does not stop deeming (42 CFR 435.601). + # Spouse wages 40,000 > (1,450 - 967) x 12 = 5,796. + # Couple: (500 - 20) x 12 + (40,000 - 65 x 12) / 2 = 25,370. + # Alone: (500 - 20) x 12 = 5,760. Deemed: 25,370 - 5,760 = 19,610. + medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse: [19_610, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.yaml index 5606b16f437..a0b2f1b20f4 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.yaml @@ -727,3 +727,54 @@ # 21,480 is under the 2026 guideline for two (21,640). A 75-dollar # disregard would leave 21,780, over the guideline. is_optional_senior_or_disabled_income_eligible: [true, true] + +- name: An aged permanent resident without 40 SSI quarters has their pension counted. + period: 2025 + absolute_error_margin: 0.01 + input: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 60_000 + state_code: MA + output: + # Failing SSI's noncitizen test does not zero income under SSI + # methodology (42 CFR 435.601): 60,000 - 20 x 12 = 59,760. + medicaid_optional_senior_or_disabled_countable_income: 59_760 + is_optional_senior_or_disabled_income_eligible: false + +- name: Spouse income is deemed to an aged permanent resident without 40 SSI quarters. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 6_000 + person2: + age: 55 + is_tax_unit_spouse: true + employment_income: 40_000 + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MA + output: + # Own income: 6,000 - 20 x 12 = 5,760. + # Deemed from the spouse who is not aged, blind, or disabled: + # 40,000 > (1,450 - 967) x 12 = 5,796, so the couple total is + # 5,760 + (40,000 - 65 x 12) / 2 = 25,370, and 25,370 - 5,760 = 19,610. + # The spouse's own countable income stays 0 to avoid counting it twice. + medicaid_optional_senior_or_disabled_countable_income: [25_370, 0] + is_optional_senior_or_disabled_income_eligible: [false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicare/savings_programs/income/msp_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicare/savings_programs/income/msp_countable_income.yaml index df9c65a5611..fb81c53bf64 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicare/savings_programs/income/msp_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicare/savings_programs/income/msp_countable_income.yaml @@ -427,3 +427,32 @@ # Rule 4.2(C)(5) withholds the exclusion only from income based on need: # 12,000 / 12 - 50 = 950. msp_countable_income: 950 + +- name: Case 20, spouse income is deemed to an aged permanent resident without 40 SSI quarters. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + ssi_unearned_income: 12_000 + person2: + age: 55 + is_tax_unit_spouse: true + ssi_earned_income: 20_000 + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] + output: + # SSI methodology deems the spouse's wages whether or not the person + # meets SSI's noncitizen test: 20,000 > (1,450 - 967) x 12 = 5,796. + # (1,000 - 20) + (1,666.67 - 65) / 2 = 980 + 800.83 = 1,780.83. + is_ssi_spousal_deeming_applies: [true, false] + msp_countable_income: [1_780.83, 790.83] diff --git a/policyengine_us/tests/policy/baseline/gov/local/ca/sf/caap/ca_sf_caap.yaml b/policyengine_us/tests/policy/baseline/gov/local/ca/sf/caap/ca_sf_caap.yaml index 3e8dcad1290..cb6ca423414 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ca/sf/caap/ca_sf_caap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ca/sf/caap/ca_sf_caap.yaml @@ -316,8 +316,8 @@ # size-1 grant ($714) is paid through the top-level benefit, not the GA $578. ca_sf_caap: 714 -- name: Case 15, aged TPS member with a CAPI payment is excluded from the - budget unit along with her income. +- name: Case 15, aged TPS member whose pension rules out CAPI stays in the + budget unit with her income. period: 2026-01 absolute_error_margin: 0.01 input: @@ -339,22 +339,14 @@ spm_unit_cash_assets: 0 output: # person2 is categorically CAPI-eligible (aged 68 + noncitizen + TPS is not - # an SSI-qualified status) and the model pays her unit CAPI, so the - # receipt-based bar (ca_capi > 0) drops her from the budget unit and her - # pension is masked out of countable income; the remaining member collects - # the size-1 grant. - # NOTE: in real life her 2,000/month pension is roughly double the CAPI - # payment standard, so she would receive no CAPI and would stay in the - # CAAP budget unit (size 2, max grant 1,036), where her income fails the - # strict income test: ca_sf_caap = 0. The model currently pays her CAPI - # regardless of income because ca_capi's income test reads - # ssi_countable_income, which is zeroed for anyone failing the SSI - # immigration test (CAPI's entire target population) -- an upstream CAPI - # limitation. When that is fixed upstream, this case's expectations flip - # to budget_unit_size 2, countable_income 2_000, ca_sf_caap 0. - ca_sf_caap_budget_unit_size: 1 - ca_sf_caap_countable_income: 0 - ca_sf_caap: 578 + # an SSI-qualified status), but CAPI counts her pension: her countable + # pension (2,000 - 20 = 1,980/month) exceeds CAPI's payment standard, so + # ca_capi = 0. The receipt-based bar (ca_capi > 0) does not apply, and she + # stays in the CAAP budget unit (size 2, max grant 1,036), where her + # income fails the strict income test. + ca_sf_caap_budget_unit_size: 2 + ca_sf_caap_countable_income: 2_000 + ca_sf_caap: 0 - name: Case 16, one spouse receiving SSI and only one spouse applying yields the full one-person grant against the applicant's own income. diff --git a/policyengine_us/tests/policy/baseline/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.yaml b/policyengine_us/tests/policy/baseline/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.yaml index 0b05128cf11..e1968e9c591 100644 --- a/policyengine_us/tests/policy/baseline/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.yaml +++ b/policyengine_us/tests/policy/baseline/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.yaml @@ -224,3 +224,33 @@ members: [person1, person2] output: ssi_income_deemed_from_ineligible_spouse: [0, 0] + +- name: Spouse income is deemed to an aged permanent resident without 40 SSI quarters (2025) + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 6_000 + person2: + age: 55 + is_tax_unit_spouse: true + employment_income: 40_000 + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] + output: + # Deeming turns on aged, blind, or disabled status, not on SSI's + # noncitizen test: spouse wages 40,000 > (1,450 - 967) x 12 = 5,796. + # Couple: (500 - 20) x 12 + (40,000 - 65 x 12) / 2 = 25,370. + # Alone: (500 - 20) x 12 = 5,760. Deemed: 25,370 - 5,760 = 19,610. + is_ssi_spousal_deeming_applies: [true, false] + ssi_income_deemed_from_ineligible_spouse: [19_610, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/ssa/ssi/ssi_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/ssa/ssi/ssi_countable_income.yaml index 3f66920e3c1..af96ba13287 100644 --- a/policyengine_us/tests/policy/baseline/gov/ssa/ssi/ssi_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/ssa/ssi/ssi_countable_income.yaml @@ -147,3 +147,47 @@ # No earned income, so earned exclusions don't apply # Countable = 3_868 ssi_countable_income: 3_868 + +- name: An aged permanent resident without 40 SSI quarters has their pension counted. + period: 2025 + absolute_error_margin: 0.01 + input: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 60_000 + output: + # The noncitizen test bars SSI itself but does not zero the income + # that Medicaid and state programs count: 60,000 - 20 x 12 = 59,760. + ssi_countable_income: 59_760 + ssi: 0 + +- name: Spouse income is deemed to an aged permanent resident without 40 SSI quarters. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 6_000 + person2: + age: 55 + is_tax_unit_spouse: true + employment_income: 40_000 + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit: + members: [person1, person2] + output: + # Own: (500 - 20) x 12 = 5,760. Deemed from the spouse who is not aged, + # blind, or disabled: 19,610 (20 CFR 416.1163). The spouse's own + # countable income stays 0. + ssi_countable_income: [25_370, 0] + ssi: [0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi.yaml index ba3bf69df9c..edcf59a37e7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi.yaml @@ -9,16 +9,14 @@ ssi_qualifying_quarters_earnings: 39 # 520 per month foreign pension. pension_income: 6_240 - # SSI zeroes countable income for people who fail its immigration - # test, so the case supplies it: 520 - 20 general exclusion = 500 per - # month (6,000 per year). - ssi_countable_income: 6_000 households: household: members: [person1] state_code: CA living_arrangements_allow_for_food_preparation: true output: + # 520 - 20 general exclusion = 500 per month (6,000 per year). + ssi_countable_income: 6_000 # Individual standard 1,233.94 (no offset since June 2019, WIC 18941), # less countable income 500 = 733.94 per month (MPP 49-055.32). # 733.94 x 12 = 8,807.28. @@ -120,8 +118,7 @@ # Disabled individual standard 1,233.94 per month with no offset. Living # arrangements allow food preparation by default, so no no-cooking food # allowance applies. Earnings of 83.33 per month fall within the - # $20 + $65 exclusions, so countable income is 0 (until PR 10240, SSI - # also zeroes this income for people who fail its noncitizen test). + # $20 + $65 exclusions, so countable income is 0. # 1,233.94 x 12 = 14,807.28. ca_capi: 14_807.28 @@ -166,10 +163,6 @@ ssi_qualifying_quarters_earnings: 39 # 1,520 per month foreign pension. pension_income: 18_240 - # SSI zeroes countable income for people who fail its immigration - # test, so the case supplies it: 1,520 - 20 = 1,500 per month - # (18,000 per year). - ssi_countable_income: 18_000 person2: age: 68 immigration_status: LEGAL_PERMANENT_RESIDENT @@ -193,6 +186,8 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # person1: 1,520 - 20 = 1,500 per month (18,000 per year). + ssi_countable_income: [18_000, 0] # Each person is assessed on their own income (MPP 49-035.1, 49-055.32). # person1: 1,500 is not lower than the 1,233.94 standard, so 0. # person2: no income, so 1,233.94 per month; x 12 = 14,807.28. Pooling @@ -223,3 +218,83 @@ # 1,182.94 (POMS SI 01415.056); issue 10480 removes the floor. ca_capi_person: 11_316 ca_capi: 11_316 + +- name: Case 9, integration test, aged permanent resident without 40 SSI quarters whose pension exceeds the CAPI standard. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 0 + pension_income: 24_000 # 2,000 a month + households: + household: + members: [person1] + state_code: CA + output: + ssi: 0 + ca_capi_eligible_person: true + # (2,000 - 20) x 12 = 23,760 of countable income. + ssi_countable_income: 23_760 + # 1,980 a month exceeds CAPI's individual payment standard, which is at + # most the 1,335.81 SSI/SSP no-cooking standard, so CAPI pays nothing. + ca_capi: 0 + +- name: Case 10, integration test, mixed couple with income, the noncitizen spouse receives CAPI. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + immigration_status: CITIZEN + social_security_retirement: 6_000 # 500 a month + person2: + age: 68 + is_tax_unit_spouse: true + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 + pension_income: 6_000 # 500 a month foreign pension + 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: CA + living_arrangements_allow_for_food_preparation: false + output: + # Both spouses are aged, so the model applies the SSI couple computation: + # (500 + 500 - 20) / 2 = 490 a month each (5,880 a year). + ssi_countable_income: [5_880, 5_880] + # The citizen's SSI is 1,450 / 2 - 490 = 235 a month. + # NOTE: SSA deems none of the CAPI member's income, because income + # counted in figuring CAPI is excluded from deeming (20 CFR + # 416.1161(a)(2)-(3); POMS SI 01320.141 A), so it pays the citizen 487 + + # 368.81 = 855.81. The model's SSI is still the couple computation + # (#10481), so it pays 235 + 620.81, the same 855.81. + ssi: [2_820, 0] # 235 * 12 + # The citizen's state supplement is the 1,206.94 + 128.87 = 1,335.81 + # no-cooking individual standard less SSI 235 and the citizen's own + # 500 - 20 = 480: 620.81 a month. + ca_state_supplement: 7_449.72 # 620.81 * 12 + # The CAPI member takes the whole couple standard (MPP 49-050.13), the + # 2,057.83 + 257.74 = 2,315.57 no-cooking aged couple standard, with no + # offset since June 2019 (WIC 18941). + ca_capi_payment_standard: [0, 27_786.84] # 2,315.57 * 12 + # The couple's countable income 490 + 490 = 980 (MPP 49-055.32) and the + # citizen's SSI/SSP 235 + 620.81, counted as unearned income based on + # need (MPP 49-035.221), are subtracted: + # 2,315.57 - 980 - 235 - 620.81 = 479.76 a month. + ca_capi_person: [0, 5_757.12] # 479.76 * 12 + ca_capi: 5_757.12 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_person.yaml index d5abc2efdd6..4b5d9901829 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_person.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_person.yaml @@ -9,16 +9,10 @@ ssi_qualifying_quarters_earnings: 39 # 420 per month foreign pension. pension_income: 5_040 - # SSI zeroes countable income for people who fail its immigration - # test, so the case supplies it. The couple's countable income is - # 420 - 20 general exclusion = 400 per month, split equally as SSI - # does for a couple: 200 per month (2,400 per year) each. - ssi_countable_income: 2_400 person2: age: 68 immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 - ssi_countable_income: 2_400 marital_units: marital_unit: members: [person1, person2] @@ -28,6 +22,9 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # The couple's countable income is 420 - 20 general exclusion = 400 per + # month, split equally as SSI does for a couple: 200 per month each. + ssi_countable_income: [200, 200] # Couple standard 2,098.83 (no offset since June 2019, WIC 18941), less # the couple's countable income 400 = 1,698.83 (MPP 49-055.32); each # member receives one-half (MPP 49-055.4): 849.415. @@ -42,15 +39,6 @@ age: 70 immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 - # SSI does not compute these for people who fail its immigration - # test, so the case supplies them. The spouse earns 500 per month, - # above the 497 gap between the couple and individual FBRs - # (1,491 - 994), so deeming applies. Couple countable income is - # (500 - 20 - 65) / 2 = 207.50 per month (2,490 per year), all of it - # deemed because person1 has no income of her own. - is_ssi_spousal_deeming_applies: true - ssi_income_deemed_from_ineligible_spouse: 2_490 - ssi_countable_income: 2_490 person2: age: 50 employment_income: 6_000 @@ -63,6 +51,13 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # The spouse earns 500 per month, above the 497 gap between the couple + # and individual FBRs (1,491 - 994), so deeming applies. Couple countable + # income is (500 - 20 - 65) / 2 = 207.50 per month, all of it deemed + # because person1 has no income of her own. + is_ssi_spousal_deeming_applies: [true, false] + ssi_income_deemed_from_ineligible_spouse: [207.50, 0] + ssi_countable_income: [207.50, 0] # POMS SI 01320.430 D. # As an individual: federal 994 - 0 = 994; a federal benefit is due, so # the state supplement is the full individual OSS 1,233.94 - 994 = 239.94. @@ -81,12 +76,6 @@ age: 70 immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 - # Supplied for the reason in Case 2. The spouse earns 3,867 per - # month; couple countable income is (3,867 - 85) / 2 = 1,891 per - # month (22,692 per year), all deemed. - is_ssi_spousal_deeming_applies: true - ssi_income_deemed_from_ineligible_spouse: 22_692 - ssi_countable_income: 22_692 person2: age: 50 employment_income: 46_404 @@ -99,6 +88,11 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # The spouse earns 3,867 per month; couple countable income is + # (3,867 - 85) / 2 = 1,891 per month, all deemed. + is_ssi_spousal_deeming_applies: [true, false] + ssi_income_deemed_from_ineligible_spouse: [1_891, 0] + ssi_countable_income: [1_891, 0] # POMS SI 01320.430 D. # As an individual: federal 994; state supplement 239.94. # Under deeming: 1,891 exceeds the couple FBR 1,491 by 400, so no federal @@ -117,12 +111,6 @@ is_blind: true immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 - # Supplied for the reason in Case 2. The spouse earns 4,267 per - # month; couple countable income is (4,267 - 85) / 2 = 2,091 per - # month (25,092 per year), all deemed. - is_ssi_spousal_deeming_applies: true - ssi_income_deemed_from_ineligible_spouse: 25_092 - ssi_countable_income: 25_092 person2: age: 42 employment_income: 51_204 @@ -135,6 +123,11 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # The spouse earns 4,267 per month; couple countable income is + # (4,267 - 85) / 2 = 2,091 per month, all deemed. + is_ssi_spousal_deeming_applies: [true, false] + ssi_income_deemed_from_ineligible_spouse: [2_091, 0] + ssi_countable_income: [2_091, 0] # POMS SI 01320.430 C.7 and D. # As an individual: federal 994; state supplement = blind individual # OSS 1,318.32 - 994 = 324.32. @@ -158,13 +151,6 @@ # 320 per month foreign pension; own countable income is 320 - 20 = # 300 per month. pension_income: 3_840 - # Supplied for the reason in Case 2. The spouse earns 2,000 per - # month, so (2,000 - 65) / 2 = 967.50 per month (11,610 per year) is - # deemed, and countable income is 300 + 967.50 = 1,267.50 per month - # (15,210 per year). - is_ssi_spousal_deeming_applies: true - ssi_income_deemed_from_ineligible_spouse: 11_610 - ssi_countable_income: 15_210 person2: age: 50 employment_income: 24_000 @@ -177,6 +163,12 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # The spouse earns 2,000 per month, so (2,000 - 65) / 2 = 967.50 per + # month is deemed, and countable income is 300 + 967.50 = 1,267.50 per + # month. + is_ssi_spousal_deeming_applies: [true, false] + ssi_income_deemed_from_ineligible_spouse: [967.50, 0] + ssi_countable_income: [1_267.50, 0] # POMS SI 01320.430 D. # As an individual: federal 994 - 300 = 694; a federal benefit is due, # so the state supplement is the full individual OSS 239.94. @@ -206,8 +198,11 @@ age: 68 immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 - # 420 per month foreign pension; countable income is 420 - 20 = 400 - # per month (4,800 per year), supplied as in Case 1. + # 420 per month foreign pension; her own countable income is + # 420 - 20 = 400 per month (4,800 per year). The model's SSI couple + # computation would split the couple's income, so the case supplies + # her own income, as it does the citizen's values, to isolate the + # CAPI mixed-couple formula. pension_income: 5_040 ssi_countable_income: 4_800 marital_units: @@ -244,13 +239,6 @@ # 40 per month foreign pension; own countable income is 40 - 20 = 20 # per month. pension_income: 480 - # Supplied as SSI deeming would compute them at home. The spouse - # earns 1,200 per month, so (1,200 - 65) / 2 = 567.50 per month - # (6,810 per year) is deemed, and countable income is 20 + 567.50 = - # 587.50 per month (7,050 per year). - is_ssi_spousal_deeming_applies: true - ssi_income_deemed_from_ineligible_spouse: 6_810 - ssi_countable_income: 7_050 person2: age: 50 employment_income: 14_400 @@ -263,6 +251,12 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # SSI deeming computes these as if the couple lived together at home. The + # spouse earns 1,200 per month, so (1,200 - 65) / 2 = 567.50 per month is + # deemed, and countable income is 20 + 567.50 = 587.50 per month. + is_ssi_spousal_deeming_applies: [true, false] + ssi_income_deemed_from_ineligible_spouse: [567.50, 0] + ssi_countable_income: [587.50, 0] # Deeming needs an ineligible spouse living in the same household (20 # CFR 416.1160(a)(1)), so the resident is paid the Title XIX standard 62 # less own income 20 = 42. Deeming would give @@ -516,3 +510,96 @@ output: # 20 CFR 416.414(b)(3): max(62 - 980, 0) = 0 and 1,233.94 - 0 = 1,233.94. ca_capi_person: [0, 1_233.94] + +- name: Case 16, CAPI member is the tax-unit head and the aged citizen spouse's income is too high for SSI/SSP, so CAPI deems the spouse's income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 + person2: + age: 68 + is_tax_unit_spouse: true + immigration_status: CITIZEN + # 1,600 a month; countable 1,580 after the $20 exclusion. + social_security: 19_200 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # Case 8 with the roles swapped. The state supplement counts the citizen's + # own 1,580, which exceeds the 1,233.94 standard, so the citizen is paid + # no SSI/SSP and is an ineligible spouse (MPP 49-005(i)(2)). POMS SI + # 01320.430 D: federal min(994, 1,491 - 1,580) -> 0; state min(239.94, + # 607.83 - (1,580 - 1,491)) = 239.94. + ssi: [0, 0] + ca_state_supplement: 0 + ca_capi_person: [239.94, 0] + +- name: Case 17, CAPI member is the tax-unit head and the spouse's income exceeds the couple state supplement, leaving the couple state part. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 + person2: + age: 68 + is_tax_unit_spouse: true + immigration_status: CITIZEN + # 2,000 a month; countable 1,980 after the $20 exclusion. + social_security: 24_000 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # Case 9 with the roles swapped. POMS SI 01320.430 D: federal 0; state + # min(239.94, 607.83 - (1,980 - 1,491)) = min(239.94, 118.83) = 118.83. + ssi: [0, 0] + ca_state_supplement: 0 + ca_capi_person: [118.83, 0] + +- name: Case 18, one CAPI person with a spouse who is not aged, blind or disabled and earns above the deeming threshold. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 + person2: + age: 50 + employment_income: 24_000 # 2,000 a month + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # Case 13 above the 1,491 - 994 = 497 deeming threshold. The couple's + # countable income is (2,000 - 20 - 65) / 2 = 957.50 (20 CFR 416.1163). + # POMS SI 01320.430 D: federal min(994 - 0, 1,491 - 957.50) = 533.50; + # state min(239.94, 607.83) = 239.94; 533.50 + 239.94 = 773.44. + ca_capi_payment_standard: [1_233.94, 0] + ca_capi_person: [773.44, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.yaml index cbcbbc8e195..7dd4f2a91d8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.yaml @@ -4,8 +4,8 @@ age: 70 immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 - # SSI zeroes countable income for people who fail its immigration test, - # so the case supplies it: 1,234.94 per month (14,819.28 per year). + # The case supplies countable income directly to isolate the CAPI income + # test: 1,234.94 per month (14,819.28 per year). ssi_countable_income: 14_819.28 living_arrangements_allow_for_food_preparation: true state_code: CA @@ -37,13 +37,6 @@ age: 70 immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 - # SSI does not compute these for people who fail its immigration - # test, so the case supplies them. The spouse earns 5,000 per month; - # couple countable income is (5,000 - 20 - 65) / 2 = 2,457.50 per - # month (29,490 per year), all deemed. - is_ssi_spousal_deeming_applies: true - ssi_income_deemed_from_ineligible_spouse: 29_490 - ssi_countable_income: 29_490 person2: age: 50 employment_income: 60_000 @@ -56,6 +49,12 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: + # The spouse earns 5,000 per month; couple countable income is + # (5,000 - 20 - 65) / 2 = 2,457.50 per month (29,490 per year), all + # deemed. + is_ssi_spousal_deeming_applies: [true, false] + ssi_income_deemed_from_ineligible_spouse: [29_490, 0] + ssi_countable_income: [29_490, 0] # POMS SI 01320.430 D. As an individual: federal 994, state 239.94. # Under deeming: 2,457.50 exceeds the couple FBR 1,491 by 966.50, which # exceeds the couple OSS 607.83, so neither a federal benefit nor a diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/state_supplement/ca_state_supplement.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/state_supplement/ca_state_supplement.yaml index 12c7afb14ea..a8f5eeddeb1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/state_supplement/ca_state_supplement.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/state_supplement/ca_state_supplement.yaml @@ -355,3 +355,308 @@ # 2,098.83 - 1,491 = 607.83; 2,098.83 - 2,098.83 = 0; # 2,356.57 - 2,098.83 = 257.74; 2,356.57 - 2,356.57 = 0. ca_state_supplement: [7_293.96, 0, 3_092.88, 0] + +# A CAPI-eligible member's income does not reduce the state supplement: CAPI +# budgets its own members' income (CAPI regulations MPP 49-035), and SSI/SSP +# counts another member's income only when it is deemed (20 CFR 416.1160(a)). +# 2025: federal SSI is $967; the no-cooking individual standard is +# $1,206.94 + $128.87 = $1,335.81. +- name: Case 10, 2025 aged citizen sharing an SPM unit with a CAPI-eligible sibling keeps the supplement. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: CITIZEN + social_security_retirement: 6_000 # 500 a month + person2: + age: 72 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 0 + pension_income: 6_000 # 500 a month + 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: CA + living_arrangements_allow_for_food_preparation: false + output: + # person2 is an LPR with fewer than 40 quarters, so SSI and the state + # supplement bar her and she is CAPI-eligible. + ca_capi_eligible_person: [false, true] + # Each has 500 - 20 = 480 a month of countable income. + ssi_countable_income: [5_760, 5_760] + # person1's SSI is 967 - 480 = 487 a month. + ssi: [5_844, 0] # 487 * 12 + # One eligible aged member without cooking facilities, so the standard is + # 1,206.94 + 128.87 = 1,335.81. + ca_state_supplement_payment_standard: 16_029.72 # 1,335.81 * 12 + # The supplement is 1,335.81 - 487 - 480 = 368.81 a month; person2's 480 + # is not counted. + ca_state_supplement: 4_425.72 # 368.81 * 12 + +# Under the model's SSI couple computation each aged spouse carries half of +# the couple's countable income for SSI. SSA treats the noncitizen spouse as +# an ineligible spouse (20 CFR 416.1160(d)) but deems none of the spouse's +# income: CAPI is a public income-maintenance payment (20 CFR 416.1142(a)(6); +# POMS SI 00830.175), and income counted in figuring it is not deemed +# (20 CFR 416.1161(a)(2)-(3); POMS SI 01320.141 A). So the supplement counts +# the citizen's own income. 2025: the couple federal benefit rate is $1,450; +# the no-cooking individual standard is $1,206.94 + $128.87 = $1,335.81. +# NOTE: SSA pays SSI of 967 - 480 = 487 and a supplement of 368.81. The +# model's SSI is still the couple computation, 235 (#10481), so its +# supplement is 620.81; the citizen's total, 855.81, is the same. +- name: Case 11, 2025 aged citizen married to a CAPI-eligible spouse, the supplement counts the citizen's own income. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + is_tax_unit_head: true + immigration_status: CITIZEN + social_security_retirement: 6_000 # 500 a month + person2: + age: 68 + is_tax_unit_spouse: true + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 + pension_income: 6_000 # 500 a month foreign pension + 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: CA + living_arrangements_allow_for_food_preparation: false + output: + # SSI and the state supplement bar person2 for immigration status, so she + # is CAPI-eligible. + ca_capi_eligible_person: [false, true] + # Both spouses are aged, so the model applies the SSI couple computation: + # (500 + 500 - 20) / 2 = 490 a month each (5,880 a year). + ssi_countable_income: [5_880, 5_880] + # person1's SSI is 1,450 / 2 - 490 = 235 a month. + ssi: [2_820, 0] # 235 * 12 + # One eligible aged member without cooking facilities, so the standard is + # 1,206.94 + 128.87 = 1,335.81. + ca_state_supplement_payment_standard: 16_029.72 # 1,335.81 * 12 + # The supplement counts the citizen's own 500 - 20 = 480: + # 1,335.81 - 235 - 480 = 620.81 a month. + ca_state_supplement: 7_449.72 # 620.81 * 12 + +- name: Case 12, 2025 aged citizen sharing an SPM unit with an undocumented sibling who is not CAPI-eligible keeps the supplement. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: CITIZEN + social_security_retirement: 6_000 # 500 a month + person2: + age: 72 + is_tax_unit_head: true + immigration_status: UNDOCUMENTED + pension_income: 6_000 # 500 a month + # WIC 18938 and MPP 49-020 bar undocumented people from CAPI (#10482). + ca_capi_eligible_person: false + 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: CA + living_arrangements_allow_for_food_preparation: false + output: + # Each has 500 - 20 = 480 a month of countable income. + ssi_countable_income: [5_760, 5_760] + ssi: [5_844, 0] # 487 * 12 + ca_state_supplement_payment_standard: 16_029.72 # 1,335.81 * 12 + # A sibling's income is never deemed to an SSI/SSP recipient + # (20 CFR 416.1160(a)), so the supplement stays 1,335.81 - 487 - 480 = + # 368.81 a month. + ca_state_supplement: 4_425.72 # 368.81 * 12 + +- name: Case 13, 2025 aged citizen sharing an SPM unit with a married CAPI couple keeps the supplement. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_tax_unit_head: true + immigration_status: CITIZEN + social_security_retirement: 6_000 # 500 a month + person2: + age: 72 + is_tax_unit_head: true + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 0 + pension_income: 6_000 # 500 a month + person3: + age: 70 + is_tax_unit_spouse: true + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 0 + pension_income: 6_000 # 500 a month + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # Neither member of the couple meets SSI's noncitizen test, so neither + # one's income is deemed to the citizen (20 CFR 416.1160(a)). The citizen + # has 480 a month of countable income and SSI of 967 - 480 = 487, so the + # supplement is 1,335.81 - 487 - 480 = 368.81 a month. + ssi: [5_844, 0, 0] # 487 * 12 + ca_state_supplement: 4_425.72 # 368.81 * 12 + +- name: Case 14, 2026 mixed couple where both spouses have income, the supplement counts the citizen's own income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: CITIZEN + social_security_retirement: 9_600 # 800 a month + person2: + age: 68 + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 + pension_income: 9_600 # 800 a month + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The model's SSI couple computation gives each spouse (1,600 - 20) / 2 + # = 790, so the citizen's SSI is max(745.50 - 790, 0) = 0. The supplement + # counts the citizen's own 800 - 20 = 780: 1,233.94 - 0 - 780 = 453.94. + # SSA pays the citizen 994 - 780 = 214 of SSI and 239.94 of supplement, + # the same 453.94 in all (#10481). + ssi: [0, 0] + ca_state_supplement: 453.94 + # The spouse is paid, so CAPI is the mixed-couple amount: + # 2,098.83 - 1,580 - 0 - 453.94 = 64.89. + ca_capi_person: [0, 64.89] + +- name: Case 15, 2026 mixed couple whose CAPI spouse has too much income for CAPI, so the spouse's income is deemed. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: CITIZEN + person2: + age: 68 + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 + pension_income: 24_000 # 2,000 a month + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The spouse's 2,000 - 20 = 1,980 leaves no CAPI, so it is deemed (20 CFR + # 416.1163): the lesser of 1,233.94 - 0 and 2,098.83 - 1,980 = 118.83. + # The model's joint SSI is max(745.50 - 990, 0) = 0, so the supplement is + # 118.83. + ssi: [0, 0] + ca_state_supplement: 118.83 + # CAPI: 2,098.83 - 1,980 - 118.83 = 0. + ca_capi_person: [0, 0] + +- name: Case 16, 2026 citizen married to an aged spouse who fails SSI's noncitizen test and cannot receive CAPI, so the spouse's income is not excluded. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: CITIZEN + social_security: 3_840 # 320 a month + person2: + age: 70 + immigration_status: UNDOCUMENTED + pension_income: 8_400 # 700 a month + # WIC 18938 bars undocumented people from CAPI (#10482). + ca_capi_eligible_person: false + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The spouse receives no CAPI, so 20 CFR 416.1161(a)(2)-(3) does not + # apply and the spouse's 700 a month, above the 1,491 - 994 = 497 + # threshold, is deemed (20 CFR 416.1163). The model's joint SSI gives each + # spouse (320 + 700 - 20) / 2 = 500: SSI 745.50 - 500 = 245.50 and a + # supplement of 1,233.94 - 245.50 - 500 = 488.44, 733.94 in all. + # NOTE: SSA pays min(994 - 300, 1,491 - 1,000) = 491 of SSI and 239.94 of + # supplement, 730.94 in all; the gap is the joint SSI (#10481). + ssi: [245.50, 0] + ca_state_supplement: 488.44 + ca_capi_person: [0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/dhs/fia/paa/md_paa.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/dhs/fia/paa/md_paa.yaml index 8a57dff16ca..194f834dc69 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/dhs/fia/paa/md_paa.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/dhs/fia/paa/md_paa.yaml @@ -211,3 +211,253 @@ md_paa_countable_income: 2_480 md_paa_imputed_federal_ssi: 0 md_paa: 0 + +# SSA cannot pay SSI to an LPR with fewer than 40 quarters, so PAA imputes no +# federal SSI and counts only her own income (COMAR 07.03.07.07 has no spousal +# deeming); PAA pays allowable needs less net countable income +# (COMAR 07.03.07.09A). 2025-01: provider rate $1,376; PNA $102. +- name: Case 11, aged LPR without 40 quarters in CARE_HOME_LEVEL_D with a working spouse. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + social_security_survivors: 6_000 # 500 a month + ssi_countable_resources: 1_000 + md_paa_living_arrangement: CARE_HOME_LEVEL_D + person2: + age: 60 + employment_income: 12_000 # 1,000 a month + marital_units: + marital_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # person1 qualifies through aged Social Security receipt; person2 is not + # in a PAA facility. + md_paa_eligible: [true, false] + ssi: [0, 0] + # SSI would deem person2's wages to person1: couple countable + # 480 + (1,000 - 65) * 0.5 = 947.50 less her own 480 = 467.50 a month. + ssi_income_deemed_from_ineligible_spouse: [467.50, 0] + # PAA counts person1's own 500 - 20 = 480 a month (5,760 a year) without + # the deemed amount. person2's own countable wages are + # (1,000 - 20 - 65) * 0.5 = 457.50. + md_paa_countable_income: [480, 457.50] + md_paa_imputed_federal_ssi: [0, 0] + # combined_need = 1,376 + 102 = 1,478. PAA = 1,478 - 480 - 0 = 998. + md_paa_total_cost_of_care: [1_478, 0] + md_paa: [998, 0] + +# A person who reports SSI receipt keeps the imputed federal SSI even though +# the model's alien test bars her, for example someone SSA still pays under 8 +# U.S.C. 1612(a)(2)(E) because she was receiving SSI on August 22, 1996. PAA +# counts federally funded assistance payments (COMAR 07.03.07.07B(3)) and pays +# allowable needs less net countable income (COMAR 07.03.07.09A). 2025-01: +# federal SSI individual rate $967; provider rate $1,376; PNA $102. +- name: Case 12, aged LPR without 40 quarters who reports SSI receipt keeps the imputed SSI. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 30 # entered in 1995 + ssi_qualifying_quarters_earnings: 20 + receives_ssi: true + social_security_survivors: 6_000 # 500 a month + ssi_countable_resources: 1_000 + md_paa_living_arrangement: CARE_HOME_LEVEL_D + households: + household: + members: [person1] + state_code: MD + output: + md_paa_eligible: true + # The model's SSI fails her on the 40-quarter test, so it computes no SSI. + ssi: 0 + # 500 - 20 general exclusion = 480 a month (5,760 a year). + md_paa_countable_income: 480 + # Reported SSI receipt keeps the imputation: 967 - 480 = 487. + md_paa_imputed_federal_ssi: 487 + # combined_need = 1,376 + 102 = 1,478. + md_paa_total_cost_of_care: 1_478 + # PAA = 1,478 - 480 - 487 = 511. + md_paa: 511 + +# Case 11's household when person1 reports SSI receipt. PAA counts only her +# own income (COMAR 07.03.07.07), and the imputed SSI is what SSA pays her +# under spouse deeming: the lesser of the couple computation and the +# individual computation (20 CFR 416.1163(d)-(e); POMS SI 01320.430). +# 2025-01: federal SSI couple rate $1,450 and individual rate $967; provider +# rate $1,376; PNA $102. +- name: Case 13, aged LPR without 40 quarters who reports SSI receipt and has a working spouse. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 30 # entered in 1995 + ssi_qualifying_quarters_earnings: 20 + receives_ssi: true + social_security_survivors: 6_000 # 500 a month + ssi_countable_resources: 1_000 + md_paa_living_arrangement: CARE_HOME_LEVEL_D + person2: + age: 60 + employment_income: 12_000 # 1,000 a month + marital_units: + marital_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + md_paa_eligible: [true, false] + # The model's SSI fails person1 on the 40-quarter test. + ssi: [0, 0] + # person2's 12,000 a year exceeds the (1,450 - 967) x 12 = 5,796 gap, so + # deeming applies: couple countable 480 + (1,000 - 65) x 0.5 = 947.50 + # less person1's own 480 = 467.50 a month. + ssi_income_deemed_from_ineligible_spouse: [467.50, 0] + # PAA counts person1's own income only: 500 - 20 = 480. person2's own + # countable wages are (1,000 - 20 - 65) x 0.5 = 457.50. + md_paa_countable_income: [480, 457.50] + # SSA pays min(1,450 - (480 + 467.50), 967 - 480) = min(502.50, 487) = 487. + md_paa_imputed_federal_ssi: [487, 0] + # combined_need = 1,376 + 102 = 1,478. + md_paa_total_cost_of_care: [1_478, 0] + # PAA = 1,478 - 480 - 487 = 511, the same as with no spouse (Case 12). + md_paa: [511, 0] + +- name: Case 14, SSI reporter without 40 quarters whose deemed spouse wages make the couple computation lower. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 30 + ssi_qualifying_quarters_earnings: 20 + receives_ssi: true + social_security_survivors: 6_000 # 500 a month + ssi_countable_resources: 1_000 + md_paa_living_arrangement: CARE_HOME_LEVEL_D + person2: + age: 60 + employment_income: 24_000 # 2,000 a month + marital_units: + marital_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # Couple countable 480 + (2,000 - 65) x 0.5 = 1,447.50; deemed + # 1,447.50 - 480 = 967.50 a month. + ssi_income_deemed_from_ineligible_spouse: [967.50, 0] + md_paa_countable_income: [480, 957.50] + # SSA pays min(1,450 - 1,447.50, 967 - 480) = min(2.50, 487) = 2.50 + # (20 CFR 416.1163(d)-(e)). + md_paa_imputed_federal_ssi: [2.50, 0] + # PAA = 1,478 - 480 - 2.50 = 995.50. + md_paa: [995.50, 0] + +- name: Case 15, SSI reporter without 40 quarters under the one-third reduction with a working spouse. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 30 + ssi_qualifying_quarters_earnings: 20 + receives_ssi: true + ssi_countable_resources: 1_000 + md_paa_living_arrangement: CARE_HOME_LEVEL_D + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 60 + employment_income: 12_000 # 1,000 a month + marital_units: + marital_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MD + output: + # No own income, so the $20 general exclusion goes to the wages: + # (1,000 - 20 - 65) x 0.5 = 457.50 deemed a month. + ssi_income_deemed_from_ineligible_spouse: [457.50, 0] + md_paa_countable_income: [0, 457.50] + # The one-third reduction applies to the couple rate under deeming + # (POMS SI 01320.400 B.1.e): min(1,450 x 2/3 - 457.50, 967 x 2/3 - 0) = 509.17. + md_paa_imputed_federal_ssi: [509.17, 0] + # PAA = 1,478 - 0 - 509.17 = 968.83. + md_paa: [968.83, 0] + +- name: Case 16, SSI reporter without 40 quarters in an MDH Rehabilitative Residence gets the $30 medical-facility rate. + period: 2025-01 + absolute_error_margin: 0.01 + input: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 30 + ssi_qualifying_quarters_earnings: 20 + receives_ssi: true + social_security_survivors: 120 # 10 a month + ssi_countable_resources: 1_000 + md_paa_living_arrangement: REHAB_RESIDENCE + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + state_code: MD + output: + md_paa_eligible: true + # 10 - 20 general exclusion leaves no countable income. + md_paa_countable_income: 0 + # The federal rate in a medical treatment facility is 30 a month + # (42 U.S.C. 1382(e)(1)(B)). + md_paa_imputed_federal_ssi: 30 + # PAA = the 102 personal needs allowance less 30 = 72. + md_paa: 72 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/scdhhs/ssi_state_supplement/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/scdhhs/ssi_state_supplement/integration.yaml index 9097949051a..0c630d509a8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/sc/scdhhs/ssi_state_supplement/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/scdhhs/ssi_state_supplement/integration.yaml @@ -199,3 +199,25 @@ # Not eligible so OSS = $0 sc_ssi_state_supplement: [0] + +- name: Case 8, aged permanent resident without 40 SSI quarters in a CRCF has a pension above the NIL. + period: 2026 + input: + people: + person1: + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 20 + pension_income: 24_000 + is_in_residential_care_facility: true + households: + household: + members: [person1] + state_code: SC + output: + # The pension now counts: 24,000 - 240 = 23,760, above the 21,648 net + # income limit, so the person is not eligible. + ssi_countable_income: [23_760] + sc_ssi_state_supplement_eligible: [false] + sc_ssi_state_supplement: [0] diff --git a/policyengine_us/variables/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.py b/policyengine_us/variables/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.py index a692202dac3..b2230f74783 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.py +++ b/policyengine_us/variables/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.py @@ -15,7 +15,7 @@ class medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse( "https://www.law.cornell.edu/cfr/text/20/416.1163", "https://dssmanuals.mo.gov/mo-healthnet-for-the-aged-blind-and-disabled/0805-000-00/0805-015-00/0805-015-05/", ) - defined_for = "is_ssi_eligible_individual" + defined_for = "is_ssi_aged_blind_disabled" unit = USD def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.py b/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.py index 3bf485dfcba..e040a7af8b6 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.py +++ b/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_optional_senior_or_disabled_countable_income.py @@ -12,6 +12,7 @@ class medicaid_optional_senior_or_disabled_countable_income(Variable): definition_period = YEAR reference = ( "https://www.law.cornell.edu/uscode/text/42/1396a#m", + "https://www.law.cornell.edu/cfr/text/42/435.601", "https://www.kff.org/medicaid/medicaid-financial-eligibility-for-seniors-and-people-with-disabilities-findings-from-a-50-state-survey/", # Missouri MHABD budgeting order and rounding "https://dssmanuals.mo.gov/mo-healthnet-for-the-aged-blind-and-disabled/0805-000-00/0805-015-00/", @@ -113,9 +114,11 @@ def formula(person, period, parameters): "medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse", period, ) - is_eligible_individual = person("is_ssi_eligible_individual", period) - is_eligible_spouse = person("is_ssi_eligible_spouse", period) - is_eligible = is_eligible_individual | is_eligible_spouse + # SSI methodology (42 CFR 435.601) counts the applicant's own income + # whether or not they meet SSI's noncitizen rules. People who are not + # aged, blind, or disabled have no countable income here; a spouse's + # income is deemed to the applicant instead. + is_aged_blind_disabled = person("is_ssi_aged_blind_disabled", period) # ACWDL 20-24 Examples 2 and 5 combine the non-applicant spouse's # income with the applicant's income before the deductions, as @@ -126,4 +129,4 @@ def formula(person, period, parameters): max_(personal_countable - deductions, 0) / 2, max_(personal_countable + spousal_deemed - deductions, 0), ) - return where(is_eligible, countable, 0) + return where(is_aged_blind_disabled, countable, 0) diff --git a/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/is_ssi_spousal_deeming_applies.py b/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/is_ssi_spousal_deeming_applies.py index 9c7348fb608..1492ba95097 100644 --- a/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/is_ssi_spousal_deeming_applies.py +++ b/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/is_ssi_spousal_deeming_applies.py @@ -7,12 +7,14 @@ class is_ssi_spousal_deeming_applies(Variable): label = "SSI spousal deeming applies" definition_period = YEAR reference = "https://www.law.cornell.edu/cfr/text/20/416.1163" - defined_for = "is_ssi_eligible_individual" + defined_for = "is_ssi_aged_blind_disabled" documentation = """ Returns True when spousal deeming applies according to 20 CFR ยง416.1163. Spousal deeming applies when: - 1. Person is an eligible individual (not part of an eligible couple) + 1. Person is aged, blind, or disabled (not part of an eligible couple). + SSI's noncitizen test is applied in is_ssi_eligible, so programs that + use SSI methodology also deem spouse income to noncitizens. 2. Spouse is ineligible (not aged/blind/disabled) 3. Spouse's leftover income (after child allocations) exceeds the difference between couple FBR and individual FBR diff --git a/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.py b/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.py index 8a885f8d66f..9e81894574e 100644 --- a/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.py +++ b/policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.py @@ -18,7 +18,7 @@ class ssi_income_deemed_from_ineligible_spouse(Variable): 2) Otherwise, spouse's deemed = (couple combined countable) - (individual alone countable). This yields 816 for 1986 Example 3 and 12000 for the 2025 test. """ - defined_for = "is_ssi_eligible_individual" + defined_for = "is_ssi_aged_blind_disabled" unit = USD def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/ssa/ssi/eligibility/income/ssi_countable_income.py b/policyengine_us/variables/gov/ssa/ssi/eligibility/income/ssi_countable_income.py index 1d268ec5b6c..28aa7b33979 100644 --- a/policyengine_us/variables/gov/ssa/ssi/eligibility/income/ssi_countable_income.py +++ b/policyengine_us/variables/gov/ssa/ssi/eligibility/income/ssi_countable_income.py @@ -70,14 +70,16 @@ def formula(person, period, parameters): # Add spousal deemed income (only relevant when one spouse is ineligible) spousal_deemed = person("ssi_income_deemed_from_ineligible_spouse", period) - # Check if person is eligible (either as individual OR as eligible spouse) - is_eligible_individual = person("is_ssi_eligible_individual", period) - is_eligible_spouse = person("is_ssi_eligible_spouse", period) - is_eligible = is_eligible_individual | is_eligible_spouse + # People who are not aged, blind, or disabled have no countable income + # of their own; a spouse's income is deemed to the other spouse + # instead. SSI's noncitizen test is applied in is_ssi_eligible, so it + # does not zero the income that Medicaid and state programs count + # with SSI methodology. + is_aged_blind_disabled = person("is_ssi_aged_blind_disabled", period) # Calculate final countable income return where( - ~is_eligible, + ~is_aged_blind_disabled, 0, where( both_eligible, diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_person.py b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_person.py index 8c21e8748a4..41a276700b5 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_person.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_person.py @@ -102,9 +102,6 @@ def formula(person, period, parameters): ) p = parameters(period).gov.states.ca.cdss.capi.payment_standard_offset deemed_benefit = max_(federal + supplement - p.single, 0) - # NOTE: until PR 10240 counts the income of people who fail SSI's - # noncitizen test, deeming from a spouse who is not aged, blind or - # disabled runs only with supplied inputs. deeming = ( (person("is_ssi_spousal_deeming_applies", period.this_year) & ~joint) | unpaid_spouse diff --git a/policyengine_us/variables/gov/states/ca/cdss/state_supplement/ca_state_supplement.py b/policyengine_us/variables/gov/states/ca/cdss/state_supplement/ca_state_supplement.py index cb5e88fe1df..ef86e4890a4 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/state_supplement/ca_state_supplement.py +++ b/policyengine_us/variables/gov/states/ca/cdss/state_supplement/ca_state_supplement.py @@ -1,4 +1,10 @@ from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.income._apply_ssi_exclusions import ( + _apply_ssi_exclusions, +) +from policyengine_us.variables.gov.states.ca.cdss.capi._ca_capi_ssi_ssp_standard import ( + ca_capi_ssi_ssp_standard, +) class ca_state_supplement(Variable): @@ -8,10 +14,80 @@ class ca_state_supplement(Variable): unit = USD definition_period = MONTH defined_for = StateCode.CA - reference = "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=12200" + reference = ( + "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=12200", + "https://www.law.cornell.edu/cfr/text/20/416.1160", + "https://www.law.cornell.edu/cfr/text/20/416.1161", + "https://www.law.cornell.edu/cfr/text/20/416.2025", + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=25", + ) def formula(spm_unit, period, parameters): payment_standard = spm_unit("ca_state_supplement_payment_standard", period) ssi = add(spm_unit, period, ["ssi"]) - countable_income = add(spm_unit, period, ["ssi_countable_income"]) + person = spm_unit.members + # SSI/SSP counts another member's income only when it is deemed + # (20 CFR 416.1160(a)), and CAPI budgets its own members' income (CAPI + # regulations MPP 49-035), so the income of a member who fails SSI's + # citizen or qualified-noncitizen test is not counted. + immigration_status = person("immigration_status", period.this_year) + is_citizen = immigration_status == immigration_status.possible_values.CITIZEN + is_qualified_noncitizen = person( + "is_ssi_qualified_noncitizen", period.this_year + ) + meets_ssi_immigration_test = is_citizen | is_qualified_noncitizen + # SSA treats a spouse who fails that test as an ineligible spouse (20 + # CFR 416.1160(d)). If the spouse receives CAPI, none of the income + # counted for CAPI is deemed (20 CFR 416.1161(a)(2)-(3)), so the + # recipient's own income counts, not half of the couple's. Otherwise + # the spouse's income is deemed (20 CFR 416.1163, 416.2025(b)(3)). + # Taking the lesser of the individual and couple totals gives both: + # it equals own income whenever the spouse would receive CAPI. + # NOTE: POMS SI 01320.430 D takes the lesser of each part separately; + # the totals keep CAPI at zero when the spouse's income is deemed. + # NOTE: SSI couple status ignores SSI's noncitizen test, so the + # model's SSI is still the couple computation (issue 10481). + head_or_spouse = person("is_tax_unit_head_or_spouse", period.this_year) + # The exclusion needs a spouse who can receive CAPI, so key on CAPI + # eligibility rather than on SSI's noncitizen test alone (issue 10482). + capi_eligible = person("ca_capi_eligible_person", period.this_year) + spouse_capi_eligible = ( + person.marital_unit.sum(capi_eligible & head_or_spouse) > 0 + ) + in_mixed_couple = ( + person("ssi_couple_computation_applies", period) + & meets_ssi_immigration_test + & spouse_capi_eligible + ) + earned = max_( + person("ssi_earned_income", period.this_year) + - person( + "ssi_blind_or_disabled_working_student_exclusion", period.this_year + ), + 0, + ) + # NOTE: in-kind support uses the couple's presumed maximum value here, + # because SSI still treats the pair as a couple. + unearned = person("ssi_unearned_income", period.this_year) + person( + "ssi_in_kind_support_and_maintenance", period.this_year + ) + # _apply_ssi_exclusions takes and returns annual amounts. + own_countable_income = ( + _apply_ssi_exclusions(earned, unearned, parameters, period) / MONTHS_IN_YEAR + ) + ssi_countable_income = person("ssi_countable_income", period) + couple_income = person.marital_unit.sum(ssi_countable_income) + individual_standard, couple_standard = ca_capi_ssi_ssp_standard( + person, period, parameters + ) + mixed_countable_income = max_( + own_countable_income, + couple_income - (couple_standard - individual_standard), + ) + person_countable_income = where( + in_mixed_couple, mixed_countable_income, ssi_countable_income + ) + countable_income = spm_unit.sum( + where(meets_ssi_immigration_test, person_countable_income, 0) + ) return max_(0, payment_standard - ssi - countable_income) diff --git a/policyengine_us/variables/gov/states/ky/dcbs/ssp/ky_ssp_countable_income.py b/policyengine_us/variables/gov/states/ky/dcbs/ssp/ky_ssp_countable_income.py index ed143bb9dfd..217e8fe4deb 100644 --- a/policyengine_us/variables/gov/states/ky/dcbs/ssp/ky_ssp_countable_income.py +++ b/policyengine_us/variables/gov/states/ky/dcbs/ssp/ky_ssp_countable_income.py @@ -37,6 +37,9 @@ def formula(person, period, parameters): both_eligible = person("ssi_couple_computation_applies", period) spousal_deemed = person("ssi_income_deemed_from_ineligible_spouse", period) + # NOTE: ssi_countable_income now zeroes only people who are not aged, + # blind or disabled. This keeps SSI's eligibility gate, which changes + # nothing because KY SSP requires is_ssi_eligible. is_eligible = person("is_ssi_eligible_individual", period.this_year) | person( "is_ssi_eligible_spouse", period.this_year ) diff --git a/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_countable_income.py b/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_countable_income.py index 22dcb53c08f..b32ee9f66b5 100644 --- a/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_countable_income.py +++ b/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_countable_income.py @@ -12,6 +12,7 @@ class md_paa_countable_income(Variable): definition_period = YEAR defined_for = StateCode.MD reference = ( + "https://regs.maryland.gov/us/md/exec/comar/07.03.07.07", "https://regs.maryland.gov/us/md/exec/comar/07.03.07.08", "https://regs.maryland.gov/us/md/exec/comar/07.03.07.09", "https://dhs.maryland.gov/documents/FIA/Manuals/Public%20Assistance%20to%20Adults%20%28PAA%29%20Manual/PAA%20900%20Calculation%20of%20Benefits%20rev%2011.22.docx", @@ -44,7 +45,22 @@ def formula(person, period, parameters): ) both_eligible = person("ssi_couple_computation_applies", period.this_year) - spousal_deemed = person("ssi_income_deemed_from_ineligible_spouse", period) + # COMAR 07.03.07.07 counts the individual's own income and has no + # spousal deeming, so people who fail SSI's citizen or + # qualified-noncitizen test count their own income alone, including + # those who report SSI receipt. + # NOTE: for citizens and qualified noncitizens the SSI deemed amount is + # still added, although their imputed SSI already reflects it. This + # predates the noncitizen change and is a known limitation. + immigration_status = person("immigration_status", period) + is_citizen = immigration_status == immigration_status.possible_values.CITIZEN + is_qualified_noncitizen = person("is_ssi_qualified_noncitizen", period) + meets_ssi_immigration_test = is_citizen | is_qualified_noncitizen + spousal_deemed = where( + meets_ssi_immigration_test, + person("ssi_income_deemed_from_ineligible_spouse", period), + 0, + ) return where( both_eligible, personal_countable / 2, diff --git a/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_imputed_federal_ssi.py b/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_imputed_federal_ssi.py index fed7819204f..dae9a715beb 100644 --- a/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_imputed_federal_ssi.py +++ b/policyengine_us/variables/gov/states/md/dhs/fia/paa/md_paa_imputed_federal_ssi.py @@ -1,4 +1,7 @@ from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.status.ssi_federal_living_arrangement import ( + SSIFederalLivingArrangement, +) class md_paa_imputed_federal_ssi(Variable): @@ -10,10 +13,61 @@ class md_paa_imputed_federal_ssi(Variable): defined_for = "md_paa_eligible" reference = ( "https://regs.maryland.gov/us/md/exec/comar/07.03.07.03", + "https://regs.maryland.gov/us/md/exec/comar/07.03.07.09", "https://www.law.cornell.edu/uscode/text/42/1382#e_1_A", + "https://www.law.cornell.edu/cfr/text/20/416.1163", + "https://secure.ssa.gov/poms.nsf/lnx/0501320400", ) def formula(person, period, parameters): amount = person("ssi_amount_if_eligible", period) countable_income = person("md_paa_countable_income", period) - return max_(amount - countable_income, 0) + imputed_ssi = max_(amount - countable_income, 0) + # SSA cannot pay SSI to people who fail its citizen or + # qualified-noncitizen test, so there is no federal SSI to impute. + # PAA then pays allowable needs less net countable income + # (COMAR 07.03.07.09A). + immigration_status = person("immigration_status", period.this_year) + is_citizen = immigration_status == immigration_status.possible_values.CITIZEN + is_qualified_noncitizen = person( + "is_ssi_qualified_noncitizen", period.this_year + ) + meets_ssi_immigration_test = is_citizen | is_qualified_noncitizen + # A person who reports SSI receipt although they fail the model's test + # (for example one SSA pays under 8 U.S.C. 1612(a)(2)(E), which the + # model does not encode) gets the SSI SSA pays. PAA counts only their + # own income, so impute the individual rate for the living arrangement + # less that income, and under spouse deeming the lesser of that and + # the couple rate less own and deemed income (20 CFR 416.1163(d)-(e); + # POMS SI 01320.430). + p = parameters(period).gov.ssa.ssi.amount + arrangement = person("ssi_federal_living_arrangement", period) + arrangements = SSIFederalLivingArrangement + in_medical_facility = arrangement == arrangements.MEDICAL_TREATMENT_FACILITY + # The one-third reduction applies to the Federal benefit rate in use: + # the individual rate, or the couple rate under spouse deeming + # (20 CFR 416.1131; POMS SI 01320.400 B.1.e). + vtr_factor = where( + arrangement == arrangements.ANOTHER_PERSONS_HOUSEHOLD, + 1 - p.one_third_reduction_rate, + 1, + ) + individual_rate = where( + in_medical_facility, p.medical_facility, p.individual * vtr_factor + ) + individual_ssi = individual_rate - countable_income + deemed_income = person("ssi_income_deemed_from_ineligible_spouse", period) + couple_ssi = p.couple * vtr_factor - (countable_income + deemed_income) + deeming = ( + person("is_ssi_spousal_deeming_applies", period.this_year) + & ~in_medical_facility + ) + reported_ssi = max_( + where(deeming, min_(couple_ssi, individual_ssi), individual_ssi), 0 + ) + reports_ssi = person("receives_ssi", period) + return select( + [meets_ssi_immigration_test, reports_ssi], + [imputed_ssi, reported_ssi], + default=0, + )