diff --git a/changelog.d/pa-ssp-2026.added.md b/changelog.d/pa-ssp-2026.added.md new file mode 100644 index 00000000000..422e132f7fe --- /dev/null +++ b/changelog.d/pa-ssp-2026.added.md @@ -0,0 +1 @@ +Add Pennsylvania optional state SSI supplements and institutional payments, verified for 2026, and count half of the supplement in Pennsylvania Property Tax/Rent Rebate income. diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index 4aa598b2d20..efec9b3ce44 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 + # Pennsylvania benefits + - pa_ssp # South Carolina benefits - sc_ssi_state_supplement # Texas benefits @@ -163,6 +165,8 @@ values: - nj_ssp # New Mexico benefits - nm_ssi_state_supplement + # Pennsylvania benefits + - pa_ssp # South Carolina benefits - sc_ssi_state_supplement # Texas benefits @@ -267,6 +271,8 @@ values: - nj_ssp # New Mexico benefits - nm_ssi_state_supplement + # Pennsylvania benefits + - pa_ssp # South Carolina benefits - sc_ssi_state_supplement # Texas benefits @@ -372,6 +378,8 @@ values: - nj_ssp # New Mexico benefits - nm_ssi_state_supplement + # Pennsylvania benefits + - pa_ssp # South Carolina benefits - sc_ssi_state_supplement # Texas 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 987c76494ce..30646eea1e9 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -20,6 +20,7 @@ values: - social_security - ssi - nj_ssp + - pa_ssp - general_assistance - total_unemployment_compensation - child_support_received diff --git a/policyengine_us/parameters/gov/states/pa/dhs/ssp/amount/couple.yaml b/policyengine_us/parameters/gov/states/pa/dhs/ssp/amount/couple.yaml new file mode 100644 index 00000000000..e887b92a645 --- /dev/null +++ b/policyengine_us/parameters/gov/states/pa/dhs/ssp/amount/couple.yaml @@ -0,0 +1,43 @@ +description: Pennsylvania provides these amounts as the monthly couple payment under the State Supplementary Payment program. + +metadata: + unit: currency-USD + period: month + label: Pennsylvania SSP couple amount + breakdown: + - pa_ssp_living_arrangement + reference: + - title: 55 Pa. Code § 299.37, Optional SSP levels + href: https://www.pacodeandbulletin.gov/secure/pacode/data/055/chapter299/s299.37.html + - title: POMS SI 01415.058 K.2.b, Couple payment levels for Pennsylvania (January 2026) + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#k2b + - title: Pennsylvania Medical Assistance Eligibility Handbook 387 Appendix A, SSI Payment Levels (January 1, 2026) + href: http://services.dpw.state.pa.us/oimpolicymanuals/ma/387_SSI/387_Appendix_A.htm + - title: Pennsylvania Long-Term Care Handbook 450.243, SSI Benefits + href: http://services.dpw.state.pa.us/oimpolicymanuals/ltc/450_Income/450_2_Countable_Income.htm#450.243_SSI_Benefits + +INDEPENDENT: + 2026-01-01: 33.3 + +HOUSEHOLD_OF_ANOTHER: + 2026-01-01: 38.44 + +# 55 Pa. Code § 299.37 still prints the pre-increase care home couple levels +# ($947.40 domiciliary, $957.40 personal care); POMS K.2.b and Handbook 387 +# Appendix A give the 2026 levels. +DOMICILIARY_CARE: + 2026-01-01: 1_347.4 + +# SSA pays this couple rate only in the month the couple moves into the +# personal care home (POMS SI 01415.058 K.2.b NOTE); from the next month the +# spouses are individual recipients. +PERSONAL_CARE: + 2026-01-01: 1_357.4 + +# Unused: pa_ssp pays the per-person Supplement for Personal Needs from +# individual.yaml, so this key only completes the breakdown. +MEDICAID_INSTITUTION: + 2026-01-01: 0 + +NONE: + 2026-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/pa/dhs/ssp/amount/individual.yaml b/policyengine_us/parameters/gov/states/pa/dhs/ssp/amount/individual.yaml new file mode 100644 index 00000000000..57bbb078a99 --- /dev/null +++ b/policyengine_us/parameters/gov/states/pa/dhs/ssp/amount/individual.yaml @@ -0,0 +1,41 @@ +description: Pennsylvania provides these amounts as the monthly individual payment under the State Supplementary Payment program. + +metadata: + unit: currency-USD + period: month + label: Pennsylvania SSP individual amount + breakdown: + - pa_ssp_living_arrangement + reference: + - title: 55 Pa. Code § 299.37, Optional SSP levels + href: https://www.pacodeandbulletin.gov/secure/pacode/data/055/chapter299/s299.37.html + - title: POMS SI 01415.058 K.2.a, Recipient payment levels for Pennsylvania (January 2026) + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#k2a + - title: Pennsylvania Medical Assistance Eligibility Handbook 387 Appendix A, SSI Payment Levels (January 1, 2026) + href: http://services.dpw.state.pa.us/oimpolicymanuals/ma/387_SSI/387_Appendix_A.htm + - title: Pennsylvania Long-Term Care Handbook 450.243, SSI Benefits + href: http://services.dpw.state.pa.us/oimpolicymanuals/ltc/450_Income/450_2_Countable_Income.htm#450.243_SSI_Benefits + +INDEPENDENT: + 2026-01-01: 22.1 + +HOUSEHOLD_OF_ANOTHER: + 2026-01-01: 25.53 + +# 55 Pa. Code § 299.37 still prints the pre-increase care home levels ($434.30 +# domiciliary, $439.30 personal care); POMS K.2.a and Handbook 387 Appendix A +# give the 2026 levels. +DOMICILIARY_CARE: + 2026-01-01: 634.3 + +PERSONAL_CARE: + 2026-01-01: 639.3 + +# LTC Handbook 450.243 sets the $22.10 Supplement for Personal Needs; Handbook 387 +# Appendix A's 2026 note still prints $15.00, but its $52.10 total is +# $30 + $22.10. +MEDICAID_INSTITUTION: + 2026-01-01: 22.1 + +NONE: + 2026-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/pa/dhs/ssp/care_age_threshold.yaml b/policyengine_us/parameters/gov/states/pa/dhs/ssp/care_age_threshold.yaml new file mode 100644 index 00000000000..53c9bc3c940 --- /dev/null +++ b/policyengine_us/parameters/gov/states/pa/dhs/ssp/care_age_threshold.yaml @@ -0,0 +1,11 @@ +description: Pennsylvania sets this age as the minimum for the domiciliary care and personal care home supplements under the State Supplementary Payment program. +values: + 2026-01-01: 18 + +metadata: + unit: year + period: year + label: Pennsylvania SSP care minimum age + reference: + - title: POMS SI 01415.058 K.1, Domiciliary and personal care definitions + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#k1 diff --git a/policyengine_us/parameters/gov/states/pa/tax/property/property_tax_or_rent_rebate/benefit_income_rate.yaml b/policyengine_us/parameters/gov/states/pa/tax/property/property_tax_or_rent_rebate/benefit_income_rate.yaml index 0a9b482f5c7..6ccaa1fc0cd 100644 --- a/policyengine_us/parameters/gov/states/pa/tax/property/property_tax_or_rent_rebate/benefit_income_rate.yaml +++ b/policyengine_us/parameters/gov/states/pa/tax/property/property_tax_or_rent_rebate/benefit_income_rate.yaml @@ -1,4 +1,4 @@ -description: Pennsylvania counts this share of Social Security, SSI, and Railroad Retirement Tier 1 benefits under the Property Tax/Rent Rebate program. +description: Pennsylvania counts this share of Social Security, Supplemental Security Income, State Supplementary Payment, and Railroad Retirement Tier 1 benefits under the Property Tax/Rent Rebate program. values: 2025-01-01: 0.5 metadata: @@ -6,5 +6,5 @@ metadata: period: year label: Pennsylvania Property Tax/Rent Rebate benefit income rate reference: - - title: 2025 PA-1000 Pennsylvania Property Tax or Rent Rebate Program Instruction Booklet, Lines 4 and 5 - href: https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/ptrr/documents/2025_pa-1000_inst.pdf#page=7 + - title: "2025 PA-1000 Pennsylvania Property Tax or Rent Rebate Program Instruction Booklet, State Supplementary Payment recipients and Lines 4 and 5 #page 3,7" + href: https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/ptrr/documents/2025_pa-1000_inst.pdf#page=3 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 ea209473011..859029639b8 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -48,6 +48,7 @@ values: - ne_aabd - nj_ssp - nm_ssi_state_supplement + - pa_ssp - sc_ssi_state_supplement - tx_ssi_state_supplement - wa_ssp diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 85d9c243eac..f626dd6ccc7 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1104,6 +1104,19 @@ programs: Models 2026 New Jersey optional supplement rates by living arrangement, including the ineligible-spouse variation. Mandatory grandfathered supplementation is not modeled. + - state: PA + status: partial + name: Pennsylvania SSP + full_name: Pennsylvania State Supplementary Payment + variable: pa_ssp + parameter_prefix: gov.states.pa.dhs.ssp + verified_years: "2026" + notes: >- + Models 2026 optional supplements for independent living, the + household of another and certified domiciliary and personal care + homes, plus the institutional Supplement for Personal Needs. + Mandatory grandfathered and essential-person supplements and + ancillary facility subsidies are not modeled. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/pa_property_tax_or_rent_rebate_in_aggregate.yaml b/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/pa_property_tax_or_rent_rebate_in_aggregate.yaml index ee08b6d338f..50c9537ff41 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/pa_property_tax_or_rent_rebate_in_aggregate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/household/state_property_tax_credits/pa_property_tax_or_rent_rebate_in_aggregate.yaml @@ -10,6 +10,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 real_estate_taxes: 2_000 tax_units: tax_unit: diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/integration.yaml new file mode 100644 index 00000000000..b132dd8ae2f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/integration.yaml @@ -0,0 +1,195 @@ +- name: Case 1, independent couple. + 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: PA + output: + pa_ssp: [16.65, 16.65] + +- name: Case 2, household of another couple. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 65 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: PA + output: + pa_ssp: [19.22, 19.22] + +- name: Case 3, annual benefits and SNAP income. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + output: + pa_ssp: 265.2 + household_state_benefits: 265.2 + snap_unearned_income: 12_193.2 + hud_unearned_income: 12_193.2 + +- name: Case 4, domiciliary care couple keeps the couple rate. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + pa_ssp_care_home: DOMICILIARY_CARE + person2: + age: 65 + pa_ssp_care_home: DOMICILIARY_CARE + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: PA + output: + # Both spouses are aged and live in their own household for SSI. + ssi_couple_computation_applies: [true, true] + # Couple FBR 1,491 / 2 = 745.50 each. + ssi_amount_if_eligible: [745.5, 745.5] + # No income: 745.50 - 0 = 745.50 each. + ssi: [745.5, 745.5] + # Domiciliary care couple rate 1,347.40 / 2 = 673.70 each. + pa_ssp: [673.7, 673.7] + +- name: Case 5, personal care home couple after the move month as separate claims. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + pa_ssp_care_home: PERSONAL_CARE + ssi_claim_is_joint: false + person2: + age: 65 + pa_ssp_care_home: PERSONAL_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: PA + output: + # From the month after the move both spouses are individual recipients + # (POMS SI 01415.058 K.2.b NOTE), entered as separate claims. + ssi_couple_computation_applies: [false, false] + # Individual FBR 994 each. + ssi_amount_if_eligible: [994, 994] + # No income: 994 - 0 = 994 each. + ssi: [994, 994] + # Individual personal care home rate 639.30 each. + pa_ssp: [639.3, 639.3] + +- name: Case 6, mixed independent and personal care home couple in the move month. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + person2: + age: 65 + pa_ssp_care_home: PERSONAL_CARE + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: PA + output: + # A personal care home is not a medical facility, so the couple stays joint. + ssi_couple_computation_applies: [true, true] + # Couple FBR 1,491 / 2 = 745.50 each with no income. + ssi: [745.5, 745.5] + # Couple total 33.30 / 2 + 1,357.40 / 2 = 16.65 + 678.70 = 695.35; the + # shared helper gives each spouse 695.35 / 2 = 347.675. The independent + # spouse's state-administered amount stays 347.675; SSA rounds the + # personal care spouse's amount up to 347.68. POMS PHI01415.010 Chart 35 + # note 2 splits the same total as 16.65 and 678.70 (documented limitation). + pa_ssp: [347.675, 347.68] + +- name: Case 7, aged person with an ineligible working spouse. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 67 + social_security_retirement: 8_400 + person2: + age: 60 + # Pennsylvania minimum wage, 7.25 per hour x 40 hours x 52 weeks. + employment_income: 15_080 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: PA + output: + # Spouse earnings 15,080 exceed (1,491 - 994) x 12 = 5,964, so deeming + # applies to person1; person2 is not aged, blind or disabled. + is_ssi_spousal_deeming_applies: [true, false] + # Combined countable (700 - 20) + (1,256.67 - 65) / 2 = 680 + 595.83 + # = 1,275.83, less own countable 680 = 595.83 deemed. + ssi_income_deemed_from_ineligible_spouse: [595.83, 0] + # Own 680 + deemed 595.83 = 1,275.83. + ssi_countable_income: [1_275.83, 0] + # Couple FBR 1,491 - 1,275.83 = 215.17, below the 994 individual cap. + ssi: [215.17, 0] + # Own-income payment: 680 is below 994, so 22.10. Deemed payment: 1,275.83 + # is below 1,491, so the 33.30 couple rate. The lower amount, 22.10, applies. + pa_ssp: [22.1, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/pa_ssp.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/pa_ssp.yaml new file mode 100644 index 00000000000..ed4a46bbc3d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/pa_ssp.yaml @@ -0,0 +1,276 @@ +# 55 Pa. Code Chapter 299; POMS SI 01415.058. +- name: Case 1, independent living. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + output: + pa_ssp: 22.1 + +- name: Case 2, living in household of another. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + # One-third-reduced FBR: 994 * 2 / 3 = 662.67. + ssi: 662.67 + pa_ssp: 25.53 + +- name: Case 3, certified domiciliary care. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + pa_ssp_care_home: DOMICILIARY_CARE + output: + pa_ssp: 634.3 + +- name: Case 4, certified personal care home. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + pa_ssp_care_home: PERSONAL_CARE + output: + pa_ssp: 639.3 + +- name: Case 5, care category requires adulthood. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 17 + meets_ssi_disability_criteria: true + pa_ssp_care_home: PERSONAL_CARE + output: + pa_ssp: 0 + +- name: Case 6, medical institution. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ssi: 30 + pa_ssp: 22.1 + +- name: Case 7, SSI exhausted but state payment remains. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + social_security_retirement: 12_360 + output: + # 12,360 / 12 = 1,030; countable 1,030 - 20 = 1,010 exceeds the 994 FBR + # by 16, so 22.10 - 16 = 6.10. + pa_ssp: 6.1 + +- name: Case 8, state administered payment below a dollar. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + social_security_retirement: 12_432 + output: + # 12,432 / 12 = 1,036; countable 1,036 - 20 = 1,016 exceeds the 994 FBR + # by 22, so 22.10 - 22 = 0.10. The state-administered payment gets no $1 + # federal minimum. + pa_ssp: 0.1 + +- name: Case 9, income above the combined income cutoff. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + social_security_retirement: 12_444 + output: + # 12,444 / 12 = 1,037; countable 1,037 - 20 = 1,017 exceeds the 994 FBR + # by 23, more than the 22.10 supplement, so 0. + pa_ssp: 0 + +- name: Case 10, excess resources. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + ssi_countable_resources: 2_001 + output: + pa_ssp: 0 + +- name: Case 11, not aged blind or disabled. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 30 + output: + pa_ssp: 0 + +- name: Case 12, nonresident. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: OH + age: 65 + output: + pa_ssp: 0 + +- name: Case 13, declines required SSI application. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + takes_up_ssi_if_eligible: false + output: + pa_ssp: 0 + +- name: Case 14, institutional payment requires SSI receipt. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + social_security_retirement: 600 + output: + pa_ssp: 0 + +- name: Case 15, federally administered care payment rises to the one dollar minimum. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + pa_ssp_care_home: PERSONAL_CARE + social_security_retirement: 19_836 + output: + # 19,836 / 12 = 1,653; countable 1,653 - 20 = 1,633 exceeds the 994 FBR. + ssi: 0 + # Excess 1,633 - 994 = 639, so 639.30 - 639 = 0.30; SSA administers the + # personal care home rate and pays the $1 federal minimum. + pa_ssp: 1 + +- name: Case 16, earned income exclusions keep the full independent payment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + # Pennsylvania minimum wage, 7.25 per hour x 40 hours x 52 weeks. + employment_income: 15_080 + output: + # 15,080 / 12 = 1,256.67; countable (1,256.67 - 20 - 65) / 2 = 585.83; + # 994 - 585.83 = 408.17. + ssi: 408.17 + # Countable 585.83 is below the 994 FBR, so no reduction: 22.10. + pa_ssp: 22.1 + +- name: Case 17, reported SSI receipt qualifies an institution resident without modeled SSI. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + takes_up_ssi_if_eligible: false + receives_ssi: true + output: + # No modeled take-up, so the modeled federal payment is 0. + ssi: 0 + # Reported receipt meets the SSI gate; the state-issued Supplement for + # Personal Needs is the individual MEDICAID_INSTITUTION rate, 22.10. + pa_ssp: 22.1 + +- name: Case 18, disabled child living with a working parent gets the independent supplement. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + # Full-time work at the $7.25 Pennsylvania minimum wage. + employment_income: 15_080 + own_children_in_household: 1 + person2: + age: 10 + meets_ssi_disability_criteria: true + marital_units: + parent: + members: [person1] + child: + members: [person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: PA + output: + # SSA 2011: "Blind and disabled children are eligible for optional + # supplementation." The parent's (1,256.67 - 85) / 2 = 585.83 is below the + # 994 parental allocation, so nothing is deemed. + ssi_unearned_income_deemed_from_ineligible_parent: [0, 0] + ssi: [0, 994] + pa_ssp: [0, 22.1] + +- name: Case 19, private medical facility where Medicaid pays half or less counts as independent. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: PA + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: false + output: + ssi: 994 + pa_ssp: 22.1 + +- name: Case 20, a care home input for one person does not reset another person's arrangement. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + pa_ssp_care_home: PERSONAL_CARE + person2: + age: 70 + marital_units: + unit1: + members: [person1] + unit2: + members: [person2] + tax_units: + unit1: + members: [person1] + unit2: + members: [person2] + households: + home1: + members: [person1] + state_code: PA + home2: + members: [person2] + state_code: PA + output: + pa_ssp_living_arrangement: [PERSONAL_CARE, INDEPENDENT] + pa_ssp: [639.3, 22.1] diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/pa_ssp_living_arrangement.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/pa_ssp_living_arrangement.yaml new file mode 100644 index 00000000000..9c566d8ea6e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/dhs/ssp/pa_ssp_living_arrangement.yaml @@ -0,0 +1,122 @@ +- name: Case 1, own household is independent living. + period: 2026-01 + input: + state_code: PA + age: 65 + output: + ssi_federal_living_arrangement: OWN_HOUSEHOLD + pa_ssp_living_arrangement: INDEPENDENT + +- name: Case 2, household of another. + period: 2026-01 + input: + state_code: PA + age: 65 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + ssi_federal_living_arrangement: ANOTHER_PERSONS_HOUSEHOLD + pa_ssp_living_arrangement: HOUSEHOLD_OF_ANOTHER + +- name: Case 3, Medicaid pays more than half of facility care. + period: 2026-01 + input: + state_code: PA + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + ssi_federal_living_arrangement: MEDICAL_TREATMENT_FACILITY + pa_ssp_living_arrangement: MEDICAID_INSTITUTION + +- name: Case 4, private medical facility counts as independent living. + period: 2026-01 + input: + state_code: PA + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: false + output: + # SSA 2011: "Living alone" includes recipients in private medical + # facilities where Medicaid pays no more than half of the cost of care. + ssi_federal_living_arrangement: OWN_HOUSEHOLD + pa_ssp_living_arrangement: INDEPENDENT + +- name: Case 5, disabled child living with a parent counts as independent living. + period: 2026-01 + input: + people: + person1: + age: 40 + own_children_in_household: 1 + person2: + age: 10 + meets_ssi_disability_criteria: true + marital_units: + parent: + members: [person1] + child: + members: [person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: PA + output: + ssi_federal_living_arrangement: [OWN_HOUSEHOLD, CHILD_IN_PARENTAL_HOUSEHOLD] + pa_ssp_living_arrangement: [INDEPENDENT, INDEPENDENT] + +- name: Case 6, certified domiciliary care home input. + period: 2026-01 + input: + state_code: PA + age: 65 + pa_ssp_care_home: DOMICILIARY_CARE + output: + pa_ssp_living_arrangement: DOMICILIARY_CARE + +- name: Case 7, Medicaid facility takes precedence over a care home input. + period: 2026-01 + input: + state_code: PA + age: 65 + pa_ssp_care_home: PERSONAL_CARE + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + # 55 Pa. Code § 299.21(b)(3); POMS SI 01415.058 K.1 care homes are + # non-medical. + pa_ssp_living_arrangement: MEDICAID_INSTITUTION + +- name: Case 8, a care home input takes precedence over the household of another. + period: 2026-01 + input: + state_code: PA + age: 65 + pa_ssp_care_home: PERSONAL_CARE + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + pa_ssp_living_arrangement: PERSONAL_CARE + +- name: Case 9, certified personal care home input. + period: 2026-01 + input: + state_code: PA + age: 65 + pa_ssp_care_home: PERSONAL_CARE + output: + pa_ssp_living_arrangement: PERSONAL_CARE + +- name: Case 10, nonresident with a care home input has no Pennsylvania arrangement. + period: 2026-01 + input: + state_code: OH + age: 65 + pa_ssp_care_home: PERSONAL_CARE + output: + pa_ssp_living_arrangement: NONE diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate.yaml index e3fa3bfc7e4..971cf0f89d3 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate.yaml @@ -5,6 +5,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 real_estate_taxes: 2_000 tax_units: tax_unit: @@ -24,6 +25,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 real_estate_taxes: 2_000 tax_units: tax_unit: @@ -43,6 +45,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 rent: 9_600 tax_units: tax_unit: @@ -62,6 +65,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 real_estate_taxes: 300 tax_units: tax_unit: @@ -81,6 +85,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 rent: 1_000 tax_units: tax_unit: @@ -100,6 +105,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 social_security: 40_000 real_estate_taxes: 2_000 tax_units: @@ -111,3 +117,29 @@ state_code: PA output: pa_property_tax_or_rent_rebate: 380 + +- name: Case 7, personal care home resident's half-counted supplement moves the rebate to the second bracket. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 80 + # $800 a month. + social_security_retirement: 9_600 + rent: 6_000 + pa_ssp_care_home: PERSONAL_CARE + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: PA + output: + # SSI 12 * (994 - (800 - 20)) = 2,568; supplement 12 * 639.30 = 7,671.60. + ssi: 2_568 + pa_ssp: 7_671.6 + # Half of 9,600 + 2,568 + 7,671.60 = 9,919.80, above the 8,551 edge. + pa_property_tax_or_rent_rebate_income: 9_919.8 + pa_property_tax_or_rent_rebate: 770 diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_eligible.yaml index 75047c42746..7a7a97658fb 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_eligible.yaml @@ -5,6 +5,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 real_estate_taxes: 2_000 tax_units: tax_unit: @@ -24,6 +25,7 @@ person1: age: 50 ssi: 0 + pa_ssp: 0 rent: 9_600 tax_units: tax_unit: @@ -44,6 +46,7 @@ person1: age: 18 ssi: 0 + pa_ssp: 0 is_permanently_and_totally_disabled: true rent: 9_600 tax_units: @@ -64,6 +67,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 real_estate_taxes: 2_000 tax_units: tax_unit: @@ -83,6 +87,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 tax_units: tax_unit: members: [person1] @@ -101,6 +106,7 @@ person1: age: 50 ssi: 0 + pa_ssp: 0 is_surviving_spouse: true rent: 9_600 tax_units: @@ -121,6 +127,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 tax_exempt_interest_income: 200 real_estate_taxes: 2_000 tax_units: @@ -141,6 +148,7 @@ person1: age: 18 ssi: 0 + pa_ssp: 0 is_disabled: true rent: 9_600 tax_units: @@ -161,6 +169,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 workers_compensation: 2_000 real_estate_taxes: 2_000 tax_units: diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.yaml index 5e60ce8d7b7..7b8d46fb236 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.yaml @@ -4,9 +4,10 @@ people: person1: age: 65 - # Rebate income counts computed ssi; pin it to zero so each case - # isolates its intended income source. + # Rebate income counts computed ssi and pa_ssp; pin them to zero so + # each case isolates its intended income source. ssi: 0 + pa_ssp: 0 tax_units: tax_unit: members: [person1] @@ -42,6 +43,7 @@ person1: age: 65 ssi: 2_000 + pa_ssp: 0 railroad_benefits: 10_000 tax_units: tax_unit: @@ -60,6 +62,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 tax_exempt_interest_income: 2_000 tax_exempt_pension_income: 3_000 tax_exempt_retirement_distributions: 4_000 @@ -81,6 +84,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 person2: age: 10 social_security: 40_000 @@ -101,6 +105,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 csrs_retirement_pay: 20_000 tax_units: tax_unit: @@ -119,6 +124,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 gambling_winnings: 1_000 alimony_income: 2_000 workers_compensation: 3_000 @@ -141,10 +147,12 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 csrs_retirement_pay: 5_000 person2: age: 65 ssi: 0 + pa_ssp: 0 csrs_retirement_pay: 20_000 tax_units: tax_unit: @@ -164,6 +172,7 @@ person1: age: 65 ssi: 0 + pa_ssp: 0 life_insurance_benefits: 7_000 tax_units: tax_unit: @@ -175,3 +184,23 @@ state_code: PA output: pa_property_tax_or_rent_rebate_income: 12_000 + +- name: Case 10, half of the State Supplementary Payment is counted. + period: 2026 + input: + people: + person1: + age: 80 + ssi: 0 + # The 639.30 personal care home supplement for 12 months. + pa_ssp: 7_671.6 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: PA + output: + # PA-1000 Line 4: one-half of the State Supplementary Payment. + pa_property_tax_or_rent_rebate_income: 3_835.8 diff --git a/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp.py b/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp.py new file mode 100644 index 00000000000..a9cd53730b7 --- /dev/null +++ b/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp.py @@ -0,0 +1,46 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi._ssi_state_supplement import ( + ssi_state_supplement, +) + + +class pa_ssp(Variable): + value_type = float + entity = Person + label = "Pennsylvania State Supplementary Payment" + unit = USD + definition_period = MONTH + defined_for = StateCode.PA + reference = ( + "https://www.pacodeandbulletin.gov/secure/pacode/data/055/chapter299/s299.1.html", + "https://www.pacodeandbulletin.gov/secure/pacode/data/055/chapter299/s299.21.html", + "https://www.pacodeandbulletin.gov/secure/pacode/data/055/chapter299/s299.36.html", + # POMS SI 01415.058 K.1-K.2 + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#k", + "http://services.dpw.state.pa.us/oimpolicymanuals/ma/387_SSI/387_Appendix_A.htm", + "http://services.dpw.state.pa.us/oimpolicymanuals/ltc/450_Income/450_2_Countable_Income.htm#450.243_SSI_Benefits", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.pa.dhs.ssp + arrangement = person("pa_ssp_living_arrangement", period) + arrangements = arrangement.possible_values + care = (arrangement == arrangements.DOMICILIARY_CARE) | ( + arrangement == arrangements.PERSONAL_CARE + ) + # In the household of another, income reduces the supplement only above + # the one-third-reduced FBR that the helper uses (662.67 in 2026; MA + # Handbook 387 Appendix A: $688.20 = 662.67 + 25.53). + individual = p.amount.individual[arrangement] + couple = p.amount.couple[arrangement] + payment = ssi_state_supplement( + person, period, parameters, individual, couple, federal_payment_rules=care + ) + age = person("age", period.this_year) + payment = where(care & (age < p.care_age_threshold), 0, payment) + # LTC Handbook 450.243: SSI recipients in a Medicaid facility get the + # state-issued Supplement for Personal Needs, so federal rounding and + # the federal minimum payment do not apply. + medical = arrangement == arrangements.MEDICAID_INSTITUTION + receives_ssi = (person("ssi", period) > 0) | person("receives_ssi", period) + return where(medical, receives_ssi * individual, payment) diff --git a/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp_care_home.py b/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp_care_home.py new file mode 100644 index 00000000000..e83ad278046 --- /dev/null +++ b/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp_care_home.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class PASSPCareHome(Enum): + DOMICILIARY_CARE = "State-certified domiciliary care home" + PERSONAL_CARE = "Licensed personal care home, certified for the supplement" + NONE = "Not in a certified care home" + + +class pa_ssp_care_home(Variable): + value_type = Enum + entity = Person + label = "Pennsylvania SSP certified care home" + definition_period = MONTH + defined_for = StateCode.PA + possible_values = PASSPCareHome + default_value = PASSPCareHome.NONE + reference = ( + "https://www.pacodeandbulletin.gov/secure/pacode/data/055/chapter299/s299.1.html", + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#k1", + ) diff --git a/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp_living_arrangement.py b/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp_living_arrangement.py new file mode 100644 index 00000000000..4e9dda04e73 --- /dev/null +++ b/policyengine_us/variables/gov/states/pa/dhs/ssp/pa_ssp_living_arrangement.py @@ -0,0 +1,69 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.status.ssi_federal_living_arrangement import ( + SSIFederalLivingArrangement, +) + + +class PASSPLivingArrangement(Enum): + INDEPENDENT = "Independent living" + HOUSEHOLD_OF_ANOTHER = "Household of another" + DOMICILIARY_CARE = "State-certified domiciliary care home" + PERSONAL_CARE = "Licensed personal care home, certified for the supplement" + MEDICAID_INSTITUTION = "Medicaid long-term care institution" + NONE = "No supplement" + + +class pa_ssp_living_arrangement(Variable): + value_type = Enum + entity = Person + label = "Pennsylvania SSP living arrangement" + definition_period = MONTH + defined_for = StateCode.PA + possible_values = PASSPLivingArrangement + default_value = PASSPLivingArrangement.NONE + reference = ( + "https://www.pacodeandbulletin.gov/secure/pacode/data/055/chapter299/s299.1.html", + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#k", + ) + documentation = """ + Certified domiciliary and personal care home residence comes from + pa_ssp_care_home and does not change federal SSI claim or income + calculations. SSA applies the personal care home couple rate only in the + month of the move; from the next month both spouses are individual + recipients (POMS SI 01415.058 K.2.b NOTE). For those periods override + ssi_claim_is_joint (a yearly formula variable) to false for both spouses, + which also sets each spouse's federal SSI amount; an input replaces the + formula for everyone in the simulation, so set it to true for any other + joint couple. Certified care home residents are in federal living + arrangement A (POMS SI PHI01415.010 G.3), so do not also set the + household-of-another SSI inputs for them. + Domiciliary care couples keep the couple rate, and in the move month + Pennsylvania pays each spouse of a mixed-arrangement couple half of their + own couple rate (POMS SI PHI01415.010 Appendix I Chart 35 note 2). The + shared state supplement helper instead gives each spouse in a joint + mixed-arrangement couple the average of the two couple rates, with the same + couple total unless income reduces one spouse's half to zero. + """ + + def formula(person, period, parameters): + federal = person("ssi_federal_living_arrangement", period) + care_home = person("pa_ssp_care_home", period) + care_homes = care_home.possible_values + # Title XIX facility residents first (55 Pa. Code § 299.21(b)(3)); care + # homes are non-medical (POMS SI 01415.058 K.1) and in arrangement A + # (POMS SI PHI01415.010 G.3), so they precede the household of another. + return select( + [ + federal == SSIFederalLivingArrangement.MEDICAL_TREATMENT_FACILITY, + care_home == care_homes.DOMICILIARY_CARE, + care_home == care_homes.PERSONAL_CARE, + federal == SSIFederalLivingArrangement.ANOTHER_PERSONS_HOUSEHOLD, + ], + [ + PASSPLivingArrangement.MEDICAID_INSTITUTION, + PASSPLivingArrangement.DOMICILIARY_CARE, + PASSPLivingArrangement.PERSONAL_CARE, + PASSPLivingArrangement.HOUSEHOLD_OF_ANOTHER, + ], + default=PASSPLivingArrangement.INDEPENDENT, + ) diff --git a/policyengine_us/variables/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.py b/policyengine_us/variables/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.py index 1bd76724a54..9776e65f27d 100644 --- a/policyengine_us/variables/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.py +++ b/policyengine_us/variables/gov/states/pa/tax/property/property_tax_or_rent_rebate/pa_property_tax_or_rent_rebate_income.py @@ -8,15 +8,10 @@ class pa_property_tax_or_rent_rebate_income(Variable): unit = USD definition_period = YEAR reference = ( + # PDF pages 3, 7-9 "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/" "formsandpublications/formsforindividuals/ptrr/documents/" - "2025_pa-1000_inst.pdf#page=7", - "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/" - "formsandpublications/formsforindividuals/ptrr/documents/" - "2025_pa-1000_inst.pdf#page=8", - "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/" - "formsandpublications/formsforindividuals/ptrr/documents/" - "2025_pa-1000_inst.pdf#page=9", + "2025_pa-1000_inst.pdf#page=3", ) defined_for = StateCode.PA @@ -35,6 +30,10 @@ def formula(tax_unit, period, parameters): [ "social_security", "ssi", + # pa_ssp includes the Supplement for Personal Needs for + # Medicaid facility residents; the PA-1000 does not say + # whether the Department of Revenue treats it as SSP. + "pa_ssp", "railroad_benefits", ], ) 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 a8eccf27b73..52d604f8842 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 @@ -23,6 +23,7 @@ def formula(spm_unit, period, parameters): "de_ssp", # Delaware benefits "fl_oss", "nj_ssp", # New Jersey benefits + "pa_ssp", # Pennsylvania benefits "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits