From f3006dca8bc072c16793cd3efb69dd0bdbece96a Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 15 Oct 2026 13:14:10 -0400 Subject: [PATCH 1/7] Count income of ABD people who fail SSI's noncitizen test medicaid_optional_senior_or_disabled_countable_income and ssi_countable_income zeroed income for anyone who was not an SSI-eligible individual or spouse, and that status includes SSI's citizen and qualified-noncitizen test. Aged, blind, or disabled people who fail only that test (for example, LPRs with fewer than 40 quarters, or undocumented residents of states that cover them) therefore passed the optional ABD and medically needy Medicaid income tests, and CAPI, regardless of income. Gate the zero, and the spousal-deeming variables, on aged, blind, or disabled status instead. The zero still applies to a spouse who is not aged, blind, or disabled, whose income is deemed to the other spouse. SSI benefits are unchanged because is_ssi_eligible still applies the noncitizen test. Co-Authored-By: Claude Opus 5.5 --- ...d-abd-noncitizen-countable-income.fixed.md | 1 + .../is_medically_needy_for_medicaid.yaml | 36 +++++++++++++ .../eligibility/is_medicaid_eligible.yaml | 45 ++++++++++++++++ ..._income_deemed_from_ineligible_spouse.yaml | 33 ++++++++++++ ...l_senior_or_disabled_countable_income.yaml | 51 +++++++++++++++++++ .../gov/local/ca/sf/caap/ca_sf_caap.yaml | 26 ++++------ ..._income_deemed_from_ineligible_spouse.yaml | 30 +++++++++++ .../gov/ssa/ssi/ssi_countable_income.yaml | 44 ++++++++++++++++ .../gov/states/ca/cdss/capi/ca_capi.yaml | 24 +++++++++ ...ed_income_deemed_from_ineligible_spouse.py | 2 +- ...nal_senior_or_disabled_countable_income.py | 11 ++-- .../is_ssi_spousal_deeming_applies.py | 6 ++- ...si_income_deemed_from_ineligible_spouse.py | 2 +- .../income/ssi_countable_income.py | 12 +++-- 14 files changed, 293 insertions(+), 30 deletions(-) create mode 100644 changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md 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..e52eaa35d0c --- /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. 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 4c889ee6e99..a9af369a172 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 @@ -50,3 +50,39 @@ state_code: MA output: is_medically_needy_for_medicaid: false + +- name: Case 3, 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 4, 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 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 2fb92c16b1e..697be6e4d9b 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 @@ -314,3 +314,48 @@ medicaid_category: SECTION_1115_MEC_ADULT is_medicaid_work_requirement_applicable_adult: true is_medicaid_eligible: true + +- name: Case 17, 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 18, 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 19, 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 883b6e7bed9..c86e871c723 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 @@ -105,3 +105,54 @@ # rounding, 1,131.75 would exceed the $1,131 standard. medicaid_optional_senior_or_disabled_countable_income: 13_572 is_optional_senior_or_disabled_income_eligible: 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/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..b7d0dc449bd 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 + # an SSI-qualified status), but CAPI counts her pension: 2,000 - 20 = + # 1,980/month exceeds the 994/month 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 = 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 + # 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 a613984fefd..b34926450ce 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 @@ -98,3 +98,27 @@ ca_state_supplement_aged_blind_disabled_amount: 0 ca_state_supplement: 0 ca_capi: 11_306 + +- name: Integration test, aged permanent resident without 40 SSI quarters has pension counted + period: 2024 + 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: 6_000 + households: + household: + members: [person1] + state_code: CA + output: + ssi: 0 + ca_capi_eligible_person: true + # (500 - 20) x 12 = 5,760 of countable income. + ssi_countable_income: 5_760 + ca_state_supplement: 0 + # 943 x 12 = 11,316 payment standard, less the 10 offset and 5,760. + ca_capi: 5_546 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 044371e7419..0d6dedba250 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/", @@ -62,12 +63,14 @@ 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) return where( - ~is_eligible, + ~is_aged_blind_disabled, 0, where( couple_computation, 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, From 56dc11f8dbd440c1adf96d27064b41f3f499e0ef Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 21 Oct 2026 18:22:15 -0400 Subject: [PATCH 2/7] Fix issues from review: CA SSP and MD PAA for people SSI bars by alien status Counting the own income of aged, blind or disabled people who fail SSI's noncitizen test exposed two downstream defects found in the 2026-10-19 review: - The California state supplement summed ssi_countable_income over the whole SPM unit, so a CAPI-eligible relative's income reduced an SSI recipient's supplement. CAPI budgets its own members' income (MPP 49-035), and SSI/SSP counts another member's income only when it is deemed (20 CFR 416.1160(a)), so CAPI-eligible members are left out of the sum. - Maryland PAA deemed spouse income and imputed federal SSI to people SSA cannot pay. For people who fail SSI's citizen or qualified-noncitizen test, PAA now counts only their own income and imputes no SSI (COMAR 07.03.07.07 and 07.03.07.09A). The CAPI test that encoded the federal-benefit-only standard is replaced with an over-income case that holds before and after the CAPI rework. Co-Authored-By: Claude Opus 5.5 --- ...d-abd-noncitizen-countable-income.fixed.md | 2 +- .../gov/local/ca/sf/caap/ca_sf_caap.yaml | 10 ++-- .../gov/states/ca/cdss/capi/ca_capi.yaml | 16 +++--- .../state_supplement/ca_state_supplement.yaml | 54 +++++++++++++++++++ .../gov/states/md/dhs/fia/paa/md_paa.yaml | 50 +++++++++++++++++ .../state_supplement/ca_state_supplement.py | 16 +++++- .../md/dhs/fia/paa/md_paa_countable_income.py | 15 +++++- .../dhs/fia/paa/md_paa_imputed_federal_ssi.py | 13 ++++- 8 files changed, 158 insertions(+), 18 deletions(-) diff --git a/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md index e52eaa35d0c..abfa381b4b1 100644 --- a/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md +++ b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md @@ -1 +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. +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 a CAPI-eligible member's income, and Maryland PAA no longer imputes SSI or deems spouse income for people SSI bars by alien status. 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 b7d0dc449bd..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 @@ -339,11 +339,11 @@ spm_unit_cash_assets: 0 output: # person2 is categorically CAPI-eligible (aged 68 + noncitizen + TPS is not - # an SSI-qualified status), but CAPI counts her pension: 2,000 - 20 = - # 1,980/month exceeds the 994/month 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. + # 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 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 b34926450ce..cbae90beeae 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 @@ -99,8 +99,8 @@ ca_state_supplement: 0 ca_capi: 11_306 -- name: Integration test, aged permanent resident without 40 SSI quarters has pension counted - period: 2024 +- name: Integration test, aged permanent resident without 40 SSI quarters whose pension exceeds the CAPI standard + period: 2025 absolute_error_margin: 0.01 input: people: @@ -109,7 +109,7 @@ immigration_status: LEGAL_PERMANENT_RESIDENT years_since_us_entry: 10 ssi_qualifying_quarters_earnings: 0 - pension_income: 6_000 + pension_income: 24_000 # 2,000 a month households: household: members: [person1] @@ -117,8 +117,8 @@ output: ssi: 0 ca_capi_eligible_person: true - # (500 - 20) x 12 = 5,760 of countable income. - ssi_countable_income: 5_760 - ca_state_supplement: 0 - # 943 x 12 = 11,316 payment standard, less the 10 offset and 5,760. - ca_capi: 5_546 + # (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 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..eac4ce30dd6 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,57 @@ # 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 + 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, and living_arrangements_allow_for_food_preparation + # defaults to false, 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 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..a5d9e9b3abf 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,53 @@ 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] 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..275e0e084a3 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 @@ -8,10 +8,22 @@ 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", + ) 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 + # 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)), so a CAPI-eligible member's income does not + # reduce the state supplement. + capi_eligible = person("ca_capi_eligible_person", period.this_year) + person_countable_income = person("ssi_countable_income", period) + countable_income = spm_unit.sum( + where(capi_eligible, 0, person_countable_income) + ) return max_(0, payment_standard - ssi - countable_income) 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..7e63fa527a4 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,19 @@ 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. The SSI cascade deems spouse income only to people + # SSA can pay, so people who fail SSI's citizen or qualified-noncitizen + # test count their own income alone. + 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..b999e4f1c67 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 @@ -10,10 +10,21 @@ 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", ) 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 + ) + return where(is_citizen | is_qualified_noncitizen, imputed_ssi, 0) From e126f9fa303e7ab8de648bb07d21a9e87c8b508c Mon Sep 17 00:00:00 2001 From: Ziming Date: Wed, 21 Oct 2026 18:22:29 -0400 Subject: [PATCH 3/7] Pay California CAPI from the SSI/SSP standard per person, with deeming CAPI payment standards equal the SSI/SSP payment standards less $10 for an individual and $20 for a couple (MPP 49-050.1, .11-.13). The model instead used the federal benefit rate plus the SPM unit's state supplement payment, pooled every CAPI-eligible member's income against one unit standard, applied the $10/$20 offset once a year, and left the tax-unit spouse of a noncitizen couple out. - ca_capi_payment_standard: the SSI/SSP standard for an individual, or half the couple standard, built from the state supplement parameters, less the monthly offset. - ca_capi_person: the standard less the person's own countable income (MPP 49-055.3), with spouse-to-spouse deeming computed as POMS SI 01320.430 D prescribes (federal and state parts each the lesser of the individual and deeming amounts). - ca_capi sums ca_capi_person; ca_capi_income_eligible asks whether any member's income is below their standard (MPP 49-035.1). - Both members of a noncitizen couple, and the noncitizen spouse of a citizen, are CAPI-eligible (MPP 49-055.4, 49-050.13). Co-Authored-By: Claude Opus 5.5 --- changelog.d/ca-capi-ssi-ssp-standard.fixed.md | 1 + .../capi/payment_standard_offset/couple.yaml | 6 +- .../capi/payment_standard_offset/single.yaml | 6 +- .../gov/states/ca/cdss/capi/ca_capi.yaml | 136 ++++++++++++--- .../cdss/capi/ca_capi_payment_standard.yaml | 155 ++++++++++++++++++ .../states/ca/cdss/capi/ca_capi_person.yaml | 142 ++++++++++++++++ .../eligibility/ca_capi_eligible_person.yaml | 26 ++- .../eligibility/ca_capi_income_eligible.yaml | 63 +++++-- .../ca/cdss/capi/_ca_capi_ssi_ssp_standard.py | 75 +++++++++ .../gov/states/ca/cdss/capi/ca_capi.py | 21 +-- .../ca/cdss/capi/ca_capi_payment_standard.py | 27 +++ .../gov/states/ca/cdss/capi/ca_capi_person.py | 51 ++++++ .../eligibility/ca_capi_eligible_person.py | 14 +- .../eligibility/ca_capi_income_eligible.py | 18 +- 14 files changed, 660 insertions(+), 81 deletions(-) create mode 100644 changelog.d/ca-capi-ssi-ssp-standard.fixed.md create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_person.yaml create mode 100644 policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py create mode 100644 policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py create mode 100644 policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_person.py diff --git a/changelog.d/ca-capi-ssi-ssp-standard.fixed.md b/changelog.d/ca-capi-ssi-ssp-standard.fixed.md new file mode 100644 index 00000000000..40040d59dbd --- /dev/null +++ b/changelog.d/ca-capi-ssi-ssp-standard.fixed.md @@ -0,0 +1 @@ +Base California CAPI on the full SSI/SSP payment standard less the monthly $10 individual or $20 couple offset, pay each eligible person (including both spouses of a noncitizen couple) on their own income, and apply spouse-to-spouse deeming. diff --git a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml index 8c9c77fc547..27eeb894489 100644 --- a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml +++ b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml @@ -1,8 +1,8 @@ -description: California reduces the Supplemental Security Income / State Supplemental Payment payment standard by this amount for couples when calculating the Cash Assistance Program for Immigrants. +description: California deducts this amount from the Supplemental Security Income and State Supplementary Payment couple standard under the Cash Assistance Program for Immigrants. metadata: unit: currency-USD - period: year - label: California CAPI couple payment standard offset + period: month + label: California CAPI couple payment standard offset reference: - title: California Eligibility and Assistance Standards Chapter 49-050 (.1) href: https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44 diff --git a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml index 8ea02f39e03..cf2c05cff3d 100644 --- a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml +++ b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml @@ -1,8 +1,8 @@ -description: California reduces the Supplemental Security Income / State Supplemental Payment payment standard by this amount for single filers when calculating the Cash Assistance Program for Immigrants. +description: California deducts this amount from the Supplemental Security Income and State Supplementary Payment individual standard under the Cash Assistance Program for Immigrants. metadata: unit: currency-USD - period: year - label: California CAPI single payment standard offset + period: month + label: California CAPI single payment standard offset reference: - title: California Eligibility and Assistance Standards Chapter 49-050 (.1) href: https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44 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 a613984fefd..4ec8615ae66 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 @@ -1,38 +1,53 @@ - name: Single eligible person - period: 2024 + period: 2026 + absolute_error_margin: 0.01 input: people: person1: - ssi_amount_if_eligible: 1_000 - ca_capi_eligible_person: true - ssi_countable_income: 500 - spm_units: - spm_unit: + age: 70 + immigration_status: UNDOCUMENTED + # 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] - ca_capi_eligible: true - ca_state_supplement: 2_000 + state_code: CA + living_arrangements_allow_for_food_preparation: true output: - ca_capi: 2_490 + # Individual standard 1,233.94 - 10 = 1,223.94 (MPP 49-050.11), less + # countable income 500 = 723.94 per month (MPP 49-055.32). + # 723.94 x 12 = 8,687.28. + ca_capi: 8_687.28 - name: Couple, both people eligible - period: 2024 + period: 2026 + absolute_error_margin: 0.01 input: people: person1: - ssi_amount_if_eligible: 1_000 - ca_capi_eligible_person: true - ssi_countable_income: 500 + age: 72 + immigration_status: UNDOCUMENTED person2: - ssi_amount_if_eligible: 1_000 - ca_capi_eligible_person: true - ssi_countable_income: 4_000 - spm_units: - spm_unit: + age: 68 + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: members: [person1, person2] - ca_capi_eligible: true - ca_state_supplement: 4_000 + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true output: - ca_capi: 1_480 + # Couple standard 2,098.83 - 20 = 2,078.83 (MPP 49-050.12); each member + # receives one-half (MPP 49-055.4): 1,039.415 per month, 12,472.98 per + # year. The unit total is 2 x 12,472.98 = 24,945.96. + ca_capi_person: [12_472.98, 12_472.98] + ca_capi: 24_945.96 - name: Integration test, ineligible period: 2024 @@ -74,7 +89,8 @@ ca_capi: 0 - name: Integration test, undocumented - period: 2024 + period: 2026 + absolute_error_margin: 0.01 input: people: person1: @@ -97,4 +113,78 @@ ca_state_supplement_blind_amount: 0 ca_state_supplement_aged_blind_disabled_amount: 0 ca_state_supplement: 0 - ca_capi: 11_306 + # Disabled individual standard 1,233.94 + no-cooking food allowance + # 128.87 (living arrangements default to no food preparation) = + # 1,362.81; less $10 = 1,352.81 per month. Earnings of 83.33 per month + # fall within the $20 + $65 exclusions, so countable income is 0. + # 1,352.81 x 12 = 16,233.72. + ca_capi: 16_233.72 + +- name: Mixed couple, only the noncitizen spouse receives CAPI + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: CITIZEN + person2: + age: 68 + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The citizen receives SSI/SSP, which CAPI does not add. The noncitizen + # spouse's standard is 2,098.83 / 2 - 10 = 1,039.415 per month + # (MPP 49-050.13); 1,039.415 x 12 = 12,472.98. + ca_capi_person: [0, 12_472.98] + ca_capi: 12_472.98 + +- name: Two unrelated eligible people in one unit, income is not pooled + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: UNDOCUMENTED + # 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: UNDOCUMENTED + 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: true + output: + # Each person is assessed on their own income (MPP 49-035.1, 49-055.32). + # person1: 1,500 is not lower than the 1,223.94 standard, so 0. + # person2: no income, so 1,223.94 per month; x 12 = 14,687.28. Pooling + # person1's excess income with person2's standard would lower this. + ca_capi_person: [0, 14_687.28] + ca_capi: 14_687.28 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml new file mode 100644 index 00000000000..9e277d6c34f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml @@ -0,0 +1,155 @@ +- name: Case 1, aged individual with cooking facilities. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # MPP 49-050.11: the SSI/SSP aged or disabled individual standard + # 1,233.94 less $10 = 1,223.94. + ca_capi_payment_standard: 1_223.94 + +- name: Case 2, aged individual without cooking facilities in 2025. + period: 2025-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # 2025 aged or disabled individual standard 1,206.94 + no-cooking food + # allowance 128.87 (WIC 12200(e)) = 1,335.81; less $10 = 1,325.81. + ca_capi_payment_standard: 1_325.81 + +- name: Case 3, blind individual without cooking facilities gets no food allowance. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_blind: true + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # Blind individual standard 1,318.32. The no-cooking allowance applies + # only to aged or disabled people (WIC 12200(e)), so 1,318.32 - 10 = + # 1,308.32. + ca_capi_payment_standard: 1_308.32 + +- name: Case 4, aged noncitizen couple with cooking facilities splits the couple standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: UNDOCUMENTED + person2: + age: 68 + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # Both spouses are aged, so the SSI couple computation applies. + # Couple standard 2,098.83 less $20 (MPP 49-050.12) = 2,078.83; each + # member receives one-half (MPP 49-055.4): 1,039.415. + ca_capi_payment_standard: [1_039.415, 1_039.415] + +- name: Case 5, aged noncitizen couple without cooking facilities adds the couple food allowance. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: UNDOCUMENTED + person2: + age: 68 + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # Couple standard 2,098.83 + couple no-cooking allowance 257.74 = + # 2,356.57; less $20 = 2,336.57; one-half each = 1,168.285. + ca_capi_payment_standard: [1_168.285, 1_168.285] + +- name: Case 6, noncitizen couple with one blind member uses the one-blind couple standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + person2: + age: 60 + is_blind: true + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The one-blind couple standard 2,238.44 (WIC 12200(b)) exceeds the + # aged couple standard 2,098.83 and applies (MPP 49-050.27). Less $20 = + # 2,218.44; one-half each = 1,109.22. + ca_capi_payment_standard: [1_109.22, 1_109.22] + +- name: Case 7, noncitizen spouse of an aged citizen gets half the couple standard less $10. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: CITIZEN + person2: + age: 68 + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The citizen receives SSI/SSP, not CAPI. MPP 49-050.13 sets the couple + # standard $10 below the SSI/SSP couple standard, so the CAPI member's + # half is 2,098.83 / 2 - 10 = 1,039.415. + ca_capi_payment_standard: [0, 1_039.415] 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 new file mode 100644 index 00000000000..80cb66deb4f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_person.yaml @@ -0,0 +1,142 @@ +- name: Case 1, aged noncitizen couple splits the couple's countable income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: UNDOCUMENTED + # 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: UNDOCUMENTED + ssi_countable_income: 2_400 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # Couple standard 2,098.83 - 20 = 2,078.83, less the couple's countable + # income 400 = 1,678.83 (MPP 49-055.32); each member receives one-half + # (MPP 49-055.4): 839.415. + ca_capi_person: [839.415, 839.415] + +- name: Case 2, deemed income from an ineligible spouse below the couple FBR. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + # 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 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # 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. + # Under deeming: federal 1,491 - 207.50 = 1,283.50; a federal benefit is + # due, so the state supplement is the couple OSS 2,098.83 - 1,491 = 607.83. + # Federal = min(994, 1,283.50) = 994; state = min(239.94, 607.83) = 239.94. + # CAPI = 994 + 239.94 - 10 = 1,223.94. + ca_capi_person: [1_223.94, 0] + +- name: Case 3, deemed income above the couple FBR reduces the couple state supplement. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + # 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 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # 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 + # benefit; state supplement = couple OSS 607.83 - 400 = 207.83. + # Federal = min(994, 0) = 0; state = min(239.94, 207.83) = 207.83. + # CAPI = 0 + 207.83 - 10 = 197.83. + ca_capi_person: [197.83, 0] + +- name: Case 4, blind noncitizen with an ineligible spouse uses the two-blind couple rate under deeming. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + is_blind: true + immigration_status: UNDOCUMENTED + # 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 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # POMS SI 01320.430 C.7 and D. + # As an individual: federal 994; state supplement = blind individual + # OSS 1,318.32 - 994 = 324.32. + # Under deeming the ineligible spouse is treated as blind too, so the + # couple OSS is the two-blind rate 2,324.35 - 1,491 = 833.35. 2,091 + # exceeds the couple FBR by 600, so no federal benefit; state supplement + # = 833.35 - 600 = 233.35. + # Federal = 0; state = min(324.32, 233.35) = 233.35. + # CAPI = 0 + 233.35 - 10 = 223.35. + ca_capi_person: [223.35, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml index 4991ca5f673..287beb1cab9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml @@ -2,7 +2,6 @@ period: 2023 input: is_ssi_aged_blind_disabled: true - is_ssi_eligible_spouse: false immigration_status: UNDOCUMENTED state_code: CA output: @@ -12,7 +11,6 @@ period: 2023 input: is_ssi_aged_blind_disabled: true - is_ssi_eligible_spouse: false immigration_status: CITIZEN state_code: CA output: @@ -22,9 +20,31 @@ period: 2023 input: is_ssi_aged_blind_disabled: true - is_ssi_eligible_spouse: false immigration_status: LEGAL_PERMANENT_RESIDENT ssi_qualifying_quarters_earnings: 39 state_code: CA output: ca_capi_eligible_person: true + +- name: Eligible couple - both spouses aged and undocumented + period: 2026 + input: + people: + person1: + age: 72 + immigration_status: UNDOCUMENTED + person2: + age: 68 + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + output: + # person2 is the tax-unit spouse of an aged couple. Each member of an + # eligible couple receives CAPI (MPP 49-055.4), so the spouse is eligible + # too. + ca_capi_eligible_person: [true, true] 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 a33d38fa225..accef876957 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 @@ -1,21 +1,60 @@ -- name: Ineligible - period: 2024 +- name: Ineligible, countable income one dollar above the payment standard + period: 2026 input: - ssi_amount_if_eligible: 2_000 - ca_state_supplement_payment_standard: 1_000 - ssi_countable_income: 3_001 - ca_capi_eligible_person: true + age: 70 + immigration_status: UNDOCUMENTED + # SSI zeroes countable income for people who fail its immigration test, + # so the case supplies it: 1,224.94 per month (14,699.28 per year). + ssi_countable_income: 14_699.28 + living_arrangements_allow_for_food_preparation: true state_code: CA output: + # Standard 1,233.94 - 10 = 1,223.94. Countable income must be lower than + # the standard (MPP 49-035.1); 1,224.94 is not, so there is no CAPI. ca_capi_income_eligible: false -- name: Eligible - period: 2024 +- name: Eligible, countable income one dollar below the payment standard + period: 2026 input: - ssi_amount_if_eligible: 2_000 - ca_state_supplement_payment_standard: 1_000 - ssi_countable_income: 2_999 - ca_capi_eligible_person: true + age: 70 + immigration_status: UNDOCUMENTED + # Supplied as above: 1,222.94 per month (14,675.28 per year). + ssi_countable_income: 14_675.28 + living_arrangements_allow_for_food_preparation: true state_code: CA output: + # 1,222.94 is lower than the 1,223.94 standard: 1 per month of CAPI. ca_capi_income_eligible: true + +- name: Ineligible, income deemed from a high-earning spouse exhausts the couple state supplement + period: 2026 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + # 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 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # 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 + # state supplement is due. Federal = 0, state = min(239.94, 0) = 0, and + # CAPI = max(0, 0 - 10) = 0 in every month. + ca_capi_income_eligible: false diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py b/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py new file mode 100644 index 00000000000..28bec390276 --- /dev/null +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py @@ -0,0 +1,75 @@ +from policyengine_us.model_api import * + + +def ca_capi_ssi_ssp_standard(person, period, parameters): + """Return a person's monthly SSI/SSP individual and couple standards. + + CAPI payment standards equal the SSI/SSP standards less an offset (MPP + 49-050.1). These follow ca_state_supplement_payment_standard, whose amounts + include the federal benefit rate: the higher of the blind amount and the + aged or disabled amount (the disabled child amount for a dependent child, + MPP 49-050.25; blind children take the blind amount, MPP 49-050.253), the + food allowance for an aged or disabled adult who cannot prepare meals, and + the out-of-home-care and medical-care-facility allowances per person. + In an SSI couple computation the couple standard uses both members; + otherwise it treats the ineligible spouse as the person's category (POMS + SI 01320.430 C.7) and adds only the person's own allowances. + """ + p = parameters(period).gov.states.ca.cdss.state_supplement.payment_standard + age = person("monthly_age", period) + child = person("is_tax_unit_dependent", period.this_year) & ( + age < p.dependent.age_limit + ) + blind = person("is_blind", period.this_year) + aged_or_disabled = (age >= p.aged_or_disabled.age_threshold) | person( + "is_ssi_disabled", period.this_year + ) + no_cooking = ~person.household( + "living_arrangements_allow_for_food_preparation", period.this_year + ) + allowance = ( + person("in_out_of_home_care_facility", period.this_year) + * p.allowance.out_of_home_care + + person("ca_in_medical_care_facility", period.this_year) + * p.allowance.medical_care_facility + ) + individual = ( + max_( + blind * p.blind.single, + aged_or_disabled + * where(child, p.dependent.amount, p.aged_or_disabled.amount.single), + ) + + aged_or_disabled * ~child * no_cooking * p.allowance.food.single + + allowance + ) + + joint = person("ssi_couple_computation_applies", period) + blind_count = where(joint, person.marital_unit.sum(blind), 2 * blind) + aged_or_disabled_count = where( + joint, person.marital_unit.sum(aged_or_disabled), 2 * aged_or_disabled + ) + blind_amount = select( + [blind_count > 1, blind_count == 1], + [p.blind.married.two_blind, p.blind.married.one_blind], + default=0, + ) + aged_or_disabled_amount = select( + [aged_or_disabled_count > 1, aged_or_disabled_count == 1], + [p.aged_or_disabled.amount.married, p.aged_or_disabled.amount.single], + default=0, + ) + food = ( + (aged_or_disabled_count > 0) + * no_cooking + * where( + aged_or_disabled_count > 1, + p.allowance.food.married, + p.allowance.food.single, + ) + ) + couple = ( + max_(blind_amount, aged_or_disabled_amount) + + food + + where(joint, person.marital_unit.sum(allowance), allowance) + ) + return individual, couple diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi.py b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi.py index c7d975049b2..ddf4a41ed0c 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi.py @@ -8,21 +8,8 @@ class ca_capi(Variable): label = "California CAPI" definition_period = YEAR defined_for = "ca_capi_eligible" - reference = "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf" + reference = ( + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=47" + ) - def formula(spm_unit, period, parameters): - state_supplement_payment_standard = spm_unit("ca_state_supplement", period) - person = spm_unit.members - ssi_amount_if_eligible = person("ssi_amount_if_eligible", period) - eligible_person = person("ca_capi_eligible_person", period) - total_ssi_amount = spm_unit.sum(ssi_amount_if_eligible * eligible_person) - payment_standard = state_supplement_payment_standard + total_ssi_amount - p = parameters(period).gov.states.ca.cdss.capi.payment_standard_offset - married = spm_unit("spm_unit_is_married", period) - offset = where(married, p.couple, p.single) - total_payment_standard = max_(payment_standard - offset, 0) - person = spm_unit.members - countable_income = spm_unit.sum( - (person("ssi_countable_income", period) * eligible_person) - ) - return max_(0, total_payment_standard - countable_income) + adds = ["ca_capi_person"] diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py new file mode 100644 index 00000000000..3f9b820804c --- /dev/null +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.ca.cdss.capi._ca_capi_ssi_ssp_standard import ( + ca_capi_ssi_ssp_standard, +) + + +class ca_capi_payment_standard(Variable): + value_type = float + entity = Person + label = "California CAPI payment standard" + unit = USD + definition_period = MONTH + defined_for = "ca_capi_eligible_person" + reference = ( + # PDF pages 44-46 + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44", + "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=12200", + ) + + def formula(person, period, parameters): + individual, couple = ca_capi_ssi_ssp_standard(person, period, parameters) + p = parameters(period).gov.states.ca.cdss.capi.payment_standard_offset + joint = person("ssi_couple_computation_applies", period) + # Each member of a couple takes half the couple standard less half the + # couple offset, so a couple with one SSI/SSP member is one half-offset + # below the SSI/SSP couple standard (MPP 49-050.12-.13). + return where(joint, (couple - p.couple) / 2, individual - p.single) 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 new file mode 100644 index 00000000000..888aba48190 --- /dev/null +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_person.py @@ -0,0 +1,51 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.ca.cdss.capi._ca_capi_ssi_ssp_standard import ( + ca_capi_ssi_ssp_standard, +) + + +class ca_capi_person(Variable): + value_type = float + entity = Person + label = "California CAPI amount per person" + unit = USD + definition_period = MONTH + defined_for = "ca_capi_eligible_person" + reference = ( + # PDF pages 25, 30, 47 + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=25", + "https://secure.ssa.gov/poms.nsf/lnx/0501320430", + ) + + def formula(person, period, parameters): + countable_income = person("ssi_countable_income", period) + payment_standard = person("ca_capi_payment_standard", period) + benefit = max_(payment_standard - countable_income, 0) + + # MPP 49-035.71 follows the SSI spouse-to-spouse deeming steps: compute + # the federal and state parts as an individual and under deeming, then + # take the lesser of each (POMS SI 01320.430 D). + # NOTE: the federal parts use the independent-living benefit rates, + # matching the independent-living SSI/SSP standards. + individual_standard, couple_standard = ca_capi_ssi_ssp_standard( + person, period, parameters + ) + fbr = parameters(period).gov.ssa.ssi.amount + deemed_income = person("ssi_income_deemed_from_ineligible_spouse", period) + own_income = max_(countable_income - deemed_income, 0) + individual_federal = fbr.individual - own_income + couple_federal = fbr.couple - countable_income + federal = max_(min_(individual_federal, couple_federal), 0) + individual_supplement = individual_standard - fbr.individual + couple_supplement = max_(couple_standard - fbr.couple, individual_supplement) + # Income above a federal rate reduces the matching state supplement. + supplement = min_( + individual_supplement + min_(individual_federal, 0), + couple_supplement + min_(couple_federal, 0), + ) + p = parameters(period).gov.states.ca.cdss.capi.payment_standard_offset + deemed_benefit = max_(federal + supplement - p.single, 0) + deeming = person("is_ssi_spousal_deeming_applies", period.this_year) & ~person( + "ssi_couple_computation_applies", period + ) + return where(deeming, deemed_benefit, benefit) diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py b/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py index 6309ee13c10..ea946c5b4ea 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py @@ -7,18 +7,16 @@ class ca_capi_eligible_person(Variable): label = "California CAPI eligible person" definition_period = YEAR defined_for = StateCode.CA - reference = "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf" + # PDF pages 10, 47 + reference = ( + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=10" + ) def formula(person, period, parameters): + # Both members of a couple can be eligible (MPP 49-055.4). aged_blind_disabled = person("is_ssi_aged_blind_disabled", period) - is_ssi_eligible_spouse = person("is_ssi_eligible_spouse", period) immigration_status = person("immigration_status", period) is_citizen = immigration_status == immigration_status.possible_values.CITIZEN is_qualified_noncitizen = person("is_ssi_qualified_noncitizen", period) - return ( - aged_blind_disabled - & ~is_ssi_eligible_spouse - & ~is_citizen - & ~is_qualified_noncitizen - ) + return aged_blind_disabled & ~is_citizen & ~is_qualified_noncitizen diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.py b/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.py index ed3148b592d..a3351201fbf 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_income_eligible.py @@ -7,17 +7,11 @@ class ca_capi_income_eligible(Variable): label = "California CAPI income eligible" definition_period = YEAR defined_for = StateCode.CA - reference = "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf" + reference = ( + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=25" + ) def formula(spm_unit, period, parameters): - payment_standard = add( - spm_unit, - period, - ["ssi_amount_if_eligible", "ca_state_supplement_payment_standard"], - ) - person = spm_unit.members - eligible_person = person("ca_capi_eligible_person", period) - countable_income = spm_unit.sum( - (person("ssi_countable_income", period) * eligible_person) - ) - return payment_standard > countable_income + # MPP 49-035.1 compares each individual's or couple's countable income + # with the CAPI payment standard; a payment remains only when it is lower. + return add(spm_unit, period, ["ca_capi_person"]) > 0 From 9e39da393d57d12291349b34a1a8b90fd8e8fde7 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 26 Oct 2026 21:04:51 -0400 Subject: [PATCH 4/7] Fix issues from review: CAPI equals SSI/SSP since June 2019, mixed couples, one standard per arrangement - Offsets are $0 from June 1, 2019 (WIC 18941; ACIN I-23-19); new mixed-couple offset (MPP 49-050.13) before then - Mixed couple: couple standard less the couple's countable income and the spouse's SSI/SSP (MPP 49-005(e)(3), 49-035.221) - Title XIX facility $62 and non-medical out-of-home care $1,626.07 replace the community standard; no-cooking allowance only on the aged or disabled amount - Floor the standards at the federal benefit rate while the CA SSP parameters hold 1991 totals (issue 7787) - No deeming for a Title XIX facility resident (20 CFR 416.1160(a)(1)) - candidates.yaml: us-ca:capi-payment-standard-offset (open, Pavel's sign-off) and us-ca:capi-spousal-deeming-method (unreviewed) Co-Authored-By: Claude Opus 5.5 --- changelog.d/ca-capi-ssi-ssp-standard.fixed.md | 2 +- .../capi/payment_standard_offset/couple.yaml | 15 +- .../payment_standard_offset/mixed_couple.yaml | 17 ++ .../capi/payment_standard_offset/single.yaml | 15 +- .../gov/states/ca/cdss/capi/ca_capi.yaml | 68 ++++-- .../cdss/capi/ca_capi_payment_standard.yaml | 230 ++++++++++++++++-- .../states/ca/cdss/capi/ca_capi_person.yaml | 142 ++++++++++- .../eligibility/ca_capi_income_eligible.yaml | 19 +- .../ca/cdss/capi/_ca_capi_ssi_ssp_standard.py | 107 ++++---- .../ca/cdss/capi/ca_capi_payment_standard.py | 26 +- .../gov/states/ca/cdss/capi/ca_capi_person.py | 63 ++++- source_conflicts/candidates.yaml | 77 ++++++ 12 files changed, 653 insertions(+), 128 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/mixed_couple.yaml diff --git a/changelog.d/ca-capi-ssi-ssp-standard.fixed.md b/changelog.d/ca-capi-ssi-ssp-standard.fixed.md index 40040d59dbd..beb3dba5fdd 100644 --- a/changelog.d/ca-capi-ssi-ssp-standard.fixed.md +++ b/changelog.d/ca-capi-ssi-ssp-standard.fixed.md @@ -1 +1 @@ -Base California CAPI on the full SSI/SSP payment standard less the monthly $10 individual or $20 couple offset, pay each eligible person (including both spouses of a noncitizen couple) on their own income, and apply spouse-to-spouse deeming. +Pay California CAPI at the SSI/SSP payment standard (with no offset since June 2019) using one standard per living arrangement, compute each eligible person's benefit on their own income, count the SSI/SSP of a spouse who receives it, and apply spouse-to-spouse deeming. diff --git a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml index 27eeb894489..3e76e4ce95c 100644 --- a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml +++ b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml @@ -1,10 +1,17 @@ -description: California deducts this amount from the Supplemental Security Income and State Supplementary Payment couple standard under the Cash Assistance Program for Immigrants. +description: California deducts this amount from the Supplemental Security Income and State Supplementary Payment couple standard under the Cash Assistance Program for Immigrants until June 2019. +values: + 1991-01-01: 20 + 2019-06-01: 0 metadata: unit: currency-USD period: month label: California CAPI couple payment standard offset reference: - - title: California Eligibility and Assistance Standards Chapter 49-050 (.1) + - title: California Eligibility and Assistance Standards Chapter 49-050 (.12) href: https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44 -values: - 1991-01-01: 20 + - title: California Welfare and Institutions Code Section 18941 + href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941 + - title: California Department of Social Services, All County Information Notice I-23-19, CAPI payment standards effective June 1, 2019 + href: https://www.cdss.ca.gov/Portals/9/ACIN/2019/I-23_19.pdf#page=2 + - title: California Department of Social Services, All County Information Notice I-59-25, CAPI payment standards for January 2026 + href: https://cdss.ca.gov/Portals/9/Additional-Resources/Letters-and-Notices/ACINs/2025/I-59_25.pdf#page=5 diff --git a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/mixed_couple.yaml b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/mixed_couple.yaml new file mode 100644 index 00000000000..050c39241ed --- /dev/null +++ b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/mixed_couple.yaml @@ -0,0 +1,17 @@ +description: California deducts this amount from the Supplemental Security Income and State Supplementary Payment couple standard for mixed couples under the Cash Assistance Program for Immigrants until June 2019. +values: + 1991-01-01: 10 + 2019-06-01: 0 +metadata: + unit: currency-USD + period: month + label: California CAPI mixed couple payment standard offset + reference: + - title: California Eligibility and Assistance Standards Chapter 49-050 (.13) + href: https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44 + - title: California Welfare and Institutions Code Section 18941 + href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941 + - title: California Department of Social Services, All County Information Notice I-23-19, CAPI payment standards effective June 1, 2019 + href: https://www.cdss.ca.gov/Portals/9/ACIN/2019/I-23_19.pdf#page=2 + - title: California Department of Social Services, All County Information Notice I-59-25, CAPI payment standards for January 2026 + href: https://cdss.ca.gov/Portals/9/Additional-Resources/Letters-and-Notices/ACINs/2025/I-59_25.pdf#page=5 diff --git a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml index cf2c05cff3d..db5ece35f70 100644 --- a/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml +++ b/policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml @@ -1,10 +1,17 @@ -description: California deducts this amount from the Supplemental Security Income and State Supplementary Payment individual standard under the Cash Assistance Program for Immigrants. +description: California deducts this amount from the Supplemental Security Income and State Supplementary Payment individual standard under the Cash Assistance Program for Immigrants until June 2019. +values: + 1991-01-01: 10 + 2019-06-01: 0 metadata: unit: currency-USD period: month label: California CAPI single payment standard offset reference: - - title: California Eligibility and Assistance Standards Chapter 49-050 (.1) + - title: California Eligibility and Assistance Standards Chapter 49-050 (.11) href: https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44 -values: - 1991-01-01: 10 + - title: California Welfare and Institutions Code Section 18941 + href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941 + - title: California Department of Social Services, All County Information Notice I-23-19, CAPI payment standards effective June 1, 2019 + href: https://www.cdss.ca.gov/Portals/9/ACIN/2019/I-23_19.pdf#page=2 + - title: California Department of Social Services, All County Information Notice I-59-25, CAPI payment standards for January 2026 + href: https://cdss.ca.gov/Portals/9/Additional-Resources/Letters-and-Notices/ACINs/2025/I-59_25.pdf#page=5 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 4ec8615ae66..7ddbe20a697 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 @@ -18,10 +18,10 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: - # Individual standard 1,233.94 - 10 = 1,223.94 (MPP 49-050.11), less - # countable income 500 = 723.94 per month (MPP 49-055.32). - # 723.94 x 12 = 8,687.28. - ca_capi: 8_687.28 + # 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. + ca_capi: 8_807.28 - name: Couple, both people eligible period: 2026 @@ -43,11 +43,11 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: - # Couple standard 2,098.83 - 20 = 2,078.83 (MPP 49-050.12); each member - # receives one-half (MPP 49-055.4): 1,039.415 per month, 12,472.98 per - # year. The unit total is 2 x 12,472.98 = 24,945.96. - ca_capi_person: [12_472.98, 12_472.98] - ca_capi: 24_945.96 + # Couple standard 2,098.83 with no offset; each member receives one-half + # (MPP 49-055.4): 1,049.415 per month, 12,592.98 per year. The unit + # total is 2 x 12,592.98 = 25,185.96. + ca_capi_person: [12_592.98, 12_592.98] + ca_capi: 25_185.96 - name: Integration test, ineligible period: 2024 @@ -115,10 +115,10 @@ ca_state_supplement: 0 # Disabled individual standard 1,233.94 + no-cooking food allowance # 128.87 (living arrangements default to no food preparation) = - # 1,362.81; less $10 = 1,352.81 per month. Earnings of 83.33 per month - # fall within the $20 + $65 exclusions, so countable income is 0. - # 1,352.81 x 12 = 16,233.72. - ca_capi: 16_233.72 + # 1,362.81 per month with no offset. Earnings of 83.33 per month fall + # within the $20 + $65 exclusions, so countable income is 0. + # 1,362.81 x 12 = 16,353.72. + ca_capi: 16_353.72 - name: Mixed couple, only the noncitizen spouse receives CAPI period: 2026 @@ -140,11 +140,14 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: - # The citizen receives SSI/SSP, which CAPI does not add. The noncitizen - # spouse's standard is 2,098.83 / 2 - 10 = 1,039.415 per month - # (MPP 49-050.13); 1,039.415 x 12 = 12,472.98. - ca_capi_person: [0, 12_472.98] - ca_capi: 12_472.98 + # The citizen receives SSI/SSP, which counts as the CAPI member's + # unearned income (MPP 49-035.221). The model pays the citizen SSI of + # 1,491 / 2 = 745.50 and a state supplement of 1,233.94 - 745.50 = + # 488.44 per month; SSA pays 994 + 239.94, the same 1,233.94 total. + # CAPI = couple standard 2,098.83 (MPP 49-050.13, no offset) - 0 income + # - 745.50 - 488.44 = 864.89 per month; 864.89 x 12 = 10,378.68. + ca_capi_person: [0, 10_378.68] + ca_capi: 10_378.68 - name: Two unrelated eligible people in one unit, income is not pooled period: 2026 @@ -183,8 +186,29 @@ living_arrangements_allow_for_food_preparation: true output: # Each person is assessed on their own income (MPP 49-035.1, 49-055.32). - # person1: 1,500 is not lower than the 1,223.94 standard, so 0. - # person2: no income, so 1,223.94 per month; x 12 = 14,687.28. Pooling + # 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 # person1's excess income with person2's standard would lower this. - ca_capi_person: [0, 14_687.28] - ca_capi: 14_687.28 + ca_capi_person: [0, 14_807.28] + ca_capi: 14_807.28 + +- name: Aged person in 2024, the independent-living standard is floored at the federal benefit rate + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The state supplement parameters hold the 1991 aged amount of 630 until + # 2025 (issue 7787). CAPI equals SSI/SSP (WIC 18941), so the standard is + # floored at the 2024 federal benefit rate: max(630, 943) = 943 per + # month with no offset and no income; 943 x 12 = 11,316. + ca_capi_person: 11_316 + ca_capi: 11_316 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml index 9e277d6c34f..14389061408 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml @@ -12,9 +12,10 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: - # MPP 49-050.11: the SSI/SSP aged or disabled individual standard - # 1,233.94 less $10 = 1,223.94. - ca_capi_payment_standard: 1_223.94 + # WIC 18941: the CAPI standard equals the SSI/SSP aged or disabled + # individual standard, with no offset since June 2019 (ACIN I-59-25): + # 994 + 239.94 = 1,233.94. + ca_capi_payment_standard: 1_233.94 - name: Case 2, aged individual without cooking facilities in 2025. period: 2025-01 @@ -31,8 +32,9 @@ living_arrangements_allow_for_food_preparation: false output: # 2025 aged or disabled individual standard 1,206.94 + no-cooking food - # allowance 128.87 (WIC 12200(e)) = 1,335.81; less $10 = 1,325.81. - ca_capi_payment_standard: 1_325.81 + # allowance 128.87 (WIC 12200(e)) = 1,335.81, above the 967 federal + # benefit rate; no offset. + ca_capi_payment_standard: 1_335.81 - name: Case 3, blind individual without cooking facilities gets no food allowance. period: 2026-01 @@ -50,9 +52,9 @@ living_arrangements_allow_for_food_preparation: false output: # Blind individual standard 1,318.32. The no-cooking allowance applies - # only to aged or disabled people (WIC 12200(e)), so 1,318.32 - 10 = - # 1,308.32. - ca_capi_payment_standard: 1_308.32 + # only to aged or disabled people (WIC 12200(e)), so the standard stays + # 1,318.32. + ca_capi_payment_standard: 1_318.32 - name: Case 4, aged noncitizen couple with cooking facilities splits the couple standard. period: 2026-01 @@ -75,9 +77,9 @@ living_arrangements_allow_for_food_preparation: true output: # Both spouses are aged, so the SSI couple computation applies. - # Couple standard 2,098.83 less $20 (MPP 49-050.12) = 2,078.83; each - # member receives one-half (MPP 49-055.4): 1,039.415. - ca_capi_payment_standard: [1_039.415, 1_039.415] + # Couple standard 2,098.83 with no offset; each member receives one-half + # (MPP 49-055.4): 2,098.83 / 2 = 1,049.415. + ca_capi_payment_standard: [1_049.415, 1_049.415] - name: Case 5, aged noncitizen couple without cooking facilities adds the couple food allowance. period: 2026-01 @@ -100,8 +102,8 @@ living_arrangements_allow_for_food_preparation: false output: # Couple standard 2,098.83 + couple no-cooking allowance 257.74 = - # 2,356.57; less $20 = 2,336.57; one-half each = 1,168.285. - ca_capi_payment_standard: [1_168.285, 1_168.285] + # 2,356.57; one-half each = 1,178.285. + ca_capi_payment_standard: [1_178.285, 1_178.285] - name: Case 6, noncitizen couple with one blind member uses the one-blind couple standard. period: 2026-01 @@ -125,11 +127,11 @@ living_arrangements_allow_for_food_preparation: true output: # The one-blind couple standard 2,238.44 (WIC 12200(b)) exceeds the - # aged couple standard 2,098.83 and applies (MPP 49-050.27). Less $20 = - # 2,218.44; one-half each = 1,109.22. - ca_capi_payment_standard: [1_109.22, 1_109.22] + # aged couple standard 2,098.83 and applies (MPP 49-050.27); one-half + # each = 1,119.22. + ca_capi_payment_standard: [1_119.22, 1_119.22] -- name: Case 7, noncitizen spouse of an aged citizen gets half the couple standard less $10. +- name: Case 7, noncitizen spouse of an aged SSI/SSP recipient takes the whole couple standard. period: 2026-01 absolute_error_margin: 0.01 input: @@ -149,7 +151,193 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: - # The citizen receives SSI/SSP, not CAPI. MPP 49-050.13 sets the couple - # standard $10 below the SSI/SSP couple standard, so the CAPI member's - # half is 2,098.83 / 2 - 10 = 1,039.415. - ca_capi_payment_standard: [0, 1_039.415] + # The citizen receives SSI/SSP, not CAPI, and counts as an eligible + # spouse (MPP 49-005(e)(3)). The CAPI member takes the whole couple + # standard (MPP 49-050.13), whose offset is 0 since June 2019 (WIC + # 18941): 2,098.83. ca_capi_person subtracts the citizen's SSI/SSP. + ca_capi_payment_standard: [0, 2_098.83] + +- name: Case 8, Title XIX medical facility resident takes the facility standard alone. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 75 + immigration_status: UNDOCUMENTED + ca_in_medical_care_facility: true + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # ACIN I-59-25 and POMS SI 01415.058 code J: the Title XIX medical + # facility standard is 30 + 32 = 62 (MPP 49-050.26). It replaces the + # independent-living standard, adds no food allowance and is not floored + # at the federal benefit rate. + ca_capi_payment_standard: 62 + +- name: Case 9, nonmedical out-of-home care uses one standard for every category. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 75 + immigration_status: UNDOCUMENTED + in_out_of_home_care_facility: true + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # ACIN I-59-25 and POMS SI 01415.058 code B: half the couple + # out-of-home care standard, (2,098.83 + 1,153.31) / 2 = 3,252.14 / 2 = + # 1,626.07 (MPP 49-050.24). No food allowance is added. + ca_capi_payment_standard: 1_626.07 + +- name: Case 10, aged and blind individual without cooking takes the higher aged amount with food. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + is_blind: true + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # California pays the highest category (POMS SI 01415.058 B.2): + # max(blind 1,318.32, aged 1,233.94 + food 128.87 = 1,362.81) = + # 1,362.81. The food allowance does not stack on the blind amount. + ca_capi_payment_standard: 1_362.81 + +- name: Case 11, disabled dependent child takes the disabled minor standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + person2: + age: 10 + is_disabled: true + meets_ssi_disability_criteria: true + immigration_status: UNDOCUMENTED + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # ACIN I-59-25 disabled minor 994 + 97.27 = 1,091.27 (MPP 49-050.25), + # with no food allowance. The parent is not aged, blind or disabled. + ca_capi_payment_standard: [0, 1_091.27] + +- name: Case 12, blind dependent child takes the blind standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + person2: + age: 10 + is_blind: true + immigration_status: UNDOCUMENTED + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # A blind child takes the blind amount, 1,318.32 (MPP 49-050.253). + ca_capi_payment_standard: [0, 1_318.32] + +- name: Case 13, aged couple with one blind member without cooking adds the individual food allowance. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: UNDOCUMENTED + person2: + age: 70 + is_blind: true + immigration_status: UNDOCUMENTED + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: false + output: + # POMS SI 01415.058 code C note: the blind/aged couple level plus the + # individual restaurant allowance, 2,238.44 + 128.87 = 2,367.31. This + # beats the aged couple without cooking, 2,098.83 + 257.74 = 2,356.57. + # One-half each: 2,367.31 / 2 = 1,183.655. + ca_capi_payment_standard: [1_183.655, 1_183.655] + +- name: Case 14, 2024 independent-living standard is floored at the federal benefit rate. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The state supplement parameters hold the 1991 aged amount of 630 until + # 2025 (issue 7787), below the 2024 federal benefit rate of 943. CAPI + # equals SSI/SSP (WIC 18941), so the standard is max(630, 943) = 943. + ca_capi_payment_standard: 943 + +- name: Case 15, the 10 individual offset applies through May 2019 and ends in June 2019. + period: 2019 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + households: + household: + members: [person1] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The state supplement parameters hold the 1991 aged amount of 630 until + # 2025 (issue 7787), so the model floors the standard at the 2019 federal + # benefit rate: max(630, 771) = 771. The actual 2019 SSI/SSP standard was + # 931.72 (ACIN I-23-19). This case pins only the offset boundary: + # 771 - 10 = 761 through May 2019 (MPP 49-050.11) and 771 - 0 = 771 from + # June 1, 2019 (WIC 18941). + ca_capi_payment_standard: + 2019-05: 761 + 2019-06: 771 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 80cb66deb4f..00789c189c0 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 @@ -26,10 +26,10 @@ state_code: CA living_arrangements_allow_for_food_preparation: true output: - # Couple standard 2,098.83 - 20 = 2,078.83, less the couple's countable - # income 400 = 1,678.83 (MPP 49-055.32); each member receives one-half - # (MPP 49-055.4): 839.415. - ca_capi_person: [839.415, 839.415] + # 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. + ca_capi_person: [849.415, 849.415] - name: Case 2, deemed income from an ineligible spouse below the couple FBR. period: 2026-01 @@ -66,8 +66,8 @@ # Under deeming: federal 1,491 - 207.50 = 1,283.50; a federal benefit is # due, so the state supplement is the couple OSS 2,098.83 - 1,491 = 607.83. # Federal = min(994, 1,283.50) = 994; state = min(239.94, 607.83) = 239.94. - # CAPI = 994 + 239.94 - 10 = 1,223.94. - ca_capi_person: [1_223.94, 0] + # CAPI = 994 + 239.94 = 1,233.94 (no offset since June 2019). + ca_capi_person: [1_233.94, 0] - name: Case 3, deemed income above the couple FBR reduces the couple state supplement. period: 2026-01 @@ -100,8 +100,8 @@ # Under deeming: 1,891 exceeds the couple FBR 1,491 by 400, so no federal # benefit; state supplement = couple OSS 607.83 - 400 = 207.83. # Federal = min(994, 0) = 0; state = min(239.94, 207.83) = 207.83. - # CAPI = 0 + 207.83 - 10 = 197.83. - ca_capi_person: [197.83, 0] + # CAPI = 0 + 207.83 = 207.83. + ca_capi_person: [207.83, 0] - name: Case 4, blind noncitizen with an ineligible spouse uses the two-blind couple rate under deeming. period: 2026-01 @@ -138,5 +138,127 @@ # exceeds the couple FBR by 600, so no federal benefit; state supplement # = 833.35 - 600 = 233.35. # Federal = 0; state = min(324.32, 233.35) = 233.35. - # CAPI = 0 + 233.35 - 10 = 223.35. - ca_capi_person: [223.35, 0] + # CAPI = 0 + 233.35 = 233.35. + ca_capi_person: [233.35, 0] + +- name: Case 5, deeming with the CAPI person's own income uses the couple federal amount. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: UNDOCUMENTED + # 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 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # 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. + # Under deeming: federal 1,491 - 1,267.50 = 223.50; a federal benefit is + # due, so the state supplement is the couple OSS 607.83. + # Federal = min(694, 223.50) = 223.50; state = min(239.94, 607.83) = + # 239.94. CAPI = 223.50 + 239.94 = 463.44. + ca_capi_person: [463.44, 0] + +- name: Case 6, mixed couple subtracts the couple's income and the spouse's SSI/SSP from the couple standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + immigration_status: CITIZEN + # SSA treats the noncitizen as an ineligible spouse whose 420 pension + # is below the 497 deeming threshold (1,491 - 994), so the citizen + # receives the individual rate with no countable income: SSI 994 + # plus state supplement 239.94 (POMS SI 01415.058). The case supplies + # these, since the model's split of the couple's SSI and income is + # being reworked separately. + ssi: 994 + ssi_countable_income: 0 + person2: + age: 68 + immigration_status: UNDOCUMENTED + # 420 per month foreign pension; countable income is 420 - 20 = 400 + # per month (4,800 per year), supplied as in Case 1. + pension_income: 5_040 + ssi_countable_income: 4_800 + marital_units: + marital_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + ca_state_supplement: 239.94 + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # The CAPI member takes the couple standard 2,098.83 (MPP 49-050.13, no + # offset since June 2019). The couple's countable income 0 + 400 (MPP + # 49-055.32) and the citizen's SSI/SSP 994 + 239.94, counted as unearned + # income based on need (MPP 49-035.221), are subtracted: + # 2,098.83 - 400 - 994 - 239.94 = 464.89. + ca_capi_payment_standard: [0, 2_098.83] + ca_capi_person: [0, 464.89] + +- name: Case 7, Title XIX facility resident is paid on own income without deeming. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 75 + immigration_status: UNDOCUMENTED + ca_in_medical_care_facility: true + # 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 + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: CA + living_arrangements_allow_for_food_preparation: true + output: + # 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 + # max(min(994 - 20, 1,491 - 587.50) + (62 - 994), 0) = 0, and subtracting + # the deemed income would give max(62 - 587.50, 0) = 0. + ca_capi_payment_standard: [62, 0] + ca_capi_person: [42, 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 accef876957..f57268bfd93 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,13 +4,14 @@ age: 70 immigration_status: UNDOCUMENTED # SSI zeroes countable income for people who fail its immigration test, - # so the case supplies it: 1,224.94 per month (14,699.28 per year). - ssi_countable_income: 14_699.28 + # so the case supplies it: 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 output: - # Standard 1,233.94 - 10 = 1,223.94. Countable income must be lower than - # the standard (MPP 49-035.1); 1,224.94 is not, so there is no CAPI. + # Standard 1,233.94 with no offset since June 2019 (WIC 18941). + # Countable income must be lower than the standard (MPP 49-035.1); + # 1,234.94 is not, so there is no CAPI. ca_capi_income_eligible: false - name: Eligible, countable income one dollar below the payment standard @@ -18,12 +19,12 @@ input: age: 70 immigration_status: UNDOCUMENTED - # Supplied as above: 1,222.94 per month (14,675.28 per year). - ssi_countable_income: 14_675.28 + # Supplied as above: 1,232.94 per month (14,795.28 per year). + ssi_countable_income: 14_795.28 living_arrangements_allow_for_food_preparation: true state_code: CA output: - # 1,222.94 is lower than the 1,223.94 standard: 1 per month of CAPI. + # 1,232.94 is lower than the 1,233.94 standard: 1 per month of CAPI. ca_capi_income_eligible: true - name: Ineligible, income deemed from a high-earning spouse exhausts the couple state supplement @@ -55,6 +56,6 @@ # 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 - # state supplement is due. Federal = 0, state = min(239.94, 0) = 0, and - # CAPI = max(0, 0 - 10) = 0 in every month. + # state supplement is due. Federal = 0, state = min(239.94, 607.83 - + # 966.50) = -358.67, and CAPI = max(0 - 358.67, 0) = 0 in every month. ca_capi_income_eligible: false diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py b/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py index 28bec390276..0be284f8a9f 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py @@ -4,18 +4,30 @@ def ca_capi_ssi_ssp_standard(person, period, parameters): """Return a person's monthly SSI/SSP individual and couple standards. - CAPI payment standards equal the SSI/SSP standards less an offset (MPP - 49-050.1). These follow ca_state_supplement_payment_standard, whose amounts - include the federal benefit rate: the higher of the blind amount and the - aged or disabled amount (the disabled child amount for a dependent child, - MPP 49-050.25; blind children take the blind amount, MPP 49-050.253), the - food allowance for an aged or disabled adult who cannot prepare meals, and - the out-of-home-care and medical-care-facility allowances per person. - In an SSI couple computation the couple standard uses both members; - otherwise it treats the ineligible spouse as the person's category (POMS - SI 01320.430 C.7) and adds only the person's own allowances. + CAPI payment standards equal the SSI/SSP standards (WIC 18941), and the + living arrangement selects one standard (MPP 49-050.2; POMS SI 01415.058 + B). These follow ca_state_supplement_payment_standard, whose amounts + include the federal benefit rate: + - Title XIX medical facility: the facility standard alone (MPP 49-050.26). + - Nonmedical out-of-home care: one standard for every category, half the + couple out-of-home care standard per person (MPP 49-050.24). + - Independent living: the higher of the blind amount and the aged or + disabled amount (the disabled child amount for a dependent child, MPP + 49-050.25; blind children take the blind amount, MPP 49-050.253). Only + the aged or disabled amount adds the food allowance for people who + cannot prepare meals (WIC 12200(e)); a couple with one blind member + adds the individual food allowance for the other member (POMS SI + 01415.058 B.1 code C). California pays the highest category a person or + couple qualifies for. + In an SSI couple computation the couple standard sums both members' + shares; otherwise it treats the ineligible spouse as the person's + category (POMS SI 01320.430 C.7). + NOTE: the reduced-needs standards for people living in another person's + household (POMS SI 01415.058 code D) are not modeled; they need their own + state supplement amounts (issue 7892). """ p = parameters(period).gov.states.ca.cdss.state_supplement.payment_standard + fbr = parameters(period).gov.ssa.ssi.amount age = person("monthly_age", period) child = person("is_tax_unit_dependent", period.this_year) & ( age < p.dependent.age_limit @@ -27,20 +39,20 @@ def ca_capi_ssi_ssp_standard(person, period, parameters): no_cooking = ~person.household( "living_arrangements_allow_for_food_preparation", period.this_year ) - allowance = ( - person("in_out_of_home_care_facility", period.this_year) - * p.allowance.out_of_home_care - + person("ca_in_medical_care_facility", period.this_year) - * p.allowance.medical_care_facility - ) - individual = ( - max_( - blind * p.blind.single, - aged_or_disabled - * where(child, p.dependent.amount, p.aged_or_disabled.amount.single), - ) - + aged_or_disabled * ~child * no_cooking * p.allowance.food.single - + allowance + medical_facility = person("ca_in_medical_care_facility", period.this_year) + out_of_home_care = person("in_out_of_home_care_facility", period.this_year) + out_of_home_care_share = ( + p.aged_or_disabled.amount.married + p.allowance.out_of_home_care + ) / 2 + + community_individual = max_( + blind * p.blind.single, + aged_or_disabled + * where( + child, + p.dependent.amount, + p.aged_or_disabled.amount.single + no_cooking * p.allowance.food.single, + ), ) joint = person("ssi_couple_computation_applies", period) @@ -48,28 +60,39 @@ def ca_capi_ssi_ssp_standard(person, period, parameters): aged_or_disabled_count = where( joint, person.marital_unit.sum(aged_or_disabled), 2 * aged_or_disabled ) - blind_amount = select( - [blind_count > 1, blind_count == 1], - [p.blind.married.two_blind, p.blind.married.one_blind], - default=0, + two_blind = (blind_count > 1) * p.blind.married.two_blind + one_blind = (blind_count == 1) * ( + p.blind.married.one_blind + no_cooking * p.allowance.food.single ) - aged_or_disabled_amount = select( + aged_or_disabled_couple = select( [aged_or_disabled_count > 1, aged_or_disabled_count == 1], - [p.aged_or_disabled.amount.married, p.aged_or_disabled.amount.single], + [ + p.aged_or_disabled.amount.married + no_cooking * p.allowance.food.married, + p.aged_or_disabled.amount.single + no_cooking * p.allowance.food.single, + ], default=0, ) - food = ( - (aged_or_disabled_count > 0) - * no_cooking - * where( - aged_or_disabled_count > 1, - p.allowance.food.married, - p.allowance.food.single, - ) + community_couple = max_(max_(two_blind, one_blind), aged_or_disabled_couple) + + # The state supplement amounts hold 1991 totals until 2025 (issue 7787), + # below the federal benefit rate from 2008. CAPI equals SSI/SSP (WIC + # 18941), and SSI alone pays at least the federal rate, so the + # independent-living and out-of-home care standards are floored at it. + individual = select( + [medical_facility, out_of_home_care], + [ + p.allowance.medical_care_facility, + max_(out_of_home_care_share, fbr.individual), + ], + default=max_(community_individual, fbr.individual), ) - couple = ( - max_(blind_amount, aged_or_disabled_amount) - + food - + where(joint, person.marital_unit.sum(allowance), allowance) + couple_share = select( + [medical_facility, out_of_home_care], + [ + p.allowance.medical_care_facility, + max_(out_of_home_care_share, fbr.couple / 2), + ], + default=max_(community_couple / 2, fbr.couple / 2), ) + couple = where(joint, person.marital_unit.sum(couple_share), 2 * couple_share) return individual, couple diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py index 3f9b820804c..78318db3cbb 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py @@ -12,16 +12,30 @@ class ca_capi_payment_standard(Variable): definition_period = MONTH defined_for = "ca_capi_eligible_person" reference = ( - # PDF pages 44-46 - "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44", + # PDF pages 3, 44-47 + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=3", "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=12200", + "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941", + "https://secure.ssa.gov/apps10/poms.nsf/lnx/0501415058", + "https://cdss.ca.gov/Portals/9/Additional-Resources/Letters-and-Notices/ACINs/2025/I-59_25.pdf#page=5", ) def formula(person, period, parameters): individual, couple = ca_capi_ssi_ssp_standard(person, period, parameters) p = parameters(period).gov.states.ca.cdss.capi.payment_standard_offset joint = person("ssi_couple_computation_applies", period) - # Each member of a couple takes half the couple standard less half the - # couple offset, so a couple with one SSI/SSP member is one half-offset - # below the SSI/SSP couple standard (MPP 49-050.12-.13). - return where(joint, (couple - p.couple) / 2, individual - p.single) + capi_members = person.marital_unit.sum( + person("ca_capi_eligible_person", period.this_year) + ) + # Each member of a CAPI couple takes one-half (MPP 49-050.12, 49-055.4). + both_capi = joint & (capi_members > 1) + # A spouse receiving SSI/SSP counts as an eligible spouse (MPP + # 49-005(e)(3)), so the CAPI member of a mixed couple takes the whole + # couple standard (MPP 49-050.13) and ca_capi_person subtracts that + # spouse's SSI/SSP. + mixed = joint & ~both_capi + return select( + [both_capi, mixed], + [(couple - p.couple) / 2, couple - p.mixed_couple], + default=individual - p.single, + ) 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 888aba48190..780c4c50c6d 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 @@ -12,27 +12,66 @@ class ca_capi_person(Variable): definition_period = MONTH defined_for = "ca_capi_eligible_person" reference = ( - # PDF pages 25, 30, 47 - "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=25", + # PDF pages 3-4, 25, 30, 47 + "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=3", + "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18940", + "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941", "https://secure.ssa.gov/poms.nsf/lnx/0501320430", + "https://www.law.cornell.edu/cfr/text/20/416.1160", ) def formula(person, period, parameters): countable_income = person("ssi_countable_income", period) payment_standard = person("ca_capi_payment_standard", period) - benefit = max_(payment_standard - countable_income, 0) + deemed_income = person("ssi_income_deemed_from_ineligible_spouse", period) + own_income = max_(countable_income - deemed_income, 0) + # Deeming needs an ineligible spouse living in the same household + # (20 CFR 416.1160(a)(1)), so a Title XIX facility resident counts + # only their own income. + medical_facility = person("ca_in_medical_care_facility", period.this_year) + income = where(medical_facility, own_income, countable_income) + # NOTE: the reduced-needs standards for another person's household are + # not modeled (issue 7892), so those recipients get the + # independent-living standard. + benefit = max_(payment_standard - income, 0) + + # Mixed couple: the spouse's SSI/SSP counts as unearned income based on + # need (MPP 49-035.221), subtracted with the couple's countable income + # from the couple standard (MPP 49-055.32). + # NOTE: an aged, blind or disabled spouse who receives neither SSI/SSP + # nor CAPI is an ineligible spouse (MPP 49-005(i)(2)), but the model has + # no spouse-to-spouse deeming for such a spouse, so this computation + # applies. That spouse's SSI/SSP is zero mainly when the couple's income + # exceeds the couple standard, which already leaves no CAPI. + capi_eligible = person("ca_capi_eligible_person", period.this_year) + joint = person("ssi_couple_computation_applies", period) + mixed = joint & ~(person.marital_unit.sum(capi_eligible) > 1) + spouse = ~capi_eligible + spouse_ssi = person.marital_unit.sum(person("ssi", period) * spouse) + # NOTE: ca_state_supplement is an SPM-unit amount; as a simplification, + # the spouse's share is pro rata among the unit's SSP-eligible members. + ssp_eligible = person("ca_state_supplement_eligible_person", period) + spouse_ssp_share = person.marital_unit.sum(ssp_eligible * spouse) / max_( + person.spm_unit.sum(ssp_eligible), 1 + ) + spouse_ssp = spouse_ssp_share * person.spm_unit("ca_state_supplement", period) + couple_income = person.marital_unit.sum(countable_income) + mixed_benefit = max_( + payment_standard - couple_income - spouse_ssi - spouse_ssp, 0 + ) # MPP 49-035.71 follows the SSI spouse-to-spouse deeming steps: compute # the federal and state parts as an individual and under deeming, then - # take the lesser of each (POMS SI 01320.430 D). + # take the lesser of each (POMS SI 01320.430 D). WIC 18940(b) applies + # the federal deeming rules and WIC 18941 makes CAPI equal SSI/SSP, + # which SSA computes this way; the 1999 CAPI form SOC 452 takes the + # lesser of the two totals instead. # NOTE: the federal parts use the independent-living benefit rates, # matching the independent-living SSI/SSP standards. individual_standard, couple_standard = ca_capi_ssi_ssp_standard( person, period, parameters ) fbr = parameters(period).gov.ssa.ssi.amount - deemed_income = person("ssi_income_deemed_from_ineligible_spouse", period) - own_income = max_(countable_income - deemed_income, 0) individual_federal = fbr.individual - own_income couple_federal = fbr.couple - countable_income federal = max_(min_(individual_federal, couple_federal), 0) @@ -45,7 +84,13 @@ def formula(person, period, parameters): ) p = parameters(period).gov.states.ca.cdss.capi.payment_standard_offset deemed_benefit = max_(federal + supplement - p.single, 0) - deeming = person("is_ssi_spousal_deeming_applies", period.this_year) & ~person( - "ssi_couple_computation_applies", period + deeming = ( + person("is_ssi_spousal_deeming_applies", period.this_year) + & ~joint + & ~medical_facility + ) + return select( + [mixed, deeming], + [mixed_benefit, deemed_benefit], + default=benefit, ) - return where(deeming, deemed_benefit, benefit) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index ab0faa5b4ec..578a4062247 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -628,6 +628,83 @@ candidates: prs: [] state: unreviewed note: Verify the legal basis for the amended-return remedy and treatment of exactly $3,000. +- id: us-ca:capi-payment-standard-offset + program: capi + years: + from: 2019 + type: calendar + question: From June 1, 2019, do CAPI payment standards equal the SSI/SSP standards, or remain $10 (individual), + $20 (CAPI couple) or $10 (couple with one SSI/SSP member) below them as the regulations state? + sources: + - kind: statute + citation: Cal. WIC §18941 + url: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941 + - kind: regulation + citation: CDSS MPP §49-050.11-.13 (Manual Letter EAS-03-09, effective 10/16/03) + url: https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=44 + - kind: guidance + citation: CDSS ACIN I-59-25, Attachment A + url: https://cdss.ca.gov/Portals/9/Additional-Resources/Letters-and-Notices/ACINs/2025/I-59_25.pdf#page=5 + readings: + statute: CAPI benefits equal SSI/SSP benefits, retroactive to June 1, 2019. + other: CAPI standards are $10 below the SSI/SSP individual standard, $20 below the couple standard for a CAPI + couple and $10 below the couple standard when the other spouse receives SSI/SSP. + example: In January 2026, an aged CAPI recipient living independently with cooking facilities and no income receives + $1,233.94 a month under the statute, which PE-US follows, and $1,223.94 under the regulation. + pe_us: + follows: statute + code: + - policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/couple.yaml + - policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/mixed_couple.yaml + - policyengine_us/parameters/gov/states/ca/cdss/capi/payment_standard_offset/single.yaml + - policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10379 + state: open + note: 'Pavel''s sign-off requested (statute against regulation). PE-US follows the statute: the three offsets are + $0 from 2019-06-01 and keep the regulation amounts before then (payment_standard_offset/*.yaml, read by + ca_capi_payment_standard.py). The 2003 regulation predates the 2019 statute; CDSS applies the statute in ACIN + I-23-19 (June 1, 2019 increase of $10 per individual and $20 per couple) and ACIN I-59-25.' +- id: us-ca:capi-spousal-deeming-method + program: capi + years: + from: 1999 + type: calendar + question: When income is deemed from an ineligible spouse, does CAPI take the lesser federal and lesser state amounts + separately, as SSA computes SSI/SSP, or the smaller of the two totals on form SOC 452? + sources: + - kind: statute + citation: Cal. WIC §18940(b) + url: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18940 + - kind: statute + citation: Cal. WIC §18941 + url: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941 + - kind: regulation + citation: CDSS MPP §49-035.71 + url: https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=30 + - kind: manual + citation: SSA POMS SI 01320.430 D + url: https://secure.ssa.gov/apps10/poms.nsf/lnx/0501320430 + - kind: form + citation: CDSS SOC 452 (4/99), CAPI Income Eligibility - Adult, line C + url: https://www.cdss.ca.gov/cdssweb/entres/forms/English/SOC452.pdf + readings: + statute: Federal deeming rules govern CAPI and CAPI benefits equal SSI/SSP benefits, which SSA computes by taking + the lesser federal amount and the lesser state supplement separately (POMS SI 01320.430 D). + other: SOC 452 pays the smaller of the couple standard less the couple's countable income and the individual standard + less the recipient's own countable income. + example: In January 2026, a CAPI recipient with no income whose ineligible spouse earns $1,200 a month receives $1,173.44 + under the statute and the POMS method, which PE-US follows, and $1,233.94 under SOC 452. + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_person.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10379 + state: unreviewed + note: 'PE-US follows the statute: ca_capi_person.py takes the lesser of the federal parts and the lesser of the + state parts (POMS SI 01320.430 D). MPP 49-035.71 points to both 20 CFR 416.1160 et seq. and SOC 452. Verify + whether CDSS still uses the 1999 form''s line C rule and the years affected.' - id: us-ca:care-fera-housing-subsidies program: care-fera years: From 771f1d850287871ef06b23d66928c86fe804278a Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 26 Oct 2026 21:39:30 -0400 Subject: [PATCH 5/7] Fix issues from review round 2: MD PAA receipt gate, CA mixed-couple tests, CAPI test pins - Maryland PAA keeps imputed SSI and spouse deeming for people who report SSI receipt - CA state supplement: mixed-couple case and the matching computed CAPI case; comment and reference fixes - CAPI tests from #10379: drop pins this PR now computes, keep the rest with accurate comments Co-Authored-By: Claude Opus 5.5 --- ...d-abd-noncitizen-countable-income.fixed.md | 2 +- .../gov/states/ca/cdss/capi/ca_capi.yaml | 72 ++++++++++++-- .../states/ca/cdss/capi/ca_capi_person.yaml | 80 +++++++-------- .../eligibility/ca_capi_income_eligible.yaml | 17 ++-- .../state_supplement/ca_state_supplement.yaml | 59 +++++++++++ .../gov/states/md/dhs/fia/paa/md_paa.yaml | 97 +++++++++++++++++++ .../state_supplement/ca_state_supplement.py | 11 ++- .../md/dhs/fia/paa/md_paa_countable_income.py | 10 +- .../dhs/fia/paa/md_paa_imputed_federal_ssi.py | 10 +- 9 files changed, 288 insertions(+), 70 deletions(-) diff --git a/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md index abfa381b4b1..cf078370c11 100644 --- a/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md +++ b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md @@ -1 +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 a CAPI-eligible member's income, and Maryland PAA no longer imputes SSI or deems spouse income for people SSI bars by alien status. +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 a CAPI-eligible member's income, and Maryland PAA no longer imputes SSI or deems spouse income for people SSI bars by alien status unless they report SSI receipt. 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 3bfcfe79c07..da240a267e9 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 @@ -8,16 +8,14 @@ immigration_status: UNDOCUMENTED # 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. @@ -159,10 +157,6 @@ immigration_status: UNDOCUMENTED # 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: UNDOCUMENTED @@ -185,6 +179,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 @@ -236,3 +232,63 @@ # 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: 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: UNDOCUMENTED + 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 + 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 treats the undocumented spouse as an ineligible spouse + # (20 CFR 416.1160(d)). Her 500 exceeds the 1,450 - 967 = 483 gap, so SSA + # deems her income and pays SSI of min(967 - 480, 1,450 - 980) = 470 and + # a state supplement of min(1,335.81 - 967, 2,315.57 - 1,450) = 368.81, + # 838.81 in all (POMS SI 01320.430 D; 20 CFR 416.1163(e)(2)). CAPI would + # then be 2,315.57 - 980 - 838.81 = 496.76 a month (5,961.12 a year). The + # model's couple computation for a mixed-status couple pays + # 235 + 610.81 = 845.81, so CAPI is 489.76 instead of 496.76. This is a + # pre-existing ssi_claim_is_joint limitation: it counts aged, blind or + # disabled head/spouse status rather than SSI eligibility. The expected + # values below are the model's. + 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 his own 490: + # 610.81 a month. The CAPI member's 490 is not counted. + ca_state_supplement: 7_329.72 # 610.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 + 610.81, counted as unearned income based on + # need (MPP 49-035.221), are subtracted: + # 2,315.57 - 980 - 235 - 610.81 = 489.76 a month. + ca_capi_person: [0, 5_877.12] # 489.76 * 12 + ca_capi: 5_877.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 00789c189c0..f0f2032f5f6 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 @@ -8,15 +8,9 @@ immigration_status: UNDOCUMENTED # 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: UNDOCUMENTED - ssi_countable_income: 2_400 marital_units: marital_unit: members: [person1, person2] @@ -26,6 +20,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. @@ -39,15 +36,6 @@ person1: age: 70 immigration_status: UNDOCUMENTED - # 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 @@ -60,6 +48,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. @@ -77,12 +72,6 @@ person1: age: 70 immigration_status: UNDOCUMENTED - # 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 @@ -95,6 +84,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 @@ -112,12 +106,6 @@ age: 45 is_blind: true immigration_status: UNDOCUMENTED - # 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 @@ -130,6 +118,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. @@ -152,13 +145,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 @@ -171,6 +157,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. @@ -199,8 +191,11 @@ person2: age: 68 immigration_status: UNDOCUMENTED - # 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: @@ -236,13 +231,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 @@ -255,6 +243,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 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 f57268bfd93..1c32531ffba 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 @@ -3,8 +3,8 @@ input: age: 70 immigration_status: UNDOCUMENTED - # 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 @@ -34,13 +34,6 @@ person1: age: 70 immigration_status: UNDOCUMENTED - # 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 @@ -53,6 +46,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 eac4ce30dd6..18063ca4609 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 @@ -409,3 +409,62 @@ # 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. The model leaves the CAPI member's half out +# of the citizen's state supplement because CAPI budgets the couple's income +# (MPP 49-055.32), and the citizen's own half is already in his countable +# 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 treats the undocumented spouse as an ineligible spouse (20 CFR +# 416.1160(d)). Her 500 exceeds the 1,450 - 967 = 483 gap, so SSA deems her +# income and pays SSI of min(967 - 480, 1,450 - 980) = 470 and a state +# supplement of min(1,335.81 - 967, 2,315.57 - 1,450) = 368.81, 838.81 in +# all (POMS SI 01320.430 D; 20 CFR 416.1163(e)(2)). The model's couple +# computation for a mixed-status couple pays 235 + 610.81 = 845.81, so CAPI +# is 489.76 instead of 496.76. This is a pre-existing ssi_claim_is_joint +# limitation: it counts aged, blind or disabled head/spouse status rather +# than SSI eligibility. The expected values below are the model's. +- name: Case 11, 2025 aged citizen married to a CAPI-eligible spouse, whose half of the couple's income is not counted. + 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: UNDOCUMENTED + 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 + 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, and living_arrangements_allow_for_food_preparation + # defaults to false, 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 - 235 - 490 = 610.81 a month; person2's 490 + # is not counted. + ca_state_supplement: 7_329.72 # 610.81 * 12 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 a5d9e9b3abf..563dc032b89 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 @@ -261,3 +261,100 @@ # 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 keeps the SSI +# treatment, so person2's wages are deemed to her and the imputed federal SSI +# uses the couple rate, the same cascade as for a citizen. 2025-01: federal +# SSI couple rate $1,450 and individual rate $967; provider rate $1,376; +# PNA $102. +# NOTE: SSI under deeming cannot exceed the amount computed on her own income +# alone, so SSA would pay min(967 - 480, 1,450 - 947.50) = 487 (20 CFR +# 416.1163(e)(2)), and COMAR 07.03.07.09A would give 1,478 - 480 - 487 = 511. +# The 28 below reflects the existing uncapped couple-rate imputation and +# spousal deeming, which also apply to citizens. +- 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] + # Reported SSI receipt keeps the deemed amount: 480 + 467.50 = 947.50. + # person2's own countable wages are (1,000 - 20 - 65) x 0.5 = 457.50. + md_paa_countable_income: [947.50, 457.50] + # Deeming applies, so person1's federal amount is the couple rate. + ssi_amount_if_eligible: [1_450, 967] + # 1,450 - 947.50 = 502.50. + md_paa_imputed_federal_ssi: [502.50, 0] + # combined_need = 1,376 + 102 = 1,478. + md_paa_total_cost_of_care: [1_478, 0] + # PAA = 1,478 - 947.50 - 502.50 = 28. + md_paa: [28, 0] 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 275e0e084a3..e9cda34fda1 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 @@ -11,16 +11,19 @@ class ca_state_supplement(Variable): 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.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"]) person = spm_unit.members - # 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)), so a CAPI-eligible member's income does not - # reduce the state supplement. + # 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). A spouse's income already reaches the SSI + # recipient's own countable income through the couple computation or + # deeming, so a CAPI-eligible member's countable income is not added + # again. capi_eligible = person("ca_capi_eligible_person", period.this_year) person_countable_income = person("ssi_countable_income", period) countable_income = spm_unit.sum( 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 7e63fa527a4..7a8f5f18697 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 @@ -48,13 +48,17 @@ def formula(person, period, parameters): # COMAR 07.03.07.07 counts the individual's own income and has no # spousal deeming. The SSI cascade deems spouse income only to people # SSA can pay, so people who fail SSI's citizen or qualified-noncitizen - # test count their own income alone. + # test count their own income alone. A person who reports SSI receipt + # (for example one SSA pays under an exception the model does not + # encode such as 8 U.S.C. 1612(a)(2)(E)) keeps the SSI treatment, + # matching md_paa_imputed_federal_ssi. 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 + reports_ssi = add(person, period, ["receives_ssi"]) > 0 + not_barred_from_ssi = is_citizen | is_qualified_noncitizen | reports_ssi spousal_deemed = where( - meets_ssi_immigration_test, + not_barred_from_ssi, person("ssi_income_deemed_from_ineligible_spouse", period), 0, ) 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 b999e4f1c67..ec202c4fb81 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 @@ -21,10 +21,16 @@ def formula(person, period, parameters): # 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). + # (COMAR 07.03.07.09A). A person who reports SSI receipt, for example + # one SSA pays under an exception the model does not encode such as + # 8 U.S.C. 1612(a)(2)(E), keeps the imputed SSI. The repository's SSI + # receipt convention is (ssi > 0) | receives_ssi, and ssi > 0 already + # implies the citizen or qualified-noncitizen test. 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 ) - return where(is_citizen | is_qualified_noncitizen, imputed_ssi, 0) + reports_ssi = person("receives_ssi", period) + not_barred_from_ssi = is_citizen | is_qualified_noncitizen | reports_ssi + return where(not_barred_from_ssi, imputed_ssi, 0) From a7def30d37de14b83b047112e0640766dc6ba67b Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 26 Oct 2026 22:15:51 -0400 Subject: [PATCH 6/7] Keep Maryland PAA free of spouse deeming for SSI reporters barred by alien status COMAR 07.03.07.07 counts the individual's own income; only the imputed SSI keeps the receipt exception. Drop md_paa.yaml Case 13, which codified the deeming. Co-Authored-By: Claude Opus 5.5 --- ...d-abd-noncitizen-countable-income.fixed.md | 2 +- .../gov/states/md/dhs/fia/paa/md_paa.yaml | 60 ------------------- .../md/dhs/fia/paa/md_paa_countable_income.py | 11 ++-- 3 files changed, 5 insertions(+), 68 deletions(-) diff --git a/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md index cf078370c11..646ff7ccf9a 100644 --- a/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md +++ b/changelog.d/medicaid-abd-noncitizen-countable-income.fixed.md @@ -1 +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 a CAPI-eligible member's income, and Maryland PAA no longer imputes SSI or deems spouse income for people SSI bars by alien status unless they report SSI receipt. +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 a CAPI-eligible member's income, and Maryland PAA no longer deems spouse income to people SSI bars by alien status and imputes SSI to them only if they report SSI receipt. 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 563dc032b89..a93510da563 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 @@ -298,63 +298,3 @@ 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 keeps the SSI -# treatment, so person2's wages are deemed to her and the imputed federal SSI -# uses the couple rate, the same cascade as for a citizen. 2025-01: federal -# SSI couple rate $1,450 and individual rate $967; provider rate $1,376; -# PNA $102. -# NOTE: SSI under deeming cannot exceed the amount computed on her own income -# alone, so SSA would pay min(967 - 480, 1,450 - 947.50) = 487 (20 CFR -# 416.1163(e)(2)), and COMAR 07.03.07.09A would give 1,478 - 480 - 487 = 511. -# The 28 below reflects the existing uncapped couple-rate imputation and -# spousal deeming, which also apply to citizens. -- 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] - # Reported SSI receipt keeps the deemed amount: 480 + 467.50 = 947.50. - # person2's own countable wages are (1,000 - 20 - 65) x 0.5 = 457.50. - md_paa_countable_income: [947.50, 457.50] - # Deeming applies, so person1's federal amount is the couple rate. - ssi_amount_if_eligible: [1_450, 967] - # 1,450 - 947.50 = 502.50. - md_paa_imputed_federal_ssi: [502.50, 0] - # combined_need = 1,376 + 102 = 1,478. - md_paa_total_cost_of_care: [1_478, 0] - # PAA = 1,478 - 947.50 - 502.50 = 28. - md_paa: [28, 0] 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 7a8f5f18697..37e2e23bcdf 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 @@ -48,17 +48,14 @@ def formula(person, period, parameters): # COMAR 07.03.07.07 counts the individual's own income and has no # spousal deeming. The SSI cascade deems spouse income only to people # SSA can pay, so people who fail SSI's citizen or qualified-noncitizen - # test count their own income alone. A person who reports SSI receipt - # (for example one SSA pays under an exception the model does not - # encode such as 8 U.S.C. 1612(a)(2)(E)) keeps the SSI treatment, - # matching md_paa_imputed_federal_ssi. + # test count their own income alone, including those who report SSI + # receipt: PAA itself has no spousal deeming. immigration_status = person("immigration_status", period) is_citizen = immigration_status == immigration_status.possible_values.CITIZEN is_qualified_noncitizen = person("is_ssi_qualified_noncitizen", period) - reports_ssi = add(person, period, ["receives_ssi"]) > 0 - not_barred_from_ssi = is_citizen | is_qualified_noncitizen | reports_ssi + meets_ssi_immigration_test = is_citizen | is_qualified_noncitizen spousal_deemed = where( - not_barred_from_ssi, + meets_ssi_immigration_test, person("ssi_income_deemed_from_ineligible_spouse", period), 0, ) From 31fb952c291dce8c18f0317c43aa34060d79b0f4 Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 26 Oct 2026 22:52:04 -0400 Subject: [PATCH 7/7] Follow WIC 12200(e) for the blind-couple food allowance; mark the pre-2025 floor a stopgap; LPR test personas - One-blind couple rate adds no food allowance (WIC 12200(b), (e)); candidates item us-ca:ssp-blind-couple-food-allowance (unreviewed) - Floor comment and pinned pre-2025 cases say the values are known-low; issue 10480 backfills the totals - Mixed-couple note gives the ineligible-spouse example (issue 10481) - CAPI test personas are aged permanent residents with 39 quarters (issue 10482) - PDF page comments without spaces Co-Authored-By: Claude Opus 5.5 --- .../gov/states/ca/cdss/capi/ca_capi.yaml | 30 ++++--- .../cdss/capi/ca_capi_payment_standard.yaml | 85 ++++++++++++------- .../states/ca/cdss/capi/ca_capi_person.yaml | 24 ++++-- .../eligibility/ca_capi_eligible_person.yaml | 8 +- .../eligibility/ca_capi_income_eligible.yaml | 9 +- .../ca/cdss/capi/_ca_capi_ssi_ssp_standard.py | 27 +++--- .../ca/cdss/capi/ca_capi_payment_standard.py | 2 +- .../gov/states/ca/cdss/capi/ca_capi_person.py | 14 +-- .../eligibility/ca_capi_eligible_person.py | 2 +- source_conflicts/candidates.yaml | 35 ++++++++ 10 files changed, 165 insertions(+), 71 deletions(-) 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 7ddbe20a697..f95d3d4c450 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 @@ -5,7 +5,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 # 520 per month foreign pension. pension_income: 6_240 # SSI zeroes countable income for people who fail its immigration @@ -30,10 +31,12 @@ people: person1: age: 72 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] @@ -88,7 +91,7 @@ ca_state_supplement: 0 ca_capi: 0 -- name: Integration test, undocumented +- name: Integration test, permanent resident without 40 SSI quarters period: 2026 absolute_error_margin: 0.01 input: @@ -98,7 +101,8 @@ employment_income: 1_000 is_disabled: true meets_ssi_disability_criteria: true - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 10 employment_income: 0 @@ -130,7 +134,8 @@ immigration_status: CITIZEN person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] @@ -156,7 +161,8 @@ people: person1: age: 72 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + 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 @@ -165,7 +171,8 @@ ssi_countable_income: 18_000 person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 tax_units: tax_unit1: members: [person1] @@ -199,7 +206,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 households: household: members: [person1] @@ -209,6 +217,8 @@ # The state supplement parameters hold the 1991 aged amount of 630 until # 2025 (issue 7787). CAPI equals SSI/SSP (WIC 18941), so the standard is # floored at the 2024 federal benefit rate: max(630, 943) = 943 per - # month with no offset and no income; 943 x 12 = 11,316. + # month with no offset and no income; 943 x 12 = 11,316. This pins a + # known-low value from the stopgap floor: the published aged standard was + # 1,182.94 (POMS SI 01415.056); issue 10480 removes the floor. ca_capi_person: 11_316 ca_capi: 11_316 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml index 14389061408..17de1047ca5 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/ca_capi_payment_standard.yaml @@ -5,7 +5,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 households: household: members: [person1] @@ -24,7 +25,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 households: household: members: [person1] @@ -44,7 +46,8 @@ person1: age: 40 is_blind: true - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 households: household: members: [person1] @@ -63,10 +66,12 @@ people: person1: age: 72 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] @@ -88,10 +93,12 @@ people: person1: age: 72 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] @@ -112,11 +119,13 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 60 is_blind: true - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] @@ -141,7 +150,8 @@ immigration_status: CITIZEN person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] @@ -164,7 +174,8 @@ people: person1: age: 75 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 ca_in_medical_care_facility: true households: household: @@ -185,7 +196,8 @@ people: person1: age: 75 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 in_out_of_home_care_facility: true households: household: @@ -206,7 +218,8 @@ person1: age: 70 is_blind: true - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 households: household: members: [person1] @@ -225,12 +238,14 @@ people: person1: age: 40 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 10 is_disabled: true meets_ssi_disability_criteria: true - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit1: members: [person1] @@ -253,11 +268,13 @@ people: person1: age: 40 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 10 is_blind: true - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit1: members: [person1] @@ -272,18 +289,20 @@ # A blind child takes the blind amount, 1,318.32 (MPP 49-050.253). ca_capi_payment_standard: [0, 1_318.32] -- name: Case 13, aged couple with one blind member without cooking adds the individual food allowance. +- name: Case 13, aged couple with one blind member without cooking takes the aged couple rate with the food allowance. period: 2026-01 absolute_error_margin: 0.01 input: people: person1: age: 72 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 70 is_blind: true - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] @@ -293,11 +312,13 @@ state_code: CA living_arrangements_allow_for_food_preparation: false output: - # POMS SI 01415.058 code C note: the blind/aged couple level plus the - # individual restaurant allowance, 2,238.44 + 128.87 = 2,367.31. This - # beats the aged couple without cooking, 2,098.83 + 257.74 = 2,356.57. - # One-half each: 2,367.31 / 2 = 1,183.655. - ca_capi_payment_standard: [1_183.655, 1_183.655] + # WIC 12200(e) gives the food allowance only to an aged or disabled + # individual or couple (12200(c), (d)), so the one-blind couple rate + # (12200(b)) adds none: 2,238.44. Both spouses are aged, so the aged + # couple rate without cooking also applies: 2,098.83 + 257.74 = 2,356.57, + # the higher. One-half each: 2,356.57 / 2 = 1,178.285. POMS SI 01415.058 + # code C would add 128.87 to the one-blind rate instead (2,367.31). + ca_capi_payment_standard: [1_178.285, 1_178.285] - name: Case 14, 2024 independent-living standard is floored at the federal benefit rate. period: 2024-01 @@ -306,7 +327,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 households: household: members: [person1] @@ -315,7 +337,10 @@ output: # The state supplement parameters hold the 1991 aged amount of 630 until # 2025 (issue 7787), below the 2024 federal benefit rate of 943. CAPI - # equals SSI/SSP (WIC 18941), so the standard is max(630, 943) = 943. + # equals SSI/SSP (WIC 18941), so the stopgap floor gives max(630, 943) = + # 943. This pins a known-low value: the published January 2024 aged + # standard is 943 + 239.94 = 1,182.94 (POMS SI 01415.056); issue 10480 + # backfills the totals and removes the floor. ca_capi_payment_standard: 943 - name: Case 15, the 10 individual offset applies through May 2019 and ends in June 2019. @@ -325,7 +350,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 households: household: members: [person1] @@ -335,7 +361,8 @@ # The state supplement parameters hold the 1991 aged amount of 630 until # 2025 (issue 7787), so the model floors the standard at the 2019 federal # benefit rate: max(630, 771) = 771. The actual 2019 SSI/SSP standard was - # 931.72 (ACIN I-23-19). This case pins only the offset boundary: + # 931.72 (ACIN I-23-19), so these are known-low values from the stopgap + # floor (issue 10480). This case pins only the offset boundary: # 771 - 10 = 761 through May 2019 (MPP 49-050.11) and 771 - 0 = 771 from # June 1, 2019 (WIC 18941). ca_capi_payment_standard: 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 00789c189c0..07d06ea9b8e 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 @@ -5,7 +5,8 @@ people: person1: age: 72 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 # 420 per month foreign pension. pension_income: 5_040 # SSI zeroes countable income for people who fail its immigration @@ -15,7 +16,8 @@ ssi_countable_income: 2_400 person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 ssi_countable_income: 2_400 marital_units: marital_unit: @@ -38,7 +40,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + 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 @@ -76,7 +79,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + 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. @@ -111,7 +115,8 @@ person1: age: 45 is_blind: true - immigration_status: UNDOCUMENTED + 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. @@ -148,7 +153,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 # 320 per month foreign pension; own countable income is 320 - 20 = # 300 per month. pension_income: 3_840 @@ -198,7 +204,8 @@ ssi_countable_income: 0 person2: age: 68 - immigration_status: UNDOCUMENTED + 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. pension_income: 5_040 @@ -231,7 +238,8 @@ people: person1: age: 75 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 ca_in_medical_care_facility: true # 40 per month foreign pension; own countable income is 40 - 20 = 20 # per month. diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml index 287beb1cab9..cfde31c565e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.yaml @@ -26,16 +26,18 @@ output: ca_capi_eligible_person: true -- name: Eligible couple - both spouses aged and undocumented +- name: Eligible couple - both spouses aged permanent residents without 40 SSI quarters period: 2026 input: people: person1: age: 72 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 person2: age: 68 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 marital_units: marital_unit: members: [person1, person2] 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 f57268bfd93..909d90394e9 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 @@ -2,7 +2,8 @@ period: 2026 input: age: 70 - immigration_status: UNDOCUMENTED + 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). ssi_countable_income: 14_819.28 @@ -18,7 +19,8 @@ period: 2026 input: age: 70 - immigration_status: UNDOCUMENTED + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi_qualifying_quarters_earnings: 39 # Supplied as above: 1,232.94 per month (14,795.28 per year). ssi_countable_income: 14_795.28 living_arrangements_allow_for_food_preparation: true @@ -33,7 +35,8 @@ people: person1: age: 70 - immigration_status: UNDOCUMENTED + 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 diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py b/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py index 0be284f8a9f..33ea748fdf3 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py @@ -15,9 +15,11 @@ def ca_capi_ssi_ssp_standard(person, period, parameters): disabled amount (the disabled child amount for a dependent child, MPP 49-050.25; blind children take the blind amount, MPP 49-050.253). Only the aged or disabled amount adds the food allowance for people who - cannot prepare meals (WIC 12200(e)); a couple with one blind member - adds the individual food allowance for the other member (POMS SI - 01415.058 B.1 code C). California pays the highest category a person or + cannot prepare meals, for an individual under WIC 12200(c) or a couple + under 12200(d) (WIC 12200(e)), so the one-blind couple rate under + 12200(b) adds none. POMS SI 01415.058 B.1 code C adds the individual + allowance for the aged or disabled member of such a couple; the code + follows the statute. California pays the highest category a person or couple qualifies for. In an SSI couple computation the couple standard sums both members' shares; otherwise it treats the ineligible spouse as the person's @@ -36,9 +38,14 @@ def ca_capi_ssi_ssp_standard(person, period, parameters): aged_or_disabled = (age >= p.aged_or_disabled.age_threshold) | person( "is_ssi_disabled", period.this_year ) + # NOTE: living_arrangements_allow_for_food_preparation has no default + # value, so unless it is set every aged or disabled person gets the + # no-cooking allowance. no_cooking = ~person.household( "living_arrangements_allow_for_food_preparation", period.this_year ) + # NOTE: the Title XIX standard reads ca_in_medical_care_facility, while + # SSI reads ssi_federal_living_arrangement; the two inputs can disagree. medical_facility = person("ca_in_medical_care_facility", period.this_year) out_of_home_care = person("in_out_of_home_care_facility", period.this_year) out_of_home_care_share = ( @@ -61,9 +68,7 @@ def ca_capi_ssi_ssp_standard(person, period, parameters): joint, person.marital_unit.sum(aged_or_disabled), 2 * aged_or_disabled ) two_blind = (blind_count > 1) * p.blind.married.two_blind - one_blind = (blind_count == 1) * ( - p.blind.married.one_blind + no_cooking * p.allowance.food.single - ) + one_blind = (blind_count == 1) * p.blind.married.one_blind aged_or_disabled_couple = select( [aged_or_disabled_count > 1, aged_or_disabled_count == 1], [ @@ -74,10 +79,12 @@ def ca_capi_ssi_ssp_standard(person, period, parameters): ) community_couple = max_(max_(two_blind, one_blind), aged_or_disabled_couple) - # The state supplement amounts hold 1991 totals until 2025 (issue 7787), - # below the federal benefit rate from 2008. CAPI equals SSI/SSP (WIC - # 18941), and SSI alone pays at least the federal rate, so the - # independent-living and out-of-home care standards are floored at it. + # Stopgap: the state supplement amounts hold 1991 totals until 2025, + # below the federal benefit rate from 2008, so the independent-living and + # out-of-home care standards are floored at that rate (SSI alone pays at + # least it, and CAPI equals SSI/SSP under WIC 18941). This still leaves + # out the whole state supplement before 2025; issue 10480 backfills the + # totals and removes the floor. individual = select( [medical_facility, out_of_home_care], [ diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py index 78318db3cbb..7ec5a717150 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/ca_capi_payment_standard.py @@ -12,7 +12,7 @@ class ca_capi_payment_standard(Variable): definition_period = MONTH defined_for = "ca_capi_eligible_person" reference = ( - # PDF pages 3, 44-47 + # PDF pages 3,44-47 "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=3", "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=12200", "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941", 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 780c4c50c6d..e2fc0094e39 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 @@ -12,7 +12,7 @@ class ca_capi_person(Variable): definition_period = MONTH defined_for = "ca_capi_eligible_person" reference = ( - # PDF pages 3-4, 25, 30, 47 + # PDF pages 3-4,25,30,47 "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=3", "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18940", "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=18941", @@ -38,11 +38,13 @@ def formula(person, period, parameters): # Mixed couple: the spouse's SSI/SSP counts as unearned income based on # need (MPP 49-035.221), subtracted with the couple's countable income # from the couple standard (MPP 49-055.32). - # NOTE: an aged, blind or disabled spouse who receives neither SSI/SSP - # nor CAPI is an ineligible spouse (MPP 49-005(i)(2)), but the model has - # no spouse-to-spouse deeming for such a spouse, so this computation - # applies. That spouse's SSI/SSP is zero mainly when the couple's income - # exceeds the couple standard, which already leaves no CAPI. + # NOTE: the model applies this computation whenever both spouses are + # aged, blind or disabled (ssi_couple_computation_applies ignores SSI's + # noncitizen test), even when SSA would pay the spouse nothing. Such a + # spouse is an ineligible spouse (MPP 49-005(i)(2); 20 CFR 416.1160(d)) + # and deeming applies. Example, January 2026: a citizen with $1,300 of + # Social Security and a CAPI spouse with no income get $818.83 a month + # in the model; the law gives $450.94 of CAPI alone (issue 10481). capi_eligible = person("ca_capi_eligible_person", period.this_year) joint = person("ssi_couple_computation_applies", period) mixed = joint & ~(person.marital_unit.sum(capi_eligible) > 1) diff --git a/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py b/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py index ea946c5b4ea..7cb73540e17 100644 --- a/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py +++ b/policyengine_us/variables/gov/states/ca/cdss/capi/eligibility/ca_capi_eligible_person.py @@ -7,7 +7,7 @@ class ca_capi_eligible_person(Variable): label = "California CAPI eligible person" definition_period = YEAR defined_for = StateCode.CA - # PDF pages 10, 47 + # PDF pages 10,47 reference = ( "https://www.cdss.ca.gov/Portals/9/CAPI/CAPI_Regulations-Accessible.pdf#page=10" ) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 578a4062247..358057a2e75 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -1114,6 +1114,41 @@ candidates: state: unreviewed note: 'The rule requires statutory timing rather than the model''s 2025-11-01 proxy; verify commencement and authorized transitions before changing it. Code not yet on main: is_snap_sua_hr1_in_effect, snap_utility_allowance_type.' +- id: us-ca:ssp-blind-couple-food-allowance + program: ssi-ssp + years: + from: 2025 + type: calendar + question: Does a California couple paid the one-blind couple rate get the no-cooking food allowance for its aged + or disabled member? + sources: + - kind: statute + citation: Cal. WIC §12200(b), (e) + url: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=WIC§ionNum=12200 + - kind: manual + citation: SSA POMS SI 01415.058 B.1, code C note + url: https://secure.ssa.gov/apps10/poms.nsf/lnx/0501415058 + - kind: guidance + citation: CDSS ACIN I-59-25, Attachment A + url: https://cdss.ca.gov/Portals/9/Additional-Resources/Letters-and-Notices/ACINs/2025/I-59_25.pdf#page=5 + readings: + statute: The allowance goes only to an aged or disabled individual (12200(c)) or a couple both aged or disabled + (12200(d)), so a couple under the one-blind rate (12200(b)) gets none. + other: POMS adds the individual restaurant meals allowance for the aged or disabled member of a couple with one + blind member whose living arrangement lacks cooking facilities. + example: In January 2026, a couple of an aged person and a blind person aged 50 without cooking facilities has a + $2,238.44 standard under the statute, which PE-US follows for CAPI, and $2,367.31 under POMS. + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/ca/cdss/capi/_ca_capi_ssi_ssp_standard.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10379 + state: unreviewed + note: 'PE-US follows the statute for CAPI: _ca_capi_ssi_ssp_standard.py adds no food allowance to the one-blind + couple rate, and a couple both aged or disabled takes the aged or disabled rate with the couple allowance when + that is higher. The ACIN I-59-25 table lists no such combination. Check how ca_state_supplement_food_allowance + treats these couples.' - id: us-ca:ssp-nmohc-couple-standard program: ssi-ssp years: