From 5a84b40bfd6948d85925a71e2ddf3a6dad141ac9 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 23 Dec 2025 18:24:10 -0500 Subject: [PATCH 1/3] Initial commit for New Mexico TANF implementation Starting implementation of New Mexico TANF program. Documentation and parallel development will follow. Closes #7038 From 764c2bdd5d53161ad8cc35c94845c26de23b2eb2 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 23 Dec 2025 19:32:21 -0500 Subject: [PATCH 2/3] Add New Mexico TANF (New Mexico Works) program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the New Mexico Health Care Authority's Temporary Family Assistance program including: - Eligibility determination (income, demographic, immigration) - Income limit calculations (85% FPL gross test) - Payment standard calculations by family size - Income deductions (work incentive, child care, child support) - Benefit calculation (payment standard minus countable income) - Comprehensive integration and unit tests (122 tests) All variables include regulatory citations from 8.102 NMAC. Closes #7038 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- changelog_entry.yaml | 4 + .../age_threshold/high_school_student.yaml | 12 + .../hca/tanf/age_threshold/minor_child.yaml | 12 + .../tanf/age_threshold/special_education.yaml | 14 + .../states/nm/hca/tanf/diversion/amount.yaml | 21 + .../income/deductions/child_care/amount.yaml | 21 + .../deductions/child_support/disregard.yaml | 12 + .../deductions/child_support/passthrough.yaml | 23 + .../non_benefit_group/amount.yaml | 12 + .../work_incentive/other_member/amount.yaml | 12 + .../deductions/work_incentive/rate.yaml | 12 + .../work_incentive/single_parent/amount.yaml | 12 + .../work_incentive/two_parent/amount.yaml | 12 + .../nm/hca/tanf/income/gross_limit/rate.yaml | 12 + .../income/self_employment/mileage_rate.yaml | 12 + .../payment_standard/additional_person.yaml | 14 + .../nm/hca/tanf/payment_standard/amount.yaml | 52 ++ .../tanf/payment_standard/max_unit_size.yaml | 12 + .../nm/hca/tanf/resources/liquid/amount.yaml | 12 + .../hca/tanf/resources/non_liquid/amount.yaml | 12 + .../hca/tanf/sanctions/first_level_rate.yaml | 12 + .../hca/tanf/sanctions/second_level_rate.yaml | 12 + .../school_clothing_allowance/august.yaml | 12 + .../school_clothing_allowance/january.yaml | 12 + .../support_services/income_limit_rate.yaml | 12 + .../nm/hca/tanf/transition_bonus/amount.yaml | 14 + .../transition_bonus/income_limit_rate.yaml | 12 + .../transition_bonus/minimum_work_hours.yaml | 12 + .../gov/states/nm/hca/tanf/integration.yaml | 571 ++++++++++++++++++ .../gov/states/nm/hca/tanf/nm_tanf.yaml | 182 ++++++ .../tanf/nm_tanf_child_care_deduction.yaml | 325 ++++++++++ .../tanf/nm_tanf_countable_earned_income.yaml | 134 ++++ .../nm/hca/tanf/nm_tanf_countable_income.yaml | 57 ++ .../nm_tanf_countable_unearned_income.yaml | 362 +++++++++++ .../tanf/nm_tanf_earned_income_deduction.yaml | 428 +++++++++++++ .../states/nm/hca/tanf/nm_tanf_eligible.yaml | 53 ++ .../tanf/nm_tanf_gross_income_eligible.yaml | 269 +++++++++ .../nm/hca/tanf/nm_tanf_maximum_benefit.yaml | 97 +++ .../hca/tanf/nm_tanf_net_income_eligible.yaml | 277 +++++++++ .../hca/tanf/eligibility/nm_tanf_eligible.py | 32 + .../nm_tanf_gross_income_eligible.py | 18 + .../nm_tanf_net_income_eligible.py | 17 + .../income/nm_tanf_child_care_deduction.py | 28 + .../income/nm_tanf_child_support_deduction.py | 38 ++ .../income/nm_tanf_countable_earned_income.py | 16 + .../tanf/income/nm_tanf_countable_income.py | 23 + .../nm_tanf_countable_unearned_income.py | 18 + .../income/nm_tanf_earned_income_deduction.py | 13 + .../nm_tanf_earned_income_deduction_person.py | 44 ++ .../hca/tanf/income/nm_tanf_gross_income.py | 13 + .../gov/states/nm/hca/tanf/nm_tanf.py | 21 + .../nm/hca/tanf/nm_tanf_maximum_benefit.py | 20 + sources/working_references.md | 529 ++++++++++++++++ 53 files changed, 3988 insertions(+) create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/high_school_student.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/minor_child.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/special_education.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_care/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/disregard.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/passthrough.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/non_benefit_group/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/other_member/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/rate.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/single_parent/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/two_parent/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/gross_limit/rate.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/income/self_employment/mileage_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/additional_person.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/max_unit_size.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/resources/liquid/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/resources/non_liquid/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/first_level_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/second_level_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/august.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/january.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/support_services/income_limit_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/income_limit_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/minimum_work_hours.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_care_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_earned_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_unearned_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_earned_income_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_care_deduction.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_support_deduction.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_earned_income.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_unearned_income.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction_person.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_gross_income.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf.py create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.py create mode 100644 sources/working_references.md diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..d2df549659a 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Add New Mexico TANF (New Mexico Works) program diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/high_school_student.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/high_school_student.yaml new file mode 100644 index 00000000000..1734293b625 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/high_school_student.yaml @@ -0,0 +1,12 @@ +description: New Mexico extends Temporary Assistance for Needy Families eligibility to high school students through this age. + +values: + 2020-01-01: 19 + +metadata: + unit: year + period: year + label: New Mexico TANF high school student age threshold + reference: + - title: 8.102.100.7(R) NMAC - General Provisions + href: https://www.srca.nm.gov/parts/title08/08.102.0100.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/minor_child.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/minor_child.yaml new file mode 100644 index 00000000000..7d5aa47d4e2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/minor_child.yaml @@ -0,0 +1,12 @@ +description: New Mexico limits the Temporary Assistance for Needy Families program to applicants with children younger than this age. + +values: + 2020-01-01: 18 + +metadata: + unit: year + period: year + label: New Mexico TANF minor child age threshold + reference: + - title: 8.102.100.7(R) NMAC - General Provisions + href: https://www.srca.nm.gov/parts/title08/08.102.0100.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/special_education.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/special_education.yaml new file mode 100644 index 00000000000..cf8599a5711 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/age_threshold/special_education.yaml @@ -0,0 +1,14 @@ +description: New Mexico extends Temporary Assistance for Needy Families eligibility to special education students through this age. + +values: + 2020-01-01: 22 + +metadata: + unit: year + period: year + label: New Mexico TANF special education age threshold + reference: + - title: 8.102.420.8 NMAC - Benefit Group Composition + href: https://www.srca.nm.gov/parts/title08/08.102.0420.html + - title: 8.102.100.7(R) NMAC - General Provisions + href: https://www.srca.nm.gov/parts/title08/08.102.0100.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml new file mode 100644 index 00000000000..57729bd1e63 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml @@ -0,0 +1,21 @@ +description: New Mexico provides this one-time diversion payment in lieu of ongoing cash assistance under the Temporary Assistance for Needy Families program. + +metadata: + period: month + label: New Mexico TANF diversion payment amount + type: single_amount + threshold_unit: person + amount_unit: currency-USD + reference: + - title: 8.102.100 NMAC - General Provisions + href: https://www.srca.nm.gov/parts/title08/08.102.0100.html + +brackets: + - threshold: + 2020-01-01: 1 + amount: + 2020-01-01: 1_500 + - threshold: + 2020-01-01: 4 + amount: + 2020-01-01: 2_500 diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_care/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_care/amount.yaml new file mode 100644 index 00000000000..35c928413a4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_care/amount.yaml @@ -0,0 +1,21 @@ +description: New Mexico deducts up to this amount of child care expenses per child from countable income under the Temporary Assistance for Needy Families program. + +metadata: + period: month + label: New Mexico TANF child care deduction amount + type: single_amount + threshold_unit: year + amount_unit: currency-USD + reference: + - title: 8.102.520.12 NMAC - Earned Income Deductions + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html + +brackets: + - threshold: + 2020-01-01: 0 + amount: + 2020-01-01: 200 + - threshold: + 2020-01-01: 2 + amount: + 2020-01-01: 175 diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/disregard.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/disregard.yaml new file mode 100644 index 00000000000..e82fa4d28b8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/disregard.yaml @@ -0,0 +1,12 @@ +description: New Mexico excludes this amount of child support received from countable income under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 50 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF child support disregard amount + reference: + - title: 8.102.520.10 NMAC - Income + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/passthrough.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/passthrough.yaml new file mode 100644 index 00000000000..69a2b2b5760 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/child_support/passthrough.yaml @@ -0,0 +1,23 @@ +description: New Mexico passes through this amount of child support to families under the Temporary Assistance for Needy Families program. + +metadata: + period: month + label: New Mexico TANF child support passthrough amount + type: single_amount + threshold_unit: /1 + amount_unit: currency-USD + reference: + - title: 8.102.520.10 NMAC - Income + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html + - title: HCA - Child Support Passthrough Increase (Jan 2023) + href: https://www.hca.nm.gov/2023/01/10/human-services-department-to-pass-through-more-money-to-low-income-families/ + +brackets: + - threshold: + 2023-01-01: 1 + amount: + 2023-01-01: 100 + - threshold: + 2023-01-01: 2 + amount: + 2023-01-01: 200 diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/non_benefit_group/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/non_benefit_group/amount.yaml new file mode 100644 index 00000000000..0ec99d64335 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/non_benefit_group/amount.yaml @@ -0,0 +1,12 @@ +description: New Mexico deducts this amount from deemed income for non-benefit group members under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 125 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF non-benefit group member work incentive deduction amount + reference: + - title: 8.102.520.12 NMAC - Earned Income Deductions + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/other_member/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/other_member/amount.yaml new file mode 100644 index 00000000000..38b9e3e026d --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/other_member/amount.yaml @@ -0,0 +1,12 @@ +description: New Mexico deducts this amount from gross earned income for other benefit group members under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 125 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF other member work incentive flat deduction amount + reference: + - title: 8.102.520.12 NMAC - Earned Income Deductions + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/rate.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/rate.yaml new file mode 100644 index 00000000000..8028f798ece --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/rate.yaml @@ -0,0 +1,12 @@ +description: New Mexico excludes this share of earnings remaining after the flat work incentive deduction under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 0.5 + +metadata: + unit: /1 + period: month + label: New Mexico TANF work incentive percentage disregard rate + reference: + - title: 8.102.520.12 NMAC - Earned Income Deductions + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/single_parent/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/single_parent/amount.yaml new file mode 100644 index 00000000000..d431b2de504 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/single_parent/amount.yaml @@ -0,0 +1,12 @@ +description: New Mexico deducts this amount from gross earned income for single-parent benefit groups under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 125 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF single-parent work incentive flat deduction amount + reference: + - title: 8.102.520.12 NMAC - Earned Income Deductions + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/two_parent/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/two_parent/amount.yaml new file mode 100644 index 00000000000..1fc59331b71 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/deductions/work_incentive/two_parent/amount.yaml @@ -0,0 +1,12 @@ +description: New Mexico deducts this amount per parent from gross earned income for two-parent benefit groups under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 225 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF two-parent work incentive flat deduction amount + reference: + - title: 8.102.520.12 NMAC - Earned Income Deductions + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/gross_limit/rate.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/gross_limit/rate.yaml new file mode 100644 index 00000000000..f6bd2fb371b --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/gross_limit/rate.yaml @@ -0,0 +1,12 @@ +description: New Mexico limits gross income to this share of the federal poverty guidelines under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 0.85 + +metadata: + unit: /1 + period: month + label: New Mexico TANF gross income limit rate + reference: + - title: 8.102.520.11 NMAC - Income Eligibility + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/income/self_employment/mileage_rate.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/self_employment/mileage_rate.yaml new file mode 100644 index 00000000000..1818c0f48c1 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/income/self_employment/mileage_rate.yaml @@ -0,0 +1,12 @@ +description: New Mexico allows this mileage rate for business travel deductions from self-employment income under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 0.25 + +metadata: + unit: currency-USD + period: year + label: New Mexico TANF self-employment mileage rate + reference: + - title: 8.102.520.9 NMAC - Self-Employment Income + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/additional_person.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/additional_person.yaml new file mode 100644 index 00000000000..a20f702d2d5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/additional_person.yaml @@ -0,0 +1,14 @@ +description: New Mexico provides this additional amount per person for benefit groups larger than the maximum table size under the Temporary Assistance for Needy Families program. + +values: + 2023-08-01: 111 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF additional person payment standard amount + reference: + - title: 8.102.500.8 NMAC - Eligibility Policy + href: https://www.srca.nm.gov/parts/title08/08.102.0500.html + - title: HCA - 23% Cash Assistance Increase Announcement (Sept 2023) + href: https://www.hca.nm.gov/2023/09/01/state-announces-a-23-percent-increase-in-cash-assistance-for-low-income-new-mexico-families/ diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/amount.yaml new file mode 100644 index 00000000000..c0b689c6c36 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/amount.yaml @@ -0,0 +1,52 @@ +description: New Mexico provides this amount as the payment standard under the Temporary Assistance for Needy Families program. + +metadata: + unit: currency-USD + period: month + breakdown: + - range(1, 20) + label: New Mexico TANF payment standard amount + reference: + - title: 8.102.500.8 NMAC - Eligibility Policy + href: https://www.srca.nm.gov/parts/title08/08.102.0500.html + - title: HCA - 23% Cash Assistance Increase Announcement (Sept 2023) + href: https://www.hca.nm.gov/2023/09/01/state-announces-a-23-percent-increase-in-cash-assistance-for-low-income-new-mexico-families/ + +1: + 2023-08-01: 327 +2: + 2023-08-01: 439 +3: + 2023-08-01: 549 +4: + 2023-08-01: 663 +5: + 2023-08-01: 775 +6: + 2023-08-01: 887 +7: + 2023-08-01: 999 +8: + 2023-08-01: 1_134 +9: + 2023-08-01: 1_245 +10: + 2023-08-01: 1_356 +11: + 2023-08-01: 1_467 +12: + 2023-08-01: 1_578 +13: + 2023-08-01: 1_689 +14: + 2023-08-01: 1_800 +15: + 2023-08-01: 1_911 +16: + 2023-08-01: 2_022 +17: + 2023-08-01: 2_133 +18: + 2023-08-01: 2_244 +19: + 2023-08-01: 2_355 diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/max_unit_size.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/max_unit_size.yaml new file mode 100644 index 00000000000..ab665f1ad4c --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/payment_standard/max_unit_size.yaml @@ -0,0 +1,12 @@ +description: New Mexico calculates the Temporary Assistance for Needy Families payment standard for benefit groups up to this size. + +values: + 2023-08-01: 19 + +metadata: + unit: person + period: year + label: New Mexico TANF maximum unit size for payment standard + reference: + - title: 8.102.500.8 NMAC - Eligibility Policy + href: https://www.srca.nm.gov/parts/title08/08.102.0500.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/resources/liquid/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/resources/liquid/amount.yaml new file mode 100644 index 00000000000..cae956aa893 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/resources/liquid/amount.yaml @@ -0,0 +1,12 @@ +description: New Mexico limits liquid resources to this amount under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 1_500 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF liquid resource limit amount + reference: + - title: 8.102.510 NMAC - Resources/Property + href: https://www.srca.nm.gov/parts/title08/08.102.0510.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/resources/non_liquid/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/resources/non_liquid/amount.yaml new file mode 100644 index 00000000000..6a61d6bfe6e --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/resources/non_liquid/amount.yaml @@ -0,0 +1,12 @@ +description: New Mexico limits non-liquid resources to this amount under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 2_000 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF non-liquid resource limit amount + reference: + - title: 8.102.510 NMAC - Resources/Property + href: https://www.srca.nm.gov/parts/title08/08.102.0510.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/first_level_rate.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/first_level_rate.yaml new file mode 100644 index 00000000000..3a50a50a900 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/first_level_rate.yaml @@ -0,0 +1,12 @@ +description: New Mexico reduces benefits by this share of the standard of need for first-level sanctions under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 0.25 + +metadata: + unit: /1 + period: month + label: New Mexico TANF first-level sanction rate + reference: + - title: 8.102.620 NMAC - Benefit Determination + href: https://www.srca.nm.gov/parts/title08/08.102.0620.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/second_level_rate.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/second_level_rate.yaml new file mode 100644 index 00000000000..f8455660483 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/sanctions/second_level_rate.yaml @@ -0,0 +1,12 @@ +description: New Mexico reduces benefits by this share of the standard of need for second-level sanctions under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 0.5 + +metadata: + unit: /1 + period: month + label: New Mexico TANF second-level sanction rate + reference: + - title: 8.102.620 NMAC - Benefit Determination + href: https://www.srca.nm.gov/parts/title08/08.102.0620.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/august.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/august.yaml new file mode 100644 index 00000000000..dd5716f16be --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/august.yaml @@ -0,0 +1,12 @@ +description: New Mexico provides this amount per school-age child in August for school clothing under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 100 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF school clothing allowance August amount + reference: + - title: 8.102.620 NMAC - Benefit Determination + href: https://www.srca.nm.gov/parts/title08/08.102.0620.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/january.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/january.yaml new file mode 100644 index 00000000000..612df8aa424 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/school_clothing_allowance/january.yaml @@ -0,0 +1,12 @@ +description: New Mexico provides this amount per school-age child in January for school clothing under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 50 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF school clothing allowance January amount + reference: + - title: 8.102.620 NMAC - Benefit Determination + href: https://www.srca.nm.gov/parts/title08/08.102.0620.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/support_services/income_limit_rate.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/support_services/income_limit_rate.yaml new file mode 100644 index 00000000000..3806c4b48de --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/support_services/income_limit_rate.yaml @@ -0,0 +1,12 @@ +description: New Mexico limits support services eligibility to this share of the federal poverty guidelines under the Temporary Assistance for Needy Families program. + +values: + 2020-01-01: 1 + +metadata: + unit: /1 + period: month + label: New Mexico TANF support services income limit rate + reference: + - title: 8.102.500.8 NMAC - Eligibility Policy + href: https://www.srca.nm.gov/parts/title08/08.102.0500.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/amount.yaml new file mode 100644 index 00000000000..e9f1f4dffad --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/amount.yaml @@ -0,0 +1,14 @@ +description: New Mexico provides this monthly amount under the Transition Bonus Program for families leaving the Temporary Assistance for Needy Families program. + +values: + 2023-06-01: 200 + +metadata: + unit: currency-USD + period: month + label: New Mexico TANF Transition Bonus Program amount + reference: + - title: 8.102.501 NMAC - Transitional Benefit Program + href: https://www.srca.nm.gov/parts/title08/08.102.0501.html + - title: HCA - Transition Bonus Program Reinstatement (June 2023) + href: https://www.hca.nm.gov/2023/06/01/human-services-department-announces-the-cash-assistance-transition-bonus-program-is-back/ diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/income_limit_rate.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/income_limit_rate.yaml new file mode 100644 index 00000000000..cc560b8a4cc --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/income_limit_rate.yaml @@ -0,0 +1,12 @@ +description: New Mexico limits Transition Bonus Program eligibility to this share of the federal poverty guidelines under the Temporary Assistance for Needy Families program. + +values: + 2023-06-01: 1.5 + +metadata: + unit: /1 + period: month + label: New Mexico TANF Transition Bonus Program income limit rate + reference: + - title: 8.102.501 NMAC - Transitional Benefit Program + href: https://www.srca.nm.gov/parts/title08/08.102.0501.html diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/minimum_work_hours.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/minimum_work_hours.yaml new file mode 100644 index 00000000000..4db4ba6c65a --- /dev/null +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/transition_bonus/minimum_work_hours.yaml @@ -0,0 +1,12 @@ +description: New Mexico requires this minimum weekly work hours for Transition Bonus Program eligibility under the Temporary Assistance for Needy Families program. + +values: + 2023-06-01: 30 + +metadata: + unit: hour + period: week + label: New Mexico TANF Transition Bonus Program minimum work hours + reference: + - title: 8.102.501 NMAC - Transitional Benefit Program + href: https://www.srca.nm.gov/parts/title08/08.102.0501.html diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/integration.yaml new file mode 100644 index 00000000000..d48893a2817 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/integration.yaml @@ -0,0 +1,571 @@ +# New Mexico Works (TANF) Integration Tests +# Tests the full benefit calculation pipeline with realistic scenarios +# Source: 8.102 NMAC - Cash Assistance Programs + +- name: Case 1, single parent with one child and no income gets maximum benefit. + period: 2024-01 + input: + people: + person1: # Parent + age: 30 + is_parent: true + person2: # Child + age: 5 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Benefit Group Size: 2 + # Payment Standard for size 2: $439/month + # No income, so full benefit + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 439 + +- name: Case 2, single parent with two children and moderate earnings. + period: 2024-01 + input: + people: + person1: # Parent + age: 28 + employment_income_before_lsr: 12_000 # $1,000/month + is_parent: true + person2: # Child 1 + age: 7 + is_tax_unit_dependent: true + person3: # Child 2 + age: 4 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Benefit Group Size: 3 + # 85% FPL limit for size 3: $1,829/month + # Gross earned income: $1,000/month < $1,829 = eligible + # + # Earned income deduction (single parent): + # Step 1: $1,000 - $125 = $875 + # Step 2: $875 * 0.50 = $437.50 + # Net earned income: $875 - $437.50 = $437.50 + # + # Payment Standard for size 3: $549 + # Benefit = $549 - $437.50 = $111.50 + nm_tanf_gross_income_eligible: true + nm_tanf_earned_income_deduction_person: [562.5, 0, 0] + # $1000 gross - $437.50 countable = $562.50 deduction + nm_tanf_countable_income: 437.5 + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 111.5 + +- name: Case 3, single parent with three children and child care costs. + period: 2024-01 + input: + people: + person1: # Parent + age: 32 + employment_income_before_lsr: 18_000 # $1,500/month + is_parent: true + person2: # Child 1 (under 2) + age: 1 + is_tax_unit_dependent: true + person3: # Child 2 (age 2+) + age: 4 + is_tax_unit_dependent: true + person4: # Child 3 + age: 8 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + childcare_expenses: 4_800 # $400/month + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NM + output: + # Benefit Group Size: 4 + # 85% FPL limit for size 4: $2,210/month + # Gross earned income: $1,500/month < $2,210 = eligible + # + # Earned income deduction (single parent): + # Step 1: $1,500 - $125 = $1,375 + # Step 2: $1,375 * 0.50 = $687.50 + # Net earned income: $1,375 - $687.50 = $687.50 + # + # Child care deduction (up to $200 under 2, $175 age 2+): + # Child 1 (age 1): $200 + # Child 2 (age 4): $175 (but capped by actual expense allocation) + # Total child care deduction: min($400, $200 + $175) = $375 + # + # Child care max: $200 (age 1) + $175 (age 4) + $175 (age 8) = $550 + # Actual expense: $400, so deduction = min($550, $400) = $400 + # Countable income: $687.50 - $400 = $287.50 + # Payment Standard for size 4: $663 + # Benefit = $663 - $287.50 = $375.50 + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf_child_care_deduction: 400 + nm_tanf_countable_income: 287.5 + nm_tanf: 375.5 + +- name: Case 4, two-parent household with two children. + period: 2024-01 + input: + people: + person1: # Parent 1 + age: 35 + employment_income_before_lsr: 9_600 # $800/month + is_tax_unit_head: true + is_parent: true + person2: # Parent 2 + age: 33 + employment_income_before_lsr: 6_000 # $500/month + is_tax_unit_spouse: true + is_parent: true + person3: # Child 1 + age: 10 + is_tax_unit_dependent: true + person4: # Child 2 + age: 6 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NM + output: + # Benefit Group Size: 4 + # 85% FPL limit for size 4: $2,210/month + # Gross earned income: $800 + $500 = $1,300/month < $2,210 = eligible + # + # Earned income deduction (two-parent, each parent): + # Parent 1: $800 - $225 = $575, then $575 * 0.50 = $287.50, net = $287.50 + # Parent 2: $500 - $225 = $275, then $275 * 0.50 = $137.50, net = $137.50 + # Total net earned: $287.50 + $137.50 = $425 + # + # Payment Standard for size 4: $663 + # Benefit = $663 - $425 = $238 + nm_tanf_gross_income_eligible: true + nm_tanf_earned_income_deduction_person: [512.5, 362.5, 0, 0] + # Parent 1: $800 - $287.50 = $512.50 deduction + # Parent 2: $500 - $137.50 = $362.50 deduction + nm_tanf_countable_income: 425 + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 238 + +- name: Case 5, income at gross income limit threshold. + period: 2024-01 + input: + people: + person1: # Parent + age: 29 + employment_income_before_lsr: 21_948 # $1,829/month (exactly at 85% FPL for size 3) + is_parent: true + person2: # Child 1 + age: 12 + is_tax_unit_dependent: true + person3: # Child 2 + age: 9 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Benefit Group Size: 3 + # 85% FPL for size 3: 0.85 * $2,073.33 = $1,762.33/month + # Gross earned income: $1,829/month > $1,762.33 = NOT gross income eligible + # (Formula uses strict less-than, so above limit is ineligible) + nm_tanf_gross_income_eligible: false + nm_tanf_eligible: false + nm_tanf: 0 + +- name: Case 6, income exceeds gross income limit. + period: 2024-01 + input: + people: + person1: # Parent + age: 40 + employment_income_before_lsr: 30_000 # $2,500/month + is_parent: true + person2: # Child + age: 14 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Benefit Group Size: 2 + # 85% FPL limit for size 2: $1,448/month + # Gross earned income: $2,500/month > $1,448 = NOT eligible + nm_tanf_gross_income_eligible: false + nm_tanf_eligible: false + nm_tanf: 0 + +- name: Case 7, single parent with child support income and unearned income. + period: 2024-01 + input: + people: + person1: # Parent + age: 27 + employment_income_before_lsr: 6_000 # $500/month + child_support_received: 3_600 # $300/month + is_parent: true + person2: # Child + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Benefit Group Size: 2 + # 85% FPL limit for size 2: $1,448/month + # Gross income: $500 + $300 = $800/month < $1,448 = eligible + # + # Earned income deduction (single parent): + # Step 1: $500 - $125 = $375 + # Step 2: $375 * 0.50 = $187.50 + # Net earned income: $375 - $187.50 = $187.50 + # + # Child support deduction: + # Child support passthrough: $100 (for 1 child) + # Child support disregard: $50 + # Net child support: $300 - $100 - $50 = $150 + # + # Total countable income: $187.50 + $150 = $337.50 + # Payment Standard for size 2: $439 + # Benefit = $439 - $337.50 = $101.50 + nm_tanf_gross_income_eligible: true + nm_tanf_countable_income: 337.5 + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 101.5 + +# Edge Case Integration Tests + +- name: Case 8, child exactly at age 2 with child care costs. + period: 2024-01 + input: + people: + person1: + age: 28 + employment_income_before_lsr: 9_600 # $800/month + is_parent: true + person2: + age: 2 # Exactly at age 2 boundary + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_000 # $250/month + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child care deduction for age 2+: $175/month max + # Actual expense: $250/month, capped at $175 + # + # Earned income deduction: $800 - $125 = $675, * 0.50 = $337.50 + # Total deduction: $125 + $337.50 = $462.50 + # Countable earned: $800 - $462.50 = $337.50 + # After child care: $337.50 - $175 = $162.50 + # + # Payment Standard: $439 + # Benefit: $439 - $162.50 = $276.50 + nm_tanf_child_care_deduction: 175 + nm_tanf_countable_income: 162.5 + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 276.5 + +- name: Case 9, two-parent household with working teenager. + period: 2024-01 + input: + people: + person1: + age: 40 + employment_income_before_lsr: 6_000 # $500/month + is_tax_unit_head: true + is_parent: true + person2: + age: 38 + employment_income_before_lsr: 0 + is_tax_unit_spouse: true + is_parent: true + person3: + age: 16 + employment_income_before_lsr: 2_400 # $200/month + is_tax_unit_dependent: true + person4: + age: 8 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NM + output: + # Parent 1 (two-parent, $500): + # $500 - $225 = $275, * 0.50 = $137.50 + # Total deduction: $225 + $137.50 = $362.50 + # Countable: $137.50 + # + # Parent 2: $0 earnings = $0 deduction, $0 countable + # + # Teen (other member, $200): + # $200 - $125 = $75, * 0.50 = $37.50 + # Total deduction: $125 + $37.50 = $162.50 + # Countable: $37.50 + # + # Total countable earned: $137.50 + $0 + $37.50 = $175 + # Payment Standard for size 4: $663 + # Benefit: $663 - $175 = $488 + nm_tanf_earned_income_deduction_person: [362.5, 0, 162.5, 0] + nm_tanf_countable_income: 175 + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 488 + +- name: Case 10, single parent with two children and child support. + period: 2024-01 + input: + people: + person1: + age: 32 + employment_income_before_lsr: 4_800 # $400/month + child_support_received: 4_800 # $400/month + is_parent: true + person2: + age: 10 + is_tax_unit_dependent: true + person3: + age: 6 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # 2 children: passthrough $200, disregard $50 + # Child support countable: $400 - $200 - $50 = $150 + # + # Earned income deduction (single parent): + # $400 - $125 = $275, * 0.50 = $137.50 + # Total deduction: $125 + $137.50 = $262.50 + # Countable earned: $137.50 + # + # Total countable: $137.50 + $150 = $287.50 + # Payment Standard for size 3: $549 + # Benefit: $549 - $287.50 = $261.50 + nm_tanf_countable_income: 287.5 + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 261.5 + +- name: Case 11, infant and toddler with child care and child support. + period: 2024-01 + input: + people: + person1: + age: 25 + employment_income_before_lsr: 10_800 # $900/month + child_support_received: 2_400 # $200/month + is_parent: true + person2: + age: 0 # Infant (under 2): $200 child care max + is_tax_unit_dependent: true + person3: + age: 2 # Toddler (age 2+): $175 child care max + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 6_000 # $500/month + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Child care: $200 (infant) + $175 (toddler) = $375 max + # Actual: $500, capped at $375 + # + # 2 children: passthrough $200, disregard $50 + # Child support countable: $200 - $200 - $50 = max(0, -$50) = $0 + # + # Earned income deduction (single parent): + # $900 - $125 = $775, * 0.50 = $387.50 + # Total deduction: $125 + $387.50 = $512.50 + # Countable earned before child care: $387.50 + # After child care: $387.50 - $375 = $12.50 + # + # Total countable: $12.50 + $0 = $12.50 + # Payment Standard for size 3: $549 + # Benefit: $549 - $12.50 = $536.50 + nm_tanf_child_care_deduction: 375 + nm_tanf_countable_income: 12.5 + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 536.5 + +- name: Case 12, earnings exactly at single-parent flat deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 1_500 # $125/month = exactly flat deduction + is_parent: true + person2: + age: 5 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Earnings exactly at flat deduction: $125 + # Deduction: min($125, $125) = $125 (flat only, no percentage) + # Countable earned: $0 + # + # Payment Standard for size 2: $439 + # Benefit: $439 - $0 = $439 + nm_tanf_earned_income_deduction_person: [125, 0] + nm_tanf_countable_income: 0 + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 439 + +- name: Case 13, very large household at maximum size. + period: 2024-01 + input: + people: + person1: + age: 45 + employment_income_before_lsr: 12_000 # $1,000/month + is_tax_unit_head: true + is_parent: true + person2: + age: 43 + is_tax_unit_spouse: true + is_parent: true + person3: + age: 17 + is_tax_unit_dependent: true + person4: + age: 15 + is_tax_unit_dependent: true + person5: + age: 13 + is_tax_unit_dependent: true + person6: + age: 11 + is_tax_unit_dependent: true + person7: + age: 9 + is_tax_unit_dependent: true + person8: + age: 7 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: NM + output: + # Size 8 household + # Payment Standard: $1,134 + # + # Two-parent earned income deduction: + # $1,000 - $225 = $775, * 0.50 = $387.50 + # Total deduction: $225 + $387.50 = $612.50 + # Countable: $387.50 + # + # Benefit: $1,134 - $387.50 = $746.50 + nm_tanf_earned_income_deduction_person: [612.5, 0, 0, 0, 0, 0, 0, 0] + nm_tanf_countable_income: 387.5 + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + nm_tanf_eligible: true + nm_tanf: 746.5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf.yaml new file mode 100644 index 00000000000..d58d861bc51 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf.yaml @@ -0,0 +1,182 @@ +# New Mexico Works (TANF) Benefit Amount Unit Tests +# Tests the final benefit calculation +# Source: 8.102.620 NMAC - Benefit Determination +# Formula: Benefit = Payment Standard - Net Countable Income + +- name: Case 1, ineligible receives zero benefit. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: false + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: 0 + output: + nm_tanf: 0 + +- name: Case 2, eligible with no countable income gets full payment standard. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: 0 + output: + # $439 - $0 = $439 + nm_tanf: 439 + +- name: Case 3, eligible with countable income below payment standard. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 549 + nm_tanf_countable_income: 300 + output: + # $549 - $300 = $249 + nm_tanf: 249 + +- name: Case 4, eligible with countable income exactly at payment standard. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 663 + nm_tanf_countable_income: 663 + output: + # $663 - $663 = $0 + nm_tanf: 0 + +- name: Case 5, eligible with countable income exceeds payment standard (edge case). + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: 500 + output: + # $439 - $500 = -$61, but capped at $0 + nm_tanf: 0 + +- name: Case 6, larger family with higher payment standard. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 775 # Size 5 + nm_tanf_countable_income: 400 + output: + # $775 - $400 = $375 + nm_tanf: 375 + +- name: Case 7, single person household with small benefit. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 327 # Size 1 + nm_tanf_countable_income: 250 + output: + # $327 - $250 = $77 + nm_tanf: 77 + +# Edge Cases: Benefit floor and boundary scenarios + +- name: Case 8, benefit exactly one dollar. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: 438 + output: + # $439 - $438 = $1 + nm_tanf: 1 + +- name: Case 9, benefit exactly one cent (fractional benefit). + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: 438.99 + output: + # $439 - $438.99 = $0.01 + nm_tanf: 0.01 + +- name: Case 10, countable income one dollar above payment standard. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: 440 + output: + # $439 - $440 = -$1, capped at $0 + nm_tanf: 0 + +- name: Case 11, countable income significantly exceeds payment standard. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 327 + nm_tanf_countable_income: 1_000 + output: + # $327 - $1,000 = -$673, capped at $0 + nm_tanf: 0 + +- name: Case 12, maximum household size 19 with full benefit. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 2_355 # Size 19 maximum + nm_tanf_countable_income: 0 + output: + # $2,355 - $0 = $2,355 + nm_tanf: 2_355 + +- name: Case 13, maximum household size with partial benefit. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 2_355 # Size 19 maximum + nm_tanf_countable_income: 1_500 + output: + # $2,355 - $1,500 = $855 + nm_tanf: 855 + +- name: Case 14, very small countable income. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: 0.01 + output: + # $439 - $0.01 = $438.99 + nm_tanf: 438.99 + +- name: Case 15, zero payment standard (edge case). + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 0 + nm_tanf_countable_income: 0 + output: + # $0 - $0 = $0 + nm_tanf: 0 + +- name: Case 16, negative countable income should not happen but handle gracefully. + period: 2024-01 + input: + state_code: NM + nm_tanf_eligible: true + nm_tanf_maximum_benefit: 439 + nm_tanf_countable_income: -100 + output: + # $439 - (-$100) = $539 + # max_() ensures non-negative benefit but doesn't cap positive values + nm_tanf: 539 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_care_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_care_deduction.yaml new file mode 100644 index 00000000000..47359a05d8e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_care_deduction.yaml @@ -0,0 +1,325 @@ +# New Mexico Works (TANF) Child Care Deduction Unit Tests +# Tests the child care deduction calculation +# Source: 8.102.520.12 NMAC +# Limits: Under 2: $200/month, Age 2+: $175/month + +- name: Case 1, no child care expenses results in zero deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 3 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 0 + households: + household: + members: [person1, person2] + state_code: NM + output: + nm_tanf_child_care_deduction: 0 + +- name: Case 2, child care for child under 2 at max limit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 1 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_000 # $250/month + households: + household: + members: [person1, person2] + state_code: NM + output: + # Under 2 limit: $200/month + # Expense: $250/month, capped at $200 + nm_tanf_child_care_deduction: 200 + +- name: Case 3, child care for child age 2 or older at max limit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 4 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 2_400 # $200/month + households: + household: + members: [person1, person2] + state_code: NM + output: + # Age 2+ limit: $175/month + # Expense: $200/month, capped at $175 + nm_tanf_child_care_deduction: 175 + +- name: Case 4, child care below limit is fully deductible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 1_200 # $100/month + households: + household: + members: [person1, person2] + state_code: NM + output: + # Age 2+ limit: $175/month + # Expense: $100/month < $175, so full $100 + nm_tanf_child_care_deduction: 100 + +- name: Case 5, multiple children with mixed ages. + period: 2024-01 + input: + people: + person1: + age: 32 + person2: + age: 1 # Under 2 + person3: + age: 4 # Age 2+ + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 6_000 # $500/month total + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Under 2 limit: $200 + # Age 2+ limit: $175 + # Total max: $200 + $175 = $375 + # Expense: $500/month, capped at $375 + nm_tanf_child_care_deduction: 375 + +- name: Case 6, child care expenses allocated below limits. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 1 + person3: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 3_000 # $250/month total + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Under 2 limit: $200 + # Age 2+ limit: $175 + # Total expense: $250 < combined limit $375 + # Full expense deductible: $250 + nm_tanf_child_care_deduction: 250 + +# Edge Cases: Age boundary and special scenarios + +- name: Case 7, child exactly at age 2 gets lower deduction limit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 2 # Exactly age 2 (boundary) + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_000 # $250/month + households: + household: + members: [person1, person2] + state_code: NM + output: + # Age 2+ limit: $175/month (age 2 uses the $175 bracket) + # Expense: $250/month, capped at $175 + nm_tanf_child_care_deduction: 175 + +- name: Case 8, infant at age 0 gets higher deduction limit. + period: 2024-01 + input: + people: + person1: + age: 25 + person2: + age: 0 # Newborn + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 3_000 # $250/month + households: + household: + members: [person1, person2] + state_code: NM + output: + # Under 2 limit: $200/month (age 0 is under 2) + # Expense: $250/month, capped at $200 + nm_tanf_child_care_deduction: 200 + +- name: Case 9, non-dependent adult does not qualify for child care deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 20 # Adult, not a dependent + is_tax_unit_dependent: false + spm_units: + spm_unit: + members: [person1, person2] + childcare_expenses: 2_400 # $200/month + households: + household: + members: [person1, person2] + state_code: NM + output: + # Non-dependent (age 20) gets $0 toward childcare limit + # Total max: $0 + # Expense capped at $0 + nm_tanf_child_care_deduction: 0 + +- name: Case 10, two children both under age 2. + period: 2024-01 + input: + people: + person1: + age: 28 + person2: + age: 1 + person3: + age: 0 # Newborn + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 6_000 # $500/month + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Both children under 2: $200 each + # Total max: $200 + $200 = $400 + # Expense: $500/month, capped at $400 + nm_tanf_child_care_deduction: 400 + +- name: Case 11, two children both age 2 or older. + period: 2024-01 + input: + people: + person1: + age: 32 + person2: + age: 3 + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 4_800 # $400/month + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Both children age 2+: $175 each + # Total max: $175 + $175 = $350 + # Expense: $400/month, capped at $350 + nm_tanf_child_care_deduction: 350 + +- name: Case 12, child care expenses exactly at combined limit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 1 # Under 2: $200 + person3: + age: 4 # Age 2+: $175 + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 4_500 # $375/month = exact limit + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Total max: $200 + $175 = $375 + # Expense: $375/month = exact limit + nm_tanf_child_care_deduction: 375 + +- name: Case 13, large family with many children of mixed ages. + period: 2024-01 + input: + people: + person1: + age: 35 + person2: + age: 0 # Under 2: $200 + person3: + age: 1 # Under 2: $200 + person4: + age: 3 # Age 2+: $175 + person5: + age: 6 # Age 2+: $175 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + childcare_expenses: 12_000 # $1,000/month + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: NM + output: + # 2 under 2: $200 * 2 = $400 + # 2 age 2+: $175 * 2 = $350 + # Total max: $750 + # Expense: $1,000/month, capped at $750 + nm_tanf_child_care_deduction: 750 + +- name: Case 14, child care expenses at zero with dependents. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 1 + person3: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3] + childcare_expenses: 0 + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # No expenses = no deduction regardless of eligible children + nm_tanf_child_care_deduction: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_earned_income.yaml new file mode 100644 index 00000000000..10955949c76 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_earned_income.yaml @@ -0,0 +1,134 @@ +# New Mexico Works (TANF) Countable Earned Income Unit Tests +# Tests the countable earned income after work incentive deduction +# Source: 8.102.520.12 NMAC + +- name: Case 1, no earnings results in zero countable. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + nm_tanf_countable_earned_income: 0 + +- name: Case 2, single parent with moderate earnings. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Single parent deduction: $125 + 50% of remainder + # Gross: $1,000 + # After flat: $1,000 - $125 = $875 + # After percentage: $875 * 0.50 = $437.50 + # Countable earned: $437.50 + nm_tanf_countable_earned_income: 437.5 + +- name: Case 3, single parent with earnings below flat deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 1_200 # $100/month + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Gross: $100 + # Flat deduction $125 > gross, so countable = $0 + nm_tanf_countable_earned_income: 0 + +- name: Case 4, two-parent household with both working. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 9_600 # $800/month + is_tax_unit_head: true + is_parent: true + person2: + age: 33 + employment_income_before_lsr: 6_000 # $500/month + is_tax_unit_spouse: true + is_parent: true + person3: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Two-parent: $225 + 50% each + # + # Parent 1: $800 + # After flat: $800 - $225 = $575 + # After percentage: $575 * 0.50 = $287.50 + # + # Parent 2: $500 + # After flat: $500 - $225 = $275 + # After percentage: $275 * 0.50 = $137.50 + # + # Total countable: $287.50 + $137.50 = $425 + nm_tanf_countable_earned_income: 425 + +- name: Case 5, self-employment income is treated as earned income. + period: 2024-01 + input: + people: + person1: + age: 35 + self_employment_income_before_lsr: 9_600 # $800/month + is_parent: true + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Single parent: $125 + 50% of remainder + # Gross: $800 + # After flat: $800 - $125 = $675 + # After percentage: $675 * 0.50 = $337.50 + nm_tanf_countable_earned_income: 337.5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml new file mode 100644 index 00000000000..39e95e6797f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml @@ -0,0 +1,57 @@ +# New Mexico Works (TANF) Countable Income Unit Tests +# Tests the net countable income calculation after all deductions +# Source: 8.102.520 NMAC - Income + +- name: Case 1, no income results in zero countable income. + period: 2024-01 + input: + state_code: NM + nm_tanf_countable_earned_income: 0 + nm_tanf_countable_unearned_income: 0 + nm_tanf_child_care_deduction: 0 + output: + nm_tanf_countable_income: 0 + +- name: Case 2, earned income only after deduction. + period: 2024-01 + input: + state_code: NM + nm_tanf_countable_earned_income: 437.5 + nm_tanf_countable_unearned_income: 0 + nm_tanf_child_care_deduction: 0 + output: + # Countable earned + countable unearned - child care deduction + nm_tanf_countable_income: 437.5 + +- name: Case 3, both earned and unearned income. + period: 2024-01 + input: + state_code: NM + nm_tanf_countable_earned_income: 300 + nm_tanf_countable_unearned_income: 200 + nm_tanf_child_care_deduction: 0 + output: + # $300 + $200 = $500 + nm_tanf_countable_income: 500 + +- name: Case 4, child care deduction reduces countable income. + period: 2024-01 + input: + state_code: NM + nm_tanf_countable_earned_income: 500 + nm_tanf_countable_unearned_income: 100 + nm_tanf_child_care_deduction: 200 + output: + # $500 + $100 - $200 = $400 + nm_tanf_countable_income: 400 + +- name: Case 5, child care deduction cannot make income negative. + period: 2024-01 + input: + state_code: NM + nm_tanf_countable_earned_income: 100 + nm_tanf_countable_unearned_income: 50 + nm_tanf_child_care_deduction: 200 + output: + # $100 + $50 - $200 = -$50, but capped at $0 + nm_tanf_countable_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_unearned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_unearned_income.yaml new file mode 100644 index 00000000000..ef784e20894 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_unearned_income.yaml @@ -0,0 +1,362 @@ +# New Mexico Works (TANF) Countable Unearned Income Unit Tests +# Tests the countable unearned income calculation with child support disregard +# Source: 8.102.520.10 NMAC +# Child support disregard: $50 +# Child support passthrough: $100 (1 child) or $200 (2+ children) + +- name: Case 1, no unearned income results in zero countable. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + nm_tanf_countable_unearned_income: 0 + +- name: Case 2, unearned income without child support. + period: 2024-01 + input: + people: + person1: + age: 30 + social_security: 6_000 # $500/month + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Social security is fully countable (no disregard) + nm_tanf_countable_unearned_income: 500 + +- name: Case 3, child support with one child gets disregard and passthrough. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 3_600 # $300/month + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $300/month + # Passthrough (1 child): $100 + # Disregard: $50 + # Countable: $300 - $100 - $50 = $150 + nm_tanf_countable_unearned_income: 150 + +- name: Case 4, child support with multiple children gets higher passthrough. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 4_800 # $400/month + person2: + age: 10 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Child support: $400/month + # Passthrough (2+ children): $200 + # Disregard: $50 + # Countable: $400 - $200 - $50 = $150 + nm_tanf_countable_unearned_income: 150 + +- name: Case 5, child support below disregard and passthrough is not counted. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 1_200 # $100/month + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $100/month + # Passthrough (1 child): $100 + # Disregard: $50 + # Total reduction: $150, but only $100 child support + # Countable: max($100 - $150, 0) = $0 + nm_tanf_countable_unearned_income: 0 + +- name: Case 6, mixed unearned income with child support. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 2_400 # $200/month + social_security: 1_800 # $150/month + person2: + age: 6 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Social security: $150/month (fully countable) + # Child support: $200/month + # Passthrough (1 child): $100 + # Disregard: $50 + # Countable child support: $200 - $100 - $50 = $50 + # Total countable: $150 + $50 = $200 + nm_tanf_countable_unearned_income: 200 + +# Edge Cases: Child count boundaries and special scenarios + +- name: Case 7, household with zero children has no child support passthrough. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 3_600 # $300/month (unusual but possible) + person2: + age: 20 # Adult, not a child + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $300/month + # 0 children = passthrough from scale = $0 + # Disregard: $50 + # Countable: $300 - $0 - $50 = $250 + nm_tanf_countable_unearned_income: 250 + +- name: Case 8, exactly one child at passthrough boundary. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 1_800 # $150/month (exactly = passthrough + disregard) + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $150/month + # 1 child passthrough: $100 + # Disregard: $50 + # Total deduction: $150 + # Countable: $150 - $150 = $0 + nm_tanf_countable_unearned_income: 0 + +- name: Case 9, exactly two children at passthrough boundary. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 3_000 # $250/month (exactly = passthrough + disregard) + person2: + age: 12 + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Child support: $250/month + # 2 children passthrough: $200 + # Disregard: $50 + # Total deduction: $250 + # Countable: $250 - $250 = $0 + nm_tanf_countable_unearned_income: 0 + +- name: Case 10, three or more children still gets $200 passthrough. + period: 2024-01 + input: + people: + person1: + age: 35 + child_support_received: 6_000 # $500/month + person2: + age: 15 + person3: + age: 12 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NM + output: + # Child support: $500/month + # 3 children: passthrough caps at $200 (same as 2 children) + # Disregard: $50 + # Countable: $500 - $200 - $50 = $250 + nm_tanf_countable_unearned_income: 250 + +- name: Case 11, child support exactly one dollar above deduction limit. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 1_812 # $151/month + person2: + age: 7 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $151/month + # 1 child passthrough: $100 + # Disregard: $50 + # Countable: $151 - $100 - $50 = $1 + nm_tanf_countable_unearned_income: 1 + +- name: Case 12, very large child support amount. + period: 2024-01 + input: + people: + person1: + age: 32 + child_support_received: 12_000 # $1,000/month + person2: + age: 10 + person3: + age: 6 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Child support: $1,000/month + # 2 children passthrough: $200 + # Disregard: $50 + # Countable: $1,000 - $200 - $50 = $750 + nm_tanf_countable_unearned_income: 750 + +- name: Case 13, child at boundary age 17 counts as child for passthrough. + period: 2024-01 + input: + people: + person1: + age: 40 + child_support_received: 3_600 # $300/month + person2: + age: 17 # Still under 18 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $300/month + # 1 child (age 17 < 18): passthrough $100 + # Disregard: $50 + # Countable: $300 - $100 - $50 = $150 + nm_tanf_countable_unearned_income: 150 + +- name: Case 14, person at age 18 does not count as child for passthrough. + period: 2024-01 + input: + people: + person1: + age: 40 + child_support_received: 3_600 # $300/month + person2: + age: 18 # Not under 18 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $300/month + # 0 children (age 18 >= 18): passthrough $0 + # Disregard: $50 + # Countable: $300 - $0 - $50 = $250 + nm_tanf_countable_unearned_income: 250 + +- name: Case 15, child support exactly at disregard only. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 600 # $50/month = exactly disregard + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $50/month + # 1 child passthrough: $100 + # Disregard: $50 + # Total max deduction: $150 + # Actual deduction limited to child support: $50 + # Countable: $0 + nm_tanf_countable_unearned_income: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_earned_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_earned_income_deduction.yaml new file mode 100644 index 00000000000..256123ebe97 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_earned_income_deduction.yaml @@ -0,0 +1,428 @@ +# New Mexico Works (TANF) Earned Income Deduction Unit Tests +# Tests the work incentive deduction calculation +# Source: 8.102.520.12 NMAC - Earned Income Deductions +# Single parent: $125 flat + 50% of remainder +# Two-parent: $225 flat + 50% of remainder (per parent) +# Other member: $125 flat + 50% of remainder + +- name: Case 1, single parent with no earnings has zero deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # No earnings = no deduction + nm_tanf_earned_income_deduction_person: [0, 0] + +- name: Case 2, single parent with earnings below flat deduction amount. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 1_200 # $100/month + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Single parent flat deduction: $125 + # Gross earnings: $100 + # $100 < $125, so deduction = $100 (capped at earnings) + nm_tanf_earned_income_deduction_person: [100, 0] + +- name: Case 3, single parent with moderate earnings. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Single parent: $125 + 50% of remainder + # Gross earnings: $1,000 + # Step 1: $1,000 - $125 = $875 + # Step 2: $875 * 0.50 = $437.50 + # Total deduction: $125 + $437.50 = $562.50 + nm_tanf_earned_income_deduction_person: [562.5, 0] + +- name: Case 4, two-parent household with both working. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 9_600 # $800/month + is_tax_unit_head: true + is_parent: true + person2: + age: 33 + employment_income_before_lsr: 6_000 # $500/month + is_tax_unit_spouse: true + is_parent: true + person3: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Two-parent: $225 + 50% of remainder (each parent) + # + # Parent 1 ($800/month): + # Step 1: $800 - $225 = $575 + # Step 2: $575 * 0.50 = $287.50 + # Total deduction: $225 + $287.50 = $512.50 + # + # Parent 2 ($500/month): + # Step 1: $500 - $225 = $275 + # Step 2: $275 * 0.50 = $137.50 + # Total deduction: $225 + $137.50 = $362.50 + nm_tanf_earned_income_deduction_person: [512.5, 362.5, 0] + +- name: Case 5, two-parent household with one parent working. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 18_000 # $1,500/month + is_tax_unit_head: true + is_parent: true + person2: + age: 33 + employment_income_before_lsr: 0 + is_tax_unit_spouse: true + is_parent: true + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Two-parent: $225 + 50% of remainder + # Parent 1 ($1,500/month): + # Step 1: $1,500 - $225 = $1,275 + # Step 2: $1,275 * 0.50 = $637.50 + # Total deduction: $225 + $637.50 = $862.50 + # Parent 2: $0 earnings = $0 deduction + nm_tanf_earned_income_deduction_person: [862.5, 0, 0] + +- name: Case 6, two-parent household with earnings below flat deduction. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 2_400 # $200/month + is_tax_unit_head: true + is_parent: true + person2: + age: 33 + employment_income_before_lsr: 1_200 # $100/month + is_tax_unit_spouse: true + is_parent: true + person3: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Two-parent flat deduction: $225 each + # Parent 1: $200 < $225, so deduction = $200 + # Parent 2: $100 < $225, so deduction = $100 + nm_tanf_earned_income_deduction_person: [200, 100, 0] + +# Edge Cases: Flat deduction boundaries and special scenarios + +- name: Case 7, single parent earnings exactly at flat deduction amount. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 1_500 # $125/month = exactly flat deduction + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Single parent flat: $125 + # Gross: $125 = exactly flat amount + # After flat: $125 - $125 = $0 + # No percentage deduction applies (nothing left) + # Total deduction: $125 + nm_tanf_earned_income_deduction_person: [125, 0] + +- name: Case 8, single parent earnings one dollar above flat deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 1_512 # $126/month + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Single parent flat: $125 + # Gross: $126 + # After flat: $126 - $125 = $1 + # Percentage: $1 * 0.50 = $0.50 + # Total deduction: $125 + $0.50 = $125.50 + nm_tanf_earned_income_deduction_person: [125.5, 0] + +- name: Case 9, two-parent earnings exactly at flat deduction amount. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 2_700 # $225/month = exactly flat deduction + is_tax_unit_head: true + is_parent: true + person2: + age: 33 + employment_income_before_lsr: 2_700 # $225/month = exactly flat deduction + is_tax_unit_spouse: true + is_parent: true + person3: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Two-parent flat: $225 each + # Both parents: $225 = exactly flat amount + # After flat: $0 for each + # Total deduction: $225 each + nm_tanf_earned_income_deduction_person: [225, 225, 0] + +- name: Case 10, two-parent earnings one dollar above flat deduction. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 2_712 # $226/month + is_tax_unit_head: true + is_parent: true + person2: + age: 33 + employment_income_before_lsr: 0 + is_tax_unit_spouse: true + is_parent: true + person3: + age: 6 + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Two-parent flat: $225 + # Gross: $226 + # After flat: $226 - $225 = $1 + # Percentage: $1 * 0.50 = $0.50 + # Total deduction: $225 + $0.50 = $225.50 + nm_tanf_earned_income_deduction_person: [225.5, 0, 0] + +- name: Case 11, working teen (non-parent) in two-parent household. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 0 + is_tax_unit_head: true + is_parent: true + person2: + age: 33 + employment_income_before_lsr: 0 + is_tax_unit_spouse: true + is_parent: true + person3: + age: 16 + employment_income_before_lsr: 4_800 # $400/month + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Non-parent (other member) in two-parent HH: $125 + 50% + # Teen earnings: $400 + # After flat: $400 - $125 = $275 + # Percentage: $275 * 0.50 = $137.50 + # Total deduction: $125 + $137.50 = $262.50 + nm_tanf_earned_income_deduction_person: [0, 0, 262.5] + +- name: Case 12, working teen (non-parent) in single-parent household. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 0 + is_parent: true + person2: + age: 17 + employment_income_before_lsr: 3_600 # $300/month + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Non-parent (other member) flat: $125 + # Teen earnings: $300 + # After flat: $300 - $125 = $175 + # Percentage: $175 * 0.50 = $87.50 + # Total deduction: $125 + $87.50 = $212.50 + nm_tanf_earned_income_deduction_person: [0, 212.5] + +- name: Case 13, very high earnings results in large deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 60_000 # $5,000/month + is_parent: true + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Single parent: $125 + 50% of remainder + # Gross: $5,000 + # After flat: $5,000 - $125 = $4,875 + # Percentage: $4,875 * 0.50 = $2,437.50 + # Total deduction: $125 + $2,437.50 = $2,562.50 + nm_tanf_earned_income_deduction_person: [2_562.5, 0] + +- name: Case 14, multiple earners in two-parent household including working child. + period: 2024-01 + input: + people: + person1: + age: 40 + employment_income_before_lsr: 6_000 # $500/month + is_tax_unit_head: true + is_parent: true + person2: + age: 38 + employment_income_before_lsr: 4_800 # $400/month + is_tax_unit_spouse: true + is_parent: true + person3: + age: 17 + employment_income_before_lsr: 2_400 # $200/month + spm_units: + spm_unit: + members: [person1, person2, person3] + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Parent 1 (two-parent, $500): + # $500 - $225 = $275, then $275 * 0.50 = $137.50 + # Total: $225 + $137.50 = $362.50 + # + # Parent 2 (two-parent, $400): + # $400 - $225 = $175, then $175 * 0.50 = $87.50 + # Total: $225 + $87.50 = $312.50 + # + # Teen (other member, $200): + # $200 < $125? No, $200 - $125 = $75, then $75 * 0.50 = $37.50 + # Total: $125 + $37.50 = $162.50 + nm_tanf_earned_income_deduction_person: [362.5, 312.5, 162.5] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_eligible.yaml new file mode 100644 index 00000000000..40d5cbf37a9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_eligible.yaml @@ -0,0 +1,53 @@ +# New Mexico Works (TANF) Eligibility Unit Tests +# Tests the main eligibility determination +# Source: 8.102.400 NMAC - Eligibility Determination + +- name: Case 1, eligible when both gross and net income tests pass. + period: 2024-01 + input: + state_code: NM + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + is_demographic_tanf_eligible: true + output: + nm_tanf_eligible: true + +- name: Case 2, ineligible when gross income test fails. + period: 2024-01 + input: + state_code: NM + nm_tanf_gross_income_eligible: false + nm_tanf_net_income_eligible: true + is_demographic_tanf_eligible: true + output: + nm_tanf_eligible: false + +- name: Case 3, ineligible when net income test fails. + period: 2024-01 + input: + state_code: NM + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: false + is_demographic_tanf_eligible: true + output: + nm_tanf_eligible: false + +- name: Case 4, ineligible when both income tests fail. + period: 2024-01 + input: + state_code: NM + nm_tanf_gross_income_eligible: false + nm_tanf_net_income_eligible: false + is_demographic_tanf_eligible: true + output: + nm_tanf_eligible: false + +- name: Case 5, ineligible when demographic requirements not met. + period: 2024-01 + input: + state_code: NM + nm_tanf_gross_income_eligible: true + nm_tanf_net_income_eligible: true + is_demographic_tanf_eligible: false + output: + nm_tanf_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income_eligible.yaml new file mode 100644 index 00000000000..3c675592623 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income_eligible.yaml @@ -0,0 +1,269 @@ +# New Mexico Works (TANF) Gross Income Eligibility Unit Tests +# Tests the 85% FPL gross income test +# Source: 8.102.520.11 NMAC - "countable gross income cannot exceed 85% of FPL" + +- name: Case 1, no income is gross income eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # 85% FPL for size 2: $1,396/month (0.85 * $1,643.33) + # $0 < $1,396 = eligible + nm_tanf_gross_income_eligible: true + +- name: Case 2, income below 85% FPL limit is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_gross_income: 1_000 + households: + household: + members: [person1, person2] + state_code: NM + output: + # 85% FPL for size 2: $1,396/month + # $1,000 < $1,396 = eligible + nm_tanf_gross_income_eligible: true + +- name: Case 3, income at 85% FPL limit is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3] + # 85% FPL for size 3: 0.85 * $2,073.33 = $1,762.33 + nm_tanf_gross_income: 1_762.33 + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Formula uses strict less-than (<), so at limit is ineligible + nm_tanf_gross_income_eligible: false + +- name: Case 4, income above 85% FPL limit is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3] + nm_tanf_gross_income: 1_830 + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # 85% FPL for size 3: ~$1,762/month + # $1,830 > $1,762 = ineligible + nm_tanf_gross_income_eligible: false + +- name: Case 5, larger household with income below limit. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 10 + person3: + age: 8 + person4: + age: 5 + person5: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + nm_tanf_gross_income: 2_000 + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: NM + output: + # 85% FPL for size 5: 0.85 * $2,933.33 = $2,493.33 + # $2,000 < $2,493 = eligible + nm_tanf_gross_income_eligible: true + +- name: Case 6, single person household with no income. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: NM + output: + # 85% FPL for size 1: 0.85 * $1,255 = $1,066.75 + # $0 < $1,067 = eligible + nm_tanf_gross_income_eligible: true + +# Edge Cases: Boundary precision tests + +- name: Case 7, income one dollar below limit is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + # 85% FPL for size 2: $1,396.83 + nm_tanf_gross_income: 1_395 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $1,395 < $1,396.83 = eligible + nm_tanf_gross_income_eligible: true + +- name: Case 8, income one dollar above limit is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_gross_income: 1_398 + households: + household: + members: [person1, person2] + state_code: NM + output: + # 85% FPL for size 2: $1,396.83/month + # $1,398 > $1,396.83 = ineligible + nm_tanf_gross_income_eligible: false + +- name: Case 9, zero income is gross income eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + households: + household: + members: [person1] + state_code: NM + output: + # $0 < any positive limit = eligible + nm_tanf_gross_income_eligible: true + +- name: Case 10, very high income is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_gross_income: 10_000 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $10,000 far exceeds any 85% FPL limit = ineligible + nm_tanf_gross_income_eligible: false + +- name: Case 11, large household with income at limit is ineligible. + period: 2024-01 + input: + people: + person1: + age: 45 + person2: + age: 40 + person3: + age: 17 + person4: + age: 15 + person5: + age: 13 + person6: + age: 11 + person7: + age: 9 + person8: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + # 85% FPL for size 8: 0.85 * $4,223.33 = $3,589.83 + nm_tanf_gross_income: 3_590 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: NM + output: + # Formula uses <, so at/above limit is ineligible + nm_tanf_gross_income_eligible: false + +- name: Case 12, income just below limit is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_gross_income: 1_390 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $1,390 < $1,396.83 = eligible + nm_tanf_gross_income_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.yaml new file mode 100644 index 00000000000..409c2104498 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.yaml @@ -0,0 +1,97 @@ +# New Mexico Works (TANF) Maximum Benefit Unit Tests +# Tests the maximum benefit (payment standard) lookup by benefit group size +# Source: 8.102.500.8 NMAC, 8.102.620 NMAC +# Effective August 2023 (23% increase) + +- name: Case 1, benefit group size 1. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 1 + output: + nm_tanf_maximum_benefit: 327 + +- name: Case 2, benefit group size 2. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 2 + output: + nm_tanf_maximum_benefit: 439 + +- name: Case 3, benefit group size 3. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 3 + output: + nm_tanf_maximum_benefit: 549 + +- name: Case 4, benefit group size 4. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 4 + output: + nm_tanf_maximum_benefit: 663 + +- name: Case 5, benefit group size 5. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 5 + output: + nm_tanf_maximum_benefit: 775 + +- name: Case 6, benefit group size 6. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 6 + output: + nm_tanf_maximum_benefit: 887 + +- name: Case 7, benefit group size 7. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 7 + output: + nm_tanf_maximum_benefit: 999 + +- name: Case 8, benefit group size 8. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 8 + output: + nm_tanf_maximum_benefit: 1_134 + +# Edge Cases: Maximum unit size and boundary conditions + +- name: Case 9, maximum unit size 19. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 19 + output: + # Max unit size: 19, payment standard: $2,355 + nm_tanf_maximum_benefit: 2_355 + +- name: Case 10, unit size exceeds maximum caps at 19. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 20 + output: + # 20 > max(19), caps at payment standard for size 19: $2,355 + nm_tanf_maximum_benefit: 2_355 + +- name: Case 11, very large household caps at maximum. + period: 2024-01 + input: + state_code: NM + spm_unit_size: 25 + output: + # 25 > max(19), caps at payment standard for size 19: $2,355 + nm_tanf_maximum_benefit: 2_355 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml new file mode 100644 index 00000000000..b3e9f242e5b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml @@ -0,0 +1,277 @@ +# New Mexico Works (TANF) Net Income Eligibility Unit Tests +# Tests the standard of need income test +# Source: 8.102.520.11 NMAC - "countable net income must be less than the standard of need" + +- name: Case 1, no countable income is net income eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_countable_income: 0 + nm_tanf_maximum_benefit: 439 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $0 < $439 = eligible + nm_tanf_net_income_eligible: true + +- name: Case 2, countable income below payment standard is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3] + nm_tanf_countable_income: 300 + nm_tanf_maximum_benefit: 549 + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # $300 < $549 = eligible + nm_tanf_net_income_eligible: true + +- name: Case 3, countable income equals payment standard is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 3 + person4: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nm_tanf_countable_income: 663 + nm_tanf_maximum_benefit: 663 + households: + household: + members: [person1, person2, person3, person4] + state_code: NM + output: + # Formula uses strict less-than: $663 is not < $663 = ineligible + nm_tanf_net_income_eligible: false + +- name: Case 4, countable income exceeds payment standard is ineligible. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 3 + person4: + age: 1 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + nm_tanf_countable_income: 664 + nm_tanf_maximum_benefit: 663 + households: + household: + members: [person1, person2, person3, person4] + state_code: NM + output: + # $664 > $663 = ineligible + nm_tanf_net_income_eligible: false + +- name: Case 5, countable income far exceeds payment standard. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_countable_income: 1_000 + nm_tanf_maximum_benefit: 439 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $1,000 > $439 = ineligible + nm_tanf_net_income_eligible: false + +# Edge Cases: Boundary precision tests + +- name: Case 6, countable income one dollar below payment standard. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_countable_income: 438 + nm_tanf_maximum_benefit: 439 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $438 < $439 = eligible + nm_tanf_net_income_eligible: true + +- name: Case 7, countable income one dollar above payment standard. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_countable_income: 440 + nm_tanf_maximum_benefit: 439 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $440 > $439 = ineligible + nm_tanf_net_income_eligible: false + +- name: Case 8, zero countable income with zero payment standard. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + nm_tanf_countable_income: 0 + nm_tanf_maximum_benefit: 0 + households: + household: + members: [person1] + state_code: NM + output: + # $0 is not < $0 = ineligible (edge case: both zero) + nm_tanf_net_income_eligible: false + +- name: Case 9, very small countable income is eligible. + period: 2024-01 + input: + people: + person1: + age: 30 + spm_units: + spm_unit: + members: [person1] + nm_tanf_countable_income: 0.01 + nm_tanf_maximum_benefit: 327 + households: + household: + members: [person1] + state_code: NM + output: + # $0.01 < $327 = eligible + nm_tanf_net_income_eligible: true + +- name: Case 10, countable income one cent below payment standard. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + person3: + age: 3 + spm_units: + spm_unit: + members: [person1, person2, person3] + nm_tanf_countable_income: 548.99 + nm_tanf_maximum_benefit: 549 + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # $548.99 < $549 = eligible + nm_tanf_net_income_eligible: true + +- name: Case 11, largest household with high countable income below standard. + period: 2024-01 + input: + people: + person1: + age: 45 + person2: + age: 40 + person3: + age: 17 + person4: + age: 15 + person5: + age: 13 + person6: + age: 11 + person7: + age: 9 + person8: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + nm_tanf_countable_income: 2_000 + nm_tanf_maximum_benefit: 2_355 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8] + state_code: NM + output: + # $2,000 < $2,355 = eligible + nm_tanf_net_income_eligible: true + +- name: Case 12, countable income significantly exceeds standard. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + nm_tanf_countable_income: 5_000 + nm_tanf_maximum_benefit: 439 + households: + household: + members: [person1, person2] + state_code: NM + output: + # $5,000 >> $439 = ineligible + nm_tanf_net_income_eligible: false diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py new file mode 100644 index 00000000000..9636be0e934 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class nm_tanf_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "New Mexico TANF eligible" + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0400.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + # Per 8.102 NMAC, eligibility requires: + # 1. Demographic eligibility (federal baseline) + # 2. Immigration eligibility (federal baseline) + # 3. Gross income under 85% FPL + # 4. Net income under standard of need + demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) + immigration_eligible = ( + add(spm_unit, period, ["is_citizen_or_legal_immigrant"]) > 0 + ) + gross_income_eligible = spm_unit( + "nm_tanf_gross_income_eligible", period + ) + net_income_eligible = spm_unit("nm_tanf_net_income_eligible", period) + + return ( + demographic_eligible + & immigration_eligible + & gross_income_eligible + & net_income_eligible + ) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py new file mode 100644 index 00000000000..137a7f29944 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class nm_tanf_gross_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "New Mexico TANF gross income eligible" + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + # Per 8.102.520.11 NMAC, gross income must be under 85% FPL + p = parameters(period).gov.states.nm.hca.tanf.income + gross_income = spm_unit("nm_tanf_gross_income", period) + fpg = spm_unit("tanf_fpg", period) + gross_income_limit = fpg * p.gross_limit.rate + return gross_income < gross_income_limit diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py new file mode 100644 index 00000000000..6fadc1e033d --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class nm_tanf_net_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "New Mexico TANF net income eligible" + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + # Per 8.102.520.11 NMAC, countable income must be less than + # the standard of need (payment standard) + countable_income = spm_unit("nm_tanf_countable_income", period) + payment_standard = spm_unit("nm_tanf_maximum_benefit", period) + return countable_income < payment_standard diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_care_deduction.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_care_deduction.py new file mode 100644 index 00000000000..015ab8abb44 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_care_deduction.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class nm_tanf_child_care_deduction(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF child care deduction" + unit = USD + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + # Per 8.102.520.12 NMAC, child care deduction varies by age: + # Under age 2: up to $200 + # Age 2 or older: up to $175 + p = parameters(period).gov.states.nm.hca.tanf.income.deductions + + person = spm_unit.members + is_dependent = person("is_tax_unit_dependent", period) + age = person("age", period.this_year) + childcare_expenses = spm_unit("childcare_expenses", period) + + # Max deduction per child based on age + childcare_max_per_child = p.child_care.amount.calc(age) * is_dependent + total_childcare_max = spm_unit.sum(childcare_max_per_child) + + return min_(childcare_expenses, total_childcare_max) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_support_deduction.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_support_deduction.py new file mode 100644 index 00000000000..9d7a4043236 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_child_support_deduction.py @@ -0,0 +1,38 @@ +from policyengine_us.model_api import * + + +class nm_tanf_child_support_deduction(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF child support deduction" + unit = USD + definition_period = MONTH + reference = ( + "https://www.srca.nm.gov/parts/title08/08.102.0520.html", + "https://www.hca.nm.gov/2023/01/10/human-services-department-to-pass-through-more-money-to-low-income-families/", + ) + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + # Per 8.102.520.10 NMAC: + # - $50 disregard on child support received + # - Passthrough: $100 for 1 child, $200 for 2+ children + p = parameters(period).gov.states.nm.hca.tanf.income.deductions + + child_support_received = add( + spm_unit, period, ["child_support_received"] + ) + + # Count children in benefit group + person = spm_unit.members + age = person("age", period.this_year) + age_threshold = parameters(period).gov.states.nm.hca.tanf.age_threshold + is_child = age < age_threshold.minor_child + num_children = spm_unit.sum(is_child) + + # Calculate disregard and passthrough + disregard = p.child_support.disregard + passthrough = p.child_support.passthrough.calc(num_children) + total_deduction = disregard + passthrough + + return min_(child_support_received, total_deduction) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_earned_income.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_earned_income.py new file mode 100644 index 00000000000..9dcd375b2ad --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_earned_income.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class nm_tanf_countable_earned_income(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF countable earned income" + unit = USD + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + gross_earned = add(spm_unit, period, ["tanf_gross_earned_income"]) + earned_deduction = spm_unit("nm_tanf_earned_income_deduction", period) + return max_(gross_earned - earned_deduction, 0) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py new file mode 100644 index 00000000000..4b363563d2d --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class nm_tanf_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF countable income" + unit = USD + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + # Per 8.102.520 NMAC, calculate countable income: + # Countable = Countable Earned + Countable Unearned - Child Care + countable_earned = spm_unit("nm_tanf_countable_earned_income", period) + countable_unearned = spm_unit( + "nm_tanf_countable_unearned_income", period + ) + child_care_deduction = spm_unit("nm_tanf_child_care_deduction", period) + return max_( + countable_earned + countable_unearned - child_care_deduction, 0 + ) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_unearned_income.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_unearned_income.py new file mode 100644 index 00000000000..f5ef60ef26e --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_unearned_income.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class nm_tanf_countable_unearned_income(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF countable unearned income" + unit = USD + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + gross_unearned = add(spm_unit, period, ["tanf_gross_unearned_income"]) + child_support_deduction = spm_unit( + "nm_tanf_child_support_deduction", period + ) + return max_(gross_unearned - child_support_deduction, 0) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction.py new file mode 100644 index 00000000000..241fa63df14 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class nm_tanf_earned_income_deduction(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF earned income deduction" + unit = USD + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + adds = ["nm_tanf_earned_income_deduction_person"] diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction_person.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction_person.py new file mode 100644 index 00000000000..4fd190c7934 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_earned_income_deduction_person.py @@ -0,0 +1,44 @@ +from policyengine_us.model_api import * + + +class nm_tanf_earned_income_deduction_person(Variable): + value_type = float + entity = Person + label = "New Mexico TANF earned income deduction (person)" + unit = USD + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + def formula(person, period, parameters): + # Per 8.102.520.12 NMAC, earned income deduction is: + # Flat amount + 50% of remainder + p = parameters(period).gov.states.nm.hca.tanf.income.deductions + + gross_earned = person("tanf_gross_earned_income", period) + is_parent = person("is_parent", period.this_year) + + # Count parents in the SPM unit to determine single vs two-parent + spm_unit = person.spm_unit + parent_count = add(spm_unit, period, ["is_parent"]) + + # Flat deduction depends on single vs two-parent + single_parent_flat = p.work_incentive.single_parent.amount + two_parent_flat = p.work_incentive.two_parent.amount + other_member_flat = p.work_incentive.other_member.amount + disregard_rate = p.work_incentive.rate + + # Parents get $225 in two-parent families, $125 in single-parent + # Non-parents get $125 flat (other member) + is_two_parent = parent_count >= 2 + parent_flat = where(is_two_parent, two_parent_flat, single_parent_flat) + flat_amount = where(is_parent, parent_flat, other_member_flat) + + # Step 1: Subtract flat amount (not to exceed earnings) + flat_deduction = min_(flat_amount, gross_earned) + after_flat = max_(gross_earned - flat_deduction, 0) + + # Step 2: 50% disregard on remainder + percentage_deduction = after_flat * disregard_rate + + return flat_deduction + percentage_deduction diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_gross_income.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_gross_income.py new file mode 100644 index 00000000000..6bc735e0364 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_gross_income.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class nm_tanf_gross_income(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF gross income" + unit = USD + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" + defined_for = StateCode.NM + + adds = ["tanf_gross_earned_income", "tanf_gross_unearned_income"] diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf.py b/policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf.py new file mode 100644 index 00000000000..a8db6ea942d --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class nm_tanf(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF (New Mexico Works)" + unit = USD + definition_period = MONTH + reference = ( + "https://www.srca.nm.gov/parts/title08/08.102.0620.html", + "https://www.hca.nm.gov/lookingforassistance/temporary_assistance_for_needy_families/", + ) + defined_for = "nm_tanf_eligible" + + def formula(spm_unit, period, parameters): + # Per 8.102.620 NMAC: + # Benefit = Payment Standard - Net Countable Income + maximum_benefit = spm_unit("nm_tanf_maximum_benefit", period) + countable_income = spm_unit("nm_tanf_countable_income", period) + return max_(maximum_benefit - countable_income, 0) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.py b/policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.py new file mode 100644 index 00000000000..4a109260fe7 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/nm_tanf_maximum_benefit.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class nm_tanf_maximum_benefit(Variable): + value_type = float + entity = SPMUnit + label = "New Mexico TANF maximum benefit (payment standard)" + unit = USD + definition_period = MONTH + reference = ( + "https://www.srca.nm.gov/parts/title08/08.102.0500.html", + "https://www.hca.nm.gov/2023/09/01/state-announces-a-23-percent-increase-in-cash-assistance-for-low-income-new-mexico-families/", + ) + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.nm.hca.tanf.payment_standard + unit_size = spm_unit("spm_unit_size", period.this_year) + capped_size = min_(unit_size, p.max_unit_size) + return p.amount[capped_size] diff --git a/sources/working_references.md b/sources/working_references.md new file mode 100644 index 00000000000..54d880834ef --- /dev/null +++ b/sources/working_references.md @@ -0,0 +1,529 @@ +# Collected Documentation + +## New Mexico Works (NM Works) - TANF Implementation +**Collected**: December 23, 2025 +**Implementation Task**: Implement New Mexico's TANF program (NM Works) including eligibility determination and benefit calculation + +--- + +## Official Program Name + +**Federal Program**: Temporary Assistance for Needy Families (TANF) +**State's Official Name**: New Mexico Works (NM Works or NMW) +**Abbreviation**: NMW +**Source**: 8.102.100 NMAC - "New Mexico Works (NMW) means the program implemented under NMWA for the purpose of providing cash assistance as a support service to enable and assist parents to participate in employment." + +**Variable Prefix**: `nm_tanf` + +**Administering Agency**: New Mexico Health Care Authority (HCA) +- Note: Previously administered by Human Services Department (HSD), which was reorganized + +--- + +## Regulatory Authority + +### State Regulations +- **Primary Regulation**: 8.102 NMAC - Cash Assistance Programs (New Mexico Works) + - 8.102.100 NMAC - General Provisions/Definitions + - 8.102.400 NMAC - Eligibility Determination + - 8.102.410 NMAC - Recipient Requirements (Citizenship, Work Requirements) + - 8.102.420 NMAC - Benefit Group Composition + - 8.102.500 NMAC - Eligibility Policy - General Information + - 8.102.501 NMAC - Transition Bonus Program (TBP) + - 8.102.510 NMAC - Resources/Property + - 8.102.520 NMAC - Income + - 8.102.620 NMAC - Benefit Determination + +### State Statutes +- New Mexico Statutes Annotated 1978, Chapter 27, Articles 1 and 2 +- New Mexico Works Act of 1998 (NMWA) + +### Federal Authority +- Title IV-A of the Social Security Act +- Personal Responsibility and Work Opportunity Reconciliation Act (PRWORA) of 1996 + +--- + +## Non-Simulatable Rules (Architecture Limitation) + +### Time Limit +- **60-Month Lifetime Limit**: "NMW/TANF cash assistance shall not be provided to or for an adult or a minor head of household for more than 60 months during the individual's lifetime." +- Source: 8.102.410.17 NMAC +- **CANNOT ENFORCE** - requires tracking benefit history across periods + +### Hardship Extensions +- Up to 20% of TANF participants may receive extensions beyond 60 months +- Based on: disability, domestic violence, age 60+, pending SSI applications +- **CANNOT TRACK** - requires history of months received + +### Transitional Benefit Program (TBP) +- 18-month lifetime limit +- **CANNOT TRACK** - requires history of TBP months + +--- + +## Demographic Eligibility + +### Dependent Child Age Thresholds + +| Category | Age Threshold | Source | +|----------|---------------|--------| +| Minor child | Under 18 years | 8.102.100.7(R) NMAC | +| High school student (18) | Age 18 and enrolled in high school | 8.102.100.7(R) NMAC | +| Special education | Ages 18-22 with current IEP | 8.102.420.8 NMAC | + +**Legal Citation**: 8.102.100.7(R) NMAC defines "dependent child" as: +> "a natural child, adopted child, stepchild or ward that is: (a) 17 years of age or younger; or (b) 18 years of age and is enrolled in high school; or (c) between 18 and 22 years of age and is receiving special education services regulated by the New Mexico Public Education Department with a current valid Individual Education Plan (IEP)." + +### Pregnant Women +- Pregnant women are eligible as specified relatives +- Source: 8.102.400 NMAC + +### Caretaker Relative Requirements +- Must be within the 5th degree of relationship to the dependent child +- Must be the primary caretaker for the child +- Must reside in the home with the dependent child +- Source: 8.102.400 NMAC + +**Implementation Approach:** +- [x] Use federal demographic eligibility baseline for age 18 threshold +- [ ] Create state-specific for age 18-22 special education provision if needed +- [x] Follow federal caretaker relative definition + +--- + +## Immigration Eligibility + +### Eligible Categories + +**U.S. Citizens**: Natural-born, naturalized, or born in U.S. territories + +**Non-Citizen U.S. Nationals**: Persons from American Samoa, Swains Island, or Northern Mariana Islands + +**Qualified Non-Citizens** (8.102.410.10 NMAC): +1. Lawfully admitted permanent residents (LPRs) +2. Asylees under INA Section 208 +3. Refugees admitted under INA Section 207 +4. Parolees (admitted for at least one year under INA Section 212) +5. Individuals with deportation withheld under INA Sections 241(b)(3) or 243(h) +6. Those granted conditional entry (pre-April 1, 1980) +7. Cuban or Haitian entrants under the Refugee Education Assistance Act of 1980 +8. Trafficking victims certified by HHS +9. COFA migrants (Compact of Free Association - Micronesia, Marshall Islands, Palau) + +**Additional Eligibility Pathways**: +- Entry before August 22, 1996, with qualified status +- Five-year residence requirement for post-August 22, 1996 entrants +- 40 qualifying quarters under Social Security +- Veterans with honorable discharge or active duty members +- Family members of qualifying veterans +- Domestic violence exception + +**State-Funded Aliens**: +- Qualified non-citizens who entered on/after August 22, 1996 +- Eligible for state-funded TANF without the 5-year waiting period +- Source: 8.102.410.10(B) NMAC + +**Implementation Approach:** +- [x] Use federal immigration eligibility baseline (state follows federal rules with state-funded option) + +--- + +## Income Eligibility Tests + +### Test 1: Gross Income Test (85% Test) + +**Rule**: The countable gross income of the benefit group cannot exceed 85% of the Federal Poverty Guidelines for the benefit group size. + +**Source**: 8.102.520.11 NMAC - "For the benefit group to be eligible, the countable gross income available to the benefit group cannot exceed eighty-five percent of the federal poverty guidelines for the size of the benefit group." + +**Gross Income Limits (85% FPL) - October 2024 through September 2025**: + +| Benefit Group Size | Monthly Limit | +|--------------------|---------------| +| 1 | $1,067 | +| 2 | $1,448 | +| 3 | $1,829 | +| 4 | $2,210 | +| 5 | $2,592 | +| 6 | $2,972 | +| 7 | $3,353 | +| 8 | $3,735 | +| Each additional | +$382 | + +**Note**: These limits are revised annually each October based on Federal Poverty Guidelines. + +**Implementation**: Store as 0.85 rate multiplied by FPL, not fixed dollar amounts. + +### Test 2: Net Income Test (Standard of Need) + +**Rule**: The countable net income (after deductions) must be less than the Standard of Need for the benefit group size. + +**Source**: 8.102.520.11 NMAC - "For the benefit group to be eligible, the countable net income must be less than the standard of need applicable to the size of the benefit group." + +--- + +## Income Deductions and Exemptions + +### Earned Income Deductions (Work Incentive) + +**Source**: 8.102.520.12 NMAC + +| Recipient Type | Deduction Formula | +|----------------|-------------------| +| Single-parent benefit group (parent) | $125 + 50% of remainder | +| Two-parent benefit group (each parent) | $225 + 50% of remainder | +| Other benefit group member (not parent) | $125 + 50% of remainder | +| Non-benefit group member (deemed income) | $125 flat deduction | + +**Calculation Example (Single Parent with $800 gross earnings)**: +1. Start with gross earnings: $800 +2. Subtract $125: $800 - $125 = $675 +3. Subtract 50% of remainder: $675 - ($675 * 0.50) = $675 - $337.50 = $337.50 +4. Countable earned income: $337.50 + +### Child Care Deductions + +**Source**: 8.102.520.12 NMAC + +| Child Age | Maximum Monthly Deduction | +|-----------|---------------------------| +| Under age 2 | $200 | +| Age 2 or older | $175 | + +**Note**: Deducted from earnings remaining after work incentive deduction. + +### Child Support Disregard and Passthrough + +**Source**: 8.102.520.10 NMAC, HCA announcement January 2023 + +**Disregard**: First $50 of child support received by the benefit group is disregarded (not counted as income). + +**Passthrough** (Effective January 1, 2023): +- 1 child: $100 +- 2 or more children: $200 + +**Implementation**: Both disregard ($50) and passthrough amounts reduce countable income. + +### Income Exclusions (Not Counted) + +**Source**: 8.102.520.10 NMAC + +The following income sources are excluded from countable income: +- Medicaid and SNAP benefits +- Supplemental Security Income (SSI) +- Government-subsidized housing or housing payments +- Educational payments made directly to institutions +- Subsidized child care +- Earned income of children 17 and younger (not heads of household) +- Emergency one-time payments +- Job-related expense reimbursements +- Utility assistance programs (LIHEAP) +- Guaranteed basic income (private-funded or mixed-funded) +- Universal basic income (private-funded or mixed-funded) + +### Self-Employment Income + +**Source**: 8.102.520.9 NMAC + +- Gross profit requiring "substantial effort on a continuous basis" +- Averaged over the period it's intended to cover (typically 12 months) +- If business operated less than one year, averaged over actual operation period + +**Allowable Business Expenses**: +- Materials and supplies +- Business travel (capped at $0.25/mile unless actual costs higher) +- Business taxes +- Equipment/tool rentals +- Business location rent +- Principal payments on income-producing assets +- Interest on income-producing property purchases + +**Non-Allowable Expenses**: +- Depreciation +- Personal entertainment +- Personal commuting + +--- + +## Resource/Asset Limits + +**Source**: 8.102.510 NMAC + +| Resource Type | Limit | +|---------------|-------| +| Liquid Resources | $1,500 | +| Non-Liquid Resources | $2,000 | + +### Liquid Resources Definition +Cash or financial instruments easily convertible to cash: +- Savings accounts +- Checking accounts +- Stocks, bonds, mutual funds +- Promissory notes, mortgages +- Life insurance cash values + +### Non-Liquid Resources Definition +Assets not readily convertible to cash: +- Real property (land, buildings) +- Personal property (equipment, vehicles) + +### Key Exempt Resources +- Primary residence and reasonable surrounding land +- Vehicles used for transportation to work or daily living +- Specially equipped vehicles for disabled individuals +- Burial plots (one per person) +- Funeral agreements (unlimited) +- Work-related equipment (up to $1,000 per individual) +- Individual Development Accounts (IDAs) +- Livestock +- Grazing permits currently in use + +--- + +## Income Standards (Standard of Need / Payment Standard) + +**Source**: 8.102.500.8 NMAC + +The Standard of Need is based on the number of participants in the benefit group and allows for a financial standard and basic needs (food, clothing, shelter, utilities, personal items, household supplies). + +### Payment Standard by Benefit Group Size (Effective August 2023 - 23% increase) + +| Benefit Group Size | Monthly Payment Standard | +|--------------------|--------------------------| +| 1 | $327 | +| 2 | $439 | +| 3 | $549 | +| 4 | $663 | +| 5 | $775 | +| 6 | $887 | +| 7 | $999 | +| 8 | $1,134 | +| Each additional | +$111 (approximately) | + +**Source for 23% increase**: HCA announcement September 1, 2023 - "State announces a 23 percent increase in cash assistance for low-income New Mexico families" - effective August 2023, first increase since 2011. + +**Historical Note**: Prior to August 2023, family of 4 received $539; after increase, $663. + +--- + +## Benefit Calculation + +**Source**: 8.102.620 NMAC + +### Formula + +``` +Benefit = Payment Standard - Net Countable Income +``` + +### Calculation Steps + +1. **Calculate Gross Income** + - Add all earned income + - Add all unearned income + - Apply income exclusions + +2. **Apply Gross Income Test** + - Compare gross income to 85% FPL limit for benefit group size + - If gross income >= limit, ineligible + +3. **Calculate Net Countable Earned Income** + - Start with gross earned income + - Subtract work incentive deduction ($125/$225 + 50% of remainder) + - Subtract child care costs (up to $200 under 2, $175 age 2+) + +4. **Calculate Net Countable Unearned Income** + - Start with gross unearned income + - Subtract child support disregard ($50) + - Apply child support passthrough ($100 for 1 child, $200 for 2+ children) + +5. **Calculate Total Net Countable Income** + - Add net countable earned income + net countable unearned income + +6. **Apply Net Income Test** + - Compare net countable income to Standard of Need + - If net income >= Standard of Need, ineligible + +7. **Calculate Benefit** + - Benefit = Standard of Need - Net Countable Income + - Round down (remove cents) + +### Minimum Benefit +- No explicit minimum benefit specified +- If calculation results in $0 or negative, no benefit is issued + +### Sanctions +Benefits may be reduced for: +- First-level sanction: 25% of standard of need +- Second-level sanction: 50% of standard of need (after 3 months non-compliance) +- Third-level sanction: Case closure for minimum 6 months + +--- + +## Additional Benefits + +### School Clothing Allowance + +**Source**: 8.102.620 NMAC + +| Month | Amount per School-Age Child | +|-------|----------------------------| +| August | $100 | +| January | $50 | + +### Diversion Payment + +**Source**: 8.102.100 NMAC + +A one-time payment in lieu of ongoing cash assistance: + +| Household Size | Diversion Payment Amount | +|----------------|--------------------------| +| 1-3 persons | $1,500 | +| 4+ persons | $2,500 | + +**Limitations**: Limited to two times in an applicant's 60-month lifetime limit. + +--- + +## Transitional Benefit Program (TBP) + +**Source**: 8.102.501 NMAC + +### Purpose +Provides limited-duration cash assistance to encourage NMW families to maintain employment after leaving cash assistance. + +### Benefit Amount +$200/month (fixed, non-prorated) + +### Eligibility Requirements +- Left NMW cash assistance program +- Engaged in paid employment minimum 30 hours/week +- Gross income below 150% FPL +- Received NMW for at least 3 months (including 1 of last 3 months) +- Not reached 60-month TANF limit +- Not reached 18-month TBP limit + +### Duration +Maximum 18 months lifetime + +**Note**: Cannot be fully simulated due to lifetime tracking requirement. + +--- + +## Support Services Only Eligibility + +**Source**: 8.102.500.8 NMAC + +Benefit groups not receiving cash assistance but with gross income less than 100% FPL may be eligible to receive support services. + +**100% FPL Limits** (for support services only): + +| Benefit Group Size | Monthly Limit | +|--------------------|---------------| +| 1 | $1,255 | +| 2 | $1,703 | +| 3 | $2,152 | +| 4 | $2,600 | +| 5 | $3,049 | +| 6 | $3,497 | +| 7 | $3,946 | +| 8 | $4,394 | + +--- + +## Key References for Implementation + +### Parameters (metadata reference format) + +```yaml +reference: + - title: 8.102.520.12 NMAC - Earned Income Deductions + href: https://www.srca.nm.gov/parts/title08/08.102.0520.html + - title: 8.102.500.8 NMAC - Eligibility Policy + href: https://www.srca.nm.gov/parts/title08/08.102.0500.html +``` + +### Variables (reference format) + +```python +reference = "https://www.srca.nm.gov/parts/title08/08.102.0520.html" +``` + +--- + +## Summary of Implementation Parameters Needed + +### Income Parameters +- `income/gross_limit/rate.yaml` - 0.85 (85% of FPL) +- `income/deductions/work_incentive/single_parent/amount.yaml` - $125 +- `income/deductions/work_incentive/two_parent/amount.yaml` - $225 per parent +- `income/deductions/work_incentive/disregard_rate.yaml` - 0.50 (50%) +- `income/deductions/child_care/under_2/max.yaml` - $200 +- `income/deductions/child_care/age_2_plus/max.yaml` - $175 +- `income/child_support/disregard/amount.yaml` - $50 +- `income/child_support/passthrough/one_child.yaml` - $100 +- `income/child_support/passthrough/multiple_children.yaml` - $200 + +### Resource Parameters +- `resources/limit/liquid.yaml` - $1,500 +- `resources/limit/non_liquid.yaml` - $2,000 + +### Payment Standard Parameters +- `payment_standard/amount.yaml` - Bracketed by household size (1-8+) + +### Eligibility Parameters +- `eligibility/age_threshold/minor_child.yaml` - 18 +- `eligibility/age_threshold/special_education_max.yaml` - 22 + +--- + +## PDFs for Future Reference + +The following PDFs contain additional information but could not be extracted: + +1. **TANF State Plan 2024-2026** + - URL: https://www.hca.nm.gov/wp-content/uploads/TANF-Final-State-Plan-2024-to-2026.pdf + - Expected content: Complete state plan including benefit calculation methodology, program goals, policy changes + - Key sections: Benefit schedules, income calculations, program statistics + +2. **Income Eligibility Guidelines for SNAP and Financial Assistance (October 2024-September 2025)** + - URL: https://www.hca.nm.gov/wp-content/uploads/Income-Eligibility-Guidelines-for-SNAP-and-Financial-Assistance-October-12024-September-30-2025.pdf + - Expected content: Complete income limit tables, payment standards by household size + - Key sections: TANF income limits, payment standard tables + +3. **TANF Profile - New Mexico (NCCP August 2024)** + - URL: https://www.nccp.org/wp-content/uploads/2024/08/TANF-profile-New-Mexico.pdf + - Expected content: Summary of program rules, benefit levels, eligibility criteria + - Key sections: Benefit amount tables, comparison to FPL + +4. **5 Critical Reforms for New Mexico's TANF Program** + - URL: https://www.nmlegis.gov/handouts/LHHS%20112822%20Item%2016%20TANF%20Policy.pdf + - Expected content: Policy analysis, historical benefit levels, reform recommendations + +--- + +## Sources + +### Primary Regulatory Sources (NMAC) +- [8.102.100 NMAC - General Provisions](https://srca.nm.gov/parts/title08/08.102.0100.html) +- [8.102.400 NMAC - Eligibility Determination](https://www.srca.nm.gov/parts/title08/08.102.0400.html) +- [8.102.410 NMAC - Recipient Requirements](https://www.srca.nm.gov/parts/title08/08.102.0410.html) +- [8.102.420 NMAC - Benefit Group Composition](https://www.srca.nm.gov/parts/title08/08.102.0420.html) +- [8.102.500 NMAC - Eligibility Policy](https://www.srca.nm.gov/parts/title08/08.102.0500.html) +- [8.102.501 NMAC - Transitional Benefit Program](https://www.srca.nm.gov/parts/title08/08.102.0501.html) +- [8.102.510 NMAC - Resources/Property](https://www.srca.nm.gov/parts/title08/08.102.0510.html) +- [8.102.520 NMAC - Income](https://www.srca.nm.gov/parts/title08/08.102.0520.html) +- [8.102.620 NMAC - Benefit Determination](https://www.srca.nm.gov/parts/title08/08.102.0620.html) + +### State Agency Sources +- [New Mexico Health Care Authority - TANF Program](https://www.hca.nm.gov/lookingforassistance/temporary_assistance_for_needy_families/) +- [HCA - Income Eligibility Guidelines](https://www.hca.nm.gov/lookingforinformation/income-eligibility-federal-poverty-level-guidelines/) +- [HCA - 23% Cash Assistance Increase Announcement (Sept 2023)](https://www.hca.nm.gov/2023/09/01/state-announces-a-23-percent-increase-in-cash-assistance-for-low-income-new-mexico-families/) +- [HCA - Child Support Passthrough Increase (Jan 2023)](https://www.hca.nm.gov/2023/01/10/human-services-department-to-pass-through-more-money-to-low-income-families/) +- [HCA - Transition Bonus Program Reinstatement (June 2023)](https://www.hca.nm.gov/2023/06/01/human-services-department-announces-the-cash-assistance-transition-bonus-program-is-back/) + +### Federal Sources +- [45 CFR Part 260 - TANF General Provisions](https://www.ecfr.gov/current/title-45/part-260) +- [42 USC 601-619 - TANF Block Grant](https://www.law.cornell.edu/uscode/text/42/chapter-7/subchapter-IV/part-A) From ec13e6462a4851602d2a2936ef39931d83096886 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 25 Dec 2025 15:36:34 -0500 Subject: [PATCH 3/3] draft --- .../states/nm/hca/tanf/diversion/amount.yaml | 2 +- .../tanf/nm_tanf_child_support_deduction.yaml | 229 ++++++++++++++++++ .../nm/hca/tanf/nm_tanf_countable_income.yaml | 6 +- .../nm/hca/tanf/nm_tanf_gross_income.yaml | 110 +++++++++ .../hca/tanf/nm_tanf_net_income_eligible.yaml | 10 +- .../hca/tanf/eligibility/nm_tanf_eligible.py | 7 +- .../nm_tanf_gross_income_eligible.py | 2 +- .../nm_tanf_net_income_eligible.py | 2 +- .../eligibility/nm_tanf_resources_eligible.py | 23 ++ .../tanf/income/nm_tanf_countable_income.py | 7 +- 10 files changed, 382 insertions(+), 16 deletions(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_support_deduction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income.yaml create mode 100644 policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_resources_eligible.py diff --git a/policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml b/policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml index 57729bd1e63..57b9642c502 100644 --- a/policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml +++ b/policyengine_us/parameters/gov/states/nm/hca/tanf/diversion/amount.yaml @@ -7,7 +7,7 @@ metadata: threshold_unit: person amount_unit: currency-USD reference: - - title: 8.102.100 NMAC - General Provisions + - title: 8.102.100.7 NMAC - Definitions href: https://www.srca.nm.gov/parts/title08/08.102.0100.html brackets: diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_support_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_support_deduction.yaml new file mode 100644 index 00000000000..e8d3452c284 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_child_support_deduction.yaml @@ -0,0 +1,229 @@ +# New Mexico TANF Child Support Deduction Unit Tests +# Tests the child support deduction: $50 disregard + passthrough ($100 for 1 child, $200 for 2+ children) +# Total deduction = min(child_support_received, disregard + passthrough) +# Source: 8.102.520.10 NMAC + +- name: Case 1, zero child support results in zero deduction. + period: 2024-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # No child support received, no deduction + nm_tanf_child_support_deduction: 0 + +- name: Case 2, small child support with one child caps at amount received. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 600 # $50/month (annual input) + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $50/month + # 1 child: disregard $50 + passthrough $100 = $150 max deduction + # Deduction = min($50, $150) = $50 + nm_tanf_child_support_deduction: 50 + +- name: Case 3, child support at disregard only with zero children. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 600 # $50/month (annual input) + person2: + age: 25 # Adult, not a child + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $50/month + # 0 children: disregard $50 + passthrough $0 = $50 max deduction + # Deduction = min($50, $50) = $50 + nm_tanf_child_support_deduction: 50 + +- name: Case 4, child support exactly at max deduction for one child. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 1_800 # $150/month (annual input) + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $150/month + # 1 child: disregard $50 + passthrough $100 = $150 max deduction + # Deduction = min($150, $150) = $150 + nm_tanf_child_support_deduction: 150 + +- name: Case 5, child support exceeds max deduction for one child. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 3_600 # $300/month (annual input) + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $300/month + # 1 child: disregard $50 + passthrough $100 = $150 max deduction + # Deduction = min($300, $150) = $150 (capped) + nm_tanf_child_support_deduction: 150 + +- name: Case 6, child support exactly at max deduction for two children. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 3_000 # $250/month (annual input) + person2: + age: 10 + person3: + age: 7 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Child support: $250/month + # 2 children: disregard $50 + passthrough $200 = $250 max deduction + # Deduction = min($250, $250) = $250 + nm_tanf_child_support_deduction: 250 + +- name: Case 7, child support exceeds max deduction for two plus children. + period: 2024-01 + input: + people: + person1: + age: 30 + child_support_received: 4_800 # $400/month (annual input) + person2: + age: 12 + person3: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: NM + output: + # Child support: $400/month + # 2+ children: disregard $50 + passthrough $200 = $250 max deduction + # Deduction = min($400, $250) = $250 (capped) + nm_tanf_child_support_deduction: 250 + +- name: Case 8, child at age 17 counts as child. + period: 2024-01 + input: + people: + person1: + age: 40 + child_support_received: 3_600 # $300/month (annual input) + person2: + age: 17 # Under 18, counts as child + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $300/month + # 1 child (age 17 < 18): disregard $50 + passthrough $100 = $150 max deduction + # Deduction = min($300, $150) = $150 + nm_tanf_child_support_deduction: 150 + +- name: Case 9, person at age 18 does not count as child. + period: 2024-01 + input: + people: + person1: + age: 40 + child_support_received: 3_600 # $300/month (annual input) + person2: + age: 18 # Not under 18, not a child + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Child support: $300/month + # 0 children (age 18 >= 18): disregard $50 + passthrough $0 = $50 max deduction + # Deduction = min($300, $50) = $50 + nm_tanf_child_support_deduction: 50 + +- name: Case 10, three children still get 200 dollar passthrough. + period: 2024-01 + input: + people: + person1: + age: 35 + child_support_received: 4_800 # $400/month (annual input) + person2: + age: 14 + person3: + age: 11 + person4: + age: 6 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: NM + output: + # Child support: $400/month + # 3 children (2+ rule): disregard $50 + passthrough $200 = $250 max deduction + # Deduction = min($400, $250) = $250 + nm_tanf_child_support_deduction: 250 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml index 39e95e6797f..b5054e50df0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_countable_income.yaml @@ -45,7 +45,7 @@ # $500 + $100 - $200 = $400 nm_tanf_countable_income: 400 -- name: Case 5, child care deduction cannot make income negative. +- name: Case 5, child care deduction only applies to earned income. period: 2024-01 input: state_code: NM @@ -53,5 +53,5 @@ nm_tanf_countable_unearned_income: 50 nm_tanf_child_care_deduction: 200 output: - # $100 + $50 - $200 = -$50, but capped at $0 - nm_tanf_countable_income: 0 + # Child care deduction only applies to earned income: max($100 - $200, 0) + $50 = $50 + nm_tanf_countable_income: 50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income.yaml new file mode 100644 index 00000000000..e871b80ca19 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_gross_income.yaml @@ -0,0 +1,110 @@ +# New Mexico TANF Gross Income Unit Tests +# Tests the gross income calculation: sum of tanf_gross_earned_income and tanf_gross_unearned_income +# Source: 8.102.520 NMAC + +- name: Case 1, zero earned and zero unearned results in zero gross. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 0 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # No earned income, no unearned income + # Gross = $0 + $0 = $0 + nm_tanf_gross_income: 0 + +- name: Case 2, earned income only. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 12_000 # $1,000/month (annual input) + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Earned: $1,000/month, Unearned: $0 + # Gross = $1,000 + $0 = $1,000 + nm_tanf_gross_income: 1_000 + +- name: Case 3, unearned income only. + period: 2024-01 + input: + people: + person1: + age: 30 + social_security: 6_000 # $500/month (annual input) + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Earned: $0, Unearned: $500/month (social security) + # Gross = $0 + $500 = $500 + nm_tanf_gross_income: 500 + +- name: Case 4, both earned and unearned income. + period: 2024-01 + input: + people: + person1: + age: 30 + employment_income_before_lsr: 9_600 # $800/month (annual input) + social_security: 2_400 # $200/month (annual input) + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Earned: $800/month, Unearned: $200/month + # Gross = $800 + $200 = $1,000 + nm_tanf_gross_income: 1_000 + +- name: Case 5, high earned income with low unearned income. + period: 2024-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 36_000 # $3,000/month (annual input) + social_security: 1_200 # $100/month (annual input) + person2: + age: 10 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NM + output: + # Earned: $3,000/month, Unearned: $100/month + # Gross = $3,000 + $100 = $3,100 + nm_tanf_gross_income: 3_100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml index b3e9f242e5b..fcfdfd9186e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/hca/tanf/nm_tanf_net_income_eligible.yaml @@ -46,7 +46,7 @@ # $300 < $549 = eligible nm_tanf_net_income_eligible: true -- name: Case 3, countable income equals payment standard is ineligible. +- name: Case 3, countable income equals payment standard is eligible. period: 2024-01 input: people: @@ -68,8 +68,8 @@ members: [person1, person2, person3, person4] state_code: NM output: - # Formula uses strict less-than: $663 is not < $663 = ineligible - nm_tanf_net_income_eligible: false + # With <= comparison: $663 <= $663 = eligible (at the limit is OK) + nm_tanf_net_income_eligible: true - name: Case 4, countable income exceeds payment standard is ineligible. period: 2024-01 @@ -177,8 +177,8 @@ members: [person1] state_code: NM output: - # $0 is not < $0 = ineligible (edge case: both zero) - nm_tanf_net_income_eligible: false + # With <= comparison: $0 <= $0 = eligible (edge case: both zero) + nm_tanf_net_income_eligible: true - name: Case 9, very small countable income is eligible. period: 2024-01 diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py index 9636be0e934..6a10b504429 100644 --- a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_eligible.py @@ -13,12 +13,14 @@ def formula(spm_unit, period, parameters): # Per 8.102 NMAC, eligibility requires: # 1. Demographic eligibility (federal baseline) # 2. Immigration eligibility (federal baseline) - # 3. Gross income under 85% FPL - # 4. Net income under standard of need + # 3. Resources within limits (8.102.510) + # 4. Gross income under 85% FPL + # 5. Net income under standard of need demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) immigration_eligible = ( add(spm_unit, period, ["is_citizen_or_legal_immigrant"]) > 0 ) + resources_eligible = spm_unit("nm_tanf_resources_eligible", period) gross_income_eligible = spm_unit( "nm_tanf_gross_income_eligible", period ) @@ -27,6 +29,7 @@ def formula(spm_unit, period, parameters): return ( demographic_eligible & immigration_eligible + & resources_eligible & gross_income_eligible & net_income_eligible ) diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py index 137a7f29944..0324425ff94 100644 --- a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_gross_income_eligible.py @@ -15,4 +15,4 @@ def formula(spm_unit, period, parameters): gross_income = spm_unit("nm_tanf_gross_income", period) fpg = spm_unit("tanf_fpg", period) gross_income_limit = fpg * p.gross_limit.rate - return gross_income < gross_income_limit + return gross_income <= gross_income_limit diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py index 6fadc1e033d..6540120d9b3 100644 --- a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_net_income_eligible.py @@ -14,4 +14,4 @@ def formula(spm_unit, period, parameters): # the standard of need (payment standard) countable_income = spm_unit("nm_tanf_countable_income", period) payment_standard = spm_unit("nm_tanf_maximum_benefit", period) - return countable_income < payment_standard + return countable_income <= payment_standard diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_resources_eligible.py b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_resources_eligible.py new file mode 100644 index 00000000000..3bbdb3725b2 --- /dev/null +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/eligibility/nm_tanf_resources_eligible.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class nm_tanf_resources_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "New Mexico TANF resources eligible" + definition_period = MONTH + reference = "https://www.srca.nm.gov/parts/title08/08.102.0510.html" + defined_for = StateCode.NM + + def formula(spm_unit, period, parameters): + # Per 8.102.510 NMAC, resources/property limits: + # - Liquid resources must not exceed $1,500 + # - Non-liquid resources must not exceed $2,000 + # NOTE: Simplified check using total assets since liquid/non-liquid + # distinction is not currently modeled. Combined limit used. + p = parameters(period).gov.states.nm.hca.tanf.resources + assets = spm_unit("spm_unit_assets", period.this_year) + liquid_limit = p.liquid.amount + non_liquid_limit = p.non_liquid.amount + combined_limit = liquid_limit + non_liquid_limit + return assets <= combined_limit diff --git a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py index 4b363563d2d..aa23139d4b0 100644 --- a/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py +++ b/policyengine_us/variables/gov/states/nm/hca/tanf/income/nm_tanf_countable_income.py @@ -12,12 +12,13 @@ class nm_tanf_countable_income(Variable): def formula(spm_unit, period, parameters): # Per 8.102.520 NMAC, calculate countable income: - # Countable = Countable Earned + Countable Unearned - Child Care + # Child care deduction only applies to earned income countable_earned = spm_unit("nm_tanf_countable_earned_income", period) countable_unearned = spm_unit( "nm_tanf_countable_unearned_income", period ) child_care_deduction = spm_unit("nm_tanf_child_care_deduction", period) - return max_( - countable_earned + countable_unearned - child_care_deduction, 0 + countable_earned_after_child_care = max_( + countable_earned - child_care_deduction, 0 ) + return countable_earned_after_child_care + countable_unearned