diff --git a/changelog.d/nh-ssp-2026.added.md b/changelog.d/nh-ssp-2026.added.md new file mode 100644 index 00000000000..01909548a32 --- /dev/null +++ b/changelog.d/nh-ssp-2026.added.md @@ -0,0 +1 @@ +Add New Hampshire's adult category state supplement (Old Age Assistance, Aid to the Needy Blind and Aid to the Permanently and Totally Disabled) for 2026. diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index d2cbd6ba2d4..466af75f757 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -65,6 +65,8 @@ values: - ok_child_care_subsidies # South Carolina benefits - sc_child_care_subsidies + # New Hampshire benefits + - nh_ssp # New Mexico benefits - nm_ssi_state_supplement # South Carolina benefits @@ -157,6 +159,8 @@ values: - nv_child_care_subsidies # Oklahoma benefits - ok_child_care_subsidies + # New Hampshire benefits + - nh_ssp # New Mexico benefits - nm_ssi_state_supplement # South Carolina benefits @@ -259,6 +263,8 @@ values: - nv_child_care_subsidies # Oklahoma benefits - ok_child_care_subsidies + # New Hampshire benefits + - nh_ssp # New Mexico benefits - nm_ssi_state_supplement # South Carolina benefits @@ -362,6 +368,8 @@ values: - nv_child_care_subsidies # Oklahoma benefits - ok_child_care_subsidies + # New Hampshire benefits + - nh_ssp # New Mexico benefits - nm_ssi_state_supplement # South Carolina benefits @@ -401,6 +409,7 @@ values: - nj_property_tax_relief # New York benefits - ny_child_care_subsidies + metadata: unit: list period: year diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index 0df11213631..a94d8c7ffb1 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -19,6 +19,7 @@ values: - strike_benefits - social_security - ssi + - nh_ssp - general_assistance - total_unemployment_compensation - child_support_received @@ -29,6 +30,7 @@ values: - disability_benefits - survivor_benefits - financial_assistance + metadata: unit: list period: year diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/disabled_minimum_age.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/disabled_minimum_age.yaml new file mode 100644 index 00000000000..157ec1bb974 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/disabled_minimum_age.yaml @@ -0,0 +1,10 @@ +description: New Hampshire sets this age as the minimum for disabled applicants under the adult category financial assistance program. +values: + 2026-01-01: 18 + +metadata: + unit: year + label: New Hampshire SSP minimum disabled age + reference: + - title: RSA 167:6 VI + href: https://gc.nh.gov/rsa/html/XII/167/167-6.htm diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/aged_disabled_flat.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/aged_disabled_flat.yaml new file mode 100644 index 00000000000..291f5261d0c --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/aged_disabled_flat.yaml @@ -0,0 +1,11 @@ +description: New Hampshire excludes this amount of monthly gross earnings under the Old Age Assistance and Aid to the Permanently and Totally Disabled programs. +values: + 2026-01-01: 20 + +metadata: + unit: currency-USD + period: month + label: New Hampshire SSP aged and disabled flat earned income disregard + reference: + - title: He-W 654.15(f), Aged and disabled earned income disregard + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/aged_disabled_remainder_disregard_cap.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/aged_disabled_remainder_disregard_cap.yaml new file mode 100644 index 00000000000..03ec3ff8942 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/aged_disabled_remainder_disregard_cap.yaml @@ -0,0 +1,11 @@ +description: New Hampshire limits the disregard of remaining earnings to this amount under the Old Age Assistance and Aid to the Permanently and Totally Disabled programs. +values: + 2026-01-01: 30 + +metadata: + unit: currency-USD + period: month + label: New Hampshire SSP aged and disabled remaining earnings disregard cap + reference: + - title: He-W 654.15(f), Aged and disabled earned income disregard + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/blind_flat.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/blind_flat.yaml new file mode 100644 index 00000000000..64f49087f5e --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/blind_flat.yaml @@ -0,0 +1,11 @@ +description: New Hampshire excludes this amount of monthly gross earnings under the Aid to the Needy Blind program. +values: + 2026-01-01: 85 + +metadata: + unit: currency-USD + period: month + label: New Hampshire SSP blind flat earned income disregard + reference: + - title: He-W 654.15(b), Blind earned income disregard + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/disregard_fraction.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/disregard_fraction.yaml new file mode 100644 index 00000000000..7adfa5e757a --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/disregard_fraction.yaml @@ -0,0 +1,10 @@ +description: New Hampshire excludes this share of earnings above the flat disregard under the adult category financial assistance program. +values: + 2026-01-01: 0.5 + +metadata: + unit: /1 + label: New Hampshire SSP remaining earnings disregard rate + reference: + - title: He-W 654.15(b) and (f)(2), Earned income disregards + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/minimum_employment_expenses.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/minimum_employment_expenses.yaml new file mode 100644 index 00000000000..03120ed5a53 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/earned/minimum_employment_expenses.yaml @@ -0,0 +1,11 @@ +description: New Hampshire deducts at least this amount of employment expenses under the Old Age Assistance and Aid to the Permanently and Totally Disabled programs. +values: + 2026-01-01: 18 + +metadata: + unit: currency-USD + period: month + label: New Hampshire SSP minimum employment expense disregard + reference: + - title: He-W 654.18(b), Employment expenses + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/grant_reduction_fraction.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/grant_reduction_fraction.yaml new file mode 100644 index 00000000000..8d5a17f7749 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/grant_reduction_fraction.yaml @@ -0,0 +1,10 @@ +description: New Hampshire deducts this share of the grant for recipients subject to the grant reduction under the adult category financial assistance program. +values: + 2026-01-01: 0.3333333333333333 + +metadata: + unit: /1 + label: New Hampshire SSP grant reduction rate + reference: + - title: He-W 670.03(c), Grant reduction + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/exempt_statuses.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/exempt_statuses.yaml new file mode 100644 index 00000000000..e1587973f2d --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/exempt_statuses.yaml @@ -0,0 +1,20 @@ +description: New Hampshire excludes these immigration statuses from the qualified alien waiting period under the adult category financial assistance program. +values: + # Amerasian immigrants, COFA migrants, qualifying military noncitizens, + # certain Native Americans and trafficking victims are also eligible without + # restriction but have no immigration_status value. + 2026-01-01: + - REFUGEE + - ASYLEE + - CUBAN_HAITIAN_ENTRANT + - DEPORTATION_WITHHELD + +metadata: + unit: list + period: year + label: New Hampshire SSP immigration statuses without a waiting period + reference: + - title: NH DHHS Adult Assistance Manual 305.11, Qualified Aliens Eligible Without Restriction + href: https://dhhs.nh.gov/aam_htm/html/305_11_qualified_aliens_eligible_without_restriction_aam.htm + - title: 8 U.S.C. 1622(b)(1), Time-limited exception for refugees and asylees + href: https://www.law.cornell.edu/uscode/text/8/1622#b_1 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/permanent_resident_qualifying_quarters.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/permanent_resident_qualifying_quarters.yaml new file mode 100644 index 00000000000..0d309ecf207 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/permanent_resident_qualifying_quarters.yaml @@ -0,0 +1,13 @@ +description: New Hampshire treats a lawful permanent resident credited with at least this many qualifying quarters as exempt from the qualified alien waiting period under the adult category financial assistance program. +values: + 2026-01-01: 40 + +metadata: + unit: int + period: year + label: New Hampshire SSP permanent resident qualifying quarters exception + reference: + - title: 8 U.S.C. 1622(b)(2), Certain permanent resident aliens + href: https://www.law.cornell.edu/uscode/text/8/1622#b_2 + - title: 8 U.S.C. 1645, Qualifying quarters + href: https://www.law.cornell.edu/uscode/text/8/1645 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/waiting_period.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/waiting_period.yaml new file mode 100644 index 00000000000..1dcf9f32474 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/immigration/waiting_period.yaml @@ -0,0 +1,13 @@ +description: New Hampshire sets this number of years after entry as the qualified alien waiting period under the adult category financial assistance program. +values: + 2026-01-01: 5 + +metadata: + unit: year + period: year + label: New Hampshire SSP qualified alien waiting period + reference: + - title: He-W 616.02(a)(2), Eligibility of Qualified Aliens + href: https://gc.nh.gov/rules/state_agencies/he-w600.html + - title: NH DHHS Adult Assistance Manual 305.13, Qualified Aliens with Restricted Eligibility Based on Date of Entry into the U.S. + href: https://dhhs.nh.gov/aam_htm/html/305_13_qualified_aliens_with_restricted_eligibility_based_on_date_of_entry_into_the_us_aam.htm diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment.yaml new file mode 100644 index 00000000000..e313986fcd7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment.yaml @@ -0,0 +1,11 @@ +description: New Hampshire provides no payment when the rounded grant is below this amount under the adult category financial assistance program. +values: + 2026-01-01: 2 + +metadata: + unit: currency-USD + period: month + label: New Hampshire SSP minimum grant + reference: + - title: He-W 670.03(a)(4), Determination of grant + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment_level/one_person.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment_level/one_person.yaml new file mode 100644 index 00000000000..d572a3c0aad --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment_level/one_person.yaml @@ -0,0 +1,47 @@ +description: New Hampshire maintains this minimum supplemental payment level for a one-person assistance group in each living arrangement under the adult category financial assistance program. + +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: month + label: New Hampshire SSP one-person minimum payment level + breakdown: + - nh_ssp_living_arrangement + reference: + - title: He-W 658.03(c) and (e), and He-W 648.04, Adult category standard of need + href: https://gc.nh.gov/rules/state_agencies/he-w600.html + - title: SSA, State Assistance Programs for SSI Recipients, January 1998, New Hampshire, payment levels + href: https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/1998/nh.pdf#page=3 + - title: SSA, State Assistance Programs for SSI Recipients, January 2011, New Hampshire, Table 1 + href: https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/2011/nh.pdf#page=2 + - title: NH DHHS Supervisory Release SR 97-44, January 1998 COLA + href: https://web.archive.org/web/20210808185249/https://www.dhhs.nh.gov/sr_htm/html/sr_97-44_dated_01_98.htm + - title: NH DHHS Supervisory Release SR 26-01, January 2026 COLA + href: https://www.dhhs.nh.gov/sr_htm/html/sr_26-01_dated_01_26.htm + +# The standard of need is the SSI maximum plus this level less the $13 +# standard disregard, so each level is the grant to an SSI-only recipient. +# SR 26-01 standards: $1,008, $1,070, $1,130, $1,188 and $1,188 less the +# $994 SSI maximum plus $13 give 27, 89, 149, 207 and 207. SSA's January 1998 +# and January 2011 tables print the same state supplementation amounts, and +# NH's January releases give matching standards for every year from 1998 +# (SR 97-44) to 2026. The care levels differed in 1996. SSA's 2004 and 2008 to +# 2010 tables print other amounts, but NH's releases for those years do not. +INDEPENDENT: + 1998-01-01: 27 + +SUBSIDIZED_COMMUNITY_RESIDENCE: + 1998-01-01: 89 + +NONSUBSIDIZED_COMMUNITY_RESIDENCE: + 1998-01-01: 149 + +ENHANCED_FAMILY_CARE: + 1998-01-01: 207 + +RESIDENTIAL_CARE: + 1998-01-01: 207 + +# No adult category grant in excluded arrangements. +NONE: + 1998-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment_level/two_person.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment_level/two_person.yaml new file mode 100644 index 00000000000..b7d9a7656a0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/minimum_payment_level/two_person.yaml @@ -0,0 +1,24 @@ +description: New Hampshire maintains this minimum supplemental payment level for a two-person independent-living assistance group under the adult category financial assistance program. +values: + # SR 26-01: the $1,492 standard less the $1,491 SSI maximum for an individual + # and either a spouse or needy essential person, plus the $20 standard + # disregard. SSA's January 1998 and January 2011 tables print the same $21 + # couple supplement, and NH's January releases match it from 1998 (SR 97-44) + # to 2026. + 1998-01-01: 21 + +metadata: + unit: currency-USD + period: month + label: New Hampshire SSP two-person minimum payment level + reference: + - title: He-W 658.03(c) and (e), Adult category standard of need + href: https://gc.nh.gov/rules/state_agencies/he-w600.html + - title: SSA, State Assistance Programs for SSI Recipients, January 1998, New Hampshire, payment levels + href: https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/1998/nh.pdf#page=3 + - title: SSA, State Assistance Programs for SSI Recipients, January 2011, New Hampshire, Table 1 + href: https://www.ssa.gov/policy/docs/progdesc/ssi_st_asst/2011/nh.pdf#page=2 + - title: NH DHHS Supervisory Release SR 97-44, January 1998 COLA + href: https://web.archive.org/web/20210808185249/https://www.dhhs.nh.gov/sr_htm/html/sr_97-44_dated_01_98.htm + - title: NH DHHS Supervisory Release SR 26-01, January 2026 COLA + href: https://www.dhhs.nh.gov/sr_htm/html/sr_26-01_dated_01_26.htm diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/resource_limit.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/resource_limit.yaml new file mode 100644 index 00000000000..90537813cb0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/resource_limit.yaml @@ -0,0 +1,10 @@ +description: New Hampshire limits countable resources to this amount under the adult category financial assistance program. +values: + 2026-01-01: 1_500 + +metadata: + unit: currency-USD + label: New Hampshire SSP resource limit + reference: + - title: He-W 656.06(b), Adult category resource limit + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/standard_disregard.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/standard_disregard.yaml new file mode 100644 index 00000000000..22bc43271bd --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/standard_disregard.yaml @@ -0,0 +1,23 @@ +description: New Hampshire deducts this amount from the income of an assistance group of each size under the adult category financial assistance program. + +metadata: + propagate_metadata_to_children: true + unit: currency-USD + period: month + breakdown: + - range(1, 4) + breakdown_label: + - Assistance group size + label: New Hampshire SSP standard disregard + reference: + - title: He-W 654.16(b), Adult standard disregard + href: https://gc.nh.gov/rules/state_agencies/he-w600.html + +1: + 2026-01-01: 13 + +2: + 2026-01-01: 20 + +3: + 2026-01-01: 25 diff --git a/policyengine_us/parameters/gov/states/nh/dhhs/ssp/three_person_need.yaml b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/three_person_need.yaml new file mode 100644 index 00000000000..cb3e318aa6e --- /dev/null +++ b/policyengine_us/parameters/gov/states/nh/dhhs/ssp/three_person_need.yaml @@ -0,0 +1,20 @@ +description: New Hampshire sets this standard of need for a three-person independent-living assistance group under the adult category financial assistance program. +values: + # NOTE: NH's three-person standard is DHHS's stated SSI maximum for a couple + # and needy essential person less $12 ($1,988 - $12 = $1,976 in 2026). That + # maximum usually equals the couple rate plus the SSI essential person + # increment, but not in 2026 ($1,491 + $498 = $1,989), so the published + # standard is kept and needs a new value each January. + 2026-01-01: 1_976 + +metadata: + unit: currency-USD + period: month + label: New Hampshire SSP three-person standard of need + reference: + - title: NH DHHS Supervisory Release SR 26-01, January 2026 COLA + href: https://www.dhhs.nh.gov/sr_htm/html/sr_26-01_dated_01_26.htm + - title: NH DHHS Adult Assistance Manual 601, Table A + href: https://www.dhhs.nh.gov/aam_htm/html/601_table_a_income_limits_aam.htm + - title: He-W 658.03(e), Adult category standard of need + href: https://gc.nh.gov/rules/state_agencies/he-w600.html diff --git a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml index e9baee603e8..10a9d57dedb 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -46,6 +46,7 @@ values: - mn_msa_person - mo_ssp - ne_aabd + - nh_ssp - nm_ssi_state_supplement - sc_ssi_state_supplement - tx_ssi_state_supplement @@ -95,9 +96,7 @@ values: metadata: reference: - - title: 7 CFR 273.9(b)(2) - href: https://www.law.cornell.edu/cfr/text/7/273.9#b_2 - - title: 7 CFR 273.9(c)(1) - href: https://www.law.cornell.edu/cfr/text/7/273.9#c_1 + - title: 7 CFR 273.9(b)(2) and (c)(1) + href: https://www.law.cornell.edu/cfr/text/7/273.9 - title: POMS SI 01401.001 General Information about State Supplementation href: https://secure.ssa.gov/poms.nsf/lnx/0501401001 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 5250ab3aa89..a9c3c911ac7 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1093,6 +1093,16 @@ programs: tracks. Unmodeled paths: grandfathered medically-needy-in-medical- institution recipients per WAC 388-478-0055(2)(b); DDA-determined / PVL track per (2)(f); and foster child in BRS per (2)(g). + - state: NH + status: partial + name: New Hampshire SSP + full_name: New Hampshire State Supplement Program + variable: nh_ssp + parameter_prefix: gov.states.nh.dhhs.ssp + verified_years: '2026' + notes: Models 2026 adult category cash assistance (OAA, ANB and APTD) for independent + living, certified community care, couples and needy essential persons. Conditional + resources, sanctions and grandfathered benefits are not modeled. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/integration.yaml new file mode 100644 index 00000000000..138650b3af4 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/integration.yaml @@ -0,0 +1,288 @@ +- name: Case 1, eligible independent couple shares one grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + person2: + age: 65 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # Joint claim: 1,491 couple rate / 2 = 745.5 each. + ssi: [745.5, 745.5] + nh_ssp_eligible: [true, true] + # 745.5 + 745.5 - 20 two-person disregard = 1,471. + nh_ssp_countable_income: [1_471, 1_471] + # 1,492 - 1,471 = 21, split between two recipients. + nh_ssp: [10.5, 10.5] + +- name: Case 2, nonapplicant spouse is included in needs. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + person2: + age: 40 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # The spouse has no income to deem, so person1 receives the individual rate. + ssi: [994, 0] + nh_ssp_eligible: [true, false] + # 994 - 20 two-person disregard = 974. + nh_ssp_countable_income: [974, 974] + # 1,492 two-person standard - 974 = 518. + nh_ssp: [518, 0] + +- name: Case 3, independent couple combined resources exceed limit. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + ssi_countable_resources: 750 + person2: + age: 65 + ssi_countable_resources: 751 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # 750 + 751 = 1,501 <= 3,000 federal couple limit. + ssi: [745.5, 745.5] + # 1,501 > 1,500 state limit. + nh_ssp_eligible: [false, false] + nh_ssp: [0, 0] + +- name: Case 4, care spouses are individual assistance groups. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + nh_ssp_living_arrangement: RESIDENTIAL_CARE + ssi_claim_is_joint: false + person2: + age: 65 + nh_ssp_living_arrangement: RESIDENTIAL_CARE + ssi_claim_is_joint: false + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # Separate claims: individual rate each. + ssi: [994, 994] + # 994 - 13 one-person disregard = 981. + nh_ssp_countable_income: [981, 981] + # 1,188 residential care standard - 981 = 207. + nh_ssp: [207, 207] + +- name: Case 5, two aged applicants receive separate earned disregards. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + employment_income: 1_200 + person2: + age: 65 + employment_income: 1_200 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # Couple earnings 200: (200 - 85) * 0.5 / 2 = 28.75; 745.5 - 28.75 = 716.75. + ssi: [716.75, 716.75] + # FICA 1,200 * 0.0765 / 12 = 7.65, below the $18 minimum. + nh_ssp_employment_expenses: [7.65, 7.65] + # Each 100 - 20 - 30 - 18 = 32; 32 + 32 + 716.75 + 716.75 - 20 = 1,477.5. + nh_ssp_countable_income: [1_477.5, 1_477.5] + # 1,492 - 1,477.5 = 14.5, rounded to 15 and split. + nh_ssp: [7.5, 7.5] + +- name: Case 6, annual independent grant and SNAP income. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + output: + # 994 * 12 = 11,928. + ssi: 11_928 + # (994 - 13) * 12 = 11,772. + nh_ssp_countable_income: 11_772 + # (1,008 - 981) * 12 = 324. + nh_ssp: 324 + household_state_benefits: 324 + # 11,928 SSI + 324 state supplement = 12,252. + snap_unearned_income: 12_252 + hud_unearned_income: 12_252 + # $11,928 SSI + $324 state supplement + $678 SNAP = $12,930. + spm_unit_benefits: 12_930 + +- name: Case 7, eligible couple and essential person share a three-person grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + nh_ssp_has_essential_person: true + person2: + age: 70 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: NH + output: + ssi: [745.5, 745.5] + # 1,976 three-person standard (SR 26-01) - 1,466 = 510, split between two + # recipients. + nh_ssp: [255, 255] + # 745.5 + 745.5 - 25 three-person disregard = 1,466. + nh_ssp_countable_income: [1_466, 1_466] + +- name: Case 8, three-person grant with a non-applicant spouse. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + nh_ssp_has_essential_person: true + person2: + age: 40 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: NH + output: + ssi: [994, 0] + # 994 - 25 three-person disregard = 969. + nh_ssp_countable_income: [969, 969] + # 1,976 three-person standard (SR 26-01) - 969 = 1,007. + nh_ssp: [1_007, 0] + +- name: Case 9, nonapplicant spouse's part-time earnings are combined with the applicant's. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 67 + person2: + age: 60 + # 20 hours a week at the $14.56 New Hampshire median wage for + # cashiers (BLS OEWS, May 2023): 20 * 52 * 14.56 = 15,142.40. + employment_income: 15_142.4 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # Spousal deeming: (1,261.87 - 85) * 0.5 = 588.43; 1,491 - 588.43 = 902.57. + ssi: [902.57, 0] + # FICA: 15,142.40 * 0.0765 / 12 = 96.53. + nh_ssp_employment_expenses: [0, 96.53] + nh_ssp_eligible: [true, false] + # He-W 654.02(d): combined earnings 1,261.87 - 20 - 30 - 96.53 = 1,115.33; + # 1,115.33 + 902.57 SSI - 20 two-person disregard = 1,997.90. + nh_ssp_countable_income: [1_997.9, 1_997.9] + # 1,997.90 exceeds the 1,492 two-person standard. + nh_ssp: [0, 0] + +- name: Case 10, parental income deemed to a blind child counts as unearned income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 38 + person_id: 1 + # Full time at the $22.23 New Hampshire median wage for general + # office clerks (BLS OEWS, May 2023): 2,080 * 22.23 = 46,238.40. + employment_income: 46_238.4 + person2: + age: 10 + person_id: 2 + parent_1_id: 1 + is_blind: true + marital_units: + parent: + members: [person1] + child: + members: [person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # (3,853.20 - 85) * 0.5 = 1,884.10 - 994 parent allocation = 890.10. + ssi_unearned_income_deemed_from_ineligible_parent: [0, 890.1] + # 994 - (890.10 - 20) = 123.90. + ssi: [0, 123.9] + nh_ssp_eligible: [false, true] + # person1: 3,853.20 - 20 - 30 - 294.77 FICA - 13 = 3,495.43. + # person2, He-W 652.03(f)-(g): 890.10 + 123.90 - 13 = 1,001. + nh_ssp_countable_income: [3_495.43, 1_001] + # 1,008 - 1,001 = 7. + nh_ssp: [0, 7] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp.yaml new file mode 100644 index 00000000000..c5cd4776f6e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp.yaml @@ -0,0 +1,927 @@ +- name: Case 1, independent SSI recipient. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + output: + nh_ssp: 27 + +- name: Case 2, certified subsidized community residence. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_living_arrangement: SUBSIDIZED_COMMUNITY_RESIDENCE + output: + nh_ssp: 89 + +- name: Case 3, certified nonsubsidized community residence. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_living_arrangement: NONSUBSIDIZED_COMMUNITY_RESIDENCE + output: + nh_ssp: 149 + +- name: Case 4, certified enhanced family care. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_living_arrangement: ENHANCED_FAMILY_CARE + output: + nh_ssp: 207 + +- name: Case 5, certified residential care. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_living_arrangement: RESIDENTIAL_CARE + output: + nh_ssp: 207 + +- name: Case 6, resources at state limit. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + ssi_countable_resources: 1_500 + output: + nh_ssp: 27 + +- name: Case 7, resources exceed state limit despite federal eligibility. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + ssi_countable_resources: 1_501 + output: + nh_ssp: 0 + +- name: Case 8, twenty dollars of Social Security reduces state grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + social_security_retirement: 240 + output: + nh_ssp: 7 + +- name: Case 9, state only benefit. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + social_security_retirement: 12_216 + output: + nh_ssp: 3 + +- name: Case 10, grant below state minimum is not paid. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_countable_income: 1_007 + output: + # 1,008 - 1,007 = 1, below the $2 minimum of He-W 670.03(a)(4): no payment. + nh_ssp: 0 + +- name: Case 11, income at standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_countable_income: 1_008 + output: + nh_ssp: 0 + +- name: Case 12, aged employment rules. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + employment_income: 1_200 + output: + nh_ssp: 3 + +- name: Case 13, blind employment rules. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 40 + is_blind: true + employment_income: 1_200 + output: + nh_ssp: 27 + +- name: Case 14, payroll taxes above the minimum employment expense are deducted. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 40 + meets_ssi_disability_criteria: true + is_permanently_and_totally_disabled: true + nh_ssp_living_arrangement: ENHANCED_FAMILY_CARE + # Supported employment, 10 hours a week at the $7.25 minimum wage + # (RSA 279:21 adopts the federal rate): 10 * 52 * 7.25 = 3,770. + employment_income: 3_770 + output: + # SSI: 994 - (3,770 / 12 - 85) * 0.5 = 994 - 114.58 = 879.42. + ssi: 879.42 + # FICA: 3,770 * 0.0765 / 12 = 24.03, above the $18 minimum. + nh_ssp_employment_expenses: 24.03 + # Earned: 314.17 - 20 - 30 - 24.03 = 240.13; 240.13 + 879.42 - 13 = 1,106.55. + nh_ssp_countable_income: 1_106.55 + # 1,188 - 1,106.55 = 81.45, rounded to 81. + nh_ssp: 81 + +- name: Case 15, court-ordered child support is deducted. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 40 + meets_ssi_disability_criteria: true + is_permanently_and_totally_disabled: true + # The $50 monthly minimum support order of RSA 458-C:2, V: 50 * 12 = 600. + child_support_expense: 600 + output: + # 600 / 12 = 50 under He-W 654.20(a)(1). + nh_ssp_other_income_deductions: 50 + # 994 SSI - 13 disregard - 50 support = 931. + nh_ssp_countable_income: 931 + # 1,008 - 931 = 77. + nh_ssp: 77 + +- name: Case 16, independently determined one third grant reduction. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_grant_reduction_applies: true + output: + nh_ssp: 18 + +- name: Case 17, federal disability alone does not establish forty eight month duration. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 40 + meets_ssi_disability_criteria: true + output: + nh_ssp: 0 + +- name: Case 18, permanently disabled adult. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 40 + meets_ssi_disability_criteria: true + is_permanently_and_totally_disabled: true + output: + nh_ssp: 27 + +- name: Case 19, blind child. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 17 + is_blind: true + output: + nh_ssp: 27 + +- name: Case 20, disabled child without blindness. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 17 + meets_ssi_disability_criteria: true + is_permanently_and_totally_disabled: true + output: + nh_ssp: 0 + +- name: Case 21, nonresident. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + output: + nh_ssp: 0 + +- name: Case 22, required federal benefit application declined. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + takes_up_ssi_if_eligible: false + output: + nh_ssp: 0 + +- name: Case 23, excluded living arrangement. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + nh_ssp_living_arrangement: NONE + output: + nh_ssp: 0 + +- name: Case 24, single recipient and certified essential person use group size two. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + nh_ssp_has_essential_person: true + output: + nh_ssp: 518 + +- name: Case 25, essential person income is added before the group disregard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + nh_ssp_has_essential_person: true + nh_ssp_essential_person_countable_income: 100 + output: + nh_ssp: 418 + +- name: Case 26, essential person resources are counted even when recipient receives SSI. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + nh_ssp_has_essential_person: true + ssi_countable_resources: 1_000 + nh_ssp_essential_person_resources: 501 + output: + nh_ssp: 0 + +- name: Case 27, essential person resource limit is inclusive. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + nh_ssp_has_essential_person: true + ssi_countable_resources: 1_000 + nh_ssp_essential_person_resources: 500 + output: + nh_ssp: 518 + +- name: Case 28, care facilities remain single-person groups. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + nh_ssp_has_essential_person: true + nh_ssp_living_arrangement: RESIDENTIAL_CARE + nh_ssp_essential_person_countable_income: 100 + output: + nh_ssp: 207 + +- name: Case 29, uncertified caregiver does not increase the standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + nh_ssp_has_essential_person: false + output: + nh_ssp: 27 + +- name: Case 30, group standard disregard does not turn excess essential-person income into eligibility. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + nh_ssp_has_essential_person: true + nh_ssp_essential_person_countable_income: 518 + output: + nh_ssp: 0 + +- name: Case 31, annual essential-person resource input stays a balance in each month. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + # The monthly SSI of 994 summed over the year: 994 * 12 = 11,928. + ssi: 11_928 + nh_ssp_has_essential_person: true + ssi_countable_resources: 1_000 + nh_ssp_essential_person_resources: 501 + output: + # 1,000 + 501 = 1,501 > 1,500 in every month. + nh_ssp: 0 + +# He-W 652.03(i)-(j),(q): full parental excess, NH $1500 ceiling, and adult control. +# https://gc.nh.gov/rules/state_agencies/he-w600.html +- name: Case 32, blind child is ineligible with excess co-resident parent resources. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 40 + person_id: + 2026: 1 + bank_account_assets: + 2026: 10_000 + person2: + age: + 2026: 10 + person_id: + 2026: 3 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + marital_units: + parent1: + members: [person1] + child1: + members: [person2] + families: + family: + members: [person1, person2] + tax_units: + parent1: + members: [person1] + child1: + members: [person2] + spm_units: + unit: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: + 2026: NH + output: + nh_ssp: [0, 0] + +- name: Case 33, parental allowance plus the NH child resource ceiling is inclusive. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 40 + person_id: + 2026: 1 + bank_account_assets: + 2026: 3_500 + person2: + age: + 2026: 10 + person_id: + 2026: 3 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + marital_units: + parent1: + members: [person1] + child1: + members: [person2] + families: + family: + members: [person1, person2] + tax_units: + parent1: + members: [person1] + child1: + members: [person2] + spm_units: + unit: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: + 2026: NH + output: + nh_ssp: [0, 27] + +- name: Case 34, one cent above the parent allowance and NH resource ceiling is ineligible. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 40 + person_id: + 2026: 1 + bank_account_assets: + 2026: 3_500.01 + person2: + age: + 2026: 10 + person_id: + 2026: 3 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + marital_units: + parent1: + members: [person1] + child1: + members: [person2] + families: + family: + members: [person1, person2] + tax_units: + parent1: + members: [person1] + child1: + members: [person2] + spm_units: + unit: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: + 2026: NH + output: + nh_ssp: [0, 0] + +- name: Case 35, a blind adult does not receive deemed parental resources. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 40 + person_id: + 2026: 1 + bank_account_assets: + 2026: 10_000 + person2: + age: + 2026: 19 + person_id: + 2026: 3 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + marital_units: + parent1: + members: [person1] + child1: + members: [person2] + families: + family: + members: [person1, person2] + tax_units: + parent1: + members: [person1] + child1: + members: [person2] + spm_units: + unit: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: + 2026: NH + output: + nh_ssp: [0, 27] + +- name: Case 36, each blind sibling receives the full excess under the NH rule. + period: 2026-06 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 40 + person_id: + 2026: 1 + bank_account_assets: + 2026: 5_500 + person2: + age: + 2026: 40 + person_id: + 2026: 2 + person3: + age: + 2026: 10 + person_id: + 2026: 3 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + parent_2_id: + 2026: 2 + person4: + age: + 2026: 10 + person_id: + 2026: 4 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + parent_2_id: + 2026: 2 + marital_units: + parent1: + members: [person1] + parent2: + members: [person2] + child1: + members: [person3] + child2: + members: [person4] + families: + family: + members: [person1, person2, person3, person4] + tax_units: + parent1: + members: [person1] + parent2: + members: [person2] + child1: + members: [person3] + child2: + members: [person4] + spm_units: + unit: + members: [person1, person2, person3, person4] + households: + home: + members: [person1, person2, person3, person4] + state_code: + 2026: NH + output: + nh_ssp: [0, 0, 0, 0] + +# He-W 616.02(a) and AAM 305.11-305.13: five-year rule instead of SSI's 40 quarters. +- name: Case 37, permanent resident past the five-year wait without forty quarters. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 10 + ssi_qualifying_quarters_earnings: 0 + output: + # 0 of the 40 qualifying quarters SSI requires, so no SSI. + ssi: 0 + # 10 years since entry >= 5-year waiting period. + nh_ssp_eligible: true + # max(0 + 0 - 13, 0) = 0 countable; 1,008 - 0 = 1,008. + nh_ssp: 1_008 + +- name: Case 38, permanent resident within the five-year wait is ineligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + # No credited quarters are supplied (snap_alien_qualifying_quarters + # defaults to 0), so the 8 USC 1622(b)(2) exception does not apply. + years_since_us_entry: 2 + output: + # 2 years since entry < 5-year waiting period. + nh_ssp_eligible: false + nh_ssp: 0 + +- name: Case 39, refugee is eligible without a waiting period. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + immigration_status: REFUGEE + years_since_us_entry: 1 + output: + # Refugees are SSI qualified noncitizens. + ssi: 994 + # AAM 305.11 exempts refugees from the waiting period. + nh_ssp_eligible: true + # 994 - 13 = 981 countable; 1,008 - 981 = 27. + nh_ssp: 27 + +- name: Case 40, parent and adult child in a default marital unit use an individual budget. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + person_id: 1 + person2: + age: 40 + person_id: 2 + parent_1_id: 1 + households: + household: + members: [person1, person2] + state_code: NH + output: + # The omitted marital units put both people in one default unit; the + # parent link rules out a spouse, so each is a one-person group. + ssi: [994, 0] + # person1: 994 - 13 = 981; person2: max(0 - 13, 0) = 0. + nh_ssp_countable_income: [981, 0] + # 1,008 - 981 = 27; person2 is not aged, blind or disabled. + nh_ssp: [27, 0] + +- name: Case 41, grant reduction flag on either spouse reduces the couple grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + person2: + age: 65 + nh_ssp_grant_reduction_applies: true + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + # 745.5 SSI each: 745.5 + 745.5 - 20 = 1,471 for the couple. + nh_ssp_countable_income: [1_471, 1_471] + # 1,492 - 1,471 = 21; 21 * 2 / 3 = 14 for the couple, whichever spouse has + # the flag; 14 / 2 = 7 each. + nh_ssp: [7, 7] + +- name: Case 42, a resident of a medical facility where Medicaid pays most of the cost has no grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + nh_ssp_living_arrangement: NONE + # Federal living arrangement D: the $30 reduced SSI payment. + ssi: 30 + nh_ssp_eligible: false + nh_ssp: 0 + +- name: Case 43, an incarcerated person is ineligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + is_incarcerated: true + output: + nh_ssp_eligible: false + nh_ssp: 0 + +- name: Case 44, an undocumented immigrant is ineligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + immigration_status: UNDOCUMENTED + output: + ssi: 0 + nh_ssp_eligible: false + nh_ssp: 0 + +- name: Case 45, the federal one-third reduction alone does not reduce the state grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + # $994 * 2/3 = $662.67 federal payment in another person's household. + ssi: 662.67 + # $662.67 - $13 = $649.67 countable; $1,008 - $649.67 = $358.33, rounded to + # $358. He-W 670.03(c) also requires no SNAP receipt, so the state reduction + # is the separate nh_ssp_grant_reduction_applies input (a SNAP recipient keeps $358). + nh_ssp: 358 + +- name: Case 46, the same household without SNAP takes the state one-third reduction. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + nh_ssp_grant_reduction_applies: true + output: + ssi: 662.67 + # $358 * (1 - 1/3) = $238.67, rounded to $239. + nh_ssp: 239 + +- name: Case 47, a permanently and totally disabled applicant qualifies at exactly 18. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 18 + meets_ssi_disability_criteria: true + is_permanently_and_totally_disabled: true + output: + nh_ssp_eligible: true + # $1,008 - ($994 - $13) = $27. + nh_ssp: 27 + +- name: Case 48, a permanent resident qualifies exactly five years after entry. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 5 + ssi_qualifying_quarters_earnings: 0 + output: + # 0 of the 40 qualifying quarters SSI requires, so no SSI. + ssi: 0 + # 5 years since entry >= 5-year waiting period. + nh_ssp_eligible: true + # max(0 - 13, 0) = 0 countable; $1,008 - $0 = $1,008. + nh_ssp: 1_008 + +- name: Case 49, a mixed blind and aged applicant couple uses each member's own earned income disregard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + person2: + age: 40 + is_blind: true + # 10 hours a week as a cashier at the New Hampshire median wage of + # $16.27 (BLS OEWS May 2025): $16.27 * 10 * 52 = $8,460.40 a year. + employment_income: 8_460.4 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: NH + output: + # $8,460.40 / 12 = $705.03 a month; ($705.03 - $20 - $65) * 0.5 = $310.02 + # countable; ($1,491 - $310.02) / 2 = $590.49 each. + ssi: [590.49, 590.49] + # He-W 654.15(b), blind: ($705.03 - $85) * 0.5 = $310.02 net earnings; the + # aged member has none. $310.02 + $1,180.98 SSI - $20 = $1,471. + nh_ssp_countable_income: [1_471, 1_471] + # $1,492 two-person standard - $1,471 = $21, split between two recipients. + nh_ssp: [10.5, 10.5] + +- name: Case 50, a blind applicant's nonapplicant spouse's earnings get the blind disregard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + is_blind: true + person2: + age: 40 + # 20 hours a week as a cashier at the New Hampshire median wage of + # $16.27 (BLS OEWS May 2025): $16.27 * 20 * 52 = $16,920.80 a year. + employment_income: 16_920.8 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: NH + output: + # $16,920.80 / 12 = $1,410.07 a month, above the $497 difference, so SSI + # deems ($1,410.07 - $20 - $65) * 0.5 = $662.53; $1,491 - $662.53 = $828.47. + ssi: [828.47, 0] + nh_ssp_eligible: [true, false] + # He-W 654.02(e) combines the spouse's earnings before the blind disregard: + # ($1,410.07 - $85) * 0.5 = $662.53; $662.53 + $828.47 - $20 = $1,471. + # $1,492 two-person standard - $1,471 = $21. + nh_ssp: [21, 0] + +- name: Case 51, a permanent resident with 40 credited quarters is eligible within the five-year wait. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + immigration_status: LEGAL_PERMANENT_RESIDENT + years_since_us_entry: 2 + # 8 USC 1622(b)(2): 40 qualifying quarters credited under 8 USC 1645. + snap_alien_qualifying_quarters: 40 + # 8 USC 1613(a) bars federal SSI for 5 years after entry; the federal SSI + # model does not apply that bar, so SSI is set to the $0 it would pay. + ssi: 0 + output: + nh_ssp_eligible: true + # max(0 - 13, 0) = 0 countable; $1,008 - $0 = $1,008. + nh_ssp: 1_008 + +- name: Case 52, the independent-living standard moves with the SSI cost-of-living increase. + period: 2027-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + output: + # He-W 658.03(e): standard = SSI individual rate + $27 - $13, and countable + # income = SSI - $13, so the grant stays $27 whatever the 2027 rate is. + nh_ssp: 27 + +- name: Case 53, the residential care standard moves with the SSI cost-of-living increase. + period: 2027-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + nh_ssp_living_arrangement: RESIDENTIAL_CARE + output: + # He-W 648.04(b): standard = SSI individual rate - $13 + $207, so the grant + # stays $207. + nh_ssp: 207 + +- name: Case 54, the two-person standard moves with the SSI cost-of-living increase. + period: 2027-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + person2: + age: 70 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: NH + output: + # Standard = SSI couple rate + $21 - $20 and countable income = SSI - $20, + # so the group grant stays $21, split between two recipients. + nh_ssp: [10.5, 10.5] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp_assistance_group_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp_assistance_group_size.yaml new file mode 100644 index 00000000000..2b5b7b4a859 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp_assistance_group_size.yaml @@ -0,0 +1,87 @@ +# He-W 658.03(b): one person, plus a spouse or a needy essential person in an +# independent living arrangement (2), or both (3). +- name: Case 1, a single person living independently is a group of one. + period: 2026-01 + input: + state_code: NH + age: 70 + output: + nh_ssp_assistance_group_size: 1 + +- name: Case 2, a single person with a needy essential person is a group of two. + period: 2026-01 + input: + state_code: NH + age: 70 + nh_ssp_has_essential_person: true + output: + nh_ssp_assistance_group_size: 2 + +- name: Case 3, an independent couple is a group of two. + period: 2026-01 + input: + people: + person1: + age: 70 + person2: + age: 70 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: NH + output: + nh_ssp_assistance_group_size: [2, 2] + +- name: Case 4, an independent couple with a needy essential person is a group of three. + period: 2026-01 + input: + people: + person1: + age: 70 + nh_ssp_has_essential_person: true + person2: + age: 70 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: NH + output: + nh_ssp_assistance_group_size: [3, 3] + +- name: Case 5, spouses in residential care are separate groups of one. + period: 2026-01 + input: + people: + person1: + age: 65 + nh_ssp_living_arrangement: RESIDENTIAL_CARE + ssi_claim_is_joint: false + person2: + age: 65 + nh_ssp_living_arrangement: RESIDENTIAL_CARE + ssi_claim_is_joint: false + marital_units: + couple: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NH + output: + nh_ssp_assistance_group_size: [1, 1] + +- name: Case 6, an essential person does not enlarge a residential care group. + period: 2026-01 + input: + state_code: NH + age: 70 + nh_ssp_living_arrangement: RESIDENTIAL_CARE + nh_ssp_has_essential_person: true + output: + nh_ssp_assistance_group_size: 1 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp_resources_deemed_from_parents.yaml b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp_resources_deemed_from_parents.yaml new file mode 100644 index 00000000000..db5ff5254a6 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp_resources_deemed_from_parents.yaml @@ -0,0 +1,112 @@ +# Resource balances and certified budgets are stocks. Annual demographic and asset inputs are explicit. +- name: Case 1, annual asset balances remain undivided in January and July. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 40 + person_id: + 2026: 1 + bank_account_assets: + 2026: 10_000 + person2: + age: + 2026: 10 + person_id: + 2026: 3 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + marital_units: + parent1: + members: [person1] + child1: + members: [person2] + families: + family: + members: [person1, person2] + tax_units: + parent1: + members: [person1] + child1: + members: [person2] + spm_units: + unit: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: + 2026: NH + output: + nh_ssp_resources_deemed_from_parents: + 2026-01: [0, 8_000] + 2026-07: [0, 8_000] + +- name: Case 2, annual agency-certified resource budget remains a monthly stock. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NH + nh_ssp_resources_deemed_from_parents: 2_500 + output: + nh_ssp_resources_deemed_from_parents: + 2026-01: 2_500 + 2026-07: 2_500 + +# He-W 601.06(b) counts a stepparent as a parent, so the federal pool adds the +# named mother's co-resident spouse. +- name: Case 3, stepparent resources are deemed with the named parent's resources. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: + 2026: 38 + person_id: + 2026: 1 + bank_account_assets: + 2026: 2_000 + person2: + age: + 2026: 40 + person_id: + 2026: 2 + bank_account_assets: + 2026: 2_000 + person3: + age: + 2026: 10 + person_id: + 2026: 3 + parent_1_id: + 2026: 1 + is_blind: + 2026: true + bank_account_assets: + 2026: 600 + marital_units: + parents: + members: [person1, person2] + child: + members: [person3] + tax_units: + unit: + members: [person1, person2, person3] + households: + home: + members: [person1, person2, person3] + state_code: + 2026: NH + output: + # Mother 2,000 + stepfather 2,000 = 4,000 - 3,000 two-parent allowance = 1,000. + nh_ssp_resources_deemed_from_parents: [0, 0, 1_000] + # Federal SSI: 600 + 1,000 = 1,600 <= 2,000, so the child receives 994. + ssi: [0, 0, 994] + # NH: 600 + 1,000 = 1,600 > 1,500 resource limit. + nh_ssp_eligible: [false, false, false] + nh_ssp: [0, 0, 0] diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/_nh_ssp_couple.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/_nh_ssp_couple.py new file mode 100644 index 00000000000..2b0d069ea58 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/_nh_ssp_couple.py @@ -0,0 +1,26 @@ +"""Couples that share one New Hampshire adult category assistance group.""" + +import numpy as np + +from policyengine_us.variables.gov.ssa.ssi.eligibility.resources.deemed._ssi_spouses import ( + _ssi_spouse_index, +) + + +def nh_ssp_spouse(person, period): + """Row of each person's co-resident spouse in a shared group, or -1. + + Spouses share a group only when both live independently; care categories + are one-person groups (SPA NH-26-0001 Section E). The SSI spouse test + keeps a default marital unit from pairing a parent with their child. + """ + arrangement = person("nh_ssp_living_arrangement", period) + independent = arrangement == arrangement.possible_values.INDEPENDENT + spouse = _ssi_spouse_index(person, period) + shared = independent & (spouse >= 0) & independent[np.maximum(spouse, 0)] + return np.where(shared, spouse, -1) + + +def spouse_value(values, spouse, default=0): + """Each person's spouse's value, or the default without a spouse.""" + return np.where(spouse >= 0, values[np.maximum(spouse, 0)], default) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp.py new file mode 100644 index 00000000000..1f5e3adfa3a --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp.py @@ -0,0 +1,53 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.nh.dhhs.ssp._nh_ssp_couple import ( + nh_ssp_spouse, + spouse_value, +) + + +class nh_ssp(Variable): + value_type = float + entity = Person + label = "New Hampshire State Supplement Program" + definition_period = MONTH + unit = USD + defined_for = "nh_ssp_eligible" + reference = ( + # PDF pages 14-16 + "https://www.medicaid.gov/medicaid/spa/downloads/NH-26-0001.pdf#page=14", + "https://gc.nh.gov/rules/state_agencies/he-w600.html", + "https://www.dhhs.nh.gov/sr_htm/html/sr_26-01_dated_01_26.htm", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.nh.dhhs.ssp + arrangement = person("nh_ssp_living_arrangement", period) + spouse = nh_ssp_spouse(person, period) + size = person("nh_ssp_assistance_group_size", period) + # He-W 658.03(e) and 648.04(b): the standard of need is the SSI maximum + # for the group plus the minimum payment level less the standard + # disregard, so it moves with each SSI cost-of-living increase. + ssi = parameters(period).gov.ssa.ssi.amount + disregard = p.standard_disregard[size] + level = p.minimum_payment_level + one_person = ssi.individual + level.one_person[arrangement] - disregard + two_person = ssi.couple + level.two_person - disregard + standard = select( + [size == 3, size == 2], + [p.three_person_need, two_person], + default=one_person, + ) + income = person("nh_ssp_countable_income", period) + grant = np.floor(max_(standard - income, 0) + 0.5) + # He-W 670.03(a)(4): no payment when the rounded grant is below the minimum. + grant = where(grant >= p.minimum_payment, grant, 0) + # He-W 670.03(c) reduces "the adult category grant pursuant to (a)", and + # the rule does not apply the minimum again afterwards, so a reduced $2 + # grant pays $1. Either spouse's flag reduces the group grant. + reduction = person("nh_ssp_grant_reduction_applies", period) + reduction = reduction | spouse_value(reduction, spouse, False) + grant = np.floor(grant * (1 - reduction * p.grant_reduction_fraction) + 0.5) + # Applicant spouses split the couple's grant. + eligible = person("nh_ssp_eligible", period) + recipients = eligible.astype(int) + spouse_value(eligible, spouse, False) + return grant / max_(recipients, 1) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_assistance_group_size.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_assistance_group_size.py new file mode 100644 index 00000000000..7d9fc1bdfb0 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_assistance_group_size.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.nh.dhhs.ssp._nh_ssp_couple import ( + nh_ssp_spouse, + spouse_value, +) + + +class nh_ssp_assistance_group_size(Variable): + value_type = int + entity = Person + label = "New Hampshire adult category assistance group size" + definition_period = MONTH + defined_for = StateCode.NH + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + + def formula(person, period, parameters): + # He-W 658.03(b): one person, plus a spouse or a needy essential person + # in an independent living arrangement (2), or both (3). + arrangement = person("nh_ssp_living_arrangement", period) + independent = arrangement == arrangement.possible_values.INDEPENDENT + spouse = nh_ssp_spouse(person, period) + has_essential_person = person("nh_ssp_has_essential_person", period) + essential = independent & ( + has_essential_person | spouse_value(has_essential_person, spouse, False) + ) + return 1 + (spouse >= 0) + essential diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_countable_income.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_countable_income.py new file mode 100644 index 00000000000..a7db9c30456 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_countable_income.py @@ -0,0 +1,69 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.nh.dhhs.ssp._nh_ssp_couple import ( + nh_ssp_spouse, + spouse_value, +) + + +class nh_ssp_countable_income(Variable): + value_type = float + entity = Person + label = "New Hampshire adult assistance group countable income" + definition_period = MONTH + unit = USD + defined_for = StateCode.NH + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + documentation = "Income for the whole assistance group; a couple shares one grant." + + def formula(person, period, parameters): + p = parameters(period).gov.states.nh.dhhs.ssp + spouse = nh_ssp_spouse(person, period) + couple = spouse >= 0 + size = person("nh_ssp_assistance_group_size", period) + # A group larger than the person and any spouse includes an essential person. + essential = size > 1 + couple + eligible = person("nh_ssp_eligible", period) + both_applicants = eligible & spouse_value(eligible, spouse, False) + earned = max_(person("ssi_earned_income", period), 0) + expenses = max_(person("nh_ssp_employment_expenses", period), 0) + # With a nonapplicant spouse, combine earnings before the applicant's + # category disregard under He-W 654.02(d)-(e). + combined = couple & ~both_applicants + earned = where(combined, earned + spouse_value(earned, spouse), earned) + expenses = where(combined, expenses + spouse_value(expenses, spouse), expenses) + blind = person("is_blind", period.this_year) + blind_net = max_(earned - p.earned.blind_flat, 0) * ( + 1 - p.earned.disregard_fraction + ) + remaining = max_(earned - p.earned.aged_disabled_flat, 0) + aged_disabled_net = max_( + remaining + - min_( + remaining * p.earned.disregard_fraction, + p.earned.aged_disabled_remainder_disregard_cap, + ) + - max_(expenses, p.earned.minimum_employment_expenses), + 0, + ) + net_earned = where(blind, blind_net, aged_disabled_net) + net_earned = where( + both_applicants, net_earned + spouse_value(net_earned, spouse), net_earned + ) + unearned = max_(person("ssi_unearned_income", period), 0) + person( + "ssi", period + ) + # Blind children use the parental allocation in He-W 652.03(f)-(g). + unearned = unearned + person( + "ssi_unearned_income_deemed_from_ineligible_parent", period + ) + unearned = unearned + spouse_value(unearned, spouse) + other = max_(person("nh_ssp_other_income_deductions", period), 0) + other = other + spouse_value(other, spouse) + essential_income = max_( + person("nh_ssp_essential_person_countable_income", period), 0 + ) + unearned = unearned + essential * max_( + essential_income, spouse_value(essential_income, spouse) + ) + disregard = p.standard_disregard[size] + return max_(net_earned + unearned - disregard - other, 0) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_disability_eligible.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_disability_eligible.py new file mode 100644 index 00000000000..1e18dc64b86 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_disability_eligible.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class nh_ssp_disability_eligible(Variable): + value_type = bool + entity = Person + label = "Meets New Hampshire APTD medical criteria" + definition_period = YEAR + defined_for = StateCode.NH + reference = "https://gc.nh.gov/rsa/html/XII/167/167-6.htm" + documentation = """ + State medical eligibility requires federal disability criteria and the + state's 48-month impairment-duration test. The formula identifies people + already reported permanently and totally disabled. Set the state decision + explicitly for qualifying impairments of finite duration. + """ + # NOTE: is_permanently_and_totally_disabled is an input that defaults to + # false, so microsimulation pays Aid to the Permanently and Totally Disabled + # only where the dataset sets it; Old Age Assistance and Aid to the Needy + # Blind do not depend on it. + + def formula(person, period, parameters): + return person("meets_ssi_disability_criteria", period) & person( + "is_permanently_and_totally_disabled", period + ) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_eligible.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_eligible.py new file mode 100644 index 00000000000..1e54977b753 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_eligible.py @@ -0,0 +1,79 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.states.nh.dhhs.ssp._nh_ssp_couple import ( + nh_ssp_spouse, + spouse_value, +) + + +class nh_ssp_eligible(Variable): + value_type = bool + entity = Person + label = "New Hampshire adult cash assistance non-income eligibility" + definition_period = MONTH + defined_for = StateCode.NH + reference = ( + "https://gc.nh.gov/rsa/html/XII/167/167-6.htm", + "https://gc.nh.gov/rules/state_agencies/he-w600.html", + "https://dhhs.nh.gov/aam_htm/html/305_11_qualified_aliens_eligible_without_restriction_aam.htm", + "https://dhhs.nh.gov/aam_htm/html/305_13_qualified_aliens_with_restricted_eligibility_based_on_date_of_entry_into_the_us_aam.htm", + "https://www.law.cornell.edu/uscode/text/8/1622#b", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.nh.dhhs.ssp + age = person("age", period.this_year) + aged = age >= parameters(period).gov.ssa.ssi.eligibility.aged_threshold + blind = person("is_blind", period.this_year) + disabled = (age >= p.disabled_minimum_age) & person( + "nh_ssp_disability_eligible", period.this_year + ) + arrangement = person("nh_ssp_living_arrangement", period) + la = arrangement.possible_values + spouse = nh_ssp_spouse(person, period) + size = person("nh_ssp_assistance_group_size", period) + # A group larger than the person and any spouse includes an essential person. + essential = size > 1 + (spouse >= 0) + resources = person("ssi_countable_resources", period.this_year) + resources = resources + spouse_value(resources, spouse) + resources = resources + person("nh_ssp_resources_deemed_from_parents", period) + essential_resources = max_( + person("nh_ssp_essential_person_resources", period), 0 + ) + resources = resources + essential * max_( + essential_resources, spouse_value(essential_resources, spouse) + ) + # He-W 616.02(a): qualified aliens under 8 USC 1641(b) are eligible once + # the waiting period since entry has elapsed, which also covers entry + # before August 22, 1996. AAM 305.11 exempts the listed statuses, as + # 8 USC 1622(b)(1) requires. + # NOTE: source conflict. AAM 305.13 keeps "lawfully admitted permanent + # residents regardless of work history" out for the 5 years. 8 USC + # 1622(b)(2) instead makes a permanent resident credited with 40 + # qualifying quarters (8 USC 1645) "eligible for any State public + # benefits", and He-W 616.02 does not address it. The model follows + # the federal statute. The quarters come from + # snap_alien_qualifying_quarters, the same legal count, which defaults + # to 0, so the exception applies only when quarters are supplied. + immigration = person("immigration_status", period.this_year) + statuses = immigration.possible_values + citizen = immigration == statuses.CITIZEN + exempt = np.isin(immigration.decode_to_str(), p.immigration.exempt_statuses) + quarters = person("snap_alien_qualifying_quarters", period.this_year) + credited_permanent_resident = ( + immigration == statuses.LEGAL_PERMANENT_RESIDENT + ) & (quarters >= p.immigration.permanent_resident_qualifying_quarters) + waited = ( + person("years_since_us_entry", period.this_year) + >= p.immigration.waiting_period + ) + immigration_eligible = person( + "is_citizen_or_legal_immigrant", period.this_year + ) & (citizen | exempt | credited_permanent_resident | waited) + return ( + (aged | blind | disabled) + & (resources <= p.resource_limit) + & immigration_eligible + & (arrangement != la.NONE) + & ~person("is_incarcerated", period) + & person("takes_up_ssi_if_eligible", period.this_year) + ) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_employment_expenses.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_employment_expenses.py new file mode 100644 index 00000000000..0972c88d9c4 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_employment_expenses.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + + +class nh_ssp_employment_expenses(Variable): + value_type = float + entity = Person + label = "New Hampshire SSP employment expenses" + definition_period = MONTH + unit = USD + defined_for = StateCode.NH + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + documentation = """Employment expenses under He-W 654.18(c)(1): the employee's Federal Insurance Contributions Act taxes. The countable income formula allows at least the regulatory flat amount of He-W 654.18(b) for aged and disabled workers.""" + # NOTE: Expenses in He-W 654.18(c)(2)-(9), such as withholding, are not derived. + adds = ["employee_social_security_tax", "employee_medicare_tax"] diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_essential_person_countable_income.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_essential_person_countable_income.py new file mode 100644 index 00000000000..443942c5e7f --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_essential_person_countable_income.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class nh_ssp_essential_person_countable_income(Variable): + value_type = float + entity = Person + label = "New Hampshire SSP essential-person countable income" + definition_period = MONTH + unit = USD + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + documentation = "Essential person's net earned income after He-W 654.15 and 654.18 deductions plus gross countable unearned income. Do not subtract the assistance-group standard disregard. Enter once, or the same amount on both applicant spouses." diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_essential_person_resources.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_essential_person_resources.py new file mode 100644 index 00000000000..0e7a476e240 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_essential_person_resources.py @@ -0,0 +1,12 @@ +from policyengine_us.model_api import * + + +class nh_ssp_essential_person_resources(Variable): + value_type = float + entity = Person + label = "New Hampshire SSP essential-person countable resources" + definition_period = MONTH + unit = USD + quantity_type = STOCK + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + documentation = "Countable resources of the certified co-resident essential person under adult cash-assistance rules. Enter once, or the same amount on both applicant spouses." diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_grant_reduction_applies.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_grant_reduction_applies.py new file mode 100644 index 00000000000..5642e5c00ba --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_grant_reduction_applies.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class nh_ssp_grant_reduction_applies(Variable): + value_type = bool + entity = Person + label = "New Hampshire SSP one-third grant reduction applies" + definition_period = MONTH + default_value = False + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + documentation = """ + State determination under He-W 670.03(c): the independent-living recipient + lives with others, has no food or residence expenses and receives no SNAP, + or fails the required documentation. This is a separate determination from + the federal SSI household reduction. It is explicit to avoid a cycle with + SNAP, which counts the state grant as income. + """ diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_has_essential_person.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_has_essential_person.py new file mode 100644 index 00000000000..4c38251e425 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_has_essential_person.py @@ -0,0 +1,10 @@ +from policyengine_us.model_api import * + + +class nh_ssp_has_essential_person(Variable): + value_type = bool + entity = Person + label = "New Hampshire SSP certified needy essential person" + definition_period = MONTH + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + documentation = "A co-resident person essential to the recipient's well-being who does not qualify for assistance in their own right under He-W 601.05(p). Set on the recipient, not the caregiver; one caregiver is shared by an applicant couple." diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_living_arrangement.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_living_arrangement.py new file mode 100644 index 00000000000..81aabe2b084 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_living_arrangement.py @@ -0,0 +1,34 @@ +from policyengine_us.model_api import * + + +class NHSSPLivingArrangement(Enum): + INDEPENDENT = "Independent living" + SUBSIDIZED_COMMUNITY_RESIDENCE = "Certified subsidized community residence" + NONSUBSIDIZED_COMMUNITY_RESIDENCE = "Certified nonsubsidized community residence" + ENHANCED_FAMILY_CARE = "Certified enhanced family care" + RESIDENTIAL_CARE = "Certified residential care" + NONE = "No eligible adult assistance living arrangement" + + +class nh_ssp_living_arrangement(Variable): + value_type = Enum + entity = Person + label = "New Hampshire adult assistance living arrangement" + definition_period = MONTH + possible_values = NHSSPLivingArrangement + default_value = NHSSPLivingArrangement.INDEPENDENT + defined_for = StateCode.NH + # PDF pages 14-16 + reference = "https://www.medicaid.gov/medicaid/spa/downloads/NH-26-0001.pdf#page=14" + documentation = """ + Care categories require state approval. Care recipients are individual + assistance groups, including married residents. Reflect separate federal + SSI claims explicitly when applicable. Use NONE for excluded facilities. + """ + + def formula(person, period, parameters): + return where( + person("ssi_lives_in_medical_treatment_facility", period), + NHSSPLivingArrangement.NONE, + NHSSPLivingArrangement.INDEPENDENT, + ) diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_other_income_deductions.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_other_income_deductions.py new file mode 100644 index 00000000000..5c1b7841b7b --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_other_income_deductions.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class nh_ssp_other_income_deductions(Variable): + value_type = float + entity = Person + label = "New Hampshire SSP other allowable income deductions" + definition_period = MONTH + unit = USD + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + documentation = """Court-ordered child support and alimony payments deducted under He-W 654.20(a)(1).""" + # NOTE: Other He-W 654.20-654.21 and 654.15(c) deductions are not derived. + adds = ["child_support_expense", "alimony_expense"] diff --git a/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_resources_deemed_from_parents.py b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_resources_deemed_from_parents.py new file mode 100644 index 00000000000..074bef3c182 --- /dev/null +++ b/policyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_resources_deemed_from_parents.py @@ -0,0 +1,36 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.resources.deemed.ssi_resources_deemed_from_ineligible_parent import ( + _ssi_parental_resource_pool, +) + + +class nh_ssp_resources_deemed_from_parents(Variable): + value_type = float + entity = Person + label = "New Hampshire ANB resources deemed from parents" + definition_period = MONTH + quantity_type = STOCK + unit = USD + defined_for = StateCode.NH + reference = "https://gc.nh.gov/rules/state_agencies/he-w600.html" + # He-W 652.03(i)-(j) adds the co-resident parents' resources above the federal + # one/two-parent allowance to a blind child's own resources. It does not divide that + # excess between siblings. Parent includes a biological, adoptive or stepparent + # under He-W 601.06(b); the federal pool also counts a named parent's + # co-resident spouse. Override with the agency-determined amount for a different + # certified budget, temporary absence, or the month of the eighteenth birthday; + # annual age cannot identify that month. He-W 652.03(j) cites "He-W 656.06(c)", + # which does not exist; the adult category resource limit is He-W 656.06(b). + + def formula(person, period, parameters): + p = parameters(period).gov.ssa.ssi.eligibility.resources.limit + parental_resources, parent_count, _ = _ssi_parental_resource_pool( + person, period, person("ssi_resources_for_deeming", period) + ) + allowance = where(parent_count > 1, p.couple, p.individual) + excess = max_(0, parental_resources - allowance) + return ( + person("is_child", period.this_year) + * person("is_blind", period.this_year) + * excess + ) diff --git a/policyengine_us/variables/gov/usda/snap/eligibility/waiting_period/snap_alien_qualifying_quarters.py b/policyengine_us/variables/gov/usda/snap/eligibility/waiting_period/snap_alien_qualifying_quarters.py index ec087ae9bf4..b7c56144201 100644 --- a/policyengine_us/variables/gov/usda/snap/eligibility/waiting_period/snap_alien_qualifying_quarters.py +++ b/policyengine_us/variables/gov/usda/snap/eligibility/waiting_period/snap_alien_qualifying_quarters.py @@ -18,8 +18,9 @@ class snap_alien_qualifying_quarters(Variable): "total net of quarters after December 31, 1996, in which the person, " "parent or spouse actually received any Federal means-tested public " "benefit or SNAP benefits, which are not creditable " - "(273.4(a)(6)(ii)(A)(2)). Consulted only for lawful permanent " - "residents inside the SNAP qualified alien waiting period. Defaults " + "(273.4(a)(6)(ii)(A)(2)). Consulted for lawful permanent residents " + "inside the SNAP qualified alien waiting period, and for New " + "Hampshire's adult category assistance under 8 USC 1622(b)(2). Defaults " "to 0, so the 40-quarter exception applies only when this input is " "supplied. This is the same legal count as " "ssi_qualifying_quarters_earnings. 8 USC 1612(a)(2)(B) is one " diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py index a473c2b438d..53c8633cb8b 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py @@ -22,6 +22,7 @@ def formula(spm_unit, period, parameters): "ky_ssp", # Kentucky benefits "de_ssp", # Delaware benefits "fl_oss", + "nh_ssp", # New Hampshire benefits "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits