diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..2b8ca1a797f 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Add Mississippi TANF program. diff --git a/policyengine_us/parameters/gov/states/ms/dhs/tanf/income/gross_income_limit_rate.yaml b/policyengine_us/parameters/gov/states/ms/dhs/tanf/income/gross_income_limit_rate.yaml new file mode 100644 index 00000000000..6ee864c7e41 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/tanf/income/gross_income_limit_rate.yaml @@ -0,0 +1,14 @@ +description: Mississippi limits gross income to this share of the need standard under the Temporary Assistance for Needy Families program. + +values: + 2018-07-01: 1.85 + +metadata: + unit: /1 + period: month + label: Mississippi TANF gross income limit rate + reference: + - title: Miss. Code. tit. 18, pt. 19 - TANF State Plan (185% of Need Standard) + href: https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19 + - title: MDHS TANF Eligibility Flyer (2018) - Shows 185% Requirements + href: https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf diff --git a/policyengine_us/parameters/gov/states/ms/dhs/tanf/need_standard/amount.yaml b/policyengine_us/parameters/gov/states/ms/dhs/tanf/need_standard/amount.yaml new file mode 100644 index 00000000000..9828f9654e2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/tanf/need_standard/amount.yaml @@ -0,0 +1,46 @@ +description: Mississippi sets this amount as the need standard under the Temporary Assistance for Needy Families program. + +metadata: + unit: currency-USD + period: month + breakdown: + - range(1, 11) + label: Mississippi TANF need standard amount + reference: + - title: MDHS TANF Eligibility Flyer (2018) - 100% Requirements Table + href: https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf + - title: Mississippi Department of Human Services - Applying for TANF (Gross Income Limits, values derived by dividing by 1.85) + href: https://www.mdhs.ms.gov/help/tanf/applying-for-tanf/ +# 2018 values from MDHS Eligibility Flyer (100% Requirements = Need Standard) +# 2025 values derived from current MDHS website gross income limits / 1.85 + +1: + 2018-07-01: 218 + 2025-07-01: 339 +2: + 2018-07-01: 293 + 2025-07-01: 460 +3: + 2018-07-01: 368 + 2025-07-01: 581 +4: + 2018-07-01: 443 + 2025-07-01: 702 +5: + 2018-07-01: 518 + 2025-07-01: 823 +6: + 2018-07-01: 593 + 2025-07-01: 944 +7: + 2018-07-01: 668 + 2025-07-01: 1_065 +8: + 2018-07-01: 743 + 2025-07-01: 1_186 +9: + 2018-07-01: 818 + 2025-07-01: 1_307 +10: + 2018-07-01: 893 + 2025-07-01: 1_428 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/tanf/need_standard/max_table_size.yaml b/policyengine_us/parameters/gov/states/ms/dhs/tanf/need_standard/max_table_size.yaml new file mode 100644 index 00000000000..94aa3f726c3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/tanf/need_standard/max_table_size.yaml @@ -0,0 +1,14 @@ +description: Mississippi caps need standard calculations at this household size under the Temporary Assistance for Needy Families program. + +values: + 2018-07-01: 10 + +metadata: + unit: person + period: year + label: Mississippi TANF need standard maximum table size + reference: + - title: MDHS TANF Eligibility Flyer (2018) - Income Requirements Table (shows sizes 1-10) + href: https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf + - title: Mississippi Department of Human Services - Applying for TANF (Income Limits Table shows sizes 1-10) + href: https://www.mdhs.ms.gov/help/tanf/applying-for-tanf/ diff --git a/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/additional_person.yaml b/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/additional_person.yaml new file mode 100644 index 00000000000..cd473cd71ce --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/additional_person.yaml @@ -0,0 +1,14 @@ +description: Mississippi provides this amount for each additional person beyond the second under the Temporary Assistance for Needy Families program. + +values: + 2018-07-01: 24 + +metadata: + unit: currency-USD + period: month + label: Mississippi TANF payment standard additional person + reference: + - title: MDHS TANF Eligibility Flyer (2018) - Maximum TANF Grant Table + href: https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf + - title: Miss. Code. tit. 18, pt. 19 - TANF State Plan (Payment Standards) + href: https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/first_person.yaml b/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/first_person.yaml new file mode 100644 index 00000000000..2b99d80f67e --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/first_person.yaml @@ -0,0 +1,17 @@ +description: Mississippi provides this amount for the first person under the Temporary Assistance for Needy Families program. + +values: + 2018-07-01: 110 + 2021-05-01: 200 + +metadata: + unit: currency-USD + period: month + label: Mississippi TANF payment standard first person + reference: + - title: MDHS TANF Eligibility Flyer (2018) - Maximum TANF Grant Table + href: https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf + - title: SB 2759 (2021) - TANF Benefit Increase (first person from $110 to $200) + href: https://billstatus.ls.state.ms.us/documents/2021/html/SB/2700-2799/SB2759SG.htm + - title: Miss. Code. tit. 18, pt. 19 - TANF State Plan (Payment Standards) + href: https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/second_person.yaml b/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/second_person.yaml new file mode 100644 index 00000000000..0076deca747 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/tanf/payment_standard/second_person.yaml @@ -0,0 +1,14 @@ +description: Mississippi provides this amount for the second person under the Temporary Assistance for Needy Families program. + +values: + 2018-07-01: 36 + +metadata: + unit: currency-USD + period: month + label: Mississippi TANF payment standard second person + reference: + - title: MDHS TANF Eligibility Flyer (2018) - Maximum TANF Grant Table + href: https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf + - title: Miss. Code. tit. 18, pt. 19 - TANF State Plan (Payment Standards) + href: https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19 diff --git a/policyengine_us/parameters/gov/states/ms/dhs/tanf/resources/limit.yaml b/policyengine_us/parameters/gov/states/ms/dhs/tanf/resources/limit.yaml new file mode 100644 index 00000000000..34fd5bfa7ce --- /dev/null +++ b/policyengine_us/parameters/gov/states/ms/dhs/tanf/resources/limit.yaml @@ -0,0 +1,14 @@ +description: Mississippi limits resources to this amount under the Temporary Assistance for Needy Families program. + +values: + 2018-07-01: 2_000 + +metadata: + unit: currency-USD + period: month + label: Mississippi TANF resource limit + reference: + - title: Miss. Code. tit. 18, pt. 19 - TANF State Plan + href: https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19 + - title: Mississippi Department of Human Services - TANF + href: https://www.mdhs.ms.gov/help/tanf/ diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/integration.yaml new file mode 100644 index 00000000000..ce0c68e42f9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/integration.yaml @@ -0,0 +1,267 @@ +# Mississippi TANF Integration Tests +# +# Program Rules: +# - Income eligibility: Gross income <= 185% of need standard +# - Need standards by size: 1=$339, 2=$460, 3=$581, 4=$702, 5=$823 +# - Income limits by size: 1=$627, 2=$851, 3=$1,074, 4=$1,298, 5=$1,523 +# - Payment standards: First person $200, second $36, each additional $24 +# - Resource limit: $2,000 +# - Benefit: Maximum Payment Standard - Countable Income + +- name: Case 1, single parent with one child, no income, receives maximum benefit. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 500 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Household size: 2 + spm_unit_size: 2 + # Payment standard: $200 + $36 = $236 + ms_tanf_maximum_benefit: 236 + # Resources: $500 <= $2,000 + ms_tanf_resources_eligible: true + # Income: $0 <= $851 (185% of $460) + ms_tanf_income_eligible: true + # Final benefit: $236 - $0 = $236 + ms_tanf_eligible: true + ms_tanf: 236 + +- name: Case 2, family of 3 with low earned income. + period: 2026-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 6_000 + # Annual income: $6,000 -> Monthly: $500 + person2: + age: 8 + is_tax_unit_dependent: true + person3: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 800 + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + output: + # Household size: 3 + spm_unit_size: 3 + # Payment standard: $200 + $36 + $24 = $260 + ms_tanf_maximum_benefit: 260 + # Resources: $800 <= $2,000 + ms_tanf_resources_eligible: true + # Gross income: $500/month + # Limit: $581 * 1.85 = $1,074.85 + # $500 <= $1,074.85 + ms_tanf_income_eligible: true + # Final eligibility + ms_tanf_eligible: true + +- name: Case 3, family of 3 with income at 185% threshold. + period: 2026-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 12_888 + # Annual income: $12,888 -> Monthly: $1,074 + person2: + age: 8 + is_tax_unit_dependent: true + person3: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 500 + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + output: + # Household size: 3 + spm_unit_size: 3 + # Payment standard: $200 + $36 + $24 = $260 + ms_tanf_maximum_benefit: 260 + # Gross income: $1,074/month + # Limit: $581 * 1.85 = $1,074.85 + # $1,074 <= $1,074.85 = true (exactly at threshold) + ms_tanf_income_eligible: true + ms_tanf_resources_eligible: true + ms_tanf_eligible: true + +- name: Case 4, family of 3 with income above 185% threshold. + period: 2026-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 15_000 + # Annual income: $15,000 -> Monthly: $1,250 + person2: + age: 8 + is_tax_unit_dependent: true + person3: + age: 3 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3] + spm_unit_assets: 500 + tax_units: + tax_unit: + members: [person1, person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: MS + output: + # Household size: 3 + spm_unit_size: 3 + # Gross income: $1,250/month + # Limit: $581 * 1.85 = $1,074.85 + # $1,250 > $1,074.85 = false + ms_tanf_income_eligible: false + ms_tanf_resources_eligible: true + ms_tanf_eligible: false + ms_tanf: 0 + +- name: Case 5, family of 4 with resources at limit. + period: 2026-01 + input: + people: + person1: + age: 40 + person2: + age: 38 + person3: + age: 10 + is_tax_unit_dependent: true + person4: + age: 6 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + spm_unit_assets: 2_000 + tax_units: + tax_unit: + members: [person1, person2, person3, person4] + households: + household: + members: [person1, person2, person3, person4] + state_code: MS + output: + # Household size: 4 + spm_unit_size: 4 + # Payment standard: $200 + $36 + $24 + $24 = $284 + ms_tanf_maximum_benefit: 284 + # Resources: $2,000 <= $2,000 + ms_tanf_resources_eligible: true + # Income: $0/month <= $1,298.7 + ms_tanf_income_eligible: true + ms_tanf_eligible: true + # Benefit: $284 - $0 = $284 + ms_tanf: 284 + +- name: Case 6, family with resources exceeding limit. + period: 2026-01 + input: + people: + person1: + age: 30 + person2: + age: 5 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2] + spm_unit_assets: 3_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MS + output: + # Household size: 2 + spm_unit_size: 2 + # Resources: $3,000 > $2,000 + ms_tanf_resources_eligible: false + # Income: $0 <= $851 = true + ms_tanf_income_eligible: true + # Fails resources test, so ineligible + ms_tanf_eligible: false + ms_tanf: 0 + +- name: Case 7, large family of 5 with mixed income. + period: 2026-01 + input: + people: + person1: + age: 35 + employment_income_before_lsr: 6_000 + # Annual: $6,000 -> Monthly: $500 + person2: + age: 12 + is_tax_unit_dependent: true + person3: + age: 8 + is_tax_unit_dependent: true + person4: + age: 5 + is_tax_unit_dependent: true + person5: + age: 2 + is_tax_unit_dependent: true + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5] + spm_unit_assets: 200 + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5] + households: + household: + members: [person1, person2, person3, person4, person5] + state_code: MS + output: + # Household size: 5 + spm_unit_size: 5 + # Payment standard: $200 + $36 + ($24 * 3) = $308 + ms_tanf_maximum_benefit: 308 + # Resources: $200 <= $2,000 + ms_tanf_resources_eligible: true + # Gross income: $500/month + # Limit: $823 * 1.85 = $1,522.55 + # $500 <= $1,522.55 = true + ms_tanf_income_eligible: true + ms_tanf_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf.yaml new file mode 100644 index 00000000000..efa341c2bc3 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf.yaml @@ -0,0 +1,124 @@ +# Mississippi TANF benefit calculation tests +# Benefit = Maximum Payment Standard - Countable Income +# If countable income exceeds payment standard, benefit = $0 +# Must be eligible (ms_tanf_eligible) to receive any benefit + +- name: Case 1, ineligible household receives zero benefit. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: false + ms_tanf_maximum_benefit: 260 + ms_tanf_countable_income: 0 + output: + ms_tanf: 0 + +- name: Case 2, eligible household with no income receives maximum benefit. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 260 + ms_tanf_countable_income: 0 + output: + # $260 - $0 = $260 + ms_tanf: 260 + +- name: Case 3, eligible household with countable income receives reduced benefit. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 260 + ms_tanf_countable_income: 100 + output: + # $260 - $100 = $160 + ms_tanf: 160 + +- name: Case 4, eligible family of 2 with no income. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 236 + ms_tanf_countable_income: 0 + output: + # $236 - $0 = $236 + ms_tanf: 236 + +- name: Case 5, eligible family of 2 with some income. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 236 + ms_tanf_countable_income: 150 + output: + # $236 - $150 = $86 + ms_tanf: 86 + +- name: Case 6, eligible family of 4 with no income. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 284 + ms_tanf_countable_income: 0 + output: + # $284 - $0 = $284 + ms_tanf: 284 + +- name: Case 7, eligible family of 4 with income. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 284 + ms_tanf_countable_income: 200 + output: + # $284 - $200 = $84 + ms_tanf: 84 + +- name: Case 8, countable income equals maximum benefit. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 260 + ms_tanf_countable_income: 260 + output: + # $260 - $260 = $0 + ms_tanf: 0 + +- name: Case 9, countable income exceeds maximum benefit. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 260 + ms_tanf_countable_income: 300 + output: + # $260 - $300 = -$40, capped at $0 + ms_tanf: 0 + +- name: Case 10, single person eligible with small income. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 200 + ms_tanf_countable_income: 50 + output: + # $200 - $50 = $150 + ms_tanf: 150 + +- name: Case 11, high income reduces benefit to near zero. + period: 2026-01 + input: + state_code: MS + ms_tanf_eligible: true + ms_tanf_maximum_benefit: 260 + ms_tanf_countable_income: 255 + output: + # $260 - $255 = $5 + ms_tanf: 5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_eligible.yaml new file mode 100644 index 00000000000..c644c446aea --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_eligible.yaml @@ -0,0 +1,86 @@ +# Mississippi TANF overall eligibility tests +# Eligible when: +# - In Mississippi (defined_for = MS) +# - Has eligible household member (is_person_demographic_tanf_eligible) +# - Meets income test (ms_tanf_income_eligible) +# - Meets resources test (ms_tanf_resources_eligible) + +- name: Case 1, eligible when all conditions met. + period: 2026-01 + input: + state_code: MS + is_person_demographic_tanf_eligible: true + ms_tanf_income_eligible: true + ms_tanf_resources_eligible: true + output: + ms_tanf_eligible: true + +- name: Case 2, ineligible when not in Mississippi. + period: 2026-01 + input: + state_code: NY + is_person_demographic_tanf_eligible: true + ms_tanf_income_eligible: true + ms_tanf_resources_eligible: true + output: + ms_tanf_eligible: false + +- name: Case 3, ineligible when not demographically eligible. + period: 2026-01 + input: + state_code: MS + is_person_demographic_tanf_eligible: false + ms_tanf_income_eligible: true + ms_tanf_resources_eligible: true + output: + ms_tanf_eligible: false + +- name: Case 4, ineligible when income test fails. + period: 2026-01 + input: + state_code: MS + is_person_demographic_tanf_eligible: true + ms_tanf_income_eligible: false + ms_tanf_resources_eligible: true + output: + ms_tanf_eligible: false + +- name: Case 5, ineligible when resources test fails. + period: 2026-01 + input: + state_code: MS + is_person_demographic_tanf_eligible: true + ms_tanf_income_eligible: true + ms_tanf_resources_eligible: false + output: + ms_tanf_eligible: false + +- name: Case 6, ineligible when all tests fail. + period: 2026-01 + input: + state_code: NY + is_person_demographic_tanf_eligible: false + ms_tanf_income_eligible: false + ms_tanf_resources_eligible: false + output: + ms_tanf_eligible: false + +- name: Case 7, ineligible when income and resources fail. + period: 2026-01 + input: + state_code: MS + is_person_demographic_tanf_eligible: true + ms_tanf_income_eligible: false + ms_tanf_resources_eligible: false + output: + ms_tanf_eligible: false + +- name: Case 8, ineligible when demographic and resources fail. + period: 2026-01 + input: + state_code: MS + is_person_demographic_tanf_eligible: false + ms_tanf_income_eligible: true + ms_tanf_resources_eligible: false + output: + ms_tanf_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_income_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_income_eligible.yaml new file mode 100644 index 00000000000..a2622b0e44c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_income_eligible.yaml @@ -0,0 +1,158 @@ +# Mississippi TANF income eligibility tests +# Gross income limit = Need Standard x 1.85 (185%) +# Need standards by size: 1=$339, 2=$460, 3=$581, 4=$702 +# Income limits by size: 1=$627, 2=$851, 3=$1,074, 4=$1,298 + +- name: Case 1, single person with zero income. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 1 + tanf_gross_earned_income: 0 + tanf_gross_unearned_income: 0 + output: + # Limit: $339 * 1.85 = $627.15 + ms_tanf_income_eligible: true + +- name: Case 2, single person with income at limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 1 + tanf_gross_earned_income: 627 + tanf_gross_unearned_income: 0 + output: + # Limit: $339 * 1.85 = $627.15 + # Income: $627 <= $627.15 = true + ms_tanf_income_eligible: true + +- name: Case 3, single person with income above limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 1 + tanf_gross_earned_income: 628 + tanf_gross_unearned_income: 0 + output: + # Limit: $339 * 1.85 = $627.15 + # Income: $628 > $627.15 = false + ms_tanf_income_eligible: false + +- name: Case 4, family of 2 with income below limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 2 + tanf_gross_earned_income: 500 + tanf_gross_unearned_income: 200 + output: + # Limit: $460 * 1.85 = $851 + # Income: $700 <= $851 = true + ms_tanf_income_eligible: true + +- name: Case 5, family of 2 with income at limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 2 + tanf_gross_earned_income: 600 + tanf_gross_unearned_income: 251 + output: + # Limit: $460 * 1.85 = $851 + # Income: $851 <= $851 = true + ms_tanf_income_eligible: true + +- name: Case 6, family of 2 with income above limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 2 + tanf_gross_earned_income: 600 + tanf_gross_unearned_income: 252 + output: + # Limit: $460 * 1.85 = $851 + # Income: $852 > $851 = false + ms_tanf_income_eligible: false + +- name: Case 7, family of 3 with income below limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 3 + tanf_gross_earned_income: 800 + tanf_gross_unearned_income: 0 + output: + # Limit: $581 * 1.85 = $1,074.85 + # Income: $800 <= $1,074.85 = true + ms_tanf_income_eligible: true + +- name: Case 8, family of 3 with income at limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 3 + tanf_gross_earned_income: 1_074 + tanf_gross_unearned_income: 0 + output: + # Limit: $581 * 1.85 = $1,074.85 + # Income: $1,074 <= $1,074.85 = true + ms_tanf_income_eligible: true + +- name: Case 9, family of 3 with income above limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 3 + tanf_gross_earned_income: 1_075 + tanf_gross_unearned_income: 0 + output: + # Limit: $581 * 1.85 = $1,074.85 + # Income: $1,075 > $1,074.85 = false + ms_tanf_income_eligible: false + +- name: Case 10, family of 4 with income below limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 4 + tanf_gross_earned_income: 1_000 + tanf_gross_unearned_income: 200 + output: + # Limit: $702 * 1.85 = $1,298.7 + # Income: $1,200 <= $1,298.7 = true + ms_tanf_income_eligible: true + +- name: Case 11, family of 4 with income above limit. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 4 + tanf_gross_earned_income: 1_000 + tanf_gross_unearned_income: 300 + output: + # Limit: $702 * 1.85 = $1,298.7 + # Income: $1,300 > $1,298.7 = false + ms_tanf_income_eligible: false + +- name: Case 12, family of 11 need standard capped at size 10. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 11 + tanf_gross_earned_income: 2_641 + tanf_gross_unearned_income: 0 + output: + # Limit: $1,428 * 1.85 = $2,641.80 (uses size 10 need standard) + # Income: $2,641 <= $2,641.80 = true + ms_tanf_income_eligible: true + +- name: Case 13, not in Mississippi. + period: 2026-01 + input: + state_code: NY + spm_unit_size: 3 + tanf_gross_earned_income: 500 + tanf_gross_unearned_income: 0 + output: + # Not in MS, returns false (defined_for = MS) + ms_tanf_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_maximum_benefit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_maximum_benefit.yaml new file mode 100644 index 00000000000..c8dd03647ea --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_maximum_benefit.yaml @@ -0,0 +1,113 @@ +# Mississippi TANF maximum benefit (payment standard) tests +# Per MS Code 43-17-5(1): +# - First person: $200 +# - Second person: $36 +# - Each additional person: $24 + +- name: Case 1, family of 1. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 1 + output: + # $200 (first person only) + ms_tanf_maximum_benefit: 200 + +- name: Case 2, family of 2. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 2 + output: + # $200 + $36 = $236 + ms_tanf_maximum_benefit: 236 + +- name: Case 3, family of 3. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 3 + output: + # $200 + $36 + $24 = $260 + ms_tanf_maximum_benefit: 260 + +- name: Case 4, family of 4. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 4 + output: + # $200 + $36 + $24 + $24 = $284 + ms_tanf_maximum_benefit: 284 + +- name: Case 5, family of 5. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 5 + output: + # $200 + $36 + ($24 * 3) = $308 + ms_tanf_maximum_benefit: 308 + +- name: Case 6, family of 6. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 6 + output: + # $200 + $36 + ($24 * 4) = $332 + ms_tanf_maximum_benefit: 332 + +- name: Case 7, family of 7. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 7 + output: + # $200 + $36 + ($24 * 5) = $356 + ms_tanf_maximum_benefit: 356 + +- name: Case 8, family of 8. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 8 + output: + # $200 + $36 + ($24 * 6) = $380 + ms_tanf_maximum_benefit: 380 + +- name: Case 9, family of 9. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 9 + output: + # $200 + $36 + ($24 * 7) = $404 + ms_tanf_maximum_benefit: 404 + +- name: Case 10, family of 10. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 10 + output: + # $200 + $36 + ($24 * 8) = $428 + ms_tanf_maximum_benefit: 428 + +- name: Case 11, family of 11. + period: 2026-01 + input: + state_code: MS + spm_unit_size: 11 + output: + # $200 + $36 + ($24 * 9) = $452 + ms_tanf_maximum_benefit: 452 + +- name: Case 12, not in Mississippi. + period: 2026-01 + input: + state_code: NY + spm_unit_size: 3 + output: + # Not in MS, returns 0 (defined_for = MS) + ms_tanf_maximum_benefit: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_resources_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_resources_eligible.yaml new file mode 100644 index 00000000000..833dd23510b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ms/dhs/tanf/ms_tanf_resources_eligible.yaml @@ -0,0 +1,66 @@ +# Mississippi TANF resources eligibility tests +# Resource limit: $2,000 for all households +# Effective date: July 1, 2019 + +- name: Case 1, zero resources. + period: 2026-01 + input: + state_code: MS + spm_unit_assets: 0 + output: + # $0 <= $2,000 = true + ms_tanf_resources_eligible: true + +- name: Case 2, resources well below limit. + period: 2026-01 + input: + state_code: MS + spm_unit_assets: 500 + output: + # $500 <= $2,000 = true + ms_tanf_resources_eligible: true + +- name: Case 3, resources below limit. + period: 2026-01 + input: + state_code: MS + spm_unit_assets: 1_500 + output: + # $1,500 <= $2,000 = true + ms_tanf_resources_eligible: true + +- name: Case 4, resources exactly at limit. + period: 2026-01 + input: + state_code: MS + spm_unit_assets: 2_000 + output: + # $2,000 <= $2,000 = true + ms_tanf_resources_eligible: true + +- name: Case 5, resources slightly above limit. + period: 2026-01 + input: + state_code: MS + spm_unit_assets: 2_001 + output: + # $2,001 > $2,000 = false + ms_tanf_resources_eligible: false + +- name: Case 6, resources well above limit. + period: 2026-01 + input: + state_code: MS + spm_unit_assets: 5_000 + output: + # $5,000 > $2,000 = false + ms_tanf_resources_eligible: false + +- name: Case 7, not in Mississippi. + period: 2026-01 + input: + state_code: NY + spm_unit_assets: 500 + output: + # Not in MS, returns false (defined_for = MS) + ms_tanf_resources_eligible: false diff --git a/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_eligible.py new file mode 100644 index 00000000000..bc85c924011 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_eligible.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class ms_tanf_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Mississippi TANF eligibility" + definition_period = MONTH + defined_for = StateCode.MS + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf", + "https://law.justia.com/codes/mississippi/title-43/chapter-17/section-43-17-1/", + "https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19", + ) + + def formula(spm_unit, period, parameters): + # Use federal demographic eligibility baseline + demographic_eligible = spm_unit("is_demographic_tanf_eligible", period) + + # Use federal immigration eligibility baseline + immigration_eligible = ( + add(spm_unit, period, ["is_citizen_or_legal_immigrant"]) > 0 + ) + + income_eligible = spm_unit("ms_tanf_income_eligible", period) + resources_eligible = spm_unit("ms_tanf_resources_eligible", period) + + return ( + demographic_eligible + & immigration_eligible + & income_eligible + & resources_eligible + ) diff --git a/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_income_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_income_eligible.py new file mode 100644 index 00000000000..b1b08eb2f29 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_income_eligible.py @@ -0,0 +1,34 @@ +from policyengine_us.model_api import * + + +class ms_tanf_income_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Mississippi TANF income eligibility" + definition_period = MONTH + defined_for = StateCode.MS + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf", + "https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19", + "https://www.mdhs.ms.gov/help/tanf/applying-for-tanf/", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.tanf + + # Use federal baseline for gross income + gross_income = add( + spm_unit, + period, + ["tanf_gross_earned_income", "tanf_gross_unearned_income"], + ) + + # Get need standard based on household size (capped at table max) + size = spm_unit("spm_unit_size", period.this_year) + capped_size = min_(size, p.need_standard.max_table_size).astype(int) + need_standard = p.need_standard.amount[capped_size] + + # Gross income limit is 185% of need standard + gross_income_limit = need_standard * p.income.gross_income_limit_rate + + return gross_income <= gross_income_limit diff --git a/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_resources_eligible.py b/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_resources_eligible.py new file mode 100644 index 00000000000..78c88b87091 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/tanf/eligibility/ms_tanf_resources_eligible.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ms_tanf_resources_eligible(Variable): + value_type = bool + entity = SPMUnit + label = "Mississippi TANF resources eligibility" + definition_period = MONTH + defined_for = StateCode.MS + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf", + "https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19", + "https://www.mdhs.ms.gov/help/tanf/", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.tanf.resources + household_assets = spm_unit("spm_unit_assets", period.this_year) + return household_assets <= p.limit diff --git a/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf.py b/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf.py new file mode 100644 index 00000000000..34f9ba67265 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ms_tanf(Variable): + value_type = float + entity = SPMUnit + label = "Mississippi TANF" + unit = USD + definition_period = MONTH + defined_for = "ms_tanf_eligible" + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf", + "https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19", + ) + + def formula(spm_unit, period, parameters): + maximum_benefit = spm_unit("ms_tanf_maximum_benefit", period) + countable_income = spm_unit("ms_tanf_countable_income", period) + return max_(maximum_benefit - countable_income, 0) diff --git a/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf_countable_income.py b/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf_countable_income.py new file mode 100644 index 00000000000..b5eed6bf585 --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf_countable_income.py @@ -0,0 +1,19 @@ +from policyengine_us.model_api import * + + +class ms_tanf_countable_income(Variable): + value_type = float + entity = SPMUnit + label = "Mississippi TANF countable income" + unit = USD + definition_period = MONTH + defined_for = StateCode.MS + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf", + "https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19", + ) + # NOTE: Mississippi has 6-month and 3-month total earned income disregards + # that cannot be tracked in PolicyEngine. This simplified implementation + # uses gross income without those time-limited disregards. + + adds = ["tanf_gross_earned_income", "tanf_gross_unearned_income"] diff --git a/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf_maximum_benefit.py b/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf_maximum_benefit.py new file mode 100644 index 00000000000..b8c322e976a --- /dev/null +++ b/policyengine_us/variables/gov/states/ms/dhs/tanf/ms_tanf_maximum_benefit.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class ms_tanf_maximum_benefit(Variable): + value_type = float + entity = SPMUnit + label = "Mississippi TANF maximum benefit" + unit = USD + definition_period = MONTH + defined_for = StateCode.MS + reference = ( + "https://www.mdhs.ms.gov/wp-content/uploads/2018/02/MDHS_TANF-Eligibility-Flyer.pdf", + "https://billstatus.ls.state.ms.us/documents/2021/html/SB/2700-2799/SB2759SG.htm", + "https://www.law.cornell.edu/regulations/mississippi/Miss-Code-tit-18-pt-19", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ms.dhs.tanf.payment_standard + size = spm_unit("spm_unit_size", period.this_year) + + # Payment standard: first_person + second_person (if size >= 2) + additional_person * (size - 2) + first_person = p.first_person + second_person = where(size >= 2, p.second_person, 0) + additional_persons = max_(size - 2, 0) * p.additional_person + + return first_person + second_person + additional_persons diff --git a/uv.lock b/uv.lock index 8092e2f4e8e..e1974756b97 100644 --- a/uv.lock +++ b/uv.lock @@ -1534,7 +1534,7 @@ wheels = [ [[package]] name = "policyengine-us" -version = "1.477.0" +version = "1.478.0" source = { editable = "." } dependencies = [ { name = "microdf-python" },