diff --git a/changelog.d/ca-snap-zero-allotment.fixed.md b/changelog.d/ca-snap-zero-allotment.fixed.md new file mode 100644 index 00000000000..2d21035a74d --- /dev/null +++ b/changelog.d/ca-snap-zero-allotment.fixed.md @@ -0,0 +1 @@ +Apply California's zero-allotment participation screen to SNAP households of three or more while preserving Modified Categorical Eligibility's net-income waiver and smaller households' minimum allotments. diff --git a/changelog.d/fix-ca-mce-net-income-test.fixed.md b/changelog.d/fix-ca-mce-net-income-test.fixed.md new file mode 100644 index 00000000000..e13016530b1 --- /dev/null +++ b/changelog.d/fix-ca-mce-net-income-test.fixed.md @@ -0,0 +1 @@ +Remove the SNAP net income test from California's broad-based categorical eligibility (CalFresh Modified Categorical Eligibility) for households with and without elderly or disabled members, per CDSS ACLs 12-62, 13-32, 14-56 and 15-42. diff --git a/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/hheod.yaml b/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/hheod.yaml index 85355ff472d..8326c5f22b7 100644 --- a/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/hheod.yaml +++ b/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/hheod.yaml @@ -5,7 +5,16 @@ AL: AZ: 2015-10-01: false CA: - 2015-10-01: true + # Elderly or disabled households with gross income at or below 200% of the + # poverty line are conferred MCE like any other household, and MCE has no + # net income test (CDSS ACL 13-32 note; ACL 15-42). Those above 200% are + # not MCE and face the regular net income and resource tests instead, + # which gross_hheod.yaml routes them to. + # ACL 11-11 expanded MCE to all non-assistance CalFresh households on + # 2011-02-01. Retain 2015-10-01 as this model's BBCE baseline, matching + # the surrounding California gross, asset, and poverty-year parameters; + # this flag alone does not establish modeled eligibility in 2011. + 2015-10-01: false CO: 2015-10-01: true 2024-07-01: false @@ -104,5 +113,23 @@ metadata: href: https://www.snapscreener.com/?p=table - title: USDA ERS SNAP Policy Database (bbce_elddisinclmt column, Jan 1996 - Dec 2020) href: https://www.ers.usda.gov/data-products/snap-policy-data-sets + - title: CDSS All County Letter 13-32, MCE/BBCE and elderly/disabled CalFresh households + href: https://www.cdss.ca.gov/lettersnotices/EntRes/getinfo/acl/2013/13-32.pdf#page=3 + - title: "CDSS All County Letter 14-56, CalFresh Modified Categorical Eligibility #page 2,4" + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-56.pdf#page=2 + - title: CDSS All County Letter 14-63, CalFresh households eligible but entitled to no benefits + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-63.pdf#page=2 + - title: CDSS All County Letter 15-42, MCE gross income limit and income reporting thresholds + href: https://www.cdss.ca.gov/lettersnotices/EntRes/getinfo/acl/2015/15-42.pdf#page=4 + - title: CDSS Manual of Policies and Procedures 63-409.1, requirements for participation + href: https://www.cdss.ca.gov/ord/entres/getinfo/pdf/fsman04b.pdf#page=34 + - title: CDSS June 30, 2014 letter, CalFresh Modified Categorical Eligibility + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/coletters/calfreshmodifiedcategoricaleligibility.pdf#page=3 + - title: CDSS All County Letter 11-11, statewide expansion of MCE to all NACF households + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2011/11-11.pdf#page=1 + - title: 7 CFR 273.2(j)(2)(xi), categorical eligibility exemptions + href: https://www.law.cornell.edu/cfr/text/7/273.2#j_2_xi + - title: 7 CFR 273.9(a), income eligibility standards + href: https://www.law.cornell.edu/cfr/text/7/273.9#a breakdown: - state_code diff --git a/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/non_hheod.yaml b/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/non_hheod.yaml index bd3e7e648b3..84604db8095 100644 --- a/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/non_hheod.yaml +++ b/policyengine_us/parameters/gov/hhs/tanf/non_cash/income_limit/net_applies/non_hheod.yaml @@ -5,7 +5,18 @@ AL: AZ: 2015-10-01: false CA: - 2015-10-01: true + # CalFresh Modified Categorical Eligibility (MCE) has no net income test. + # An MCE household of three or more receives the allotment the issuance + # table gives for its net income, even above the net standard, and a + # household of one or two receives the minimum allotment (CDSS ACL 12-62, + # examples 4-5; ACL 14-56; ACL 15-42). Zero-allotment households of three + # or more are denied for that reason, not for failing a net test + # (ACL 14-63). + # ACL 11-11 expanded MCE to all non-assistance CalFresh households on + # 2011-02-01. Retain 2015-10-01 as this model's BBCE baseline, matching + # the surrounding California gross, asset, and poverty-year parameters; + # this flag alone does not establish modeled eligibility in 2011. + 2015-10-01: false CO: 2015-10-01: true 2024-07-01: false @@ -102,5 +113,23 @@ metadata: href: https://www.snapscreener.com/?p=table - title: USDA ERS SNAP Policy Database (bbce_inclmt column, Jan 1996 - Dec 2020) href: https://www.ers.usda.gov/data-products/snap-policy-data-sets + - title: "CDSS All County Letter 12-62, examples of MCE/BBCE households for CalFresh #page 4-5" + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2012/12-62.pdf#page=4 + - title: CDSS All County Letter 14-56, CalFresh Modified Categorical Eligibility + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-56.pdf#page=4 + - title: CDSS All County Letter 14-63, CalFresh households eligible but entitled to no benefits + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-63.pdf#page=2 + - title: CDSS All County Letter 15-42, MCE gross income limit and income reporting thresholds + href: https://www.cdss.ca.gov/lettersnotices/EntRes/getinfo/acl/2015/15-42.pdf#page=4 + - title: CDSS Manual of Policies and Procedures 63-409.1, requirements for participation + href: https://www.cdss.ca.gov/ord/entres/getinfo/pdf/fsman04b.pdf#page=34 + - title: CDSS June 30, 2014 letter, CalFresh Modified Categorical Eligibility + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/coletters/calfreshmodifiedcategoricaleligibility.pdf#page=3 + - title: CDSS All County Letter 11-11, statewide expansion of MCE to all NACF households + href: https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2011/11-11.pdf#page=1 + - title: 7 CFR 273.2(j)(2)(xi), categorical eligibility exemptions + href: https://www.law.cornell.edu/cfr/text/7/273.2#j_2_xi + - title: 7 CFR 273.9(a), income eligibility standards + href: https://www.law.cornell.edu/cfr/text/7/273.9#a breakdown: - state_code diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/tanf/non_cash/meets_tanf_non_cash_net_income_test.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/tanf/non_cash/meets_tanf_non_cash_net_income_test.yaml index 8b0d0459554..aa355e00676 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/tanf/non_cash/meets_tanf_non_cash_net_income_test.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/tanf/non_cash/meets_tanf_non_cash_net_income_test.yaml @@ -1,30 +1,37 @@ -- name: Default household meets California's BBCE net income test (100%). +# California's Modified Categorical Eligibility (MCE) has no net income +# test (CDSS ACL 12-62, ACL 13-32, ACL 14-56, ACL 15-42), so the cases on the +# mechanics of the net standard use Rhode Island, whose BBCE keeps the net +# test for both household types. +- name: Default California household meets the BBCE net income test because MCE has none. period: 2022 output: meets_tanf_non_cash_net_income_test: true -- name: California household with net income exactly at the standard meets the net income test. +- name: Rhode Island household with net income exactly at the standard meets the net income test. period: 2022 input: snap_fpg: 12_000 snap_net_income: 12_000 + state_code: RI output: # Monthly standard is ceil(1.0 x 1,000) = 1,000; net income of 1,000 # per month is exactly at it. meets_tanf_non_cash_net_income_test: true -- name: California household with net income above the standard fails the net income test. +- name: Rhode Island household with net income above the standard fails the net income test. period: 2022 input: snap_fpg: 12_000 snap_net_income: 12_120 + state_code: RI output: # Net income of 1,010 per month exceeds the 1,000 standard. meets_tanf_non_cash_net_income_test: false -- name: California household at the rounded-up whole-dollar standard meets the net income test. +- name: Rhode Island household at the rounded-up whole-dollar standard meets the net income test. period: 2022 input: + state_code: RI # Monthly poverty guideline of 2,220.83 yields a whole-dollar standard # of ceil(2,220.83) = 2,221, so a rounded net income of exactly 2,221 # still passes; a raw ratio comparison (2,221 / 2,220.83 > 1) would @@ -34,7 +41,7 @@ output: meets_tanf_non_cash_net_income_test: true -- name: California nine-person household at the published FY 2026 net standard meets the net income test. +- name: Rhode Island nine-person household at the published FY 2026 net standard meets the net income test. period: 2026-01 input: people: @@ -50,11 +57,11 @@ households: household: members: [person1] - state_code: CA + state_code: RI output: meets_tanf_non_cash_net_income_test: true -- name: California nine-person household just above the FY 2026 net standard fails the net income test. +- name: Rhode Island nine-person household just above the FY 2026 net standard fails the net income test. period: 2026-01 input: people: @@ -70,9 +77,75 @@ # $4,972 under 7 CFR 273.9(a)(3)(ii). Net income of $4,973 is $1 # above it. snap_net_income: 4_973 + households: + household: + members: [person1] + state_code: RI + output: + meets_tanf_non_cash_net_income_test: false + +- name: California MCE household of four above the FY 2026 net standard meets the net income test. + period: 2026-01 + input: + people: + person1: {} + spm_units: + spm_unit: + members: [person1] + snap_unit_size: 4 + is_tanf_non_cash_hheod: false + # $286 above the four-person FY 2026 net standard of $2,680 (CDSS + # ACIN I-46-25, attachment I). + snap_net_income: 2_966 households: household: members: [person1] state_code: CA output: + # An MCE household of three or more gets the issuance-table allotment + # "even if the household's net income exceeds the maximum amount + # allowable" (CDSS ACL 12-62, example 5; ACL 14-56; ACL 15-42). + meets_tanf_non_cash_net_income_test: true + +- name: California MCE elderly or disabled household above the FY 2026 net standard meets the net income test. + period: 2026-01 + input: + people: + person1: {} + spm_units: + spm_unit: + members: [person1] + snap_unit_size: 1 + is_tanf_non_cash_hheod: true + # $486 above the one-person FY 2026 net standard of $1,305 (CDSS + # ACIN I-46-25, attachment I). + snap_net_income: 1_791 + households: + household: + members: [person1] + state_code: CA + output: + # Elderly or disabled households at or below 200% of the poverty line + # are conferred MCE, and MCE households of one or two get the minimum + # allotment even above the net standard (CDSS ACL 13-32, note). + meets_tanf_non_cash_net_income_test: true + +- name: Rhode Island household of four above the FY 2026 net standard fails the net income test. + period: 2026-01 + input: + people: + person1: {} + spm_units: + spm_unit: + members: [person1] + snap_unit_size: 4 + is_tanf_non_cash_hheod: false + snap_net_income: 2_966 + households: + household: + members: [person1] + state_code: RI + output: + # The same household fails where the state's BBCE keeps the net test: + # $2,966 exceeds the four-person FY 2026 standard of $2,680. meets_tanf_non_cash_net_income_test: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/snap/ca_snap_meets_allotment_requirement.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/snap/ca_snap_meets_allotment_requirement.yaml new file mode 100644 index 00000000000..6321f72868f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cdss/snap/ca_snap_meets_allotment_requirement.yaml @@ -0,0 +1,1171 @@ +# California MCE has no net-income ceiling for any household size or +# elderly/disabled status (ACL 12-62 examples 4-5; ACL 13-32). ACL 14-56 +# page 6 and ACL 14-63 page 2 deny zero-allotment units of three or more. +# https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2012/12-62.pdf +# https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2013/13-32.pdf +# https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-56.pdf#page=6 +# https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-63.pdf#page=2 +# FY2026 maximum/minimum allotments: CDSS ACIN I-46-25 attachment I. +# Each pair holds gross income, size and member eligibility fixed while +# varying only net income. All categorical and member gates are derived. +# Gross inputs floor the model's exact 200%-FPG limit: twice +# ($15,650 + $5,500 x (size - 1))/12. This preserves the existing model's +# exact-ratio convention rather than imposing CDSS chart rounding. +# Expected benefits are hand-calculated as max(minimum, maximum minus +# ceil(30% x net)); minimum is $24 for one/two-person units and $0 otherwise. + +# Net 0 / 2608 gives contributions 0 / 783, +# so maximum $298 yields allotments $298 / $24. +- name: California MCE size 1 without elderly or disabled members varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_1 + age: 35 + monthly_age: 35 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: false + higher_person_1: + <<: *first_member_1 + spm_units: + lower: + members: [lower_person_1] + snap_gross_income: 2608 + snap_net_income: 0 + higher: + members: [higher_person_1] + snap_gross_income: 2608 + snap_net_income: 2608 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_higher_person_1: + members: [higher_person_1] + families: + family_lower_person_1: + members: [lower_person_1] + family_higher_person_1: + members: [higher_person_1] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_higher_person_1: + members: [higher_person_1] + households: + lower_household: + members: [lower_person_1] + state_code: CA + higher_household: + members: [higher_person_1] + state_code: CA + output: + snap_unit_size: [1, 1] + is_snap_excluded_member: [false, false] + is_tanf_non_cash_hheod: [false, false] + snap_gross_test_income: [2608, 2608] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [298, 298] + snap_allotment_before_eligibility: [298, 24] + ca_snap_meets_allotment_requirement: [true, true] + is_snap_eligible: [true, true] + snap_normal_allotment: [298, 24] + snap: [298, 24] + +# Net 0 / 3525 gives contributions 0 / 1058, +# so maximum $546 yields allotments $546 / $24. +- name: California MCE size 2 elderly varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_2 + age: 65 + monthly_age: 65 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: false + lower_person_2: + <<: *first_member_2 + age: 35 + monthly_age: 35 + higher_person_1: + <<: *first_member_2 + higher_person_2: + <<: *first_member_2 + age: 35 + monthly_age: 35 + spm_units: + lower: + members: [lower_person_1, lower_person_2] + snap_gross_income: 3525 + snap_net_income: 0 + higher: + members: [higher_person_1, higher_person_2] + snap_gross_income: 3525 + snap_net_income: 3525 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + households: + lower_household: + members: [lower_person_1, lower_person_2] + state_code: CA + higher_household: + members: [higher_person_1, higher_person_2] + state_code: CA + output: + snap_unit_size: [2, 2] + is_snap_excluded_member: [false, false, false, false] + is_tanf_non_cash_hheod: [true, true] + snap_gross_test_income: [3525, 3525] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [546, 546] + snap_allotment_before_eligibility: [546, 24] + ca_snap_meets_allotment_requirement: [true, true] + is_snap_eligible: [true, true] + snap_normal_allotment: [546, 24] + snap: [546, 24] + +# Net 2613 / 2614 gives contributions 784 / 785, +# so maximum $785 yields allotments $1 / $0. +- name: California MCE size 3 disabled varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_3 + age: 35 + monthly_age: 35 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: true + lower_person_2: + <<: *first_member_3 + is_permanently_disabled_veteran: false + lower_person_3: + <<: *first_member_3 + is_permanently_disabled_veteran: false + higher_person_1: + <<: *first_member_3 + higher_person_2: + <<: *first_member_3 + is_permanently_disabled_veteran: false + higher_person_3: + <<: *first_member_3 + is_permanently_disabled_veteran: false + spm_units: + lower: + members: [lower_person_1, lower_person_2, lower_person_3] + snap_gross_income: 4441 + snap_net_income: 2613 + higher: + members: [higher_person_1, higher_person_2, higher_person_3] + snap_gross_income: 4441 + snap_net_income: 2614 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_lower_person_3: + members: [lower_person_3] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + tax_higher_person_3: + members: [higher_person_3] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_lower_person_3: + members: [lower_person_3] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + family_higher_person_3: + members: [higher_person_3] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_lower_person_3: + members: [lower_person_3] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + marital_higher_person_3: + members: [higher_person_3] + households: + lower_household: + members: [lower_person_1, lower_person_2, lower_person_3] + state_code: CA + higher_household: + members: [higher_person_1, higher_person_2, higher_person_3] + state_code: CA + output: + snap_unit_size: [3, 3] + is_snap_excluded_member: [false, false, false, false, false, false] + is_tanf_non_cash_hheod: [true, true] + snap_gross_test_income: [4441, 4441] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [785, 785] + snap_allotment_before_eligibility: [1, 0] + ca_snap_meets_allotment_requirement: [true, false] + is_snap_eligible: [true, false] + snap_normal_allotment: [1, 0] + snap: [1, 0] + +# Net 3310 / 3311 gives contributions 993 / 994, +# so maximum $994 yields allotments $1 / $0. +- name: California MCE size 4 elderly and disabled varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_4 + age: 65 + monthly_age: 65 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: true + lower_person_2: + <<: *first_member_4 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_3: + <<: *first_member_4 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_4: + <<: *first_member_4 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_1: + <<: *first_member_4 + higher_person_2: + <<: *first_member_4 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_3: + <<: *first_member_4 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_4: + <<: *first_member_4 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + spm_units: + lower: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4] + snap_gross_income: 5358 + snap_net_income: 3310 + higher: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4] + snap_gross_income: 5358 + snap_net_income: 3311 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_lower_person_3: + members: [lower_person_3] + tax_lower_person_4: + members: [lower_person_4] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + tax_higher_person_3: + members: [higher_person_3] + tax_higher_person_4: + members: [higher_person_4] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_lower_person_3: + members: [lower_person_3] + family_lower_person_4: + members: [lower_person_4] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + family_higher_person_3: + members: [higher_person_3] + family_higher_person_4: + members: [higher_person_4] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_lower_person_3: + members: [lower_person_3] + marital_lower_person_4: + members: [lower_person_4] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + marital_higher_person_3: + members: [higher_person_3] + marital_higher_person_4: + members: [higher_person_4] + households: + lower_household: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4] + state_code: CA + higher_household: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4] + state_code: CA + output: + snap_unit_size: [4, 4] + is_snap_excluded_member: [false, false, false, false, false, false, false, false] + is_tanf_non_cash_hheod: [true, true] + snap_gross_test_income: [5358, 5358] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [994, 994] + snap_allotment_before_eligibility: [1, 0] + ca_snap_meets_allotment_requirement: [true, false] + is_snap_eligible: [true, false] + snap_normal_allotment: [1, 0] + snap: [1, 0] + +# Net 3940 / 3941 gives contributions 1182 / 1183, +# so maximum $1183 yields allotments $1 / $0. +- name: California MCE size 5 without elderly or disabled members varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_5 + age: 35 + monthly_age: 35 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: false + lower_person_2: + <<: *first_member_5 + lower_person_3: + <<: *first_member_5 + lower_person_4: + <<: *first_member_5 + lower_person_5: + <<: *first_member_5 + higher_person_1: + <<: *first_member_5 + higher_person_2: + <<: *first_member_5 + higher_person_3: + <<: *first_member_5 + higher_person_4: + <<: *first_member_5 + higher_person_5: + <<: *first_member_5 + spm_units: + lower: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5] + snap_gross_income: 6275 + snap_net_income: 3940 + higher: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5] + snap_gross_income: 6275 + snap_net_income: 3941 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_lower_person_3: + members: [lower_person_3] + tax_lower_person_4: + members: [lower_person_4] + tax_lower_person_5: + members: [lower_person_5] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + tax_higher_person_3: + members: [higher_person_3] + tax_higher_person_4: + members: [higher_person_4] + tax_higher_person_5: + members: [higher_person_5] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_lower_person_3: + members: [lower_person_3] + family_lower_person_4: + members: [lower_person_4] + family_lower_person_5: + members: [lower_person_5] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + family_higher_person_3: + members: [higher_person_3] + family_higher_person_4: + members: [higher_person_4] + family_higher_person_5: + members: [higher_person_5] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_lower_person_3: + members: [lower_person_3] + marital_lower_person_4: + members: [lower_person_4] + marital_lower_person_5: + members: [lower_person_5] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + marital_higher_person_3: + members: [higher_person_3] + marital_higher_person_4: + members: [higher_person_4] + marital_higher_person_5: + members: [higher_person_5] + households: + lower_household: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5] + state_code: CA + higher_household: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5] + state_code: CA + output: + snap_unit_size: [5, 5] + is_snap_excluded_member: [false, false, false, false, false, false, false, false, false, false] + is_tanf_non_cash_hheod: [false, false] + snap_gross_test_income: [6275, 6275] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [1183, 1183] + snap_allotment_before_eligibility: [1, 0] + ca_snap_meets_allotment_requirement: [true, false] + is_snap_eligible: [true, false] + snap_normal_allotment: [1, 0] + snap: [1, 0] + +# Net 4733 / 4734 gives contributions 1420 / 1421, +# so maximum $1421 yields allotments $1 / $0. +- name: California MCE size 6 elderly varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_6 + age: 65 + monthly_age: 65 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: false + lower_person_2: + <<: *first_member_6 + age: 35 + monthly_age: 35 + lower_person_3: + <<: *first_member_6 + age: 35 + monthly_age: 35 + lower_person_4: + <<: *first_member_6 + age: 35 + monthly_age: 35 + lower_person_5: + <<: *first_member_6 + age: 35 + monthly_age: 35 + lower_person_6: + <<: *first_member_6 + age: 35 + monthly_age: 35 + higher_person_1: + <<: *first_member_6 + higher_person_2: + <<: *first_member_6 + age: 35 + monthly_age: 35 + higher_person_3: + <<: *first_member_6 + age: 35 + monthly_age: 35 + higher_person_4: + <<: *first_member_6 + age: 35 + monthly_age: 35 + higher_person_5: + <<: *first_member_6 + age: 35 + monthly_age: 35 + higher_person_6: + <<: *first_member_6 + age: 35 + monthly_age: 35 + spm_units: + lower: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5, lower_person_6] + snap_gross_income: 7191 + snap_net_income: 4733 + higher: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5, higher_person_6] + snap_gross_income: 7191 + snap_net_income: 4734 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_lower_person_3: + members: [lower_person_3] + tax_lower_person_4: + members: [lower_person_4] + tax_lower_person_5: + members: [lower_person_5] + tax_lower_person_6: + members: [lower_person_6] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + tax_higher_person_3: + members: [higher_person_3] + tax_higher_person_4: + members: [higher_person_4] + tax_higher_person_5: + members: [higher_person_5] + tax_higher_person_6: + members: [higher_person_6] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_lower_person_3: + members: [lower_person_3] + family_lower_person_4: + members: [lower_person_4] + family_lower_person_5: + members: [lower_person_5] + family_lower_person_6: + members: [lower_person_6] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + family_higher_person_3: + members: [higher_person_3] + family_higher_person_4: + members: [higher_person_4] + family_higher_person_5: + members: [higher_person_5] + family_higher_person_6: + members: [higher_person_6] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_lower_person_3: + members: [lower_person_3] + marital_lower_person_4: + members: [lower_person_4] + marital_lower_person_5: + members: [lower_person_5] + marital_lower_person_6: + members: [lower_person_6] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + marital_higher_person_3: + members: [higher_person_3] + marital_higher_person_4: + members: [higher_person_4] + marital_higher_person_5: + members: [higher_person_5] + marital_higher_person_6: + members: [higher_person_6] + households: + lower_household: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5, lower_person_6] + state_code: CA + higher_household: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5, higher_person_6] + state_code: CA + output: + snap_unit_size: [6, 6] + is_snap_excluded_member: [false, false, false, false, false, false, false, false, false, false, false, false] + is_tanf_non_cash_hheod: [true, true] + snap_gross_test_income: [7191, 7191] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [1421, 1421] + snap_allotment_before_eligibility: [1, 0] + ca_snap_meets_allotment_requirement: [true, false] + is_snap_eligible: [true, false] + snap_normal_allotment: [1, 0] + snap: [1, 0] + +# Net 5233 / 5234 gives contributions 1570 / 1571, +# so maximum $1571 yields allotments $1 / $0. +- name: California MCE size 7 disabled varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_7 + age: 35 + monthly_age: 35 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: true + lower_person_2: + <<: *first_member_7 + is_permanently_disabled_veteran: false + lower_person_3: + <<: *first_member_7 + is_permanently_disabled_veteran: false + lower_person_4: + <<: *first_member_7 + is_permanently_disabled_veteran: false + lower_person_5: + <<: *first_member_7 + is_permanently_disabled_veteran: false + lower_person_6: + <<: *first_member_7 + is_permanently_disabled_veteran: false + lower_person_7: + <<: *first_member_7 + is_permanently_disabled_veteran: false + higher_person_1: + <<: *first_member_7 + higher_person_2: + <<: *first_member_7 + is_permanently_disabled_veteran: false + higher_person_3: + <<: *first_member_7 + is_permanently_disabled_veteran: false + higher_person_4: + <<: *first_member_7 + is_permanently_disabled_veteran: false + higher_person_5: + <<: *first_member_7 + is_permanently_disabled_veteran: false + higher_person_6: + <<: *first_member_7 + is_permanently_disabled_veteran: false + higher_person_7: + <<: *first_member_7 + is_permanently_disabled_veteran: false + spm_units: + lower: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5, lower_person_6, lower_person_7] + snap_gross_income: 8108 + snap_net_income: 5233 + higher: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5, higher_person_6, higher_person_7] + snap_gross_income: 8108 + snap_net_income: 5234 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_lower_person_3: + members: [lower_person_3] + tax_lower_person_4: + members: [lower_person_4] + tax_lower_person_5: + members: [lower_person_5] + tax_lower_person_6: + members: [lower_person_6] + tax_lower_person_7: + members: [lower_person_7] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + tax_higher_person_3: + members: [higher_person_3] + tax_higher_person_4: + members: [higher_person_4] + tax_higher_person_5: + members: [higher_person_5] + tax_higher_person_6: + members: [higher_person_6] + tax_higher_person_7: + members: [higher_person_7] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_lower_person_3: + members: [lower_person_3] + family_lower_person_4: + members: [lower_person_4] + family_lower_person_5: + members: [lower_person_5] + family_lower_person_6: + members: [lower_person_6] + family_lower_person_7: + members: [lower_person_7] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + family_higher_person_3: + members: [higher_person_3] + family_higher_person_4: + members: [higher_person_4] + family_higher_person_5: + members: [higher_person_5] + family_higher_person_6: + members: [higher_person_6] + family_higher_person_7: + members: [higher_person_7] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_lower_person_3: + members: [lower_person_3] + marital_lower_person_4: + members: [lower_person_4] + marital_lower_person_5: + members: [lower_person_5] + marital_lower_person_6: + members: [lower_person_6] + marital_lower_person_7: + members: [lower_person_7] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + marital_higher_person_3: + members: [higher_person_3] + marital_higher_person_4: + members: [higher_person_4] + marital_higher_person_5: + members: [higher_person_5] + marital_higher_person_6: + members: [higher_person_6] + marital_higher_person_7: + members: [higher_person_7] + households: + lower_household: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5, lower_person_6, lower_person_7] + state_code: CA + higher_household: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5, higher_person_6, higher_person_7] + state_code: CA + output: + snap_unit_size: [7, 7] + is_snap_excluded_member: [false, false, false, false, false, false, false, false, false, false, false, false, false, false] + is_tanf_non_cash_hheod: [true, true] + snap_gross_test_income: [8108, 8108] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [1571, 1571] + snap_allotment_before_eligibility: [1, 0] + ca_snap_meets_allotment_requirement: [true, false] + is_snap_eligible: [true, false] + snap_normal_allotment: [1, 0] + snap: [1, 0] + +# Net 5960 / 5961 gives contributions 1788 / 1789, +# so maximum $1789 yields allotments $1 / $0. +- name: California MCE size 8 elderly and disabled varies net income at fixed gross income. + period: 2026-01 + input: + people: + lower_person_1: &first_member_8 + age: 65 + monthly_age: 65 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: true + lower_person_2: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_3: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_4: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_5: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_6: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_7: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + lower_person_8: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_1: + <<: *first_member_8 + higher_person_2: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_3: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_4: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_5: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_6: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_7: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + higher_person_8: + <<: *first_member_8 + age: 35 + monthly_age: 35 + is_permanently_disabled_veteran: false + spm_units: + lower: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5, lower_person_6, lower_person_7, lower_person_8] + snap_gross_income: 9025 + snap_net_income: 5960 + higher: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5, higher_person_6, higher_person_7, higher_person_8] + snap_gross_income: 9025 + snap_net_income: 5961 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_lower_person_3: + members: [lower_person_3] + tax_lower_person_4: + members: [lower_person_4] + tax_lower_person_5: + members: [lower_person_5] + tax_lower_person_6: + members: [lower_person_6] + tax_lower_person_7: + members: [lower_person_7] + tax_lower_person_8: + members: [lower_person_8] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + tax_higher_person_3: + members: [higher_person_3] + tax_higher_person_4: + members: [higher_person_4] + tax_higher_person_5: + members: [higher_person_5] + tax_higher_person_6: + members: [higher_person_6] + tax_higher_person_7: + members: [higher_person_7] + tax_higher_person_8: + members: [higher_person_8] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_lower_person_3: + members: [lower_person_3] + family_lower_person_4: + members: [lower_person_4] + family_lower_person_5: + members: [lower_person_5] + family_lower_person_6: + members: [lower_person_6] + family_lower_person_7: + members: [lower_person_7] + family_lower_person_8: + members: [lower_person_8] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + family_higher_person_3: + members: [higher_person_3] + family_higher_person_4: + members: [higher_person_4] + family_higher_person_5: + members: [higher_person_5] + family_higher_person_6: + members: [higher_person_6] + family_higher_person_7: + members: [higher_person_7] + family_higher_person_8: + members: [higher_person_8] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_lower_person_3: + members: [lower_person_3] + marital_lower_person_4: + members: [lower_person_4] + marital_lower_person_5: + members: [lower_person_5] + marital_lower_person_6: + members: [lower_person_6] + marital_lower_person_7: + members: [lower_person_7] + marital_lower_person_8: + members: [lower_person_8] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + marital_higher_person_3: + members: [higher_person_3] + marital_higher_person_4: + members: [higher_person_4] + marital_higher_person_5: + members: [higher_person_5] + marital_higher_person_6: + members: [higher_person_6] + marital_higher_person_7: + members: [higher_person_7] + marital_higher_person_8: + members: [higher_person_8] + households: + lower_household: + members: [lower_person_1, lower_person_2, lower_person_3, lower_person_4, lower_person_5, lower_person_6, lower_person_7, lower_person_8] + state_code: CA + higher_household: + members: [higher_person_1, higher_person_2, higher_person_3, higher_person_4, higher_person_5, higher_person_6, higher_person_7, higher_person_8] + state_code: CA + output: + snap_unit_size: [8, 8] + is_snap_excluded_member: [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false] + is_tanf_non_cash_hheod: [true, true] + snap_gross_test_income: [9025, 9025] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [1789, 1789] + snap_allotment_before_eligibility: [1, 0] + ca_snap_meets_allotment_requirement: [true, false] + is_snap_eligible: [true, false] + snap_normal_allotment: [1, 0] + snap: [1, 0] + +# Net 2613 / 2614 gives contributions 784 / 785, +# so maximum $785 yields allotments $1 / $0. +- name: Washington keeps categorical eligibility for a zero allotment outside California. + period: 2026-01 + input: + people: + lower_person_1: &first_member_9 + age: 35 + monthly_age: 35 + immigration_status: CITIZEN + weekly_hours_worked_before_lsr: 40 + is_tax_unit_dependent: false + is_full_time_college_student: false + is_part_time_college_student: false + is_permanently_disabled_veteran: false + lower_person_2: + <<: *first_member_9 + lower_person_3: + <<: *first_member_9 + higher_person_1: + <<: *first_member_9 + higher_person_2: + <<: *first_member_9 + higher_person_3: + <<: *first_member_9 + spm_units: + lower: + members: [lower_person_1, lower_person_2, lower_person_3] + snap_gross_income: 4441 + snap_net_income: 2613 + higher: + members: [higher_person_1, higher_person_2, higher_person_3] + snap_gross_income: 4441 + snap_net_income: 2614 + tax_units: + tax_lower_person_1: + members: [lower_person_1] + tax_lower_person_2: + members: [lower_person_2] + tax_lower_person_3: + members: [lower_person_3] + tax_higher_person_1: + members: [higher_person_1] + tax_higher_person_2: + members: [higher_person_2] + tax_higher_person_3: + members: [higher_person_3] + families: + family_lower_person_1: + members: [lower_person_1] + family_lower_person_2: + members: [lower_person_2] + family_lower_person_3: + members: [lower_person_3] + family_higher_person_1: + members: [higher_person_1] + family_higher_person_2: + members: [higher_person_2] + family_higher_person_3: + members: [higher_person_3] + marital_units: + marital_lower_person_1: + members: [lower_person_1] + marital_lower_person_2: + members: [lower_person_2] + marital_lower_person_3: + members: [lower_person_3] + marital_higher_person_1: + members: [higher_person_1] + marital_higher_person_2: + members: [higher_person_2] + marital_higher_person_3: + members: [higher_person_3] + households: + lower_household: + members: [lower_person_1, lower_person_2, lower_person_3] + state_code: WA + higher_household: + members: [higher_person_1, higher_person_2, higher_person_3] + state_code: WA + output: + snap_unit_size: [3, 3] + is_snap_excluded_member: [false, false, false, false, false, false] + is_tanf_non_cash_hheod: [false, false] + snap_gross_test_income: [4441, 4441] + meets_tanf_non_cash_gross_income_test: [true, true] + meets_tanf_non_cash_net_income_test: [true, true] + is_tanf_non_cash_eligible: [true, true] + meets_snap_categorical_eligibility: [true, true] + snap_max_allotment: [785, 785] + snap_allotment_before_eligibility: [1, 0] + ca_snap_meets_allotment_requirement: [true, true] + is_snap_eligible: [true, true] + snap_normal_allotment: [1, 0] + snap: [1, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/cpuc/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/cpuc/integration.yaml index 105d8987278..a8235711b17 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/cpuc/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/cpuc/integration.yaml @@ -177,6 +177,9 @@ person1: age: 40 employment_income: 30_000 + # Establish the worker exemption independently of the YAML runner's + # treatment of employment_income versus employment_income_before_lsr. + weekly_hours_worked_before_lsr: 30 spm_units: unit: members: [person1] @@ -190,6 +193,10 @@ ca_care_categorically_eligible: false tenant_pays_utilities: false output: + # Countable income is $30,000 in annual wages. The three $23 SNAP + # minimum allotments in October, November, and December are excluded under + # 7 USC 2017(b): $30,000 + $0 counted SNAP = $30,000. + snap: 69 ca_cpuc_countable_income: 30_000 ca_care_income_eligible: true # The model's CARE gate treats a household with utilities included in diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/is_snap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/is_snap_eligible.yaml index ae8049266a2..455ae683e00 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/is_snap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/is_snap_eligible.yaml @@ -223,3 +223,631 @@ snap_unit_size: 0 is_snap_eligible: false snap: 0 + +# California Modified Categorical Eligibility (MCE) in FY 2026. CDSS ACIN +# I-46-25, attachment I: net standard (100% of poverty) $1,305 for one person +# and $2,680 for four; MCE gross standard (200%) $2,610 and $5,360; regular +# gross standard (130%) $3,483 for four; maximum allotment $298 and $994; +# standard deduction $209 (1-3 people) and $223 (4); minimum allotment $24. +# The original cases have no housing costs, so their excess shelter deduction +# is zero at these incomes whichever utility allowance applies. +- name: California MCE household of four above the net standard is eligible for the issuance-table allotment. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + parent1: + age: 35 + employment_income: 48_000 + weekly_hours_worked_before_lsr: 40 + parent2: + age: 33 + child1: + age: 8 + child2: + age: 4 + spm_units: + spm_unit: + members: [parent1, parent2, child1, child2] + housing_cost: 0 + tax_units: + tax_unit: + members: [parent1, parent2, child1, child2] + households: + household: + members: [parent1, parent2, child1, child2] + state_code: CA + output: + # Gross $4,000 is above the regular $3,483 but within the $5,360 MCE + # standard, so MCE is conferred. + meets_snap_gross_income_test: false + is_tanf_non_cash_eligible: true + # Net $4,000 - 20% earned income deduction ($800) - $223 = $2,977, above + # the $2,680 net standard. + snap_net_income: 2_977 + meets_snap_net_income_test: false + # MCE households of three or more get the issuance-table allotment "even + # if the household's net income exceeds the maximum amount allowable" + # (CDSS ACL 12-62, example 5; ACL 14-56; ACL 15-42). + meets_snap_categorical_eligibility: true + is_snap_eligible: true + # $994 - ceil(30% x $2,977 = $893.10) = $994 - $894. + snap: 100 + +- name: California MCE elderly person above the net standard is eligible for the minimum allotment. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person: + age: 65 + social_security: 24_000 + # The 2026 standard Medicare Part B premium, $202.90 a month. + health_insurance_premiums: 2_434.8 + spm_units: + spm_unit: + members: [person] + housing_cost: 0 + tax_units: + tax_unit: + members: [person] + households: + household: + members: [person] + state_code: CA + output: + # Gross $2,000 is within the $2,610 MCE standard, and elderly or + # disabled households at or below 200% of poverty are conferred MCE + # (CDSS ACL 13-32). + is_tanf_non_cash_eligible: true + # Net $2,000 - $209 - ($202.90 - $35 excess medical) = $1,623.10, + # rounded to $1,623, above the $1,305 net standard. + snap_net_income: 1_623 + meets_snap_net_income_test: false + # Actual medical deduction $202.90 - $35 = $167.90 exceeds the $150 + # standard medical deduction. With no rent, SUA $663 is below half of + # pre-shelter income ($811.55), so the shelter deduction is zero. + snap_excess_medical_expense_deduction: 167.90 + snap_excess_shelter_expense_deduction: 0 + # MCE households of one or two get the minimum allotment even above the + # net standard (CDSS ACL 13-32, note; ACL 12-62, example 4). + meets_snap_categorical_eligibility: true + is_snap_eligible: true + # $298 - ceil(30% x $1,623 = $486.90) = $298 - $487 = -$189, + # raised to the $24 minimum. + snap: 24 + +- name: California elderly person above 200% of poverty is not MCE and fails the net standard. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + person: + age: 65 + social_security: 32_400 + # The 2026 standard Medicare Part B premium, $202.90 a month. + health_insurance_premiums: 2_434.8 + spm_units: + spm_unit: + members: [person] + housing_cost: 0 + tax_units: + tax_unit: + members: [person] + households: + household: + members: [person] + state_code: CA + output: + # Gross $2,700 exceeds the $2,610 MCE standard, so MCE is not conferred + # and the household must be net income eligible (CDSS ACL 13-32, + # example 2): net $2,700 - $209 - $167.90 = $2,323.10, rounded to + # $2,323, exceeds $1,305. + is_tanf_non_cash_eligible: false + snap_net_income: 2_323 + meets_snap_net_income_test: false + is_snap_eligible: false + snap: 0 + +- name: California household of four above 200% of poverty is not MCE and fails the gross standard. + period: 2026-01 + absolute_error_margin: 0.1 + input: + people: + parent1: + age: 35 + employment_income: 66_000 + weekly_hours_worked_before_lsr: 40 + parent2: + age: 33 + child1: + age: 8 + child2: + age: 4 + spm_units: + spm_unit: + members: [parent1, parent2, child1, child2] + housing_cost: 0 + tax_units: + tax_unit: + members: [parent1, parent2, child1, child2] + households: + household: + members: [parent1, parent2, child1, child2] + state_code: CA + output: + # Gross $5,500 exceeds the $5,360 MCE standard, so MCE is not conferred + # and the $3,483 regular gross standard applies (CDSS ACL 14-56, + # example 2). + is_tanf_non_cash_eligible: false + meets_snap_gross_income_test: false + is_snap_eligible: false + snap: 0 + +- name: California MCE household of four with rent and no utility allowance receives SNAP above the net standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + parent1: + age: 35 + employment_income: 45_000 + weekly_hours_worked_before_lsr: 40 + parent2: + age: 33 + child1: + age: 8 + child2: + age: 4 + spm_units: + spm_unit: + members: [parent1, parent2, child1, child2] + housing_cost: 10_200 + # Isolate MCE from the separate federal heat-and-eat change. The + # household has no utility costs and this case assumes no allowance. + snap_utility_allowance: 0 + tax_units: + tax_unit: + members: [parent1, parent2, child1, child2] + households: + household: + members: [parent1, parent2, child1, child2] + state_code: CA + output: + # Monthly wages $45,000 / 12 = $3,750 are within the $5,360 MCE ceiling. + snap_gross_income: 3_750 + is_tanf_non_cash_eligible: true + # Net before shelter: $3,750 - 20% x $3,750 - $223 = $2,777. + snap_earned_income_deduction: 750 + snap_standard_deduction: 223 + snap_net_income_pre_shelter: 2_777 + # Rent $10,200 / 12 = $850 is below half-net $1,388.50, with no SUA. + snap_excess_shelter_expense_deduction: 0 + snap_net_income: 2_777 + meets_snap_net_income_test: false + # CDSS June 30, 2014 MCE letter, page 3: households of three or more + # receive their issuance-table allotment even above the net standard. + meets_snap_categorical_eligibility: true + is_snap_eligible: true + # $994 - ceil(30% x $2,777 = $833.10) = $994 - $834 = $160. + snap: 160 + +# CPUC June 2026-May 2027 income tables: CARE $54,640 and FERA $68,300 +# for three people. https://www.cpuc.ca.gov/industries-and-topics/electrical-energy/electric-costs/care-fera-program +# CARE counts both earners: $40,000 + $20,000 = $60,000 > $54,640. +# SNAP excludes the under-18 K-12 student's wages (7 USC 2014(d)(7)): +# https://www.law.cornell.edu/uscode/text/7/2014#d_7 +# CDSS FY2026 table, attachment I: MCE gross $4,442, net standard $2,221, +# standard deduction $209, maximum allotment $785. +# https://www.cdss.ca.gov/Portals/9/Additional-Resources/Letters-and-Notices/ACINs/2025/I-46_25.pdf#page=7 +# SNAP gross $40,000 / 12 = $3,333.33 < $4,442; net rounds from +# $3,333.33 - $666.67 earned deduction - $209 = $2,457.67 to $2,458. +# $2,458 > $2,221, but MCE waives the net test; $785 - ceil($737.40) = $47. +# On main (static comparison), the required net test denies SNAP throughout +# 2026, so CARE categorical/overall eligibility are false and FERA is true. +# With this waiver, SNAP alone confers CARE, which excludes FERA. No rent +# also keeps main's default utility allowance from lowering the annual net +# income enough to confer CARE through SNAP in another month. +# Use calendar-year inputs for wages and CARE, and assert June SNAP explicitly. +- name: California MCE SNAP receipt alone confers CARE above its income limit and excludes FERA. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 35 + employment_income: 40_000 + weekly_hours_worked_before_lsr: 40 + medicaid_enrolled: false + wic: 0 + receives_wic: false + ssi: 0 + receives_ssi: false + student: + age: 16 + is_in_k12_school: true + employment_income: 20_000 + medicaid_enrolled: false + wic: 0 + receives_wic: false + ssi: 0 + receives_ssi: false + sibling: + age: 14 + medicaid_enrolled: false + wic: 0 + receives_wic: false + ssi: 0 + receives_ssi: false + spm_units: + spm_unit: + members: [parent, student, sibling] + housing_cost: 0 + snap_utility_allowance: 0 + receives_snap: false + tanf: 0 + receives_tanf: false + tax_units: + tax_unit: + members: [parent, student, sibling] + households: + household: + members: [parent, student, sibling] + state_code: CA + is_on_tribal_land: false + output: + snap_gross_income: + 2026-06: 3_333.33 + meets_snap_gross_income_test: + 2026-06: false + is_tanf_non_cash_eligible: + 2026-06: true + snap_net_income: + 2026-06: 2_458 + meets_snap_net_income_test: + 2026-06: false + meets_snap_categorical_eligibility: + 2026-06: true + is_snap_eligible: + 2026-06: true + snap: + 2026-06: 47 + ca_cpuc_countable_income: 60_000 + ca_care_income_eligible: false + ca_care_categorically_eligible: true + ca_care_eligible: true + ca_fera_eligible: false + +# ACL 14-56 p. 6 and ACL 14-63 p. 2: deny zero allotments for 3+; +# retain the minimum for 1-2. FY2026 CDSS maximums: $785 (3), $994 (4). +# Wages $42,330/12 x 80% minus $209 = $2,613; +# maximum minus ceil(30% x net) = $1. A $1 ongoing allotment is issued. +- name: California MCE household of 3 with net income 2613 has a 1 dollar allotment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + earner: + age: 35 + employment_income: 42330 + weekly_hours_worked_before_lsr: 40 + member_1: + age: 8 + member_2: + age: 8 + spm_units: + unit: + members: + - earner + - member_1 + - member_2 + housing_cost: 0 + snap_utility_allowance: 0 + tax_units: + unit: + members: + - earner + - member_1 + - member_2 + households: + household: + members: + - earner + - member_1 + - member_2 + state_code: CA + output: + snap_net_income: 2613 + meets_snap_net_income_test: false + is_tanf_non_cash_eligible: true + meets_snap_categorical_eligibility: true + snap_allotment_before_eligibility: 1 + ca_snap_meets_allotment_requirement: true + is_snap_eligible: true + snap: 1 + +# ACL 14-56 p. 6 and ACL 14-63 p. 2: deny zero allotments for 3+; +# retain the minimum for 1-2. FY2026 CDSS maximums: $785 (3), $994 (4). +# Wages $42,345/12 x 80% minus $209 = $2,614; +# maximum minus ceil(30% x net) = $0. The application is denied or participation discontinued. +- name: California MCE household of 3 with net income 2614 has a 0 dollar allotment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + earner: + age: 35 + employment_income: 42345 + weekly_hours_worked_before_lsr: 40 + member_1: + age: 8 + member_2: + age: 8 + spm_units: + unit: + members: + - earner + - member_1 + - member_2 + housing_cost: 0 + snap_utility_allowance: 0 + tax_units: + unit: + members: + - earner + - member_1 + - member_2 + households: + household: + members: + - earner + - member_1 + - member_2 + state_code: CA + output: + snap_net_income: 2614 + meets_snap_net_income_test: false + is_tanf_non_cash_eligible: true + meets_snap_categorical_eligibility: true + snap_allotment_before_eligibility: 0 + ca_snap_meets_allotment_requirement: false + is_snap_eligible: false + snap: 0 + +# ACL 14-56 p. 6 and ACL 14-63 p. 2: deny zero allotments for 3+; +# retain the minimum for 1-2. FY2026 CDSS maximums: $785 (3), $994 (4). +# Wages $52,995/12 x 80% minus $223 = $3,310; +# maximum minus ceil(30% x net) = $1. A $1 ongoing allotment is issued. +- name: California MCE household of 4 with net income 3310 has a 1 dollar allotment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + earner: + age: 35 + employment_income: 52995 + weekly_hours_worked_before_lsr: 40 + member_1: + age: 8 + member_2: + age: 8 + member_3: + age: 8 + spm_units: + unit: + members: + - earner + - member_1 + - member_2 + - member_3 + housing_cost: 0 + snap_utility_allowance: 0 + tax_units: + unit: + members: + - earner + - member_1 + - member_2 + - member_3 + households: + household: + members: + - earner + - member_1 + - member_2 + - member_3 + state_code: CA + output: + snap_net_income: 3310 + meets_snap_net_income_test: false + is_tanf_non_cash_eligible: true + meets_snap_categorical_eligibility: true + snap_allotment_before_eligibility: 1 + ca_snap_meets_allotment_requirement: true + is_snap_eligible: true + snap: 1 + +# ACL 14-56 p. 6 and ACL 14-63 p. 2: deny zero allotments for 3+; +# retain the minimum for 1-2. FY2026 CDSS maximums: $785 (3), $994 (4). +# Wages $53,010/12 x 80% minus $223 = $3,311; +# maximum minus ceil(30% x net) = $0. The application is denied or participation discontinued. +- name: California MCE household of 4 with net income 3311 has a 0 dollar allotment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + earner: + age: 35 + employment_income: 53010 + weekly_hours_worked_before_lsr: 40 + member_1: + age: 8 + member_2: + age: 8 + member_3: + age: 8 + spm_units: + unit: + members: + - earner + - member_1 + - member_2 + - member_3 + housing_cost: 0 + snap_utility_allowance: 0 + tax_units: + unit: + members: + - earner + - member_1 + - member_2 + - member_3 + households: + household: + members: + - earner + - member_1 + - member_2 + - member_3 + state_code: CA + output: + snap_net_income: 3311 + meets_snap_net_income_test: false + is_tanf_non_cash_eligible: true + meets_snap_categorical_eligibility: true + snap_allotment_before_eligibility: 0 + ca_snap_meets_allotment_requirement: false + is_snap_eligible: false + snap: 0 + +# ACL 14-56 p. 6 and ACL 14-63 p. 2: deny zero allotments for 3+; +# retain the minimum for 1-2. FY2026 CDSS maximums: $785 (3), $994 (4). +# Calculated benefit is below the $24 minimum; net exceeds the regular standard. +- name: California MCE household of 1 with net income 1791 has a 24 dollar allotment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + earner: + age: 35 + employment_income: 30000 + weekly_hours_worked_before_lsr: 40 + spm_units: + unit: + members: + - earner + housing_cost: 0 + snap_utility_allowance: 0 + tax_units: + unit: + members: + - earner + households: + household: + members: + - earner + state_code: CA + output: + snap_net_income: 1791 + meets_snap_net_income_test: false + is_tanf_non_cash_eligible: true + meets_snap_categorical_eligibility: true + snap_allotment_before_eligibility: 24 + ca_snap_meets_allotment_requirement: true + is_snap_eligible: true + snap: 24 + +# ACL 14-56 p. 6 and ACL 14-63 p. 2: deny zero allotments for 3+; +# retain the minimum for 1-2. FY2026 CDSS maximums: $785 (3), $994 (4). +# Calculated benefit is below the $24 minimum; net exceeds the regular standard. +- name: California MCE household of 2 with net income 1924 has a 24 dollar allotment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + earner: + age: 35 + employment_income: 32000 + weekly_hours_worked_before_lsr: 40 + member_1: + age: 8 + spm_units: + unit: + members: + - earner + - member_1 + housing_cost: 0 + snap_utility_allowance: 0 + tax_units: + unit: + members: + - earner + - member_1 + households: + household: + members: + - earner + - member_1 + state_code: CA + output: + snap_net_income: 1924 + meets_snap_net_income_test: false + is_tanf_non_cash_eligible: true + meets_snap_categorical_eligibility: true + snap_allotment_before_eligibility: 24 + ca_snap_meets_allotment_requirement: true + is_snap_eligible: true + snap: 24 + +# ACL 14-56 p. 6 and ACL 14-63 p. 2: deny zero allotments for 3+; +# retain the minimum for 1-2. FY2026 CDSS maximums: $785 (3), $994 (4). +# Review regression: $5,000 gross - $1,000 earned deduction - $223 = $3,777; +# $994 - ceil($1,133.10) is negative, so the allotment and participation are zero. +- name: California MCE household of 4 with net income 3777 has a 0 dollar allotment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + earner: + age: 35 + employment_income: 60000 + weekly_hours_worked_before_lsr: 40 + member_1: + age: 8 + member_2: + age: 8 + member_3: + age: 8 + spm_units: + unit: + members: + - earner + - member_1 + - member_2 + - member_3 + housing_cost: 0 + snap_utility_allowance: 0 + tax_units: + unit: + members: + - earner + - member_1 + - member_2 + - member_3 + households: + household: + members: + - earner + - member_1 + - member_2 + - member_3 + state_code: CA + output: + snap_net_income: 3777 + meets_snap_net_income_test: false + is_tanf_non_cash_eligible: true + meets_snap_categorical_eligibility: true + snap_allotment_before_eligibility: 0 + ca_snap_meets_allotment_requirement: false + is_snap_eligible: false + snap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_child_support_integration.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_child_support_integration.yaml index 1b8a19ece66..1c5622f5610 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_child_support_integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_child_support_integration.yaml @@ -54,17 +54,23 @@ snap_child_support_gross_income_deduction: 433.33 snap_gross_income: 2_589.63 snap_child_support_deduction: 0 - # Without deemed SUA, net is $2,589.63 - $604.59 - $209 = $1,776.04. - # Rent $880 is below half-net $888.02, so there is no shelter deduction. - # Main's California net screen denies SNAP at $1,776 > $1,305. - # The independent California MCE correction is tracked in #10036. + # Without utility costs or heat-and-eat eligibility, no allowance is deemed. snap_utility_allowance: 0 + # The earned deduction uses full wages under 7 CFR 273.9(d)(2): + # $36,275.59 / 12 x 20% = $604.5931667, before excluding child support. + snap_earned_income_deduction: 604.59 + # Net before shelter: $2,589.6325 - $604.5931667 - $209 = $1,776.0393333. + snap_net_income_pre_shelter: 1_776.04 + # Rent $880 is below half-net $888.0196667, so shelter deduction is zero. snap_excess_shelter_expense_deduction: 0 snap_net_income: 1_776 - meets_tanf_non_cash_net_income_test: false - meets_snap_categorical_eligibility: false - is_snap_eligible: false - snap: 0 + meets_snap_net_income_test: false + meets_tanf_non_cash_net_income_test: true + meets_snap_categorical_eligibility: true + is_snap_eligible: true + # MCE retains the one-person minimum: $298 - ceil(30% x $1,776) + # = $298 - $533 = -$235, raised to $24 (CDSS MCE letter, page 3). + snap: 24 - name: New York excludes child support from gross income and does not deduct it again from net income. period: 2026-01 diff --git a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/federal/nutrition/snap/ca.yaml b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/federal/nutrition/snap/ca.yaml index da65546cf34..a7b1dd4aa89 100644 --- a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/federal/nutrition/snap/ca.yaml +++ b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/federal/nutrition/snap/ca.yaml @@ -1,15 +1,15 @@ # California (CalFresh) cases that differ from the federal.yaml (TX) baseline # for state-policy reasons: -# - CA applies the BBCE NET income test (net_applies CA = true), so the binding -# eligibility boundary is net income at 100% of the poverty guideline, not -# the 200% BBCE gross limit. -# - CA is an always-SUA state (SUA $663 in FY2026, applied without utility -# expense inputs). +# - CA MCE waives the net income test and uses a 200% poverty gross limit. +# Units with three or more members also need a positive allotment. +# - CA's FY2026 SUA is $663, but after the federal heat-and-eat restriction +# it requires heating/cooling expenses or elderly/disabled deeming. +# The households below have no qualifying utility expenses. # - CA extends CalFresh to additional immigration statuses (CFAP) and delays # the OBBB refugee exclusion to 2026-04-01 (ACL 25-92). -# SNAP compares income to the poverty guideline in effect at the preceding -# Oct 1: Jan-Sep 2026 use the 2025 FPG (3-person $26,650, i.e. a monthly net -# limit of $2,220.83); Oct-Dec 2026 use the 2026 FPG ($27,320 -> $2,276.67). +# SNAP uses the poverty guideline in effect at the preceding Oct 1: +# Jan-Sep 2026 use the 2025 FPG (3-person $26,650); Oct-Dec use the 2026 FPG +# ($27,320). The MCE gross limits are twice those guidelines. - name: snap_ca_net_income_just_below_fy2026_net_limit (ca) period: 2026 absolute_error_margin: 0.1 @@ -71,9 +71,9 @@ spm_units: spm_unit: # Gross ratio 36,000/26,650 = 1.35 fails the federal 130% test, but CA - # BBCE (200% gross + net test) rescues: net = 36,000/12 x 0.8 - 209 = - # 2,191.00 (SUA 663 < half of pre-shelter net, so no shelter deduction) - # <= 2,220.83 Jan-Sep limit -> eligible all year. EC = ceil(2,191 x + # MCE's 200% gross limit and waived net test permit participation. + # Net = 36,000/12 x 0.8 - 209 = 2,191.00, with no utility allowance + # or shelter deduction. EC = ceil(2,191 x # 0.3) = 658 -> 785 - 658 = 127.00/month Jan-Sep; Oct-Dec (FY2027): net # 2,400 - 217 = 2,183 -> EC ceil(654.90) = 655 -> 808 - 655 = 153.00. # Annual = 9 x 127.00 + 3 x 153.00 = 1,602.00. @@ -139,8 +139,8 @@ output: spm_units: spm_unit: - # At the binding CA net limit: net = 36,447/12 x 0.8 - 209 = 2,220.80, - # just under the Jan-Sep limit of 26,650/12 = 2,220.83 -> eligible. + # At the former model net limit: 36,447/12 x 0.8 - 209 = 2,220.80. + # MCE waives that test; the gross limit and positive allotment apply. # EC = ceil(2,221 x 0.3) = 667 -> 785 - 667 = 118.00/month # Jan-Sep; Oct-Dec (FY2027): net 2,212.80 rounds to 2,213 -> EC 664 -> # 808 - 664 = 144.00. Annual = 9 x 118.00 + 3 x 144.00 = 1,494.00. @@ -206,14 +206,13 @@ output: spm_units: spm_unit: - # Deliberate ineligible-side pin of CA's net-test route: net = - # 38,000/12 x 0.8 - 209 = 2,324.33 exceeds the net limit in every - # month (Jan-Sep 2,220.83; Oct-Dec: 2,316.95 > 2,276.67), and the - # federal 130% gross test also fails (ratio 1.43), so the unit is - # ineligible all year. In a no-net-test 200% state this income would - # be eligible. - snap: 0.0 - is_snap_eligible: false + # MCE waives the net test: $38,000 is below the 200% gross limit. + # No utility or shelter deduction; net before rounding is + # $2,324.33/$2,316.33. Positive allotments permit participation. + # FY2026/FY2027 net $2,324/$2,316; contribution $698/$695. + # SNAP $87/$113/month; annual 9 x 87 + 3 x 113 = $1,122. + snap: 1122.0 + is_snap_eligible: true - name: snap_ca_head_immigration_refugee_cfap_transition (ca) period: 2026 absolute_error_margin: 0.1 diff --git a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/ca.yaml b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/ca.yaml index ba2c6a460ad..310c1e633cd 100644 --- a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/ca.yaml +++ b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/ca.yaml @@ -560,11 +560,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -936,11 +938,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -1903,11 +1907,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,946/$2,936; contribution $884/$881. + # SNAP $110/$142/month; annual 9 x 110 + 3 x 142 = $1,416. + snap: 1416.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -2291,11 +2297,13 @@ ca_tanf_eligible: false housing_assistance: 0.0 is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -2674,11 +2682,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,946/$2,936; contribution $884/$881. + # SNAP $110/$142/month; annual 9 x 110 + 3 x 142 = $1,416. + snap: 1416.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -2874,11 +2884,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,946/$2,936; contribution $884/$881. + # SNAP $110/$142/month; annual 9 x 110 + 3 x 142 = $1,416. + snap: 1416.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -3258,11 +3270,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -4599,11 +4613,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -4795,11 +4811,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,946/$2,936; contribution $884/$881. + # SNAP $110/$142/month; annual 9 x 110 + 3 x 142 = $1,416. + snap: 1416.0 people: head: ca_ala_general_assistance_eligible_person: false @@ -4993,11 +5011,13 @@ ca_tanf: 0.0 ca_tanf_eligible: false is_lifeline_eligible: true - is_snap_eligible: false + is_snap_eligible: true la_general_relief: 0.0 la_general_relief_eligible: false lifeline: 228.0 - snap: 0.0 + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: ca_ala_general_assistance_eligible_person: false diff --git a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/federal.yaml b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/federal.yaml index eb5e62d1ebb..365f6606236 100644 --- a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/federal.yaml +++ b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/signatures/federal.yaml @@ -167,8 +167,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: is_wic_eligible: false @@ -352,8 +354,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,796/$2,781; contribution $839/$835. + # SNAP $155/$188/month; annual 9 x 155 + 3 x 188 = $1,959. + snap: 1959.0 people: head: is_wic_eligible: false @@ -514,8 +518,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,966/$2,957; contribution $890/$888. + # SNAP $104/$135/month; annual 9 x 104 + 3 x 135 = $1,341. + snap: 1341.0 people: head: is_wic_eligible: false @@ -617,8 +623,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,966/$2,957; contribution $890/$888. + # SNAP $104/$135/month; annual 9 x 104 + 3 x 135 = $1,341. + snap: 1341.0 people: head: is_wic_eligible: false @@ -724,8 +732,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: is_wic_eligible: false @@ -1048,8 +1058,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: is_wic_eligible: false @@ -1148,8 +1160,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,946/$2,936; contribution $884/$881. + # SNAP $110/$142/month; annual 9 x 110 + 3 x 142 = $1,416. + snap: 1416.0 people: head: is_wic_eligible: false @@ -1248,8 +1262,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: is_wic_eligible: false @@ -1348,8 +1364,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,966/$2,957; contribution $890/$888. + # SNAP $104/$135/month; annual 9 x 104 + 3 x 135 = $1,341. + snap: 1341.0 people: head: is_wic_eligible: false @@ -1455,8 +1473,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: is_wic_eligible: false @@ -1550,8 +1570,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,977/$2,971; contribution $894/$892. + # SNAP $100/$131/month; annual 9 x 100 + 3 x 131 = $1,293. + snap: 1293.0 people: head: is_wic_eligible: false @@ -1649,8 +1671,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,966/$2,957; contribution $890/$888. + # SNAP $104/$135/month; annual 9 x 104 + 3 x 135 = $1,341. + snap: 1341.0 people: head: is_wic_eligible: false @@ -1760,8 +1784,10 @@ output: spm_units: spm_unit: - is_snap_eligible: false - snap: 0.0 + is_snap_eligible: true + # FY2026/FY2027 net $2,796/$2,781; contribution $839/$835. + # SNAP $155/$188/month; annual 9 x 155 + 3 x 188 = $1,959. + snap: 1959.0 people: head: is_wic_eligible: false diff --git a/policyengine_us/variables/gov/states/ca/cdss/snap/eligibility/ca_snap_meets_allotment_requirement.py b/policyengine_us/variables/gov/states/ca/cdss/snap/eligibility/ca_snap_meets_allotment_requirement.py new file mode 100644 index 00000000000..e08cd546c6d --- /dev/null +++ b/policyengine_us/variables/gov/states/ca/cdss/snap/eligibility/ca_snap_meets_allotment_requirement.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class ca_snap_meets_allotment_requirement(Variable): + value_type = bool + entity = SPMUnit + definition_period = MONTH + default_value = True + defined_for = StateCode.CA + label = "Meets California SNAP allotment requirement" + documentation = ( + "California denies or discontinues CE/MCE households of three or more " + "with zero calculated allotments. One- and two-person households retain " + "their minimum allotment. Applies from the model's October 2015 MCE " + "baseline; initial-month proration and issuance exceptions are not modeled." + ) + reference = ( + "https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-56.pdf#page=6", + "https://www.cdss.ca.gov/lettersnotices/entres/getinfo/acl/2014/14-63.pdf#page=2", + "https://www.law.cornell.edu/cfr/text/7/273.10#e_2_iii", + ) + + def formula_2015_10_01(spm_unit, period, parameters): + allotment = spm_unit("snap_allotment_before_eligibility", period) + # This is a participation screen, not the regular net-income test. + return allotment > 0 diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/is_snap_eligible.py b/policyengine_us/variables/gov/usda/snap/eligibility/is_snap_eligible.py index b9c750f0bc1..67cbb06fb33 100644 --- a/policyengine_us/variables/gov/usda/snap/eligibility/is_snap_eligible.py +++ b/policyengine_us/variables/gov/usda/snap/eligibility/is_snap_eligible.py @@ -31,4 +31,11 @@ def formula(spm_unit, period, parameters): eligible_member_present = spm_unit.any( ~person("is_snap_excluded_member", period) ) - return (normal_eligibility | categorical_eligibility) & eligible_member_present + ca_allotment_requirement = spm_unit( + "ca_snap_meets_allotment_requirement", period + ) + return ( + (normal_eligibility | categorical_eligibility) + & eligible_member_present + & ca_allotment_requirement + ) diff --git a/policyengine_us/variables/gov/usda/snap/snap_allotment_before_eligibility.py b/policyengine_us/variables/gov/usda/snap/snap_allotment_before_eligibility.py new file mode 100644 index 00000000000..cd441016abb --- /dev/null +++ b/policyengine_us/variables/gov/usda/snap/snap_allotment_before_eligibility.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class snap_allotment_before_eligibility(Variable): + value_type = float + entity = SPMUnit + definition_period = MONTH + label = "SNAP allotment before eligibility screening" + documentation = ( + "Calculated SNAP allotment, including the minimum for one- and two-person " + "units, before eligibility screening. This allows zero-allotment " + "participation rules to use the benefit calculation without a cycle." + ) + reference = "https://www.law.cornell.edu/cfr/text/7/273.10#e_2_ii" + unit = USD + + def formula(spm_unit, period, parameters): + expected_contribution = spm_unit("snap_expected_contribution", period) + max_allotment = spm_unit("snap_max_allotment", period) + min_allotment = spm_unit("snap_min_allotment", period) + return max_(min_allotment, max_allotment - expected_contribution) diff --git a/policyengine_us/variables/gov/usda/snap/snap_normal_allotment.py b/policyengine_us/variables/gov/usda/snap/snap_normal_allotment.py index 49c8d33f261..972f42faf67 100644 --- a/policyengine_us/variables/gov/usda/snap/snap_normal_allotment.py +++ b/policyengine_us/variables/gov/usda/snap/snap_normal_allotment.py @@ -13,11 +13,4 @@ class snap_normal_allotment(Variable): unit = USD defined_for = "is_snap_eligible" - def formula(spm_unit, period, parameters): - # Federal SNAP rules are defined in U.S.C Title 7, Chapter 51, which - # also defines state powers to modify the rules. - expected_contribution = spm_unit("snap_expected_contribution", period) - max_allotment = spm_unit("snap_max_allotment", period) - normal_allotment = max_allotment - expected_contribution - min_allotment = spm_unit("snap_min_allotment", period) - return max_(min_allotment, normal_allotment) + adds = ["snap_allotment_before_eligibility"]