From 728bdab4496b90b23e7a60ed3c905f4769a4205e Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 21 May 2026 17:12:11 -0400 Subject: [PATCH 1/3] Fix SNAP work requirement issues --- .../fixed/snap-work-requirement-issues.md | 1 + .../meets_snap_abawd_work_requirements.yaml | 26 +++++++- .../meets_snap_work_requirements.yaml | 62 ++++++++++++++++++- .../is_snap_abawd_indian_exempt.py | 13 ++++ .../meets_snap_abawd_work_requirements.py | 11 ++-- .../meets_snap_work_requirements.py | 8 ++- 6 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 changelog.d/fixed/snap-work-requirement-issues.md create mode 100644 policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py diff --git a/changelog.d/fixed/snap-work-requirement-issues.md b/changelog.d/fixed/snap-work-requirement-issues.md new file mode 100644 index 00000000000..fbabfecc4b1 --- /dev/null +++ b/changelog.d/fixed/snap-work-requirement-issues.md @@ -0,0 +1 @@ +Fix SNAP work-requirement treatment for per-person disqualifications and OBBBA ABAWD Indian exemptions. diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.yaml index 71f049a8119..a981c0dc15e 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.yaml @@ -345,9 +345,31 @@ output: meets_snap_abawd_work_requirements: true +# --- 2015(o)(3)(F)-(G): Indian, Urban Indian, or California Indian --- + +- name: Case 24, post-HR1 Indian, Urban Indian, or California Indian exempt. + period: 2027 + input: + age: 30 + weekly_hours_worked_before_lsr: 1 + is_disabled: false + is_snap_abawd_indian_exempt: true + output: + meets_snap_abawd_work_requirements: true + +- name: Case 25, pre-HR1 Indian exemption input does not change ABAWD rules. + period: 2024 + input: + age: 30 + weekly_hours_worked_before_lsr: 1 + is_disabled: false + is_snap_abawd_indian_exempt: true + output: + meets_snap_abawd_work_requirements: false + # --- HR1 removed exemptions: Homeless and veteran --- -- name: Case 24, post-HR1 homeless NOT exempt. +- name: Case 26, post-HR1 homeless NOT exempt. period: 2027 absolute_error_margin: 0.1 input: @@ -358,7 +380,7 @@ output: meets_snap_abawd_work_requirements: false -- name: Case 25, post-HR1 veteran NOT exempt. +- name: Case 27, post-HR1 veteran NOT exempt. period: 2027 absolute_error_margin: 0.1 input: diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.yaml index f1664d91c34..4236000edfe 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.yaml @@ -40,7 +40,6 @@ - name: Case 5, CA pre-HR1 age 55 exempt flows through SPM. period: 2026-01 - absolute_error_margin: 0.9 input: people: person1: @@ -63,7 +62,6 @@ - name: Case 6, non-CA post-HR1 age 55 not exempt. period: 2026-01 - absolute_error_margin: 0.9 input: people: person1: @@ -83,3 +81,63 @@ state_code: TX output: meets_snap_work_requirements: false + +- name: Case 7, two adults remain eligible when one adult passes. + period: 2024-01 + input: + people: + person1: + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + person2: + monthly_age: 30 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + spm_units: + spm_unit: + members: [person1, person2] + output: + meets_snap_work_requirements: true + +- name: Case 8, two adults are ineligible when both adults fail. + period: 2024-01 + input: + people: + person1: + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + person2: + monthly_age: 30 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + spm_units: + spm_unit: + members: [person1, person2] + output: + meets_snap_work_requirements: false + +- name: Case 9, two adults remain eligible when both adults pass. + period: 2024-01 + input: + people: + person1: + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + person2: + monthly_age: 30 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + spm_units: + spm_unit: + members: [person1, person2] + output: + meets_snap_work_requirements: true diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py new file mode 100644 index 00000000000..ed104d54a0f --- /dev/null +++ b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class is_snap_abawd_indian_exempt(Variable): + value_type = bool + entity = Person + label = "Exempt from SNAP ABAWD work requirements due to Indian, Urban Indian, or California Indian status" + definition_period = YEAR + reference = ( + "https://www.congress.gov/119/plaws/publ21/PLAW-119publ21.pdf#page=82", + "https://www.law.cornell.edu/uscode/text/25/1603", + "https://www.law.cornell.edu/uscode/text/25/1679", + ) diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.py b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.py index 35aa7393843..dfc4491f6ca 100644 --- a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.py +++ b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_abawd_work_requirements.py @@ -42,10 +42,9 @@ def formula(person, period, parameters): # (D) Work registration exempt (non-age) — 7 U.S.C. 2015(o)(3)(D) work_reg_exempt = person("is_snap_work_registration_exempt_non_age", period) # (E) Pregnant — 7 U.S.C. 2015(o)(3)(E) - # NOTE: (F)-(G) Native American/Indian exemptions per IHCIA - # definitions are not yet implemented (requires tribal - # membership input variable). is_pregnant = person("is_pregnant", period) + # (F)-(G) Indian, Urban Indian, or California Indian. + is_indian_exempt = person("is_snap_abawd_indian_exempt", period) # TODO: HI/AK delayed adoption (2025-11-01) to be handled # in a follow-up PR via state-level hr1_in_effect parameters. base_conditions = ( @@ -59,8 +58,10 @@ def formula(person, period, parameters): # Pre-HR1 exemptions: homeless, veteran is_homeless = person.household("is_homeless", period) is_veteran = person("is_veteran", period) + post_hr1_conditions = base_conditions | is_indian_exempt + pre_hr1_conditions = base_conditions | is_homeless | is_veteran return where( hr1_in_effect, - base_conditions, - base_conditions | is_homeless | is_veteran, + post_hr1_conditions, + pre_hr1_conditions, ) diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py index 56aa32bc660..56202daf1a2 100644 --- a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py +++ b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py @@ -6,7 +6,11 @@ class meets_snap_work_requirements(Variable): entity = SPMUnit label = "SPM Unit is eligible for SNAP benefits via work requirements" definition_period = MONTH - reference = "https://www.fns.usda.gov/snap/work-requirements" + reference = ( + "https://www.fns.usda.gov/snap/work-requirements", + "https://www.law.cornell.edu/cfr/text/7/273.7#f_1", + "https://www.law.cornell.edu/cfr/text/7/273.24#b", + ) def formula(spm_unit, period, parameters): person = spm_unit.members @@ -31,4 +35,4 @@ def formula(spm_unit, period, parameters): abawd_work_requirements & general_work_requirements, general_work_requirements, ) - return spm_unit.sum(~meets_work_requirements_person) == 0 + return spm_unit.any(meets_work_requirements_person) From b0914d89421fa7204f1893a412eaea6cafa26d44 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Mon, 25 May 2026 14:57:46 -0400 Subject: [PATCH 2/3] Fix SNAP work requirement exclusions --- .../federal_work_study_income_exclusion.yaml | 24 ++++++ .../snap/income/snap_unearned_income.yaml | 24 ++++++ .../policy/baseline/gov/usda/snap/snap.yaml | 74 +++++++++++++++++++ .../gov/usda/snap/snap_unit_size.yaml | 21 ++++++ .../is_snap_abawd_indian_exempt.py | 3 +- .../meets_snap_work_requirements.py | 23 +----- .../meets_snap_work_requirements_person.py | 36 +++++++++ .../usda/snap/income/snap_earned_income.py | 14 +++- .../usda/snap/income/snap_unearned_income.py | 6 +- .../income/snap_unearned_income_person.py | 13 ++++ ...k_requirement_income_proration_fraction.py | 16 ++++ .../variables/gov/usda/snap/snap_unit_size.py | 6 +- 12 files changed, 233 insertions(+), 27 deletions(-) create mode 100644 policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements_person.py create mode 100644 policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py create mode 100644 policyengine_us/variables/gov/usda/snap/income/snap_work_requirement_income_proration_fraction.py diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/income/federal_work_study_income_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/income/federal_work_study_income_exclusion.yaml index bec6d11b2cc..b0214a4a966 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/income/federal_work_study_income_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/income/federal_work_study_income_exclusion.yaml @@ -22,3 +22,27 @@ is_federal_work_study_participant: true output: meets_snap_work_exception: true + +- name: Case 4, work-requirement-ineligible adult earned income is prorated. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + person2: + monthly_age: 30 + is_tax_unit_dependent: false + employment_income: + 2024: 12_000 + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + spm_units: + spm_unit: + members: [person1, person2] + output: + snap_work_requirement_income_proration_fraction: [1, 0.5] + snap_earned_income: 500 diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml index 4e42d3cdfcb..91c522092e6 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml @@ -16,3 +16,27 @@ retirement_distributions: 1_000 output: snap_unearned_income: 1_000 + +- name: Case 4, work-requirement-ineligible adult unearned income is prorated. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + person2: + monthly_age: 30 + is_tax_unit_dependent: false + pension_income: + 2024: 12_000 + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + spm_units: + spm_unit: + members: [person1, person2] + output: + snap_work_requirement_income_proration_fraction: [1, 0.5] + snap_unearned_income: 500 diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml index 7fec755e685..049e0d79fed 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml @@ -116,3 +116,77 @@ # And then again subtracted as a deduction from gross income. snap_net_income: 0 snap: 3_522 + +- name: Case 5, work-requirement-ineligible adult is excluded from SNAP benefit size. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 35 + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + person2: + age: + 2024: 30 + monthly_age: 30 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: TX + output: + meets_snap_work_requirements_person: [true, false] + meets_snap_work_requirements: true + snap_unit_size: 1 + snap_max_allotment: 291 + snap: 291 + +- name: Case 6, work-requirement-ineligible adult income is prorated for SNAP. + period: 2024-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2024: 35 + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + person2: + age: + 2024: 30 + monthly_age: 30 + is_tax_unit_dependent: false + employment_income: + 2024: 12_000 + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: TX + output: + snap_unit_size: 1 + snap_work_requirement_income_proration_fraction: [1, 0.5] + snap_earned_income: 500 + snap_gross_income: 500 + snap: 230.40 diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_unit_size.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_unit_size.yaml index 8ae05db6bc2..76ffa386d72 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_unit_size.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap_unit_size.yaml @@ -160,3 +160,24 @@ spm_unit_size: 2 output: snap_unit_size: 1 + +- name: Case 10, work-requirement-ineligible adult reduces unit size. + period: 2024-01 + input: + people: + person1: + monthly_age: 35 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: true + meets_snap_abawd_work_requirements: true + person2: + monthly_age: 30 + is_tax_unit_dependent: false + meets_snap_general_work_requirements: false + meets_snap_abawd_work_requirements: false + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_size: 2 + output: + snap_unit_size: 1 diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py index ed104d54a0f..25a2b0e50e6 100644 --- a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py +++ b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/is_snap_abawd_indian_exempt.py @@ -7,7 +7,8 @@ class is_snap_abawd_indian_exempt(Variable): label = "Exempt from SNAP ABAWD work requirements due to Indian, Urban Indian, or California Indian status" definition_period = YEAR reference = ( - "https://www.congress.gov/119/plaws/publ21/PLAW-119publ21.pdf#page=82", + "https://www.congress.gov/119/plaws/publ21/PLAW-119publ21.pdf#page=11", + "https://www.congress.gov/119/plaws/publ21/PLAW-119publ21.pdf#page=12", "https://www.law.cornell.edu/uscode/text/25/1603", "https://www.law.cornell.edu/uscode/text/25/1679", ) diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py index 56202daf1a2..69ee5bf0f6e 100644 --- a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py +++ b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements.py @@ -14,25 +14,4 @@ class meets_snap_work_requirements(Variable): def formula(spm_unit, period, parameters): person = spm_unit.members - general_work_requirements = person( - "meets_snap_general_work_requirements", period - ) - abawd_work_requirements = person("meets_snap_abawd_work_requirements", period) - # Dependent child threshold differs: pre-HR1 (18) vs post-HR1 (14) - hr1_in_effect = person("is_snap_abawd_hr1_in_effect", period) - p = parameters(period).gov.usda.snap.work_requirements.abawd.age_threshold - # Snapshot pre-HR1 values (last month before 2025-07-04 effective date). - p_pre = parameters( - "2025-06-01" - ).gov.usda.snap.work_requirements.abawd.age_threshold - dep_threshold = where(hr1_in_effect, p.dependent, p_pre.dependent) - age = person("monthly_age", period) - is_dependent = person("is_tax_unit_dependent", period) - is_child = age < dep_threshold - no_dependent_child = person.spm_unit.sum(is_dependent & is_child) == 0 - meets_work_requirements_person = where( - no_dependent_child, - abawd_work_requirements & general_work_requirements, - general_work_requirements, - ) - return spm_unit.any(meets_work_requirements_person) + return spm_unit.any(person("meets_snap_work_requirements_person", period)) diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements_person.py b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements_person.py new file mode 100644 index 00000000000..05a68843506 --- /dev/null +++ b/policyengine_us/variables/gov/usda/snap/eligibility/work_requirements/meets_snap_work_requirements_person.py @@ -0,0 +1,36 @@ +from policyengine_us.model_api import * + + +class meets_snap_work_requirements_person(Variable): + value_type = bool + entity = Person + label = "Person is eligible for SNAP benefits via work requirements" + definition_period = MONTH + reference = ( + "https://www.fns.usda.gov/snap/work-requirements", + "https://www.law.cornell.edu/cfr/text/7/273.7#f_1", + "https://www.law.cornell.edu/cfr/text/7/273.24#b", + ) + + def formula(person, period, parameters): + general_work_requirements = person( + "meets_snap_general_work_requirements", period + ) + abawd_work_requirements = person("meets_snap_abawd_work_requirements", period) + # Dependent child threshold differs: pre-HR1 (18) vs post-HR1 (14) + hr1_in_effect = person("is_snap_abawd_hr1_in_effect", period) + p = parameters(period).gov.usda.snap.work_requirements.abawd.age_threshold + # Snapshot pre-HR1 values (last month before 2025-07-04 effective date). + p_pre = parameters( + "2025-06-01" + ).gov.usda.snap.work_requirements.abawd.age_threshold + dep_threshold = where(hr1_in_effect, p.dependent, p_pre.dependent) + age = person("monthly_age", period) + is_dependent = person("is_tax_unit_dependent", period) + is_child = age < dep_threshold + no_dependent_child = person.spm_unit.sum(is_dependent & is_child) == 0 + return where( + no_dependent_child, + abawd_work_requirements & general_work_requirements, + general_work_requirements, + ) diff --git a/policyengine_us/variables/gov/usda/snap/income/snap_earned_income.py b/policyengine_us/variables/gov/usda/snap/income/snap_earned_income.py index 231f1e5356c..eaef5e8148e 100644 --- a/policyengine_us/variables/gov/usda/snap/income/snap_earned_income.py +++ b/policyengine_us/variables/gov/usda/snap/income/snap_earned_income.py @@ -10,4 +10,16 @@ class snap_earned_income(Variable): reference = "https://www.law.cornell.edu/cfr/text/7/273.9#b_1" unit = USD - adds = ["snap_earned_income_person"] + def formula(spm_unit, period): + person = spm_unit.members + income = spm_unit("snap_earned_income_person", period) + countable_earner = person("snap_countable_earner", period) + employment_income = person("employment_income", period) + full_employment_income = spm_unit.sum( + where(countable_earner, employment_income, 0) + ) + fraction = person("snap_work_requirement_income_proration_fraction", period) + prorated_employment_income = spm_unit.sum( + where(countable_earner, employment_income * fraction, 0) + ) + return income - full_employment_income + prorated_employment_income diff --git a/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py b/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py index 0d6b5368aa2..fdf70afd69f 100644 --- a/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py +++ b/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py @@ -10,4 +10,8 @@ class snap_unearned_income(Variable): reference = "https://www.law.cornell.edu/cfr/text/7/273.9#b_2" unit = USD - adds = "gov.usda.snap.income.sources.unearned" + def formula(spm_unit, period): + person = spm_unit.members + income = person("snap_unearned_income_person", period) + fraction = person("snap_work_requirement_income_proration_fraction", period) + return spm_unit.sum(income * fraction) diff --git a/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py b/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py new file mode 100644 index 00000000000..73e737ecec5 --- /dev/null +++ b/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class snap_unearned_income_person(Variable): + value_type = float + entity = Person + definition_period = MONTH + label = "SNAP unearned income for each person" + documentation = "Unearned income for calculating the SNAP benefit" + reference = "https://www.law.cornell.edu/cfr/text/7/273.9#b_2" + unit = USD + + adds = "gov.usda.snap.income.sources.unearned" diff --git a/policyengine_us/variables/gov/usda/snap/income/snap_work_requirement_income_proration_fraction.py b/policyengine_us/variables/gov/usda/snap/income/snap_work_requirement_income_proration_fraction.py new file mode 100644 index 00000000000..c2c73fdef06 --- /dev/null +++ b/policyengine_us/variables/gov/usda/snap/income/snap_work_requirement_income_proration_fraction.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class snap_work_requirement_income_proration_fraction(Variable): + value_type = float + entity = Person + label = "SNAP work requirement income proration fraction" + definition_period = MONTH + reference = "https://www.law.cornell.edu/cfr/text/7/273.11#c_2" + + def formula(person, period, parameters): + meets_work_requirements = person("meets_snap_work_requirements_person", period) + snap_unit_size = person.spm_unit("snap_unit_size", period) + unit_size = person.spm_unit("spm_unit_size", period) + ineligible_fraction = where(unit_size > 0, snap_unit_size / unit_size, 0) + return where(meets_work_requirements, 1, ineligible_fraction) diff --git a/policyengine_us/variables/gov/usda/snap/snap_unit_size.py b/policyengine_us/variables/gov/usda/snap/snap_unit_size.py index d4e9ab9194f..dbb0b2f4d0f 100644 --- a/policyengine_us/variables/gov/usda/snap/snap_unit_size.py +++ b/policyengine_us/variables/gov/usda/snap/snap_unit_size.py @@ -14,8 +14,10 @@ class snap_unit_size(Variable): def formula(spm_unit, period, parameters): unit_size = spm_unit("spm_unit_size", period) person = spm_unit.members - ineligible = person("is_snap_ineligible_student", period) | ~person( - "is_snap_immigration_status_eligible", period + ineligible = ( + person("is_snap_ineligible_student", period) + | ~person("is_snap_immigration_status_eligible", period) + | ~person("meets_snap_work_requirements_person", period) ) ineligible_count = spm_unit.sum(ineligible) return max_(unit_size - ineligible_count, 0) From d3d4fa7df57b09c5db75889bd060793c42aa005e Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Mon, 25 May 2026 16:03:26 -0400 Subject: [PATCH 3/3] Fix SNAP partner regressions --- .../snap/income/snap_unearned_income.yaml | 24 ------------------- .../usda/snap/income/snap_unearned_income.py | 6 +---- .../income/snap_unearned_income_person.py | 13 ---------- 3 files changed, 1 insertion(+), 42 deletions(-) delete mode 100644 policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml index 91c522092e6..4e42d3cdfcb 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/income/snap_unearned_income.yaml @@ -16,27 +16,3 @@ retirement_distributions: 1_000 output: snap_unearned_income: 1_000 - -- name: Case 4, work-requirement-ineligible adult unearned income is prorated. - period: 2024-01 - absolute_error_margin: 0.01 - input: - people: - person1: - monthly_age: 35 - is_tax_unit_dependent: false - meets_snap_general_work_requirements: true - meets_snap_abawd_work_requirements: true - person2: - monthly_age: 30 - is_tax_unit_dependent: false - pension_income: - 2024: 12_000 - meets_snap_general_work_requirements: false - meets_snap_abawd_work_requirements: false - spm_units: - spm_unit: - members: [person1, person2] - output: - snap_work_requirement_income_proration_fraction: [1, 0.5] - snap_unearned_income: 500 diff --git a/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py b/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py index fdf70afd69f..0d6b5368aa2 100644 --- a/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py +++ b/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income.py @@ -10,8 +10,4 @@ class snap_unearned_income(Variable): reference = "https://www.law.cornell.edu/cfr/text/7/273.9#b_2" unit = USD - def formula(spm_unit, period): - person = spm_unit.members - income = person("snap_unearned_income_person", period) - fraction = person("snap_work_requirement_income_proration_fraction", period) - return spm_unit.sum(income * fraction) + adds = "gov.usda.snap.income.sources.unearned" diff --git a/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py b/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py deleted file mode 100644 index 73e737ecec5..00000000000 --- a/policyengine_us/variables/gov/usda/snap/income/snap_unearned_income_person.py +++ /dev/null @@ -1,13 +0,0 @@ -from policyengine_us.model_api import * - - -class snap_unearned_income_person(Variable): - value_type = float - entity = Person - definition_period = MONTH - label = "SNAP unearned income for each person" - documentation = "Unearned income for calculating the SNAP benefit" - reference = "https://www.law.cornell.edu/cfr/text/7/273.9#b_2" - unit = USD - - adds = "gov.usda.snap.income.sources.unearned"