diff --git a/changelog.d/nc-ssp-2026.added.md b/changelog.d/nc-ssp-2026.added.md new file mode 100644 index 00000000000..a165a54b001 --- /dev/null +++ b/changelog.d/nc-ssp-2026.added.md @@ -0,0 +1 @@ +Add North Carolina State-County Special Assistance 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 dc385efe5ef..b27adb9a164 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -69,6 +69,8 @@ values: - nj_ssp # New Mexico benefits - nm_ssi_state_supplement + # North Carolina benefits + - nc_sa # Pennsylvania benefits - pa_ssp # South Carolina benefits @@ -181,6 +183,7 @@ values: - wy_ssp # North Carolina benefits - nc_child_care_subsidies + - nc_sa # South Carolina benefits - sc_child_care_subsidies # Massachusetts benefits @@ -289,6 +292,7 @@ values: - wy_ssp # North Carolina benefits - nc_child_care_subsidies + - nc_sa # South Carolina benefits - sc_child_care_subsidies # Massachusetts benefits @@ -398,6 +402,7 @@ values: - wy_ssp # North Carolina benefits - nc_child_care_subsidies + - nc_sa # South Carolina benefits - sc_child_care_subsidies # Massachusetts benefits 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 be58eee99f2..e989412f9c4 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -22,6 +22,7 @@ values: - nj_ssp - pa_ssp - wy_ssp + - nc_sa_countable_for_hud - general_assistance - total_unemployment_compensation - child_support_received diff --git a/policyengine_us/parameters/gov/states/nc/ncdhhs/lieap/unearned_income_sources.yaml b/policyengine_us/parameters/gov/states/nc/ncdhhs/lieap/unearned_income_sources.yaml index 90a12cec543..b8d1855be8d 100644 --- a/policyengine_us/parameters/gov/states/nc/ncdhhs/lieap/unearned_income_sources.yaml +++ b/policyengine_us/parameters/gov/states/nc/ncdhhs/lieap/unearned_income_sources.yaml @@ -10,6 +10,10 @@ values: # "Social Security Benefits" (page 20). The plan checks "Including # MediCare deduction", so the benefit is counted gross. - social_security + # "Special Assistance (SA)" (page 20): facility SA, SA In-Home and SA for + # the Certain Disabled. SA-5400 II also counts the SA In-Home payment for + # Energy Programs. + - nc_sa # "General Assistance (GA)" (page 9); plan "General Assistance benefits". - general_assistance # "Pensions" (page 16); plan "Retirement / pension benefits". @@ -53,3 +57,5 @@ metadata: href: https://policies.ncdhhs.gov/wp-content/uploads/fns-300-sources-of-income.pdf#page=1 - title: North Carolina FY2026 state plan, item 1.9 countable income checklist, pages 6-7 href: https://liheapch.acf.gov/docs/2026/state-plans/NC_Plan_2026.pdf#page=6 + - title: North Carolina Special Assistance In-Home Program Manual, SA-5400 II + href: https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=47 diff --git a/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/minimum_adult_age.yaml b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/minimum_adult_age.yaml new file mode 100644 index 00000000000..d05cfe52d12 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/minimum_adult_age.yaml @@ -0,0 +1,13 @@ +description: North Carolina sets this age as the minimum for disabled and in-home applicants under the State-County Special Assistance program. +values: + 2026-01-01: 18 + +metadata: + unit: year + period: year + label: North Carolina SA minimum adult age + reference: + - title: North Carolina General Statutes § 108A-41(b)(1) + href: https://www.ncleg.gov/EnactedLegislation/Statutes/PDF/BySection/Chapter_108A/GS_108A-41.pdf#page=1 + - title: "North Carolina Special Assistance Manual SA-3100 II.A.1 and III.C #page 6,10" + href: https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=6 diff --git a/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/personal_needs_allowance.yaml b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/personal_needs_allowance.yaml new file mode 100644 index 00000000000..fb6d865f383 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/personal_needs_allowance.yaml @@ -0,0 +1,11 @@ +description: North Carolina provides this amount as the monthly personal needs allowance under the State-County Special Assistance program. +values: + 2022-01-01: 70 + +metadata: + unit: currency-USD + period: month + label: North Carolina SA personal needs allowance + reference: + - title: North Carolina Special Assistance Manual SA-3220 II.C + href: https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=205 diff --git a/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/rate/basic.yaml b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/rate/basic.yaml new file mode 100644 index 00000000000..ab22c2f1430 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/rate/basic.yaml @@ -0,0 +1,22 @@ +description: North Carolina provides this amount as the maximum monthly basic rate under the State-County Special Assistance program. +values: + 2026-01-01: 1_397 + +metadata: + unit: currency-USD + period: month + label: North Carolina SA basic rate + # G.S. 108A-42.1(a) adjusts the rate each January 1 by the Social Security + # cost-of-living adjustment; the published rate replaces the projection. + uprating: + parameter: gov.ssa.uprating + rounding: + type: nearest + interval: 1 + reference: + - title: North Carolina General Statutes § 108A-42.1(a) + href: https://www.ncleg.gov/EnactedLegislation/Statutes/PDF/BySection/Chapter_108A/GS_108A-42.1.pdf + - title: "North Carolina Special Assistance Manual SA-3220 II.A and VIII #page 204,219" + href: https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=204 + - title: North Carolina Change Notice EFS-SA-CN-01-2026 I + href: https://policies.ncdhhs.gov/wp-content/uploads/EFS-SA-CN-01-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/rate/enhanced.yaml b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/rate/enhanced.yaml new file mode 100644 index 00000000000..6bd404365dc --- /dev/null +++ b/policyengine_us/parameters/gov/states/nc/ncdhhs/sa/rate/enhanced.yaml @@ -0,0 +1,22 @@ +description: North Carolina provides this amount as the maximum monthly enhanced rate for special care units and in-home recipients with Alzheimer's disease or dementia under the State-County Special Assistance program. +values: + 2026-01-01: 1_792 + +metadata: + unit: currency-USD + period: month + label: North Carolina SA enhanced rate + # G.S. 108A-42.1(b) adjusts the rate each January 1 by the Social Security + # cost-of-living adjustment; the published rate replaces the projection. + uprating: + parameter: gov.ssa.uprating + rounding: + type: nearest + interval: 1 + reference: + - title: North Carolina General Statutes § 108A-42.1(b) + href: https://www.ncleg.gov/EnactedLegislation/Statutes/PDF/BySection/Chapter_108A/GS_108A-42.1.pdf + - title: "North Carolina Special Assistance Manual SA-3220 II.B and VIII #page 205,219" + href: https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=205 + - title: North Carolina Change Notice EFS-SA-CN-01-2026 I + href: https://policies.ncdhhs.gov/wp-content/uploads/EFS-SA-CN-01-2026.pdf#page=1 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 911286fbe0c..4fd3bd4c94a 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -45,6 +45,7 @@ values: - mi_ssp_person - mn_msa_person - mo_ssp + - nc_sa - ne_aabd - nj_ssp - nm_ssi_state_supplement diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 13c27c1be98..69d1b8a36d7 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1127,6 +1127,15 @@ programs: notes: >- Models the 2026 flat payment for Wyoming residents who receive SSI and have no other income. + - state: NC + status: partial + name: North Carolina SA + full_name: North Carolina State-County Special Assistance + variable: nc_sa + parameter_prefix: gov.states.nc.ncdhhs.sa + verified_years: '2026' + notes: Models 2026 basic and enhanced facility and in-home payments, including lower contracted + rates and first-month proration. Open/shut and discharge payments are not modeled. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/lieap/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/lieap/integration.yaml index e1995f37483..4cea8f7d21f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/lieap/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/lieap/integration.yaml @@ -333,3 +333,28 @@ has_heating_expense: [true, true, true, true] nc_lieap_eligible: [true, false, true, false] nc_lieap: [400, 0, 300, 0] + +- name: Case 10, Special Assistance In-Home counts as unearned income. + # FNS 300.02 "Special Assistance (SA)" is countable unearned income (page + # 20), and SA-5400 II counts the SA In-Home payment for Energy Programs. + # Age 65, no other income: SSI 994 x 12 = 11_928; SA In-Home basic + # (1,397 + 70 - 994) x 12 = 5_676. Gross 17_604; medical deduction 1_020 -> + # nc_lieap_income 16_584 ($1,382 a month). Limit 15_650 x 1.5 = 23_475 -> + # $1,956. Lower band ends at $978 -> $300. Without SA the income would be + # 10_908 ($909) and the payment $400. + period: 2026 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME + tanf: 0 + childcare_expenses: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_200 + output: + nc_sa: 5_676 + nc_lieap_gross_income_person: 17_604 + nc_lieap_income: 16_584 + nc_lieap_income_limit: 23_475 + nc_lieap_eligible: true + nc_lieap: 300 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/integration.yaml new file mode 100644 index 00000000000..45d56a04f07 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/integration.yaml @@ -0,0 +1,263 @@ +- name: Case 1, two in home recipients. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + nc_sa_care_setting: IN_HOME + person2: + age: 65 + nc_sa_care_setting: IN_HOME + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # Joint claim with no income: couple FBR 1,491 / 2 = 745.50 each. + ssi: [745.5, 745.5] + # Own income 0 + SSI 745.50; in-home budgets keep the couple amount. + nc_sa_countable_income: [745.5, 745.5] + # Both receive SSI; TCMI 745.50 < 1,466.51. + nc_sa_eligible: [true, true] + # In-home basic payments use the published basic rate. + nc_sa_rate: [1_397, 1_397] + # 1,397 + 70 - 745.50 = 721.50 -> 722. + nc_sa: [722, 722] + +- name: Case 2, one in home recipient with spouse income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + nc_sa_care_setting: IN_HOME + person2: + age: 65 + social_security_retirement: 14_400 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # Joint claim: (1,200 - 20) / 2 = 590 countable each; 745.50 - 590 = 155.50. + ssi: [155.5, 155.5] + # person1: own income 0 + SSI 155.50. + # person2: 1,200 - 20 = 1,180 + SSI 155.50 = 1,335.50. + nc_sa_countable_income: [155.5, 1_335.5] + # person2 has no approved care setting. + nc_sa_eligible: [true, false] + nc_sa_rate: [1_397, 1_397] + # 1,397 + 70 - 155.50 = 1,311.50 -> 1,312. + nc_sa: [1_312, 0] + +# person2 earns North Carolina's May 2023 median wage, $21.85 an hour +# (BLS OEWS, all occupations), full time: 21.85 * 2,080 = $45,448 a year. +# https://www.bls.gov/oes/2023/may/oes_nc.htm +- name: Case 3, ineligible spouse income is not directly counted. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + nc_sa_care_setting: IN_HOME + person2: + age: 40 + employment_income: 45_448 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # SSI deems the ineligible spouse's 45,448 / 12 = 3,787.33 a month: + # (3,787.33 - 20 - 65) / 2 = 1,851.17 > 1,491 couple FBR, so SSI is 0. + ssi: [0, 0] + # SA counts only the applicant's own income (budget unit of one). + # person2: (3,787.33 - 85) / 2 = 1,851.17. + nc_sa_countable_income: [0, 1_851.17] + # person1: aged citizen with own resources 0 <= 2,000 and TCMI 0. + nc_sa_eligible: [true, false] + nc_sa_rate: [1_397, 1_397] + # 1,397 + 70 - 0 = 1,467. + nc_sa: [1_467, 0] + +- name: Case 4, annual in home benefit and SNAP income. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME + output: + # 994 * 12 = 11,928. + ssi: 11_928 + # Own income 0 + SSI 994 = 994 a month; 994 * 12 = 11,928. + nc_sa_countable_income: 11_928 + nc_sa_eligible: + 2026-01: true + # 1,397 * 12 = 16,764. + nc_sa_rate: 16_764 + # (1,397 + 70 - 994) * 12 = 473 * 12 = 5,676. + nc_sa: 5_676 + household_state_benefits: 5_676 + # SSI 11,928 + SA 5,676 = 17,604. + snap_unearned_income: 17_604 + # SSI 11,928 + SA 5,676 + the SNAP minimum benefit (24 * 9 + 25 * 3 = 291). + spm_unit_benefits: 17_895 + +- name: Case 5, in home household reduction exception. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + # One-third reduction: 994 * (1 - 1/3) = 662.67. + ssi_amount_if_eligible: 662.67 + ssi: 662.67 + # In-home budgets keep the reduced SSI (SA-3210 V.D.1.e(3)): 0 + 662.67. + nc_sa_countable_income: 662.67 + nc_sa_eligible: true + nc_sa_rate: 1_397 + # 1,397 + 70 - 662.67 = 804.33 -> 804. + nc_sa: 804 + +- name: Case 6, ongoing individual facility month after the two-month admission window budgets the full federal rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + # One-third reduction: 994 * (1 - 1/3) = 662.67. + ssi_amount_if_eligible: 662.67 + ssi: 662.67 + # Individual facility budget uses max(662.67, 994 - 0) = 994. + nc_sa_countable_income: 994 + nc_sa_eligible: true + nc_sa_rate: 1_397 + # 1,397 + 70 - 994 = 473. + nc_sa: 473 + +- name: Case 7, North Carolina in-home assistance counts for SNAP and is excluded for HUD. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME + output: + # 994 * 12 = 11,928. + ssi: 11_928 + nc_sa_countable_income: 11_928 + nc_sa_eligible: + 2026-01: true + nc_sa_rate: 16_764 + # 473 * 12 = 5,676. + nc_sa: 5_676 + # SAIH payments are excluded for HUD (SA-5400 III). + nc_sa_countable_for_hud: 0 + # SSI 11,928 + SA 5,676 = 17,604. + snap_unearned_income: 17_604 + # SSI 11,928 + SA 0 = 11,928. + hud_unearned_income: 11_928 + +# SSA treats spouses as individuals once they no longer live in the same +# household on the first day of the month (20 CFR 416.1801(c); POMS SI +# 00501.154 A.1), so a facility resident whose spouse stays at home is entered +# in a separate marital unit after the month of entry. SA then budgets the +# resident at the individual FBR (SA-3210 V.D.1.e). +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=195 +- name: Case 8, adult care home resident whose spouse stays at home after the month of entry. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + nc_sa_care_setting: ADULT_CARE_HOME + person2: + age: 68 + marital_units: + resident: + members: [person1] + spouse: + members: [person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # Separate claims with no income: the individual FBR of 994 each. + ssi: [994, 994] + nc_sa_countable_income: [994, 994] + # 1,397 + 70 - 994 = 473; person2 has no approved care setting. + nc_sa: [473, 0] + +# A married SAIH applicant whose couple income is at or above the couple FBR +# need not apply for SSI (SA-3210 V.E.4.c), and SA is computed on countable +# income when SSI is denied for spousal income (SA-5400 V). The SSI take-up +# input therefore does not matter. +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=198 +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=48 +# person2 earns North Carolina's May 2023 median wage, as in Case 3. +- name: Case 9, applicant denied SSI for spousal income does not need SSI take-up. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + nc_sa_care_setting: IN_HOME + takes_up_ssi_if_eligible: false + person2: + age: 40 + employment_income: 45_448 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # Deemed income leaves no SSI: (3,787.33 - 85) / 2 = 1,851.17 > 1,491. + uncapped_ssi: [-360.17, 0] + ssi: [0, 0] + nc_sa_eligible: [true, false] + # 1,397 + 70 - 0 = 1,467. + nc_sa: [1_467, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa.yaml new file mode 100644 index 00000000000..d7a1f2a8e82 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa.yaml @@ -0,0 +1,563 @@ +- name: Case 1, basic facility with full SSI. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + output: + nc_sa: 473 + +- name: Case 2, enhanced special care unit. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: SPECIAL_CARE_UNIT + output: + nc_sa: 868 + +- name: Case 3, basic in home. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME + output: + nc_sa: 473 + +- name: Case 4, enhanced in home. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME_ENHANCED + output: + nc_sa: 868 + +- name: Case 5, income above federal SSI. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + social_security_retirement: 15_600 + output: + nc_sa: 187 + +- name: Case 6, SSI and other income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + social_security_retirement: 12_000 + output: + nc_sa: 473 + +- name: Case 7, earned income with SSI. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + employment_income: 7_200 + output: + nc_sa: 473 + +- name: Case 8, basic half dollar rounds up. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_countable_income: 1_466.5 + output: + nc_sa: 1 + +- name: Case 9, basic forty nine cents rounds down. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_countable_income: 1_466.51 + output: + nc_sa: 0 + +- name: Case 10, enhanced half dollar rounds up. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: SPECIAL_CARE_UNIT + nc_sa_countable_income: 1_861.5 + output: + nc_sa: 1 + +- name: Case 11, enhanced forty nine cents rounds down. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: SPECIAL_CARE_UNIT + nc_sa_countable_income: 1_861.51 + output: + nc_sa: 0 + +- name: Case 12, lower contracted facility rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: 1_000 + output: + nc_sa: 76 + +- name: Case 13, no qualifying care setting. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: NONE + output: + nc_sa: 0 + +- name: Case 14, out of state. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VA + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + output: + nc_sa: 0 + +- name: Case 15, disabled child is not eligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 17 + nc_sa_care_setting: ADULT_CARE_HOME + meets_ssi_disability_criteria: true + output: + nc_sa: 0 + +- name: Case 16, blind child in certified specialized center. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 17 + nc_sa_care_setting: ADULT_CARE_HOME + is_blind: true + output: + nc_sa: 473 + +- name: Case 17, blind child cannot receive in home program. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 17 + nc_sa_care_setting: IN_HOME + is_blind: true + output: + nc_sa: 0 + +- name: Case 18, adult disabled applicant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 18 + nc_sa_care_setting: ADULT_CARE_HOME + meets_ssi_disability_criteria: true + output: + nc_sa: 473 + +- name: Case 19, not aged blind disabled. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 64 + nc_sa_care_setting: ADULT_CARE_HOME + output: + nc_sa: 0 + +- name: Case 20, resource boundary. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + ssi_countable_resources: 2_000 + output: + nc_sa: 473 + +- name: Case 21, excess resources. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + ssi_countable_resources: 2_001 + output: + nc_sa: 0 + +- name: Case 22, first month twenty seven days ignores income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_partial_month_days: 27 + social_security_retirement: 15_600 + output: + nc_sa: 1_287 + +- name: Case 23, first month twenty days in home. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME + nc_sa_partial_month_days: 20 + output: + nc_sa: 971 + +- name: Case 24, first month fourteen days enhanced in home. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME_ENHANCED + nc_sa_partial_month_days: 14 + output: + nc_sa: 879 + +# A lower rate or partial-month days entered for one resident leave the other +# resident, an unrelated adult, on the published rate and a full month. +- name: Case 25, contracted rate and partial month entered for one of two residents. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: 1_000 + nc_sa_partial_month_days: 15 + person2: + age: 72 + nc_sa_care_setting: ADULT_CARE_HOME + marital_units: + unit1: + members: [person1] + unit2: + members: [person2] + tax_units: + unit1: + members: [person1] + unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + nc_sa_rate: [1_000, 1_397] + # person1: 1,000 / 31 = 32.26; 32.26 * 15 + 70 = 553.90 -> 554. + # person2: SSI 994; 1,397 + 70 - 994 = 473. + nc_sa: [554, 473] + +- name: Case 26, SSI opt out. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + takes_up_ssi_if_eligible: false + output: + nc_sa: 0 + +# SA-3220 II.E, III.C and IV.A: an applicant whose full-month payment rounds to +# $0 is ineligible, including in a prorated first month. +# Cases 29-32 enter TCMI directly at the last eligible cent and at the cutoff. +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=207 +- name: Case 27, income-ineligible basic entrant receives no partial-month grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + social_security_retirement: 36_000 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_partial_month_days: 15 + output: + nc_sa: 0 + +- name: Case 28, income-ineligible basic entrant receives no full-month grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + social_security_retirement: 36_000 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_partial_month_days: 31 + output: + nc_sa: 0 + +- name: Case 29, basic last eligible cent retains the partial-month grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_countable_income: 1_466.5 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_partial_month_days: 15 + output: + # TCMI 1,466.50 is below the 1,466.51 basic cutoff. + nc_sa_eligible: true + # Per diem 1,397 / 31 = 45.0645 -> 45.06; 45.06 * 15 + 70 = 745.90 -> 746. + nc_sa: 746 + +- name: Case 30, basic exact exclusive income limit prevents partial payment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_countable_income: 1_466.51 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_partial_month_days: 15 + output: + # TCMI 1,466.51 or more is ineligible for the basic rate. + nc_sa_eligible: false + nc_sa: 0 + +- name: Case 31, enhanced last eligible cent retains the partial-month grant. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_countable_income: 1_861.5 + nc_sa_care_setting: SPECIAL_CARE_UNIT + nc_sa_partial_month_days: 15 + output: + # TCMI 1,861.50 is below the 1,861.51 enhanced cutoff. + nc_sa_eligible: true + # Per diem 1,792 / 31 = 57.8065 -> 57.81; 57.81 * 15 + 70 = 937.15 -> 937. + nc_sa: 937 + +- name: Case 32, enhanced exact exclusive income limit prevents partial payment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_countable_income: 1_861.51 + nc_sa_care_setting: SPECIAL_CARE_UNIT + nc_sa_partial_month_days: 15 + output: + # TCMI 1,861.51 or more is ineligible for the enhanced rate. + nc_sa_eligible: false + nc_sa: 0 + +# SA-3200 I: "The budget unit is always one", so a non-SSI applicant's own +# resources are tested against $2,000; SSI's $3,000 couple test does not apply. +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=61 +- name: Case 33, married non-SSI in-home applicant is tested on own resources and income only. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 75 + social_security_retirement: 13_200 + bank_account_assets: 1_800 + nc_sa_care_setting: IN_HOME + person2: + age: 72 + social_security_retirement: 10_800 + bank_account_assets: 1_800 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # Joint SSI claim: resources 1,800 + 1,800 = 3,600 > 3,000, and income + # 1,100 + 900 - 20 = 1,980 > 1,491, so neither spouse receives SSI. + ssi: [0, 0] + # Own income only: 1,100 - 20 = 1,080 and 900 - 20 = 880. + nc_sa_countable_income: [1_080, 880] + # person1: aged, citizen, own resources 1,800 <= 2,000, TCMI 1,080 < 1,466.51. + # person2 has no approved care setting. + nc_sa_eligible: [true, false] + # 1,397 + 70 - 1,080 = 387. + nc_sa: [387, 0] + +# SA-3220 II.A and IV.A: a lower facility rate replaces the basic rate in +# the per diem, and initial-month income is not deducted. +# PDF pages 204, 209-210 +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=204 +- name: Case 34, lower contracted facility rate in a fifteen-day initial month. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: 1_000 + nc_sa_partial_month_days: 15 + output: + # SSI 994; at the contracted rate 1,000 + 70 - 994 = 76 >= 1, so the + # applicant is eligible. + nc_sa_eligible: true + # Per diem 1,000 / 31 = 32.2581 -> 32.26; 32.26 * 15 + 70 = 553.90 -> 554. + nc_sa: 554 + +# SA-3220 II.A: with a lower contracted rate, "the actual rate charged to the +# recipient ... is used in the calculations addressed in this chapter", +# including III.C's eligibility test. Social Security of $1,300 a month gives +# TCMI 1,300 - 20 = 1,280, above the 1,070 maintenance amount at a $1,000 rate. +# PDF pages 204, 209 +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=204 +- name: Case 35, income above the lower contracted maintenance amount prevents a partial-month payment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: 1_000 + nc_sa_partial_month_days: 15 + social_security_retirement: 15_600 + output: + nc_sa_countable_income: 1_280 + # 1,000 + 70 - 1,280 < 0. + nc_sa_full_month_amount: 0 + nc_sa_eligible: false + nc_sa: 0 + +- name: Case 36, income above the lower contracted maintenance amount in a full month. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: 1_000 + social_security_retirement: 15_600 + output: + nc_sa_full_month_amount: 0 + nc_sa_eligible: false + nc_sa: 0 + +# G.S. 108A-42.1 adjusts the rates each January 1 by the Social Security +# cost-of-living adjustment. The 2027 rate and FBR are projections. +# https://www.ncleg.gov/EnactedLegislation/Statutes/PDF/BySection/Chapter_108A/GS_108A-42.1.pdf +- name: Case 37, basic facility rate follows the cost-of-living adjustment in 2027. + period: 2027-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + output: + # 1,397 uprated by the projected Social Security index and rounded to the + # dollar. + nc_sa_rate: 1_436 + # Projected FBR. + ssi: 1_021.83 + # 1,436 + 70 - 1,021.83 = 484.17 -> 484. + nc_sa: 484 + +# An applicant "ineligible for SSI solely due to being over income for SSI" +# qualifies without applying for SSI (SA-3100 I, II.A.6): "If the a/b +# currently has income at or above the FBR, a referral to SSA to apply for SSI +# is not required" (SA-3210 V.A.4). +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=191 +- name: Case 38, applicant over income for SSI does not need SSI take-up. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + social_security_retirement: 15_600 + takes_up_ssi_if_eligible: false + output: + # 1,300 - 20 = 1,280 > 994, so no SSI. + ssi: 0 + nc_sa_eligible: true + # 1,397 + 70 - 1,280 = 187. + nc_sa: 187 + +# SA-3220 IV.A rounds the per diem to the cent and the total to the dollar, +# with half a dollar rounding up (III.A.4). +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=209 +- name: Case 39, partial month at a lower contracted rate ending in exactly fifty cents rounds up. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: + 2026-04: 1_059 + nc_sa_partial_month_days: + 2026-04: 25 + output: + # 1,059 / 30 = 35.30; 35.30 * 25 + 70 = 952.50 -> 953. + nc_sa: + 2026-04: 953 + +- name: Case 40, partial-month days entered for one month leave the next month full. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_partial_month_days: + 2026-01: 15 + output: + nc_sa_partial_month_days: + 2026-01: 15 + 2026-02: 0 + # January: 1,397 / 31 = 45.06; 45.06 * 15 + 70 = 745.90 -> 746. + # February is a full month: 1,397 + 70 - SSI 994 = 473. + nc_sa: + 2026-01: 746 + 2026-02: 473 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_countable_for_hud.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_countable_for_hud.yaml new file mode 100644 index 00000000000..9d9c6edd52a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_countable_for_hud.yaml @@ -0,0 +1,80 @@ +# SA-5400 III: SAIH payments are excluded as income in HUD housing programs +# (24 CFR 5.609(b)(12)(ii)); facility Special Assistance remains countable. +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=47 +- name: Case 1, basic adult care home payment counts for HUD. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + nc_sa_care_setting: ADULT_CARE_HOME + output: + # 1,397 + 70 - 994 = 473. + nc_sa: 473 + nc_sa_countable_for_hud: 473 + +- name: Case 2, special care unit payment counts for HUD. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + nc_sa_care_setting: SPECIAL_CARE_UNIT + output: + # 1,792 + 70 - 994 = 868. + nc_sa: 868 + nc_sa_countable_for_hud: 868 + +- name: Case 3, basic in-home payment is excluded for HUD. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + nc_sa_care_setting: IN_HOME + output: + nc_sa: 473 + nc_sa_countable_for_hud: 0 + +- name: Case 4, enhanced in-home payment is excluded for HUD. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + nc_sa_care_setting: IN_HOME_ENHANCED + output: + nc_sa: 868 + nc_sa_countable_for_hud: 0 + +# Disabled-worker benefit of $711 a month, the December 2024 North Carolina +# average for disabled workers who also receive SSI ($710.97, SSA SSI Annual +# Statistical Report 2024, Table 16). +# https://www.ssa.gov/policy/docs/statcomps/ssi_asr/2024/sect03.html +- name: Case 5, annual HUD unearned income includes facility Special Assistance. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 55 + meets_ssi_disability_criteria: true + social_security_disability: 8_532 + nc_sa_care_setting: ADULT_CARE_HOME + output: + # SSI 994 - (711 - 20) = 303 a month; 303 * 12 = 3,636. + ssi: 3_636 + # TCMI 691 + 303 = 994; (1,397 + 70 - 994) * 12 = 473 * 12 = 5,676. + nc_sa: 5_676 + nc_sa_countable_for_hud: 5_676 + # Social Security 8,532 + SSI 3,636 + SA 5,676 = 17,844. + hud_unearned_income: 17_844 + +- name: Case 6, outside North Carolina. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VA + age: 70 + nc_sa_care_setting: ADULT_CARE_HOME + output: + nc_sa_countable_for_hud: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_countable_income.yaml new file mode 100644 index 00000000000..b26da4473e5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_countable_income.yaml @@ -0,0 +1,110 @@ +# Retired-worker benefit of $2,088 a month, the August 2026 average +# ($2,087.52, SSA Monthly Statistical Snapshot, Table 2). +# https://www.ssa.gov/policy/docs/quickfacts/stat_snapshot/ +- name: Case 1, Social Security less the general income exclusion with no SSI. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + social_security_retirement: 25_056 + nc_sa_care_setting: ADULT_CARE_HOME + output: + # 25,056 / 12 = 2,088; 2,088 - 20 = 2,068 > 994, so no SSI. + ssi: 0 + # 2,068 + SSI 0; the facility restoration adds max(994 - 2,068, 0) = 0. + nc_sa_countable_income: 2_068 + +# Disabled-worker benefit of $1,636 a month, the August 2026 average +# ($1,635.90, SSA Monthly Statistical Snapshot, Table 2), plus 20 hours a +# week at North Carolina's $7.25 minimum wage: 7.25 * 20 * 52 = $7,540. +- name: Case 2, earned income after the $65 and one-half exclusions. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 45 + meets_ssi_disability_criteria: true + social_security_disability: 19_632 + employment_income: 7_540 + nc_sa_care_setting: IN_HOME + output: + # Unearned 1,636 - 20 = 1,616; earned (628.33 - 65) / 2 = 281.67. + # 1,616 + 281.67 = 1,897.67 > 994, so no SSI. + ssi: 0 + nc_sa_countable_income: 1_897.67 + +# SA-3210 V.D.1.e: SA budgets assume the full FBR unless SSA counts the +# applicant as part of a married couple or SSI is one-third reduced for an +# SAIH applicant. +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=195 +# Disabled-worker benefit of $711 a month, the December 2024 North Carolina +# average for disabled workers who also receive SSI ($710.97, SSA SSI Annual +# Statistical Report 2024, Table 16). +# https://www.ssa.gov/policy/docs/statcomps/ssi_asr/2024/sect03.html +- name: Case 3, ongoing facility month after the two-month admission window restores one-third-reduced SSI to the full FBR. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 55 + meets_ssi_disability_criteria: true + social_security_disability: 8_532 + nc_sa_care_setting: ADULT_CARE_HOME + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + # Reduced FBR 994 * (1 - 1/3) = 662.67 < 711 - 20 = 691, so no SSI. + ssi: 0 + # 691 + max(0, 994 - 691) = 691 + 303 = 994. + nc_sa_countable_income: 994 + +- name: Case 4, in-home budget keeps one-third-reduced SSI. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 55 + meets_ssi_disability_criteria: true + social_security_disability: 8_532 + nc_sa_care_setting: IN_HOME + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + ssi: 0 + # 711 - 20 = 691 + SSI 0; no restoration for in-home budgets. + nc_sa_countable_income: 691 + +- name: Case 5, couple sharing an adult care home room whom SSA treats as a couple keeps the couple amount. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 58 + meets_ssi_disability_criteria: true + social_security_disability: 8_532 + nc_sa_care_setting: ADULT_CARE_HOME + person2: + age: 55 + meets_ssi_disability_criteria: true + social_security_disability: 8_532 + nc_sa_care_setting: ADULT_CARE_HOME + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # Joint claim: (711 + 711 - 20) / 2 = 701 countable each; + # couple FBR 1,491 / 2 = 745.50; 745.50 - 701 = 44.50. + ssi: [44.5, 44.5] + # 711 - 20 = 691 + SSI 44.50 = 735.50; no restoration to 994 for a couple. + nc_sa_countable_income: [735.5, 735.5] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_eligible.yaml new file mode 100644 index 00000000000..cfcbdb4e257 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_eligible.yaml @@ -0,0 +1,191 @@ +# SA-3100 II.B and SA-3200 I.A: an SSI recipient automatically meets the +# categorical, financial and resource requirements. +# PDF pages 7, 61 +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=7 +- name: Case 1, SSI recipient in an adult care home is eligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 72 + nc_sa_care_setting: ADULT_CARE_HOME + output: + # No other income: SSI 994; TCMI 994 < 1,466.51. + ssi: 994 + nc_sa_eligible: true + +- name: Case 2, reported SSI receipt waives the resource test when modeled SSI is zero. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 72 + nc_sa_care_setting: ADULT_CARE_HOME + bank_account_assets: 2_500 + receives_ssi: true + output: + # Modeled SSI fails the 2,000 resource limit (2,500 > 2,000). + ssi: 0 + # Reported receipt meets the resource requirement; the facility budget + # restores TCMI to 994 < 1,466.51. + nc_sa_eligible: true + +# SA-3200 I: "The resource limit is $2000 for an applicant/recipient. The +# budget unit is always one." +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=61 +- name: Case 3, non-SSI applicant with an ineligible spouse is tested on own resources only. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 75 + social_security_retirement: 13_200 + bank_account_assets: 1_800 + nc_sa_care_setting: IN_HOME + person2: + age: 60 + bank_account_assets: 3_500 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # person1 SSI: 1,100 - 20 = 1,080 > 994, and the spouse's 3,500 + # counts against SSI's 3,000 limit; person2 is not aged, blind or disabled. + ssi: [0, 0] + # person1: own resources 1,800 <= 2,000 and TCMI 1,080 < 1,466.51. + nc_sa_eligible: [true, false] + +- name: Case 4, non-SSI applicant over the individual limit is ineligible although the couple limit is met. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 75 + social_security_retirement: 13_200 + bank_account_assets: 2_500 + nc_sa_care_setting: IN_HOME + person2: + age: 72 + social_security_retirement: 10_800 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # Joint SSI claim: resources 2,500 + 0 = 2,500 <= 3,000. + is_ssi_eligible: [true, true] + # Joint income (1,100 + 900 - 20) / 2 = 990 > 745.50 each. + ssi: [0, 0] + # person1's own resources 2,500 > 2,000. + nc_sa_eligible: [false, false] + +- name: Case 5, non-SSI applicant with resources at the limit. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + social_security_retirement: 15_600 + bank_account_assets: 2_000 + nc_sa_care_setting: ADULT_CARE_HOME + output: + # 1,300 - 20 = 1,280 > 994. + ssi: 0 + # Resources 2,000 <= 2,000 and TCMI 1,280 < 1,466.51. + nc_sa_eligible: true + +- name: Case 6, non-SSI applicant with resources one dollar over the limit. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + social_security_retirement: 15_600 + bank_account_assets: 2_001 + nc_sa_care_setting: ADULT_CARE_HOME + output: + ssi: 0 + # Resources 2,001 > 2,000. + nc_sa_eligible: false + +# SA-3100 II.A.7: be a U.S. citizen or qualified alien. +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=6 +- name: Case 7, applicant without a qualified immigration status is ineligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 70 + immigration_status: UNDOCUMENTED + nc_sa_care_setting: ADULT_CARE_HOME + output: + ssi: 0 + nc_sa_eligible: false + +# SA-3100 II.A.5: the beneficiary must "Not be an inmate in a jail or prison". +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=6 +- name: Case 8, incarcerated applicant is ineligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 72 + nc_sa_care_setting: ADULT_CARE_HOME + is_incarcerated: true + output: + nc_sa_eligible: false + nc_sa: 0 + +# An applicant whose income would qualify for SSI must be eligible for SSI; +# "If SSA denies the SSDI/SSI application ... based on eligibility criteria +# other than income (such as resources, transfers, fleeing felon, etc.), the +# SA application will also be denied" (SA-3110 V.K). SSI counts an ineligible +# spouse's resources (20 CFR 416.1202(a)). +# PDF pages 40-41 +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=40 +- name: Case 9, applicant denied SSI on a spouse's resources is ineligible. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 75 + bank_account_assets: 1_800 + nc_sa_care_setting: IN_HOME + person2: + age: 60 + bank_account_assets: 3_500 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: NC + output: + # No income, so SSI would be payable, but 1,800 + 3,500 = 5,300 exceeds + # the 3,000 limit for an individual living with an ineligible spouse + # (20 CFR 416.1205(a)). + ssi: [0, 0] + # person1's own resources (1,800) would pass SA-3200 I, but SA requires + # SSI eligibility when the income would qualify. + nc_sa_eligible: [false, false] + nc_sa: [0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_rate.yaml new file mode 100644 index 00000000000..ef5b484b3b9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/ncdhhs/sa/nc_sa_rate.yaml @@ -0,0 +1,78 @@ +# SA-3220 II.A-B: the published basic and enhanced rates, or the lower rate a +# facility actually charges an SA resident. In-home payments use the published +# rate. +# PDF pages 204-205 +# https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=204 +- name: Case 1, adult care home uses the published basic rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + output: + nc_sa_rate: 1_397 + +- name: Case 2, special care unit uses the published enhanced rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: SPECIAL_CARE_UNIT + output: + nc_sa_rate: 1_792 + +- name: Case 3, enhanced in-home care uses the published enhanced rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME_ENHANCED + output: + nc_sa_rate: 1_792 + +- name: Case 4, lower contracted adult care home rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: 1_000 + output: + nc_sa_rate: 1_000 + +- name: Case 5, contracted rate above the published basic rate is capped. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: ADULT_CARE_HOME + nc_sa_facility_rate: 2_000 + output: + nc_sa_rate: 1_397 + +- name: Case 6, lower contracted special care unit rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: SPECIAL_CARE_UNIT + nc_sa_facility_rate: 1_500 + output: + nc_sa_rate: 1_500 + +- name: Case 7, in-home care ignores a contracted facility rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NC + age: 65 + nc_sa_care_setting: IN_HOME + nc_sa_facility_rate: 1_000 + output: + nc_sa_rate: 1_397 diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa.py new file mode 100644 index 00000000000..17d2cb144e5 --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class nc_sa(Variable): + value_type = float + entity = Person + label = "North Carolina State-County Special Assistance" + definition_period = MONTH + unit = USD + defined_for = "nc_sa_eligible" + reference = ( + # PDF pages 207-210 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=207", + # PDF pages 42-43 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=42", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.nc.ncdhhs.sa + days = person("nc_sa_partial_month_days", period) + partial_month = (days > 0) & (days < period.days) + # For the first partial month, income is not deducted and the full + # personal-needs allowance is added after prorating the rate + # (SA-3220 IV.A). + # Work in whole cents so that a per diem or total ending in exactly + # half a cent or half a dollar rounds up. + rate = person("nc_sa_rate", period) + rate_cents = np.floor(rate.astype(np.float64) * 100 + 0.5) + daily_cents = np.floor(rate_cents / period.days + 0.5) + allowance_cents = np.floor(p.personal_needs_allowance * 100 + 0.5) + partial = np.floor((daily_cents * days + allowance_cents) / 100 + 0.5) + return where(partial_month, partial, person("nc_sa_full_month_amount", period)) diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_care_setting.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_care_setting.py new file mode 100644 index 00000000000..209c95efc85 --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_care_setting.py @@ -0,0 +1,25 @@ +from policyengine_us.model_api import * + + +class NCSACareSetting(Enum): + ADULT_CARE_HOME = "Approved basic residential care" + SPECIAL_CARE_UNIT = "Approved enhanced special care unit" + IN_HOME = "Approved basic in-home care" + IN_HOME_ENHANCED = "Approved enhanced in-home care" + NONE = "No approved Special Assistance care setting" + + +class nc_sa_care_setting(Variable): + value_type = Enum + entity = Person + label = "North Carolina Special Assistance certified care setting" + definition_period = MONTH + possible_values = NCSACareSetting + default_value = NCSACareSetting.NONE + documentation = "A positive category indicates an approved placement or in-home service plan with a valid FL-2, satisfaction of the state residency waiting period or exception, pursuit of other benefits, and no conflicting PACE or waiver enrollment. Enhanced settings require the qualifying dementia diagnosis. A blind child requires a certified specialized community residential center. Put spouses who no longer live in the same household, such as a facility resident whose spouse stays at home, in separate marital units from the month after they stop living together, so that SSI and Special Assistance treat each spouse as an individual. Keep one marital unit for the month of entry and for a temporary absence." + reference = ( + # PDF pages 6-7, 10, 204-205 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=6", + # PDF pages 14-17 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=14", + ) diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_countable_for_hud.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_countable_for_hud.py new file mode 100644 index 00000000000..6d3326c0e86 --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_countable_for_hud.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class nc_sa_countable_for_hud(Variable): + value_type = float + entity = Person + label = "North Carolina Special Assistance countable for HUD" + definition_period = MONTH + unit = USD + defined_for = StateCode.NC + reference = ( + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=47", + # 24 CFR 5.609(b)(12)(ii) + "https://www.law.cornell.edu/cfr/text/24/5.609", + ) + + def formula(person, period, parameters): + category = person("nc_sa_care_setting", period) + c = category.possible_values + excluded = (category == c.IN_HOME) | (category == c.IN_HOME_ENHANCED) + return person("nc_sa", period) * ~excluded diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_countable_income.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_countable_income.py new file mode 100644 index 00000000000..de6a23a93a7 --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_countable_income.py @@ -0,0 +1,55 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.income._apply_ssi_exclusions import ( + _apply_ssi_exclusions, +) + + +class nc_sa_countable_income(Variable): + value_type = float + entity = Person + label = "North Carolina SA countable income" + definition_period = MONTH + unit = USD + defined_for = StateCode.NC + # PDF pages 185-196, 204 + reference = "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=185" + + def formula(person, period, parameters): + # SA is always a one-person budget: no spousal or parental deeming. + # SA-3210 IV prints the $20, $65 and one-half exclusions as SA's own + # rules; they match SSI's, so the SSI exclusion helper applies them. + earned = max_( + person("ssi_earned_income", period) + - person("ssi_blind_or_disabled_working_student_exclusion", period), + 0, + ) + unearned = max_(person("ssi_unearned_income", period), 0) + other_income = ( + _apply_ssi_exclusions( + earned * MONTHS_IN_YEAR, unearned * MONTHS_IN_YEAR, parameters, period + ) + / MONTHS_IN_YEAR + ) + federal = person("ssi", period) + setting = person("nc_sa_care_setting", period) + settings = setting.possible_values + facility = (setting == settings.ADULT_CARE_HOME) | ( + setting == settings.SPECIAL_CARE_UNIT + ) + # Ongoing facility budgets assume the appropriate full federal rate + # while SSA restores a prior institutional or household reduction. + # SSA couple computations remain an express exception to this rule + # (SA-3210 V.D.1.e). A one-third-reduced SSI may be budgeted for at + # most two months after admission (SA-3210 V.B.1.b); those first two + # months are not modeled, so every facility month is an ongoing month. + # The joint-claim test follows the marital unit: spouses who no longer + # live together belong in separate marital units (see + # nc_sa_care_setting), which also gives each the individual SSI amount. + individual_claim = ~person("ssi_claim_is_joint", period.this_year) + individual_fbr = parameters(period).gov.ssa.ssi.amount.individual + federal = where( + facility & individual_claim, + max_(federal, max_(individual_fbr - other_income, 0)), + federal, + ) + return other_income + federal diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_eligible.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_eligible.py new file mode 100644 index 00000000000..30db42526e9 --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_eligible.py @@ -0,0 +1,84 @@ +from policyengine_us.model_api import * + + +class nc_sa_eligible(Variable): + value_type = bool + entity = Person + label = "North Carolina Special Assistance eligibility" + definition_period = MONTH + defined_for = StateCode.NC + reference = ( + "https://www.ncleg.gov/EnactedLegislation/Statutes/PDF/BySection/Chapter_108A/GS_108A-41.pdf#page=1", + # PDF pages 6-7, 40-41, 61, 190-191, 207, 209 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=6", + # PDF pages 14, 18, 41, 48 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=14", + # 10A NCAC 71P .0603 + "http://reports.oah.state.nc.us/ncac/title%2010a%20-%20health%20and%20human%20services/chapter%2071%20-%20adult%20and%20family%20support/subchapter%20p/subchapter%20p%20rules.pdf#page=11", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.nc.ncdhhs.sa + setting = person("nc_sa_care_setting", period) + settings = setting.possible_values + age = person("age", period.this_year) + in_home = (setting == settings.IN_HOME) | (setting == settings.IN_HOME_ENHANCED) + adult = age >= p.minimum_adult_age + age_eligible = adult | (person("is_blind", period.this_year) & ~in_home) + receives_ssi = (person("ssi", period) > 0) | person("receives_ssi", period) + # "To be eligible for SA, an individual must be eligible for SSI, or + # ineligible for SSI solely due to being over income for SSI" (SA-3100 + # I, II.A.6). An applicant whose income would qualify for SSI must apply + # (SA-3100 I; 10A NCAC 71P .0603(3)), and an SSI denial on other grounds + # such as resources also denies SA (SA-3110 V.K). Income here is SSI + # countable income, including deemed spousal income, so an applicant + # denied SSI for spousal income qualifies (SA-5400 V). + over_income_for_ssi = person("ssi_amount_if_eligible", period) <= person( + "ssi_countable_income", period + ) + # An SSI recipient automatically meets the categorical, financial and + # resource requirements (SA-3100 II.B; SA-3200 I.A). An applicant over + # income for SSI must meet SSI's other requirements "except for income" + # (SA-3100 II.C), but SA tests only the applicant's own resources: "The + # budget unit is always one" (SA-3200 I), so SSI's couple and spousal + # resource rules do not apply. SA-3200 I and SA-3210 IV print the $2,000 + # limit and the $20 and $65 exclusions as SA's own figures; they equal + # SSI's, so the federal parameters are used and an SSI reform carries + # over to SA. + aged_blind_disabled = person("is_ssi_aged_blind_disabled", period.this_year) + immigration_status = person("immigration_status", period.this_year) + citizen = immigration_status == immigration_status.possible_values.CITIZEN + immigration_eligible = citizen | person( + "is_ssi_qualified_noncitizen", period.this_year + ) + resource_limit = parameters( + period + ).gov.ssa.ssi.eligibility.resources.limit.individual + resources = person("ssi_countable_resources", period.this_year) + non_ssi_eligible = ( + over_income_for_ssi + & aged_blind_disabled + & immigration_eligible + & (resources <= resource_limit) + ) + # "If an individual's SA payment when rounded to the nearest lower + # whole dollar is $0.00, the individual is not eligible" (SA-3220 + # III.C). Read with III.A.4's half-up rounding, this yields the + # published cutoffs of $1,466.51 and $1,861.51 (II.E) and applies at a + # lower contracted rate (II.A). The monthly income test still applies + # when the first payment is prorated without subtracting income (IV.A, + # IV.D). + # NOTE: G.S. 108A-41(b)(2) caps countable income at the rate plus the + # personal needs allowance ("shall not exceed"), which would also admit + # countable income from $0.49 below that sum up to the sum itself, + # measured at the published rate. The two readings differ only in a + # prorated first month, where income is not deducted. The model follows + # the manual. + income_eligible = person("nc_sa_full_month_amount", period) >= 1 + return ( + (setting != settings.NONE) + & age_eligible + & (receives_ssi | non_ssi_eligible) + & income_eligible + & ~person("is_incarcerated", period) + ) diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_facility_rate.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_facility_rate.py new file mode 100644 index 00000000000..6eca6cccbbc --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_facility_rate.py @@ -0,0 +1,16 @@ +from policyengine_us.model_api import * + + +class nc_sa_facility_rate(Variable): + value_type = float + entity = Person + label = "North Carolina SA lower contracted monthly facility rate" + definition_period = MONTH + unit = USD + defined_for = StateCode.NC + default_value = 0 + documentation = "The monthly rate a facility charges a Special Assistance resident when it contracts for less than the published rate. Leave at 0 to use the published rate. In-home payments always use the published rate." + reference = ( + # PDF pages 204-206 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=204", + ) diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_full_month_amount.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_full_month_amount.py new file mode 100644 index 00000000000..cd99abcd671 --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_full_month_amount.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class nc_sa_full_month_amount(Variable): + value_type = float + entity = Person + label = "North Carolina SA full-month amount" + definition_period = MONTH + unit = USD + defined_for = StateCode.NC + reference = ( + # PDF pages 207, 209 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=207", + # PDF pages 41-42 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=41", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.nc.ncdhhs.sa + maintenance = person("nc_sa_rate", period) + p.personal_needs_allowance + income = person("nc_sa_countable_income", period) + # The maintenance amount less TCMI, rounded to the nearest dollar with + # $0.50 rounding up (SA-3220 III.A). Work in whole cents so that + # annual-to-month arithmetic cannot move a value across the half dollar. + maintenance_cents = np.floor(maintenance.astype(np.float64) * 100 + 0.5) + income_cents = np.floor(income.astype(np.float64) * 100 + 0.5) + return max_(np.floor((maintenance_cents - income_cents) / 100 + 0.5), 0) diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_partial_month_days.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_partial_month_days.py new file mode 100644 index 00000000000..e4e6dce176b --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_partial_month_days.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class nc_sa_partial_month_days(Variable): + value_type = int + entity = Person + label = "North Carolina SA eligible days in a partial first month" + definition_period = MONTH + defined_for = StateCode.NC + default_value = 0 + documentation = "For a first month in which eligibility begins after the first day, the days from the first eligible day through the end of the month. Leave at 0 for a full month of eligibility. This does not implement a discharge-month settlement." + reference = ( + # PDF pages 209-210 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=209", + # PDF pages 42-43 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=42", + ) + + def formula(person, period, parameters): + # A formula stops a one-month input from carrying into later months. + return 0 diff --git a/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_rate.py b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_rate.py new file mode 100644 index 00000000000..8312c3b4471 --- /dev/null +++ b/policyengine_us/variables/gov/states/nc/ncdhhs/sa/nc_sa_rate.py @@ -0,0 +1,32 @@ +from policyengine_us.model_api import * + + +class nc_sa_rate(Variable): + value_type = float + entity = Person + label = "North Carolina SA monthly rate" + definition_period = MONTH + unit = USD + defined_for = StateCode.NC + reference = ( + # PDF pages 204-205 + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-Manual-Rev-June-2026.pdf#page=204", + "https://policies.ncdhhs.gov/wp-content/uploads/Special-Assistance-In-Home-Program-Manual-Rev-June-2026.pdf#page=40", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.nc.ncdhhs.sa.rate + setting = person("nc_sa_care_setting", period) + settings = setting.possible_values + enhanced = (setting == settings.SPECIAL_CARE_UNIT) | ( + setting == settings.IN_HOME_ENHANCED + ) + published_rate = where(enhanced, p.enhanced, p.basic) + facility = (setting == settings.ADULT_CARE_HOME) | ( + setting == settings.SPECIAL_CARE_UNIT + ) + # A facility may charge an SA resident less than the published rate; + # the actual rate is then used in the budget (SA-3220 II.A). + contracted_rate = person("nc_sa_facility_rate", period) + lower_rate = facility & (contracted_rate > 0) + return where(lower_rate, min_(contracted_rate, published_rate), published_rate) 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 57f160d6ebe..02f7ed03df5 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 @@ -25,6 +25,7 @@ def formula(spm_unit, period, parameters): "nj_ssp", # New Jersey benefits "pa_ssp", # Pennsylvania benefits "wy_ssp", # Wyoming benefits + "nc_sa", # North Carolina benefits "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits