From 69aa782fb6edeb4dcabaeadaf3ade0ca729f1310 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 3 Oct 2026 19:25:47 -0400 Subject: [PATCH 1/7] Add Delaware LIHEAP regular heating assistance --- changelog.d/de-liheap-wave2c.added.md | 1 + .../gov/states/de/dhss/liheap/README.md | 65 + .../de/dhss/liheap/eligibility/smi_rate.yaml | 10 + .../liheap/income/earned_income_min_age.yaml | 10 + .../de/dhss/liheap/income/sources/earned.yaml | 21 + .../dhss/liheap/income/sources/unearned.yaml | 28 + .../income/student_income_exclusion_age.yaml | 12 + .../payment/income_band_upper_rates.yaml | 21 + .../liheap/payment/matrix/electricity.yaml | 28 + .../liheap/payment/matrix/natural_gas.yaml | 28 + .../de/dhss/liheap/payment/matrix/oil.yaml | 28 + .../de/dhss/liheap/payment/matrix/other.yaml | 28 + .../dhss/liheap/payment/matrix/propane.yaml | 28 + .../liheap/payment/subsidized_amount.yaml | 10 + .../payment/subsidized_rent_ceiling.yaml | 10 + policyengine_us/programs.yaml | 10 +- .../gov/states/de/dhss/liheap/de_liheap.yaml | 1068 +++++++++++++++++ .../dhss/liheap/de_liheap_household_size.yaml | 183 +++ .../de/dhss/liheap/de_liheap_income_band.yaml | 177 +++ .../eligibility/de_liheap_eligible.yaml | 151 +++ .../eligibility/de_liheap_income_limit.yaml | 29 + .../income/de_liheap_countable_income.yaml | 178 +++ .../de_liheap_countable_income_person.yaml | 528 ++++++++ .../gov/states/de/dhss/liheap/de_liheap.py | 51 + .../dhss/liheap/de_liheap_household_size.py | 15 + .../de/dhss/liheap/de_liheap_income_band.py | 26 + .../liheap/eligibility/de_liheap_eligible.py | 38 + .../eligibility/de_liheap_income_limit.py | 24 + .../income/de_liheap_countable_income.py | 27 + .../de_liheap_countable_income_person.py | 33 + 30 files changed, 2865 insertions(+), 1 deletion(-) create mode 100644 changelog.d/de-liheap-wave2c.added.md create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/README.md create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/smi_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/income/earned_income_min_age.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/income/student_income_exclusion_age.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml create mode 100644 policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py create mode 100644 policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_household_size.py create mode 100644 policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py create mode 100644 policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py create mode 100644 policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py create mode 100644 policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py create mode 100644 policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py diff --git a/changelog.d/de-liheap-wave2c.added.md b/changelog.d/de-liheap-wave2c.added.md new file mode 100644 index 00000000000..e48b897bc93 --- /dev/null +++ b/changelog.d/de-liheap-wave2c.added.md @@ -0,0 +1 @@ +Add Delaware LIHEAP regular heating assistance using the fiscal year 2026 benefit matrix. diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md b/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md new file mode 100644 index 00000000000..1adc106fc5c --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md @@ -0,0 +1,65 @@ +# Delaware regular heating assistance + +The FY2026 benefit matrix and accepted state plan support regular heating-bill +assistance. Crisis, cooling, weatherization, equipment and funding rationing are +outside this implementation. Parameters start on October 1, 2025. Earlier +backfilled results are unverified historical estimates. FY2027 has not been +verified. + +The federal Clearinghouse incorrectly names the Delaware matrix `CO` in its URL. +The document title, Delaware income figures and approval date identify it as the +Delaware FY2026 matrix. All eight income bands and five distinct fuel schedules +are represented; kerosene shares the oil schedule. The matrix already accounts +for statewide fuel costs and energy burden. No additional expense cap is imposed. + +The income limit reuses the requested year's federal SMI amount and household +adjustment factors. Rounding the four-person 60% amount before truncating the +size-adjusted limit reproduces all 12 published limits. Flooring the income +limit times each band's normalized upper rate reproduces all 96 printed income +boundaries. These are reproducible numerical conventions, not express legal +rounding instructions. The source does not resolve applicant income with cents. + +SPMUnit approximates the energy-sharing household. The historical official +manual supplies two detailed rules not restated or superseded in the FY2026 +plan: only qualified members count in size while all members' countable income +is retained; all income of dependent full-time college students under 22 is +excluded. The current plan governs conflicting rules in that older manual, +including the income threshold, nominal SNAP payments and countable cash gifts. + +Annual income flows approximate the application assessment period. Existing net +business income is used without a second expense deduction, and rental income +is assumed nonnegative. The historical manual classifies rental income as +earned. Social Security includes its survivor component; taxable and exempt +pensions are included through `pension_income`. Pension and military survivor +classifications are not added on top. The separate non-Social-Security +`survivor_benefits` input is counted. Monthly SSI and Delaware TANF are aggregated +to annual amounts; TANF is counted once for the household. + +`spm_unit_paycheck_withholdings` plus Wilmington earned income tax approximates +federal, state and city payroll withholding. This estimates annual taxes, rather +than observing actual withholding. The shared helper already includes Delaware +employee paid-leave contributions. It can also include tax attributable to +excluded child or student income; adjusted income is bounded below by zero. +The household TANF amount does not identify a student's share. Medicare and +pension health deductions are deferred because actual withheld amounts are not +represented. + +Contract earnings use existing employment or business inputs; royalties are +represented only to the extent included in rental income. Work-study or other +excluded payments embedded in reported wages cannot be distinguished. The model +does not infer boarder status, institutional residence, temporary absence, +optional exclusion of students attending out of state, legal-separation proof, +duplicate applications, application timing or funding priority. These missing +facts are limitations, not automatic eligibility exclusions. + +Heat included in full unsubsidized rent uses the electric schedule. Subsidized +heat-in-rent is ineligible. Subsidized households paying separately for heat +receive the flat amount when actual tenant rent is within the published ceiling. +Separately paid solar heating has no verified matrix classification; neither it +nor an unspecified separately paid fuel is assigned an invented benefit. + +## Sources + +- [FY2026 accepted state plan](https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5), PDF pages 5-7, 9-10 and 43. +- [FY2026 Delaware benefit matrix](https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1), PDF page 1, approved April 28, 2025. +- [Historical official DEAP manual](https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35), sections 418, 424, 426 and 429.2; PDF pages 35-36 and 40-42. diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/smi_rate.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/smi_rate.yaml new file mode 100644 index 00000000000..9bd9fa8c3a9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/smi_rate.yaml @@ -0,0 +1,10 @@ +description: Delaware limits adjusted income to this share of state median income under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 0.6 +metadata: + unit: /1 + period: year + label: Delaware LIHEAP state median income limit rate + reference: + - title: Delaware FY2026 LIHEAP State Plan, section 2.1, page 9 + href: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/earned_income_min_age.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/earned_income_min_age.yaml new file mode 100644 index 00000000000..655d94fbd81 --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/earned_income_min_age.yaml @@ -0,0 +1,10 @@ +description: Delaware counts earned income beginning at this age under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 18 +metadata: + unit: year + period: year + label: Delaware LIHEAP minimum age for counting earned income + reference: + - title: Delaware FY2026 LIHEAP State Plan, section 1.9, page 6 + href: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=6 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml new file mode 100644 index 00000000000..9c78f96ec64 --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml @@ -0,0 +1,21 @@ +description: Delaware counts these earned income sources for adults under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + - employment_income + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - partnership_s_corp_income + # Historical manual section 418 treats property rental as earned income. + # Existing net business income is used without another expense deduction. + - rental_income + - farm_rent_income +metadata: + unit: list + period: year + label: Delaware LIHEAP earned income sources + reference: + - title: Delaware FY2026 LIHEAP State Plan, sections 1.8-1.9, pages 5-7 + href: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 + - title: Historical Delaware Energy Assistance Program Manual, section 418, pages 35-36 + href: https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml new file mode 100644 index 00000000000..91ef2b203c8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml @@ -0,0 +1,28 @@ +description: Delaware counts these individual unearned income sources under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + - unemployment_compensation + # The Social Security aggregate includes its survivor-benefit component. + - social_security + - ssi + # Taxable/exempt pension components are already in pension_income. + # pension_survivors and military pensions are classifications, not additions. + - pension_income + - survivor_benefits + - general_assistance + - alimony_income + - child_support_received + - interest_income + - dividend_income + - veterans_benefits + - workers_compensation + # State TANF is added once at SPMUnit level, not once per person. + # Royalties are represented only to the extent included in rental_income. + # Actual Medicare/pension health withholding deductions are deferred. +metadata: + unit: list + period: year + label: Delaware LIHEAP unearned income sources + reference: + - title: Delaware FY2026 LIHEAP State Plan, section 1.9, pages 6-7 + href: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=6 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/student_income_exclusion_age.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/student_income_exclusion_age.yaml new file mode 100644 index 00000000000..a5bccb2d5a7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/student_income_exclusion_age.yaml @@ -0,0 +1,12 @@ +description: Delaware excludes income of dependent full-time college students younger than this age under the Low Income Home Energy Assistance Program. +# Historical rule retained because the FY2026 plan supplies no replacement. +# The parameter date identifies researched coverage, not adoption of the rule. +values: + 2025-10-01: 22 +metadata: + unit: year + period: year + label: Delaware LIHEAP dependent college student income exclusion age + reference: + - title: Historical Delaware Energy Assistance Program Manual, section 429.2, pages 41-42 + href: https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=41 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml new file mode 100644 index 00000000000..c98d59586ba --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml @@ -0,0 +1,21 @@ +description: Delaware sets these income-band upper bounds as shares of the income limit under the Low Income Home Energy Assistance Program. +# The matrix IPI upper bounds (25.4999 through 200 percent) are divided by +# 200: IPI is household income divided by half the 60% SMI income limit. +# Floor the product of these rates and the whole-dollar income limit. +values: + 2025-10-01: + - 0.1274995 + - 0.2524995 + - 0.3774995 + - 0.5024995 + - 0.6274995 + - 0.7524995 + - 0.8774995 + - 1 +metadata: + unit: list + period: year + label: Delaware LIHEAP income band upper rates + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, income intervals and footnotes 2-5, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml new file mode 100644 index 00000000000..92cf368238b --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml @@ -0,0 +1,28 @@ +description: Delaware provides these regular heating benefits for electricity under the Low Income Home Energy Assistance Program. + +1: + 2025-10-01: 1391 +2: + 2025-10-01: 1190 +3: + 2025-10-01: 988 +4: + 2025-10-01: 588 +5: + 2025-10-01: 394 +6: + 2025-10-01: 283 +7: + 2025-10-01: 215 +8: + 2025-10-01: 192 + +metadata: + unit: currency-USD + period: year + label: Delaware LIHEAP electricity benefit amounts + breakdown: + - range(1, 9) + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml new file mode 100644 index 00000000000..da739d6eefb --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml @@ -0,0 +1,28 @@ +description: Delaware provides these regular heating benefits for natural gas under the Low Income Home Energy Assistance Program. + +1: + 2025-10-01: 1126 +2: + 2025-10-01: 963 +3: + 2025-10-01: 800 +4: + 2025-10-01: 476 +5: + 2025-10-01: 318 +6: + 2025-10-01: 229 +7: + 2025-10-01: 174 +8: + 2025-10-01: 155 + +metadata: + unit: currency-USD + period: year + label: Delaware LIHEAP natural gas benefit amounts + breakdown: + - range(1, 9) + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml new file mode 100644 index 00000000000..bf5f24262b2 --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml @@ -0,0 +1,28 @@ +description: Delaware provides these regular heating benefits for oil under the Low Income Home Energy Assistance Program. + +1: + 2025-10-01: 2016 +2: + 2025-10-01: 1724 +3: + 2025-10-01: 1432 +4: + 2025-10-01: 853 +5: + 2025-10-01: 570 +6: + 2025-10-01: 411 +7: + 2025-10-01: 311 +8: + 2025-10-01: 278 + +metadata: + unit: currency-USD + period: year + label: Delaware LIHEAP oil benefit amounts + breakdown: + - range(1, 9) + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml new file mode 100644 index 00000000000..d7fe0d6cd83 --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml @@ -0,0 +1,28 @@ +description: Delaware provides these regular heating benefits for other under the Low Income Home Energy Assistance Program. + +1: + 2025-10-01: 726 +2: + 2025-10-01: 621 +3: + 2025-10-01: 516 +4: + 2025-10-01: 307 +5: + 2025-10-01: 205 +6: + 2025-10-01: 148 +7: + 2025-10-01: 112 +8: + 2025-10-01: 100 + +metadata: + unit: currency-USD + period: year + label: Delaware LIHEAP other benefit amounts + breakdown: + - range(1, 9) + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml new file mode 100644 index 00000000000..078a3ee094f --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml @@ -0,0 +1,28 @@ +description: Delaware provides these regular heating benefits for propane under the Low Income Home Energy Assistance Program. + +1: + 2025-10-01: 2464 +2: + 2025-10-01: 2108 +3: + 2025-10-01: 1751 +4: + 2025-10-01: 1043 +5: + 2025-10-01: 697 +6: + 2025-10-01: 502 +7: + 2025-10-01: 380 +8: + 2025-10-01: 339 + +metadata: + unit: currency-USD + period: year + label: Delaware LIHEAP propane benefit amounts + breakdown: + - range(1, 9) + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml new file mode 100644 index 00000000000..b233183f65c --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml @@ -0,0 +1,10 @@ +description: Delaware provides this flat Low Income Home Energy Assistance Program benefit to subsidized households paying separately for heat with tenant rent at or below the ceiling. +values: + 2025-10-01: 236 +metadata: + unit: currency-USD + period: year + label: Delaware LIHEAP subsidized housing flat benefit + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, subsidized housing note, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml new file mode 100644 index 00000000000..295f8a7554f --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml @@ -0,0 +1,10 @@ +description: Delaware pays a flat Low Income Home Energy Assistance Program benefit to subsidized households paying separately for heat when monthly tenant rent does not exceed this amount. +values: + 2025-10-01: 679 +metadata: + unit: currency-USD + period: month + label: Delaware LIHEAP subsidized monthly tenant rent ceiling + reference: + - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, subsidized housing note, page 1 + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 756dc2c4988..fc6b9b6f123 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -802,7 +802,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: OR, DC, Riverside County, MA, IL, KS, MS, TX + coverage: OR, DC, Riverside County, MA, IL, KS, MS, TX, DE state_implementations: - state: OR status: in_progress @@ -839,6 +839,14 @@ programs: parameter_prefix: gov.states.ms.mdhs.liheap verified_years: "2026" notes: FY2026 regular assistance for heating fuel and electric bills, using the published matrix as printed. Crisis assistance and energy equipment are out of scope. + - state: DE + status: partial + name: Delaware LIHEAP + full_name: Delaware Low Income Home Energy Assistance Program + variable: de_liheap + parameter_prefix: gov.states.de.dhss.liheap + verified_years: "2026" + notes: FY2026 regular heating matrix, income and housing rules. Annual income and estimated payroll taxes approximate application-period income and withholding; Medicare and pension health deductions are deferred. Historical manual supplies qualified-member and student rules. Solar fuel classification and unobserved administrative facts remain unmodeled. Earlier backfilled results are unverified historical estimates. - state: TX status: partial name: Texas CEAP diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml new file mode 100644 index 00000000000..58d0579d36b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml @@ -0,0 +1,1068 @@ +# Delaware FY2026 regular heating. Independent source-derived expectations. +# Sources: +# - https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 +# - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5,6,7,9,10 +# - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35,36,40,41,42 + +# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +- name: Case 1, complete published propane schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE] + heating_type: [PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE, PROPANE] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + bottled_gas_expense: [100, 100, 100, 100, 100, 100, 100, 100] + rent: [0, 0, 0, 0, 0, 0, 0, 0] + de_liheap_eligible: [true, true, true, true, true, true, true, true] + de_liheap_income_band: [1, 2, 3, 4, 5, 6, 7, 8] + receives_housing_assistance: [false, false, false, false, false, false, false, false] + heat_expense_included_in_rent: [false, false, false, false, false, false, false, false] + output: + de_liheap: [2_464, 2_108, 1_751, 1_043, 697, 502, 380, 339] + +# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +- name: Case 2, complete published fuel_oil schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE] + heating_type: [FUEL_OIL, FUEL_OIL, FUEL_OIL, FUEL_OIL, FUEL_OIL, FUEL_OIL, FUEL_OIL, FUEL_OIL] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + fuel_oil_expense: [100, 100, 100, 100, 100, 100, 100, 100] + rent: [0, 0, 0, 0, 0, 0, 0, 0] + de_liheap_eligible: [true, true, true, true, true, true, true, true] + de_liheap_income_band: [1, 2, 3, 4, 5, 6, 7, 8] + receives_housing_assistance: [false, false, false, false, false, false, false, false] + heat_expense_included_in_rent: [false, false, false, false, false, false, false, false] + output: + de_liheap: [2_016, 1_724, 1_432, 853, 570, 411, 311, 278] + +# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +- name: Case 3, complete published electricity schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE] + heating_type: [ELECTRICITY, ELECTRICITY, ELECTRICITY, ELECTRICITY, ELECTRICITY, ELECTRICITY, ELECTRICITY, + ELECTRICITY] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + pre_subsidy_electricity_expense: [100, 100, 100, 100, 100, 100, 100, 100] + rent: [0, 0, 0, 0, 0, 0, 0, 0] + de_liheap_eligible: [true, true, true, true, true, true, true, true] + de_liheap_income_band: [1, 2, 3, 4, 5, 6, 7, 8] + receives_housing_assistance: [false, false, false, false, false, false, false, false] + heat_expense_included_in_rent: [false, false, false, false, false, false, false, false] + output: + de_liheap: [1_391, 1_190, 988, 588, 394, 283, 215, 192] + +# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +- name: Case 4, complete published natural_gas schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [100, 100, 100, 100, 100, 100, 100, 100] + rent: [0, 0, 0, 0, 0, 0, 0, 0] + de_liheap_eligible: [true, true, true, true, true, true, true, true] + de_liheap_income_band: [1, 2, 3, 4, 5, 6, 7, 8] + receives_housing_assistance: [false, false, false, false, false, false, false, false] + heat_expense_included_in_rent: [false, false, false, false, false, false, false, false] + output: + de_liheap: [1_126, 963, 800, 476, 318, 229, 174, 155] + +# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +- name: Case 5, complete published other schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE] + heating_type: [OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + other_heating_fuel_expense: [100, 100, 100, 100, 100, 100, 100, 100] + rent: [0, 0, 0, 0, 0, 0, 0, 0] + de_liheap_eligible: [true, true, true, true, true, true, true, true] + de_liheap_income_band: [1, 2, 3, 4, 5, 6, 7, 8] + receives_housing_assistance: [false, false, false, false, false, false, false, false] + heat_expense_included_in_rent: [false, false, false, false, false, false, false, false] + output: + de_liheap: [726, 621, 516, 307, 205, 148, 112, 100] + +# REQ-011/012: oil/kerosene share a column; wood and coal use OTHER. Bill100 establishes responsibility without capping payment. +- name: Case 6, kerosene fuel uses its published shared schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: KEROSENE + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + fuel_oil_expense: 100 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 0 + de_liheap_income_band: 1 + de_liheap: 2_016 + +# REQ-011/012: oil/kerosene share a column; wood and coal use OTHER. Bill100 establishes responsibility without capping payment. +- name: Case 7, wood fuel uses its published shared schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: WOOD + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + wood_expense: 100 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 0 + de_liheap_income_band: 1 + de_liheap: 726 + +# REQ-011/012: oil/kerosene share a column; wood and coal use OTHER. Bill100 establishes responsibility without capping payment. +- name: Case 8, coal fuel uses its published shared schedule. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: COAL + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + coal_expense: 100 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 0 + de_liheap_income_band: 1 + de_liheap: 726 + +# REQ-012: tax-free annual child support supplies adjusted source example income; published whole-dollar boundary31,935/31,936 separates588/394 electric benefits. +- name: Case 9, three person source example at income 31935. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + child_support_received: 31_935 + person2: + age: 10 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: ELECTRICITY + gas_expense: 0 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + pre_subsidy_electricity_expense: 1_000 + households: + household: + members: [person1, person2, person3] + state_code: DE + output: + de_liheap_household_size: 3 + de_liheap_countable_income: 31_935 + de_liheap_income_limit: 63_553 + de_liheap_income_band: 4 + de_liheap: 588 + +# REQ-012: tax-free annual child support supplies adjusted source example income; published whole-dollar boundary31,935/31,936 separates588/394 electric benefits. +- name: Case 10, three person source example at income 31936. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + child_support_received: 31_936 + person2: + age: 10 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: ELECTRICITY + gas_expense: 0 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + pre_subsidy_electricity_expense: 1_000 + households: + household: + members: [person1, person2, person3] + state_code: DE + output: + de_liheap_household_size: 3 + de_liheap_countable_income: 31_936 + de_liheap_income_limit: 63_553 + de_liheap_income_band: 5 + de_liheap: 394 + +# REQ-009/011: full-rent household with bundled heat uses ELECTRIC band5 independent of building fuel. +- name: Case 11, ordinary heat in rent selects electricity even with natural_gas fuel. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 12_000 + child_support_received: 31_936 + person2: + age: 10 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + gas_expense: 0 + heat_expense_included_in_rent: true + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2, person3] + state_code: DE + output: + de_liheap_income_band: 5 + de_liheap: 394 + +# REQ-009/011: full-rent household with bundled heat uses ELECTRIC band5 independent of building fuel. +- name: Case 12, ordinary heat in rent selects electricity even with unspecified fuel. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 12_000 + child_support_received: 31_936 + person2: + age: 10 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: UNSPECIFIED + gas_expense: 0 + heat_expense_included_in_rent: true + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2, person3] + state_code: DE + output: + de_liheap_income_band: 5 + de_liheap: 394 + +# REQ-010: monthly rent679 exactly is flat236; above679 goes to ordinary gas band1 amount1,126. Annual rent is tenant share. +- name: Case 13, subsidized separate heat with annual tenant rent 8148. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 8_148 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: true + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap: 236 + +# REQ-010: monthly rent679 exactly is flat236; above679 goes to ordinary gas band1 amount1,126. Annual rent is tenant share. +- name: Case 14, subsidized separate heat with annual tenant rent 8148.12. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 8_148.12 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: true + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap: 1_126 + +# REQ-010: monthly rent679 exactly is flat236; above679 goes to ordinary gas band1 amount1,126. Annual rent is tenant share. +- name: Case 15, subsidized separate heat with annual tenant rent 8160. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 8_160 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: true + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap: 1_126 + +# REQ-010: pre-subsidy12,000 minus housing assistance3,852=tenant rent8,148=679/month; apply flat236. +- name: Case 16, rent ceiling uses tenant share after housing assistance. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + pre_subsidy_rent: 12_000 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: true + housing_assistance: 3_852 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + rent: 8_148 + de_liheap: 236 + +# REQ-004/009: subsidized heat-in-rent excluded; current plan has no nominal SNAP payment. +- name: Case 17, subsidized bundled heat has no regular or nominal SNAP award. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 8_000 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + heat_expense_included_in_rent: true + receives_housing_assistance: true + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + snap: + '2026': 1_200 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_eligible: false + de_liheap: 0 + +# REQ-004/012: tax-free VA represents countable income; inclusive size1 ceiling39,342 pays OTHER band8 amount100. SNAP never bypasses income ceiling. +- name: Case 18, other fuel at annual adjusted income 39342. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + veterans_benefits: 39_342 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: OTHER + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + other_heating_fuel_expense: 1_000 + snap: + '2026': 120 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 39_342 + de_liheap: 100 + +# REQ-004/012: tax-free VA represents countable income; inclusive size1 ceiling39,342 pays OTHER band8 amount100. SNAP never bypasses income ceiling. +- name: Case 19, other fuel at annual adjusted income 39343. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + veterans_benefits: 39_343 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: OTHER + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + other_heating_fuel_expense: 1_000 + snap: + '2026': 120 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 39_343 + de_liheap: 0 + +# REQ-003/014: gross21,000 minus supplied payroll1,000=20,000. Use qualified size1 and full ELECTRIC band5 amount394; no additional one-third reduction. +- name: Case 20, two nonqualified parents and citizen child retain all income without share reduction. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 21_000 + person2: + age: 38 + immigration_status: UNDOCUMENTED + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: ELECTRICITY + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 1_000 + pre_subsidy_electricity_expense: 1_000 + households: + household: + members: [person1, person2, person3] + state_code: DE + output: + de_liheap_household_size: 1 + de_liheap_countable_income: 20_000 + de_liheap_income_band: 5 + de_liheap: 394 + +# REQ-007: student25,000 excluded; size2 income16,000 exceeds band2 maximum12,990 but is within band3 maximum19,421; gas800. +- name: Case 21, dependent student exclusion affects income but not benefit household size. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + child_support_received: 16_000 + person2: + age: 21 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: true + rent: 0 + is_tax_unit_dependent: true + employment_income: 20_000 + social_security_survivors: 5_000 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [16_000, 0] + de_liheap_countable_income: 16_000 + de_liheap_household_size: 2 + de_liheap_income_band: 3 + de_liheap: 800 + +# REQ-006/012: gross10,000 minus existing withholding helper1,000=9,000; size1 band2 gas963. Helper is estimated withholding, not observed payroll data. +- name: Case 22, given payroll deductions change income interval. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 10_000 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 1_000 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 9_000 + de_liheap_income_band: 2 + de_liheap: 963 + +# REQ-013: both households have zero income and gas heat; elder/disability/young-child priority creates no payment supplement. +- name: Case 23, priority household characteristics do not add benefit dollars. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 10 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 60 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + is_disabled: true + person4: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit1: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + tax_unit2: + members: [person3, person4] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit1: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + spm_unit2: + members: [person3, person4] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household1: + members: [person1, person2] + state_code: DE + household2: + members: [person3, person4] + state_code: DE + output: + de_liheap_household_size: [2, 2] + de_liheap_income_band: [1, 1] + de_liheap: [1_126, 1_126] + +# REQ-001: separate household/SPM/tax entities for DE/CT/MD; CT and MD rows have no Delaware award or unguarded matrix lookup. +- name: Case 24, mixed state batch isolates Delaware variables. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit1: + members: [person1] + de_wilmington_earned_income_tax: 0 + tax_unit2: + members: [person2] + de_wilmington_earned_income_tax: 0 + tax_unit3: + members: [person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + spm_unit2: + members: [person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + spm_unit3: + members: [person3] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household1: + members: [person1] + state_code: DE + household2: + members: [person2] + state_code: CT + household3: + members: [person3] + state_code: MD + output: + de_liheap_countable_income_person: [0, 0, 0] + de_liheap_countable_income: [0, 0, 0] + de_liheap_household_size: [1, 0, 0] + de_liheap_income_limit: [39_342, 0, 0] + de_liheap_income_band: [1, 0, 0] + de_liheap_eligible: [true, false, false] + de_liheap: [1_126, 0, 0] + +# REQ-012: the published size-six band-seven maximum is $87,634. +# A post-2018 alimony recipient with no employment has no payroll withholding. +# At the boundary natural gas pays $174; the next dollar moves to $155. +- name: Case 25, size six natural gas payment at adjusted income 87,634. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + alimony_income: 87_634 + ssi: {2026: 0} + is_full_time_college_student: false + person2: {age: 15, immigration_status: CITIZEN, ssi: {2026: 0}} + person3: {age: 12, immigration_status: CITIZEN, ssi: {2026: 0}} + person4: {age: 10, immigration_status: CITIZEN, ssi: {2026: 0}} + person5: {age: 8, immigration_status: CITIZEN, ssi: {2026: 0}} + person6: {age: 6, immigration_status: CITIZEN, ssi: {2026: 0}} + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + de_tanf: {2026: 0} + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: DE + output: + de_liheap_household_size: 6 + de_liheap_countable_income: 87_634 + de_liheap_income_limit: 99_869 + de_liheap_income_band: 7 + de_liheap_eligible: true + de_liheap: 174 + +# REQ-012: the published size-six band-seven maximum is $87,634. +# A post-2018 alimony recipient with no employment has no payroll withholding. +# At the boundary natural gas pays $174; the next dollar moves to $155. +- name: Case 26, size six natural gas payment at adjusted income 87,635. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + alimony_income: 87_635 + ssi: {2026: 0} + is_full_time_college_student: false + person2: {age: 15, immigration_status: CITIZEN, ssi: {2026: 0}} + person3: {age: 12, immigration_status: CITIZEN, ssi: {2026: 0}} + person4: {age: 10, immigration_status: CITIZEN, ssi: {2026: 0}} + person5: {age: 8, immigration_status: CITIZEN, ssi: {2026: 0}} + person6: {age: 6, immigration_status: CITIZEN, ssi: {2026: 0}} + tax_units: + tax_unit: + members: [person1, person2, person3, person4, person5, person6] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + de_tanf: {2026: 0} + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2, person3, person4, person5, person6] + state_code: DE + output: + de_liheap_household_size: 6 + de_liheap_countable_income: 87_635 + de_liheap_income_limit: 99_869 + de_liheap_income_band: 8 + de_liheap_eligible: true + de_liheap: 155 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml new file mode 100644 index 00000000000..2c12922d4ac --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml @@ -0,0 +1,183 @@ +# Delaware FY2026 regular heating. Independent source-derived expectations. +# Sources: +# - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5,6,7,9,10 +# - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35,36,40,41,42 + +# REQ-002/003: historical manual section 426 includes all members income but only qualified members in benefit size. +- name: Case 1, citizens and qualified noncitizens count. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 38 + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 5 + immigration_status: REFUGEE + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2, person3] + state_code: DE + output: + de_liheap_household_size: 3 + +# REQ-002/003: historical manual section 426 includes all members income but only qualified members in benefit size. +- name: Case 2, two nonqualified parents and citizen child count as one. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 38 + immigration_status: UNDOCUMENTED + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person3: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2, person3] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2, person3] + state_code: DE + output: + de_liheap_household_size: 1 + +# REQ-002/003: historical manual section 426 includes all members income but only qualified members in benefit size. +- name: Case 3, no qualified members yield zero. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 38 + immigration_status: DACA + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_household_size: 0 + +# REQ-002/007: section 429.2 excludes qualifying student income, not household membership. +- name: Case 4, dependent college student remains a household member. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 21 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: true + rent: 0 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_household_size: 2 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml new file mode 100644 index 00000000000..d4a31bfaa79 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml @@ -0,0 +1,177 @@ +# Delaware FY2026 regular heating. Independent source-derived expectations. +# Sources: +# - https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 1, published band 1 maxima for all twelve sizes and next dollar. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [5_016, 6_559, 8_102, 9_646, 11_189, 12_733, 13_022, 13_312, 13_601, 13_890, + 14_180, 14_469, 5_017, 6_560, 8_103, 9_647, 11_190, 12_734, 13_023, 13_313, 13_602, 13_891, 14_181, + 14_470] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 2, published band 2 maxima for all twelve sizes and next dollar. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [9_933, 12_990, 16_047, 19_103, 22_160, 25_216, 25_790, 26_363, 26_936, + 27_509, 28_082, 28_655, 9_934, 12_991, 16_048, 19_104, 22_161, 25_217, 25_791, 26_364, 26_937, 27_510, + 28_083, 28_656] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 3, published band 3 maxima for all twelve sizes and next dollar. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [14_851, 19_421, 23_991, 28_561, 33_130, 37_700, 38_557, 39_414, 40_271, + 41_127, 41_984, 42_841, 14_852, 19_422, 23_992, 28_562, 33_131, 37_701, 38_558, 39_415, 40_272, + 41_128, 41_985, 42_842] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 4, published band 4 maxima for all twelve sizes and next dollar. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [19_769, 25_852, 31_935, 38_018, 44_101, 50_184, 51_324, 52_465, 53_606, + 54_746, 55_886, 57_027, 19_770, 25_853, 31_936, 38_019, 44_102, 50_185, 51_325, 52_466, 53_607, + 54_747, 55_887, 57_028] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5] + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 5, published band 5 maxima for all twelve sizes and next dollar. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [24_687, 32_283, 39_879, 47_475, 55_071, 62_667, 64_092, 65_516, 66_941, + 68_364, 69_789, 71_213, 24_688, 32_284, 39_880, 47_476, 55_072, 62_668, 64_093, 65_517, 66_942, + 68_365, 69_790, 71_214] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6] + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 6, published band 6 maxima for all twelve sizes and next dollar. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [29_604, 38_714, 47_823, 56_933, 66_042, 75_151, 76_859, 78_567, 80_275, + 81_983, 83_691, 85_399, 29_605, 38_715, 47_824, 56_934, 66_043, 75_152, 76_860, 78_568, 80_276, + 81_984, 83_692, 85_400] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7] + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 7, published band 7 maxima for all twelve sizes and next dollar. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [34_522, 45_145, 55_767, 66_390, 77_012, 87_634, 89_626, 91_618, 93_610, + 95_601, 97_593, 99_585, 34_523, 45_146, 55_768, 66_391, 77_013, 87_635, 89_627, 91_619, 93_611, + 95_602, 97_594, 99_586] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8] + +# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +- name: Case 8, published band 8 maxima for all twelve sizes. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_countable_income: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + output: + de_liheap_income_band: [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8] + +# REQ-012: three-person printed example assigns 31,936 to band 5. Cent case follows the approved whole-dollar maximum convention; source income rounding is unspecified. +- name: Case 9, printed example crosses whole dollar boundary. + period: 2026 + input: + state_code: [DE, DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000] + de_liheap_countable_income: [31_935, 31_935.01, 31_936] + de_liheap_income_limit: [63_553, 63_553, 63_553] + output: + de_liheap_income_band: [4, 5, 5] diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml new file mode 100644 index 00000000000..841dfe19dd8 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml @@ -0,0 +1,151 @@ +# Delaware FY2026 regular heating. Independent source-derived expectations. +# Sources: +# - https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 +# - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5,6,7,9,10 +# - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35,36,40,41,42 + +# REQ-004: first12 rows at published60% SMI ceiling; next12 one dollar above. No categorical income bypass. +- name: Case 1, all twelve published limits are inclusive and next dollar is ineligible. + period: 2026 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, + DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, + 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_household_size: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12] + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + de_liheap_countable_income: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488, 39_343, 51_449, 63_554, 75_660, 87_765, 99_870, 102_140, 104_410, 106_680, + 108_949, 111_219, 113_489] + output: + de_liheap_eligible: [true, true, true, true, true, true, true, true, true, true, true, true, false, + false, false, false, false, false, false, false, false, false, false, false] + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 2, direct gas with positive matching bill. + period: 2026 + input: + state_code: DE + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + output: + de_liheap_eligible: true + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 3, known direct fuel with no bill. + period: 2026 + input: + state_code: DE + heating_type: NATURAL_GAS + gas_expense: 0 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + output: + de_liheap_eligible: false + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 4, no heating despite reported fuel bills. + period: 2026 + input: + state_code: DE + heating_type: NONE + gas_expense: 1_000 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + output: + de_liheap_eligible: false + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 5, unspecified direct fuel has no supported matrix column. + period: 2026 + input: + state_code: DE + heating_type: UNSPECIFIED + gas_expense: 1_000 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + output: + de_liheap_eligible: false + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 6, solar direct fuel has no sourced matrix column. + period: 2026 + input: + state_code: DE + heating_type: SOLAR + gas_expense: 1_000 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + pre_subsidy_electricity_expense: 1_000 + output: + de_liheap_eligible: false + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 7, ordinary heat in rent with unknown building fuel. + period: 2026 + input: + state_code: DE + heating_type: UNSPECIFIED + gas_expense: 0 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + heat_expense_included_in_rent: true + output: + de_liheap_eligible: true + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 8, subsidized heat in rent is excluded. + period: 2026 + input: + state_code: DE + heating_type: UNSPECIFIED + gas_expense: 0 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + heat_expense_included_in_rent: true + receives_housing_assistance: true + output: + de_liheap_eligible: false + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 9, no qualified household member. + period: 2026 + input: + state_code: DE + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_liheap_household_size: 0 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + output: + de_liheap_eligible: false + +# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +- name: Case 10, assets do not create an eligibility test. + period: 2026 + input: + state_code: DE + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + spm_unit_assets: 1_000_000 + output: + de_liheap_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml new file mode 100644 index 00000000000..6b10ce92d81 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml @@ -0,0 +1,29 @@ +# Delaware FY2026 regular heating. Independent source-derived expectations. +# Sources: +# - https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 + +# REQ-004: literal FY2026 matrix 60% SMI limits, independent of inferred rounding convention. +- name: Case 1, all twelve published household income limits. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE, DE] + heating_type: [NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, + NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS, NATURAL_GAS] + gas_expense: [1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000, 1_000] + de_liheap_household_size: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + output: + de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, + 108_948, 111_218, 113_488] + +# REQ-003/004: positive qualified size is required. +- name: Case 2, no qualified members have no income allowance. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: DE + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_liheap_household_size: 0 + output: + de_liheap_income_limit: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml new file mode 100644 index 00000000000..302b9d6a512 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml @@ -0,0 +1,178 @@ +# Delaware FY2026 regular heating. Independent source-derived expectations. +# Sources: +# - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5,6,7,9,10 + +# REQ-005/006: person income10,000+3,000, TANF12x200=2,400, helper800+150+50=1,000 including state payroll100, city125; 15,400-1,000-125=14,275. +- name: Case 1, TANF counts once and payroll helper includes state contributions once. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 10_000 + de_employee_state_payroll_tax: 100 + person2: + age: 10 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + social_security_survivors: 3_000 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 125 + employee_payroll_tax: 800 + state_withheld_income_tax: 150 + income_tax_before_credits: 50 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + 2026-01: 200 + 2026-02: 200 + 2026-03: 200 + 2026-04: 200 + 2026-05: 200 + 2026-06: 200 + 2026-07: 200 + 2026-08: 200 + 2026-09: 200 + 2026-10: 200 + 2026-11: 200 + 2026-12: 200 + households: + household: + members: [person1, person2] + state_code: DE + output: + spm_unit_paycheck_withholdings: 1_000 + de_liheap_countable_income: 14_275 + +# REQ-006: max(500-800,0)=0. +- name: Case 2, deductions cannot make household income negative. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 500 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 800 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 0 + +# REQ-006: negative deduction is floored at zero, so500 remains500; refunds are not income. +- name: Case 3, negative tax total cannot increase income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + child_support_received: 500 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: -100 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income: 500 + +# REQ-003/006: nonqualified parent gross21,000 minus given withholding1,000 leaves20,000 for qualified size1. +- name: Case 4, income of members excluded from qualified size still counts. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 21_000 + person2: + age: 5 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 1_000 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_household_size: 1 + de_liheap_countable_income: 20_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml new file mode 100644 index 00000000000..394f2e749db --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml @@ -0,0 +1,528 @@ +# Delaware FY2026 regular heating. Independent source-derived expectations. +# Sources: +# - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5,6,7,9,10 +# - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35,36,40,41,42 + +# REQ-005: 1,000+2,000+3,000+4,000+5,000+6,000+7,000=28,000. Historical section 418 classifies property rent as earned. +- name: Case 1, adult earned sources including rents count. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 1_000 + self_employment_income: 2_000 + sstb_self_employment_income: 3_000 + farm_operations_income: 4_000 + partnership_s_corp_income: 5_000 + rental_income: 6_000 + farm_rent_income: 7_000 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income_person: 28_000 + +# REQ-005: 100+200+...+1,200=7,800; SSI is an annual total for a monthly variable. Ordinary dividends feed the existing compatibility alias once. +- name: Case 2, disjoint unearned income sources count. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 300 + is_full_time_college_student: false + rent: 0 + unemployment_compensation: 100 + social_security: 200 + pension_income: 400 + survivor_benefits: 500 + general_assistance: 600 + alimony_income: 700 + child_support_received: 800 + interest_income: 900 + ordinary_dividend_income: 1_000 + veterans_benefits: 1_100 + workers_compensation: 1_200 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income_person: 7_800 + +# REQ-007: minor earned 13,000 excluded; 2,000 child support plus 1,000 SSA survivors counts. +- name: Case 3, minor wages and rental income excluded but support and Social Security retained. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 17.99 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 10_000 + rental_income: 1_800 + farm_rent_income: 1_200 + child_support_received: 2_000 + social_security_survivors: 1_000 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [0, 3_000] + +# REQ-007: 10,000+1,800+1,200 earned plus 3,000 unearned=16,000 at age 18. +- name: Case 4, earned income counts at eighteen. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 18 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 10_000 + rental_income: 1_800 + farm_rent_income: 1_200 + child_support_received: 2_000 + social_security_survivors: 1_000 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income_person: 16_000 + +# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +- name: Case 5, dependent full time college student under twenty two excludes all income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 21.99 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: true + rent: 0 + is_tax_unit_dependent: true + employment_income: 10_000 + child_support_received: 2_000 + social_security_survivors: 1_000 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [0, 0] + +# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +- name: Case 6, dependent student at twenty two counts all income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 22 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: true + rent: 0 + is_tax_unit_dependent: true + employment_income: 10_000 + child_support_received: 2_000 + social_security_survivors: 1_000 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [0, 13_000] + +# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +- name: Case 7, nondependent college student counts income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 21 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: true + rent: 0 + is_tax_unit_dependent: false + employment_income: 10_000 + child_support_received: 2_000 + social_security_survivors: 1_000 + tax_units: + tax_unit1: + members: [person1] + de_wilmington_earned_income_tax: 0 + tax_unit2: + members: [person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [0, 13_000] + +# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +- name: Case 8, dependent who is not a full time college student counts income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + person2: + age: 21 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + is_tax_unit_dependent: true + employment_income: 10_000 + child_support_received: 2_000 + social_security_survivors: 1_000 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [0, 13_000] + +# REQ-005/008: twelve monthly SSI awards of 500 contribute 6,000 annual income. +- name: Case 9, monthly SSI aggregates across the entire year. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 65 + immigration_status: CITIZEN + ssi: + 2026-01: 500 + 2026-02: 500 + 2026-03: 500 + 2026-04: 500 + 2026-05: 500 + 2026-06: 500 + 2026-07: 500 + 2026-08: 500 + 2026-09: 500 + 2026-10: 500 + 2026-11: 500 + 2026-12: 500 + is_full_time_college_student: false + rent: 0 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income_person: 6_000 + +# REQ-005: pension components total3,000 (including classified survivor pension), SSA survivors1,000 and distinct non-SSA survivor benefit500 total4,500. +- name: Case 10, pension and Social Security survivor components are counted once. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + tax_exempt_pension_income: 1_000 + taxable_pension_income: 2_000 + pension_survivors: 1_000 + social_security_survivors: 1_000 + survivor_benefits: 500 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income_person: 4_500 + +# REQ-007: current plan unchecked categories override conflicting historical manual rules; only wages1,000 count. +- name: Case 11, current plan excludes cash gifts strike pay and lottery lump sums. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + employment_income: 1_000 + financial_assistance: 2_000 + strike_benefits: 3_000 + gambling_winnings: 4_000 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income_person: 1_000 + +# REQ-005: qualified200+nonqualified300=ordinary500; do not add the alias again. +- name: Case 12, dividend components are counted once. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 0 + qualified_dividend_income: 200 + non_qualified_dividend_income: 300 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + output: + de_liheap_countable_income_person: 500 diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py new file mode 100644 index 00000000000..f260586de75 --- /dev/null +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py @@ -0,0 +1,51 @@ +from policyengine_us.model_api import * + + +class de_liheap(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Delaware LIHEAP regular heating assistance" + defined_for = "de_liheap_eligible" + reference = ( + "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1", + "https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=9", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.de.dhss.liheap.payment + # Other-state rows have a zero band; keep all vectorized lookups valid. + band = max_(spm_unit("de_liheap_income_band", period), 1) + fuel = spm_unit("heating_type", period) + types = fuel.possible_values + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + matrix_amount = select( + [ + heat_in_rent | (fuel == types.ELECTRICITY), + fuel == types.PROPANE, + (fuel == types.FUEL_OIL) | (fuel == types.KEROSENE), + fuel == types.NATURAL_GAS, + (fuel == types.WOOD) | (fuel == types.COAL) | (fuel == types.OTHER), + ], + [ + p.matrix.electricity[band], + p.matrix.propane[band], + p.matrix.oil[band], + p.matrix.natural_gas[band], + p.matrix.other[band], + ], + default=0, + ) + subsidized = spm_unit("receives_housing_assistance", period) + # rent is the tenant's share after housing assistance, in annual units. + rent = add(spm_unit, period, ["rent"]) + flat_benefit = ( + subsidized + & ~heat_in_rent + & (rent <= p.subsidized_rent_ceiling * MONTHS_IN_YEAR) + ) + # Published matrix amounts already incorporate statewide heating-cost + # evidence. No additional household bill cap or priority supplement + # is imposed on the regular heating award in the verified sources. + return where(flat_benefit, p.subsidized_amount, matrix_amount) diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_household_size.py b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_household_size.py new file mode 100644 index 00000000000..45bc3b94118 --- /dev/null +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_household_size.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class de_liheap_household_size(Variable): + value_type = int + entity = SPMUnit + definition_period = YEAR + label = "Delaware LIHEAP eligible household size" + defined_for = StateCode.DE + reference = "https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=40" + + # Historical DEAP manual section 426 counts only qualified members in + # household size, but retains every member's countable income. The FY2026 + # plan does not restate or replace this allocation rule. + adds = ["is_citizen_or_legal_immigrant"] diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py new file mode 100644 index 00000000000..683de3dc698 --- /dev/null +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class de_liheap_income_band(Variable): + value_type = int + entity = SPMUnit + definition_period = YEAR + label = "Delaware LIHEAP income band" + defined_for = StateCode.DE + reference = "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1" + + def formula(spm_unit, period, parameters): + rates = parameters( + period + ).gov.states.de.dhss.liheap.payment.income_band_upper_rates + income = spm_unit("de_liheap_countable_income", period) + # Float32 can round a product just below a whole dollar up before floor + # (e.g. size six, band seven). Preserve the printed whole-dollar bound. + limit = spm_unit("de_liheap_income_limit", period).astype(np.float64) + # The published whole-dollar maximums reproduce all 96 cells. The + # source does not specify rounding applicant income containing cents. + return select( + [income <= np.floor(limit * rate) for rate in rates], + list(range(1, len(rates) + 1)), + default=len(rates), + ) diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py new file mode 100644 index 00000000000..6161b8a4401 --- /dev/null +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py @@ -0,0 +1,38 @@ +from policyengine_us.model_api import * + + +class de_liheap_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Eligible for Delaware LIHEAP regular heating assistance" + defined_for = StateCode.DE + reference = ( + "https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=9", + # Historical manual sections 424 and 426, page 40. + "https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=40", + ) + + def formula(spm_unit, period, parameters): + size = spm_unit("de_liheap_household_size", period) + income = spm_unit("de_liheap_countable_income", period) + limit = spm_unit("de_liheap_income_limit", period) + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + subsidized = spm_unit("receives_housing_assistance", period) + pays_for_heat = spm_unit("has_heating_expense", period) + fuel = spm_unit("heating_type", period) + types = fuel.possible_values + supported_fuel = ( + (fuel != types.NONE) & (fuel != types.UNSPECIFIED) & (fuel != types.SOLAR) + ) + # Full-rent households use the electric column even if the building's + # fuel is unknown. Solar has no separately supported matrix mapping. + heating_responsibility = where( + heat_in_rent, + ~subsidized & (fuel != types.NONE), + pays_for_heat & supported_fuel, + ) + # SPMUnit approximates the energy-sharing household. Application, + # funding, boarder/absence exceptions and duplicate claims are not + # represented by existing inputs; they are not automatic exclusions. + return (size > 0) & (income <= limit) & heating_responsibility diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py new file mode 100644 index 00000000000..32cbd6cc409 --- /dev/null +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import smi + + +class de_liheap_income_limit(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Delaware LIHEAP annual income limit" + defined_for = StateCode.DE + reference = "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.de.dhss.liheap.eligibility + federal = parameters(period).gov.hhs.smi + size = spm_unit("de_liheap_household_size", period) + state = spm_unit.household("state_code_str", period) + # Rounding the four-person limit first and then truncating the adjusted + # limit reproduces all 12 FY2026 amounts. This order is inferred from + # the published table, not an express legal rounding instruction. + base = np.round(federal.amount[state] * p.smi_rate) + size_share = smi(size, state, period, parameters) / federal.amount[state] + return where(size > 0, np.floor(base * size_share), 0) diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py new file mode 100644 index 00000000000..e0b1bdc5911 --- /dev/null +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class de_liheap_countable_income(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Delaware LIHEAP adjusted annual countable income" + defined_for = StateCode.DE + reference = "https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5" + + def formula(spm_unit, period, parameters): + # Keep income of members excluded from qualified household size. + # Annual flows approximate the application's assessment period. + income = add(spm_unit, period, ["de_liheap_countable_income_person", "de_tanf"]) + # This existing annual tax estimate approximates payroll withholding; + # it does not observe actual withheld tax. It already includes the DE + # employee paid-leave contribution through employee_payroll_tax. + deductions = add( + spm_unit, + period, + ["spm_unit_paycheck_withholdings", "de_wilmington_earned_income_tax"], + ) + # Shared tax estimates can include tax on excluded child/student income. + # TANF is a household amount with no person-level student allocation. + return max_(income - max_(deductions, 0), 0) diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py new file mode 100644 index 00000000000..77b4e6eef76 --- /dev/null +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py @@ -0,0 +1,33 @@ +from policyengine_us.model_api import * + + +class de_liheap_countable_income_person(Variable): + value_type = float + entity = Person + definition_period = YEAR + unit = USD + label = "Delaware LIHEAP countable income of a person before payroll deductions" + defined_for = StateCode.DE + reference = ( + "https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5", + # Historical manual sections 418 and 429.2, pages 35 and 41-42. + "https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35,41,42", + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.de.dhss.liheap.income + age = person("age", period) + earned = add(person, period, p.sources.earned) + unearned = add(person, period, p.sources.unearned) + income = where(age >= p.earned_income_min_age, earned, 0) + unearned + # The historical manual excludes ALL income of dependent full-time + # college students under 22. The FY2026 plan is silent on this rule. + student_exempt = ( + person("is_full_time_college_student", period) + & person("is_tax_unit_dependent", period) + & (age < p.student_income_exclusion_age) + ) + # add() aggregates monthly SSI over the year. Net business income is + # used without another expense deduction. Medicare and pension health + # deductions are deferred because their withheld amounts are unknown. + return where(student_exempt, 0, income) From 9fbabfe053ffd045c30245b90ee5aaa58a99fd93 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 3 Oct 2026 20:18:38 -0400 Subject: [PATCH 2/7] Align Delaware LIHEAP deductions and count recurring retirement income --- .../gov/states/de/dhss/liheap/README.md | 12 +- .../dhss/liheap/income/sources/unearned.yaml | 3 + .../gov/states/de/dhss/liheap/de_liheap.yaml | 182 ++++++++++++++++++ .../income/de_liheap_countable_income.yaml | 102 ++++++++++ .../income/de_liheap_countable_income.py | 43 ++++- 5 files changed, 334 insertions(+), 8 deletions(-) diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md b/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md index 1adc106fc5c..a42dd431078 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md @@ -30,7 +30,9 @@ Annual income flows approximate the application assessment period. Existing net business income is used without a second expense deduction, and rental income is assumed nonnegative. The historical manual classifies rental income as earned. Social Security includes its survivor component; taxable and exempt -pensions are included through `pension_income`. Pension and military survivor +pensions are included through `pension_income`; ongoing IRA/401k receipts enter +through the separate `retirement_distributions` aggregate. Annual inputs do not +identify excluded one-time retirement lump sums. Pension and military survivor classifications are not added on top. The separate non-Social-Security `survivor_benefits` input is counted. Monthly SSI and Delaware TANF are aggregated to annual amounts; TANF is counted once for the household. @@ -38,8 +40,12 @@ to annual amounts; TANF is counted once for the household. `spm_unit_paycheck_withholdings` plus Wilmington earned income tax approximates federal, state and city payroll withholding. This estimates annual taxes, rather than observing actual withholding. The shared helper already includes Delaware -employee paid-leave contributions. It can also include tax attributable to -excluded child or student income; adjusted income is bounded below by zero. +employee paid-leave contributions. Identifiable Social Security, Medicare, +Delaware paid-leave and Wilmington taxes on excluded child or student earnings +are removed from the aggregate deductions, each bounded below by zero. Remaining +supplied deductions are preserved. Federal income tax and additional Medicare +are tax-unit aggregates without person allocations; their attribution remains +an annual-estimate limitation. Adjusted income is bounded below by zero. The household TANF amount does not identify a student's share. Medicare and pension health deductions are deferred because actual withheld amounts are not represented. diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml index 91ef2b203c8..36624e95a3b 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml @@ -8,6 +8,9 @@ values: # Taxable/exempt pension components are already in pension_income. # pension_survivors and military pensions are classifications, not additions. - pension_income + # Ongoing IRA/401k distributions are separate from pension_income. + # Existing annual inputs do not identify an excluded one-time lump sum. + - retirement_distributions - survivor_benefits - general_assistance - alimony_income diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml index 58d0579d36b..38996ebd740 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml @@ -1066,3 +1066,185 @@ de_liheap_income_band: 8 de_liheap_eligible: true de_liheap: 155 + +# Plan excludes the earner's income; source matrix size2 band5 pays gas318. +# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. +- name: Excluded minor payroll does not lower support income, Wilmington false. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + immigration_status: CITIZEN + child_support_received: 26_000 + child: + age: 17 + immigration_status: CITIZEN + employment_income: 20_000 + is_full_time_college_student: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + marital_units: + parent_unit: + members: [parent] + child_unit: + members: [child] + spm_units: + spm_unit: + members: [parent, child] + heating_type: NATURAL_GAS + gas_expense: 1_000 + households: + household: + members: [parent, child] + state_code: DE + in_wilmington: false + output: + de_liheap_countable_income: 26_000 + de_liheap_income_band: 5 + de_liheap: 318 + +# Plan excludes the earner's income; source matrix size2 band5 pays gas318. +# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. +- name: Excluded minor payroll does not lower support income, Wilmington true. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + immigration_status: CITIZEN + child_support_received: 26_000 + child: + age: 17 + immigration_status: CITIZEN + employment_income: 20_000 + is_full_time_college_student: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + marital_units: + parent_unit: + members: [parent] + child_unit: + members: [child] + spm_units: + spm_unit: + members: [parent, child] + heating_type: NATURAL_GAS + gas_expense: 1_000 + households: + household: + members: [parent, child] + state_code: DE + in_wilmington: true + output: + de_liheap_countable_income: 26_000 + de_liheap_income_band: 5 + de_liheap: 318 + +# Plan excludes the earner's income; source matrix size2 band5 pays gas318. +# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. +- name: Excluded dependent full-time college student payroll does not lower support income, Wilmington false. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + immigration_status: CITIZEN + child_support_received: 26_000 + child: + age: 21 + immigration_status: CITIZEN + employment_income: 20_000 + is_full_time_college_student: true + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + marital_units: + parent_unit: + members: [parent] + child_unit: + members: [child] + spm_units: + spm_unit: + members: [parent, child] + heating_type: NATURAL_GAS + gas_expense: 1_000 + households: + household: + members: [parent, child] + state_code: DE + in_wilmington: false + output: + de_liheap_countable_income: 26_000 + de_liheap_income_band: 5 + de_liheap: 318 + +# Plan excludes the earner's income; source matrix size2 band5 pays gas318. +# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. +- name: Excluded dependent full-time college student payroll does not lower support income, Wilmington true. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + immigration_status: CITIZEN + child_support_received: 26_000 + child: + age: 21 + immigration_status: CITIZEN + employment_income: 20_000 + is_full_time_college_student: true + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + marital_units: + parent_unit: + members: [parent] + child_unit: + members: [child] + spm_units: + spm_unit: + members: [parent, child] + heating_type: NATURAL_GAS + gas_expense: 1_000 + households: + household: + members: [parent, child] + state_code: DE + in_wilmington: true + output: + de_liheap_countable_income: 26_000 + de_liheap_income_band: 5 + de_liheap: 318 + +# Recurring IRA receipts exceed the published one-person income ceiling. +- name: Recurring IRA income above the limit prevents regular heating assistance. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person: + age: 70 + immigration_status: CITIZEN + taxable_ira_distributions: 100_000 + spm_units: + spm_unit: + members: [person] + heating_type: NATURAL_GAS + gas_expense: 1_000 + households: + household: + members: [person] + state_code: DE + output: + de_liheap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml index 302b9d6a512..b1ebe8556c2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml @@ -176,3 +176,105 @@ output: de_liheap_household_size: 1 de_liheap_countable_income: 20_000 + +- name: Excluded child taxes, zero supplied deductions stay zero. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + immigration_status: CITIZEN + child_support_received: 26_000 + ssi: {'2026': 0} + child: + age: 17 + immigration_status: CITIZEN + employment_income: 20_000 + is_tax_unit_dependent: true + ssi: {'2026': 0} + tax_units: + tax_unit: + members: [parent, child] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [parent, child] + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_tanf: {'2026': 0} + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [parent, child] + state_code: DE + in_wilmington: true + output: + de_liheap_countable_income: 26000 + +- name: Excluded child taxes, remaining supplied deductions are retained. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + immigration_status: CITIZEN + child_support_received: 26_000 + ssi: {'2026': 0} + child: + age: 17 + immigration_status: CITIZEN + employment_income: 20_000 + is_tax_unit_dependent: true + ssi: {'2026': 0} + tax_units: + tax_unit: + members: [parent, child] + de_wilmington_earned_income_tax: 350 + spm_units: + spm_unit: + members: [parent, child] + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_tanf: {'2026': 0} + spm_unit_paycheck_withholdings: 2110 + households: + household: + members: [parent, child] + state_code: DE + in_wilmington: true + output: + de_liheap_countable_income: 25400 + +# Ongoing retirement receipts: pension 1,000 + taxable IRA 12,000 + exempt IRA 3,000. +# Count the two aggregates once; one-time lump sums are not represented here. +- name: Recurring taxable and exempt retirement distributions count beside pensions. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person: + age: 70 + immigration_status: CITIZEN + ssi: 0 + pension_income: 1_000 + taxable_ira_distributions: 12_000 + tax_exempt_ira_distributions: 3_000 + tax_units: + tax_unit: + members: [person] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person] + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_tanf: 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person] + state_code: DE + output: + de_liheap_countable_income: 16_000 diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py index e0b1bdc5911..53f2fd0bb50 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py @@ -17,11 +17,44 @@ def formula(spm_unit, period, parameters): # This existing annual tax estimate approximates payroll withholding; # it does not observe actual withheld tax. It already includes the DE # employee paid-leave contribution through employee_payroll_tax. - deductions = add( - spm_unit, + person = spm_unit.members + p = parameters(period).gov.states.de.dhss.liheap.income + age = person("age", period) + excluded_earner = (age < p.earned_income_min_age) | ( + person("is_full_time_college_student", period) + & person("is_tax_unit_dependent", period) + & (age < p.student_income_exclusion_age) + ) + payroll_tax = add( + person, period, - ["spm_unit_paycheck_withholdings", "de_wilmington_earned_income_tax"], + [ + "employee_social_security_tax", + "employee_medicare_tax", + "de_employee_state_payroll_tax", + ], + ) + # Remove identifiable taxes on excluded earnings from the supplied + # aggregate; keep any remaining deduction and never create a refund. + withholding = max_( + spm_unit("spm_unit_paycheck_withholdings", period) + - spm_unit.sum(where(excluded_earner, payroll_tax, 0)), + 0, + ) + city_earnings = where( + person.household("in_wilmington", period), + person("employment_income", period) + + person("self_employment_income", period), + person("de_wilmington_nonresident_earnings", period), + ) + city_rate = parameters(period).gov.local.de.wilmington.tax.income.rate + city_tax = max_( + add(spm_unit, period, ["de_wilmington_earned_income_tax"]) + - spm_unit.sum(where(excluded_earner, max_(city_earnings, 0), 0)) + * city_rate, + 0, ) - # Shared tax estimates can include tax on excluded child/student income. + # Federal income tax and additional Medicare are TaxUnit aggregates + # without a person allocation; retain that annual-estimate limitation. # TANF is a household amount with no person-level student allocation. - return max_(income - max_(deductions, 0), 0) + return max_(income - withholding - city_tax, 0) From 2c5b86bb9739c7d748bece891bdb55eea272c176 Mon Sep 17 00:00:00 2001 From: Ziming Date: Sat, 3 Oct 2026 20:32:25 -0400 Subject: [PATCH 3/7] Exclude Delaware income tax on excluded minor earnings --- .../gov/states/de/dhss/liheap/README.md | 7 +- .../gov/states/de/dhss/liheap/de_liheap.yaml | 50 +++++ .../income/de_liheap_countable_income.yaml | 178 ++++++++++++++++++ .../income/de_liheap_countable_income.py | 48 ++++- 4 files changed, 279 insertions(+), 4 deletions(-) diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md b/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md index a42dd431078..6535f858d91 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md @@ -41,9 +41,12 @@ to annual amounts; TANF is counted once for the household. federal, state and city payroll withholding. This estimates annual taxes, rather than observing actual withholding. The shared helper already includes Delaware employee paid-leave contributions. Identifiable Social Security, Medicare, -Delaware paid-leave and Wilmington taxes on excluded child or student earnings +Delaware paid-leave, Delaware income and Wilmington taxes on excluded earnings are removed from the aggregate deductions, each bounded below by zero. Remaining -supplied deductions are preserved. Federal income tax and additional Medicare +supplied deductions are preserved. The person-level Delaware income-tax estimate +retains tax on a minor's counted unearned income; excluded earnings use IRS wages +after pre-tax contributions and existing person business adjustments. Federal +income tax, additional Medicare and other shared tax-unit adjustments are tax-unit aggregates without person allocations; their attribution remains an annual-estimate limitation. Adjusted income is bounded below by zero. The household TANF amount does not identify a student's share. Medicare and diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml index 38996ebd740..4beee58b93b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml @@ -1248,3 +1248,53 @@ state_code: DE output: de_liheap: 0 + +# Separate-filer minor wages are excluded by the plan, regardless of dependency. +# The published two-person band5 starts above25,852 and pays natural gas318. +# No tax, receipt or LIHEAP intermediate overrides are supplied. +- name: Excluded wages of a minor filing separately do not reduce countable support. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + parent: + age: 40 + immigration_status: CITIZEN + child_support_received: 25900 + child: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: false + employment_income: 10000 + tax_units: + parent_tax: + members: + - parent + child_tax: + members: + - child + marital_units: + parent_marital: + members: + - parent + child_marital: + members: + - child + spm_units: + unit: + members: + - parent + - child + heating_type: NATURAL_GAS + gas_expense: 1000 + households: + household: + members: + - parent + - child + state_code: DE + in_wilmington: false + output: + de_liheap_countable_income: 25900 + de_liheap_income_band: 5 + de_liheap: 318 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml index b1ebe8556c2..ab8fee35973 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml @@ -278,3 +278,181 @@ state_code: DE output: de_liheap_countable_income: 16_000 + +# Counted income is15,900 support+10,000 interest in all four households. +# Shared DE withholding contract: (10,000-3,250 standard deduction) yields134.25. +# Excluded wages/business income and their payroll/AGI adjustments cannot reduce +# the25,765.75 remaining countable income. Federal tax is explicitly zero here +# to isolate the person-level state-tax deduction, not allocate federal liability. +- name: Excluded minor earnings preserve state tax on counted interest, including + pre-tax wages and business adjustments. + period: 2026 + absolute_error_margin: 0.02 + input: + people: + parent_interest_only: + age: 40 + immigration_status: CITIZEN + child_support_received: 15900 + ssi: 0 + child_interest_only: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: false + taxable_interest_income: 10000 + ssi: 0 + parent_wages: + age: 40 + immigration_status: CITIZEN + child_support_received: 15900 + ssi: 0 + child_wages: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: false + taxable_interest_income: 10000 + ssi: 0 + employment_income: 10000 + parent_pretax_wages: + age: 40 + immigration_status: CITIZEN + child_support_received: 15900 + ssi: 0 + child_pretax_wages: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: false + taxable_interest_income: 10000 + ssi: 0 + employment_income: 10000 + traditional_401k_contributions: 2000 + parent_business: + age: 40 + immigration_status: CITIZEN + child_support_received: 15900 + ssi: 0 + child_business: + age: 17 + immigration_status: CITIZEN + is_tax_unit_dependent: false + taxable_interest_income: 10000 + ssi: 0 + self_employment_income: 10000 + tax_units: + tax_parent_interest_only: + members: + - parent_interest_only + income_tax_before_credits: 0 + tax_child_interest_only: + members: + - child_interest_only + income_tax_before_credits: 0 + tax_parent_wages: + members: + - parent_wages + income_tax_before_credits: 0 + tax_child_wages: + members: + - child_wages + income_tax_before_credits: 0 + tax_parent_pretax_wages: + members: + - parent_pretax_wages + income_tax_before_credits: 0 + tax_child_pretax_wages: + members: + - child_pretax_wages + income_tax_before_credits: 0 + tax_parent_business: + members: + - parent_business + income_tax_before_credits: 0 + tax_child_business: + members: + - child_business + income_tax_before_credits: 0 + marital_units: + marital_parent_interest_only: + members: + - parent_interest_only + marital_child_interest_only: + members: + - child_interest_only + marital_parent_wages: + members: + - parent_wages + marital_child_wages: + members: + - child_wages + marital_parent_pretax_wages: + members: + - parent_pretax_wages + marital_child_pretax_wages: + members: + - child_pretax_wages + marital_parent_business: + members: + - parent_business + marital_child_business: + members: + - child_business + spm_units: + interest_only: + members: + - parent_interest_only + - child_interest_only + heating_type: NATURAL_GAS + gas_expense: 1000 + de_tanf: 0 + wages: + members: + - parent_wages + - child_wages + heating_type: NATURAL_GAS + gas_expense: 1000 + de_tanf: 0 + pretax_wages: + members: + - parent_pretax_wages + - child_pretax_wages + heating_type: NATURAL_GAS + gas_expense: 1000 + de_tanf: 0 + business: + members: + - parent_business + - child_business + heating_type: NATURAL_GAS + gas_expense: 1000 + de_tanf: 0 + households: + interest_only: + members: + - parent_interest_only + - child_interest_only + state_code: DE + in_wilmington: false + wages: + members: + - parent_wages + - child_wages + state_code: DE + in_wilmington: false + pretax_wages: + members: + - parent_pretax_wages + - child_pretax_wages + state_code: DE + in_wilmington: false + business: + members: + - parent_business + - child_business + state_code: DE + in_wilmington: false + output: + de_liheap_countable_income: + - 25765.75 + - 25765.75 + - 25765.75 + - 25765.75 diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py index 53f2fd0bb50..f5789724b1b 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py @@ -20,11 +20,12 @@ def formula(spm_unit, period, parameters): person = spm_unit.members p = parameters(period).gov.states.de.dhss.liheap.income age = person("age", period) - excluded_earner = (age < p.earned_income_min_age) | ( + student_exempt = ( person("is_full_time_college_student", period) & person("is_tax_unit_dependent", period) & (age < p.student_income_exclusion_age) ) + excluded_earner = (age < p.earned_income_min_age) | student_exempt payroll_tax = add( person, period, @@ -34,11 +35,54 @@ def formula(spm_unit, period, parameters): "de_employee_state_payroll_tax", ], ) + # DE withholding is a Person estimate. Remove the excluded earnings' + # contribution to its AGI base, preserving tax on counted unearned + # income. IRS wages already exclude pre-tax payroll contributions. + taxable_earned = sum( + max_( + person( + "irs_employment_income" + if source == "employment_income" + else source, + period, + ), + 0, + ) + for source in p.sources.earned + ) + business_adjustments = add( + person, + period, + [ + "self_employment_tax_ald_person", + "self_employed_health_insurance_ald_person", + "self_employed_pension_contribution_ald_person", + ], + ) + earned_agi = where( + person("is_tax_unit_dependent", period), + 0, + max_(taxable_earned - business_adjustments, 0), + ) + remaining_agi = where( + student_exempt, + 0, + person("adjusted_gross_income_person", period) - earned_agi, + ) + state_tax = parameters(period).gov.states.de.tax.income + remaining_state_tax = state_tax.rate.calc( + max_(remaining_agi - state_tax.deductions.standard.amount["SINGLE"], 0) + ) + excluded_state_tax = where( + excluded_earner, + max_(person("de_withheld_income_tax", period) - remaining_state_tax, 0), + 0, + ) # Remove identifiable taxes on excluded earnings from the supplied # aggregate; keep any remaining deduction and never create a refund. withholding = max_( spm_unit("spm_unit_paycheck_withholdings", period) - - spm_unit.sum(where(excluded_earner, payroll_tax, 0)), + - spm_unit.sum(where(excluded_earner, payroll_tax, 0) + excluded_state_tax), 0, ) city_earnings = where( From d400cbc4d932b308e1ccb4a9bf6bbab29beb32cb Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 2 Nov 2026 11:53:49 -0500 Subject: [PATCH 4/7] Apply Wave 2C sweep and review fixes Co-Authored-By: Claude Opus 5.5 --- changelog.d/de-liheap-wave2c.added.md | 2 +- .../gov/states/de/dhss/liheap/README.md | 87 --------- .../dhss/liheap/eligibility/fpg_year_lag.yaml | 2 +- .../de/dhss/liheap/income/sources/earned.yaml | 6 +- .../liheap/income/sources/minor_unearned.yaml | 16 ++ .../dhss/liheap/income/sources/unearned.yaml | 21 +- .../payment/income_band_upper_rates.yaml | 2 +- .../liheap/payment/matrix/electricity.yaml | 2 +- .../liheap/payment/matrix/natural_gas.yaml | 2 +- .../de/dhss/liheap/payment/matrix/oil.yaml | 2 +- .../de/dhss/liheap/payment/matrix/other.yaml | 4 +- .../dhss/liheap/payment/matrix/propane.yaml | 2 +- .../liheap/payment/subsidized_amount.yaml | 2 +- .../payment/subsidized_rent_ceiling.yaml | 2 +- policyengine_us/programs.yaml | 2 +- .../gov/states/de/dhss/liheap/de_liheap.yaml | 181 ++++++++++++------ .../dhss/liheap/de_liheap_household_size.yaml | 8 +- .../de/dhss/liheap/de_liheap_income_band.yaml | 18 +- .../eligibility/de_liheap_eligible.yaml | 38 ++-- .../eligibility/de_liheap_income_limit.yaml | 4 +- .../income/de_liheap_countable_income.yaml | 119 ++++++++++-- .../de_liheap_countable_income_person.yaml | 109 +++++++++-- .../gov/states/de/dhss/liheap/de_liheap.py | 10 +- .../de/dhss/liheap/de_liheap_income_band.py | 6 +- .../liheap/eligibility/de_liheap_eligible.py | 9 +- .../eligibility/de_liheap_income_limit.py | 13 +- .../income/de_liheap_countable_income.py | 47 +---- .../de_liheap_countable_income_person.py | 32 ++-- source_conflicts/candidates.yaml | 28 +++ 29 files changed, 481 insertions(+), 295 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/README.md create mode 100644 policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/minor_unearned.yaml diff --git a/changelog.d/de-liheap-wave2c.added.md b/changelog.d/de-liheap-wave2c.added.md index 2e75b127f27..296233430f2 100644 --- a/changelog.d/de-liheap-wave2c.added.md +++ b/changelog.d/de-liheap-wave2c.added.md @@ -1 +1 @@ -Add Delaware LIHEAP regular heating assistance for fiscal year 2026, including federal income protection, received income, net Social Security and supported subsidized solar heating. +Add Delaware LIHEAP regular heating assistance for fiscal year 2026, including the income-interval benefit matrix, the subsidized-housing flat award, federal income protection and Social Security net of Part B. diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md b/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md deleted file mode 100644 index d14f80ba5d9..00000000000 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/README.md +++ /dev/null @@ -1,87 +0,0 @@ -# Delaware regular heating assistance - -The FY2026 benefit matrix and accepted state plan support regular heating-bill -assistance. Crisis, cooling, weatherization, equipment and funding rationing are -outside this implementation. Parameters start on October 1, 2025. Earlier -backfilled results are unverified historical estimates. FY2027 has not been -verified. - -The federal Clearinghouse incorrectly names the Delaware matrix `CO` in its URL. -The document title, Delaware income figures and approval date identify it as the -Delaware FY2026 matrix. All eight income bands and five distinct fuel schedules -are represented; kerosene shares the oil schedule. The matrix already accounts -for statewide fuel costs and energy burden. No additional expense cap is imposed. - -The income limit reuses the requested year's federal SMI amount and household -adjustment factors. Rounding the four-person 60% amount before truncating the -size-adjusted limit reproduces all 12 published limits. Flooring the income -limit times each band's normalized upper rate reproduces all 96 printed income -boundaries. These are reproducible numerical conventions, not express legal -rounding instructions. The source does not resolve applicant income with cents. -The income gate also preserves the strict federal 110% FPG protection, using -the same actual qualified household size and the prior-year guidelines. The -printed state limit and benefit bands remain intact; protected income above -that limit uses the supported final benefit band. Exact 110% income has no -federal protection. - -SPMUnit approximates the energy-sharing household. The historical official -manual supplies two detailed rules not restated or superseded in the FY2026 -plan: only qualified members count in size while all members' countable income -is retained; all income of dependent full-time college students under 22 is -excluded. The current plan governs conflicting rules in that older manual, -including the income threshold, nominal SNAP payments and countable cash gifts. - -Annual income flows approximate the application assessment period. Existing net -business and rental income retain their existing net treatment without a -second expense deduction. The historical manual classifies rental income as -earned. Social Security includes its survivor component; taxable and exempt -pensions are included through `pension_income`; ongoing IRA/401k receipts enter -through the separate `retirement_distributions` aggregate. Annual inputs do not -identify excluded one-time retirement lump sums. Military retirement pay is -counted separately once; pension-survivor classification is not added on top. -The cross-state military-survivor aggregate migration remains deferred. -The separate non-Social-Security -`survivor_benefits` input is counted. Monthly SSI and take-up-gated TANF are -aggregated to annual amounts; TANF counts once for the household. UI uses the -shared reported-or-modeled unemployment-compensation amount. - -`spm_unit_paycheck_withholdings` plus Wilmington earned income tax approximates -federal, state and city payroll withholding. This estimates annual taxes, rather -than observing actual withholding. The shared helper already includes Delaware -employee paid-leave contributions. Identifiable Social Security, Medicare, -Delaware paid-leave, Delaware income and Wilmington taxes on excluded earnings -are removed from the aggregate deductions, each bounded below by zero. Remaining -supplied deductions are preserved. The person-level Delaware income-tax estimate -retains tax on a minor's counted unearned income; excluded earnings use IRS wages -after pre-tax contributions and existing person business adjustments. Federal -income tax, additional Medicare and other shared tax-unit adjustments -are tax-unit aggregates without person allocations; their attribution remains -an annual-estimate limitation. Adjusted income is bounded below by zero. -The household TANF amount does not identify a student's share. Each person's -Social Security is net of their existing out-of-pocket Medicare Part B premium, -bounded at zero. That premium variable accepts an actual supplied amount or -uses the shared enrolled/MSP calculation. The separate reported-only premium -field is not wired here. Generic ordinary and payroll premiums do not establish -pension-health withholding, which remains unobserved and is not deducted. - -Contract earnings use existing employment or business inputs; royalties are -represented only to the extent included in rental income. Work-study or other -excluded payments embedded in reported wages cannot be distinguished. The model -does not infer boarder status, institutional residence, temporary absence, -optional exclusion of students attending out of state, legal-separation proof, -duplicate applications, application timing or funding priority. These missing -facts are limitations, not automatic eligibility exclusions. - -Heat included in full unsubsidized rent uses the electric schedule. Subsidized -heat-in-rent is ineligible. Subsidized households paying separately for heat -receive the flat amount when actual tenant rent is within the published ceiling. -Solar with a positive supplemental-electric bill can receive the fuel-independent -subsidized flat award. Ordinary solar pricing has no verified matrix mapping, -so it remains eligible with a zero ordinary matrix amount; an unspecified -separately paid fuel establishes no matching bill. - -## Sources - -- [FY2026 accepted state plan #page 5-7,9-10,43](https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5), PDF pages 5-7, 9-10 and 43. -- [FY2026 Delaware benefit matrix](https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf), PDF page 1, approved April 28, 2025. -- [Historical official DEAP manual #page 35-38,40-42](https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35), sections 418, 424, 426 and 429.2; PDF pages 35-36 and 40-42. diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/fpg_year_lag.yaml index b275a73b715..cc40087d851 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/fpg_year_lag.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/fpg_year_lag.yaml @@ -7,6 +7,6 @@ metadata: label: Delaware LIHEAP poverty guideline year lag reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, guideline footnotes - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 - title: LIHEAP IM 2025-02, Attachment 2, poverty guidelines for mandatory use in FY26 href: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_FPGSte-Table_Att2.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml index 5f69c3a654f..737d04093ab 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml @@ -10,6 +10,8 @@ values: # Existing net business income is used without another expense deduction. - rental_income - farm_rent_income + # Manual 416.1 counts other taxable income as earned income. + - miscellaneous_income metadata: unit: list period: year @@ -17,5 +19,5 @@ metadata: reference: - title: "Delaware FY2026 LIHEAP State Plan, sections 1.8-1.9 #page 5-7" href: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 - - title: "Historical Delaware Energy Assistance Program Manual, section 418 #page 35-36" - href: https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 \ No newline at end of file + - title: "Historical Delaware Energy Assistance Program Manual, sections 416 and 418 #page 33,35-36" + href: https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=33 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/minor_unearned.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/minor_unearned.yaml new file mode 100644 index 00000000000..8b56824f55d --- /dev/null +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/minor_unearned.yaml @@ -0,0 +1,16 @@ +description: Delaware counts these unearned income sources of household members younger than the earned income age under the Low Income Home Energy Assistance Program. +# Manual 418 excludes minors' income except child support and Social Security; +# 419.1 includes SSI and railroad retirement among Social Security benefits. +values: + 2025-10-01: + - child_support_received + - social_security + - ssi + - railroad_benefits +metadata: + unit: list + period: year + label: Delaware LIHEAP minor unearned income sources + reference: + - title: "Historical Delaware Energy Assistance Program Manual, sections 418-419 #page 35,37" + href: https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml index 08decc666f0..eb67bebb70a 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml @@ -6,9 +6,9 @@ values: - social_security - ssi # Taxable/exempt pension components are already in pension_income. - # pension_survivors classifies pension_income; military pay is separate. + # Military retirement includes Survivor Benefit Plan annuities. - pension_income - - military_retirement_pay + - military_retirement_income # Ongoing IRA/401k distributions are separate from pension_income. # Existing annual inputs do not identify an excluded one-time lump sum. - retirement_distributions @@ -17,9 +17,20 @@ values: - alimony_income - child_support_received - interest_income - - dividend_income + - ordinary_dividend_income - veterans_benefits - workers_compensation + # Manual 419.1 counts railroad retirement. + - railroad_benefits + # Plan vs manual: 419.3 counts disability payments from insurance and 416.2 + # counts strike benefits; plan 1.9 leaves "Insurance payments made directly + # to the insured" and "Strike Pay" unchecked. The manual is followed. + - disability_benefits + - strike_benefits + # Manual 416.2 counts trusts; the plan has no line for them. + - estate_income + # Manual 416.2 counts gifts only from the same source more than once a + # month; the annual financial_assistance input cannot identify those. # Take-up-gated TANF is added once at SPMUnit level, not once per person. # Royalties are represented only to the extent included in rental_income. # Part B nets Social Security; pension-health withholding lacks attribution. @@ -29,4 +40,6 @@ metadata: label: Delaware LIHEAP unearned income sources reference: - title: "Delaware FY2026 LIHEAP State Plan, section 1.9 #page 6-7" - href: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=6 \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=6 + - title: "Historical Delaware Energy Assistance Program Manual, sections 416 and 419 #page 33,37-39" + href: https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=33 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml index e6c9b073099..cdd901d0031 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/income_band_upper_rates.yaml @@ -18,4 +18,4 @@ metadata: label: Delaware LIHEAP income band upper rates reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, income intervals and footnotes 2-5 - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml index 309cc0e896d..7c2293d91ee 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/electricity.yaml @@ -25,4 +25,4 @@ metadata: - range(1, 9) reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml index b57088a4a6b..22b0508c4b4 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/natural_gas.yaml @@ -25,4 +25,4 @@ metadata: - range(1, 9) reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml index 855af771e57..61cd014dd3d 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/oil.yaml @@ -25,4 +25,4 @@ metadata: - range(1, 9) reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml index 9ad0234409b..06589cfe489 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/other.yaml @@ -1,4 +1,4 @@ -description: Delaware provides these regular heating benefits for other under the Low Income Home Energy Assistance Program. +description: Delaware provides these regular heating benefits for other fuels under the Low Income Home Energy Assistance Program. 1: 2025-10-01: 726 @@ -25,4 +25,4 @@ metadata: - range(1, 9) reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml index ab6607ad894..e783e58f1e7 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/matrix/propane.yaml @@ -25,4 +25,4 @@ metadata: - range(1, 9) reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml index eb9d5b7d96b..62c484494d5 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml @@ -7,4 +7,4 @@ metadata: label: Delaware LIHEAP subsidized housing flat benefit reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, subsidized housing note - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml index 8d2f30e2a70..3d2ffd7cfca 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml @@ -7,4 +7,4 @@ metadata: label: Delaware LIHEAP subsidized monthly tenant rent ceiling reference: - title: Delaware FY2026 Energy Assistance Program Benefit Matrix, subsidized housing note - href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf \ No newline at end of file + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1 \ No newline at end of file diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 4808aba027b..b5fd5e4bb36 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -967,7 +967,7 @@ programs: variable: de_liheap parameter_prefix: gov.states.de.dhss.liheap verified_years: "2026" - notes: FY2026 regular heating matrix, income and housing rules, including strict federal income protection, received UI/TANF and Social Security net of Part B. Annual income and estimated payroll taxes approximate application-period income and withholding; pension-health withholding attribution remains unobserved. Historical manual supplies qualified-member and student rules. Solar with a supplemental electric bill can reach the subsidized flat award; its ordinary matrix price is unsupported. Unobserved administrative facts remain unmodeled. Earlier backfilled results are unverified historical estimates. + notes: FY2026 regular heating matrix and the subsidized-housing flat award. Crisis, cooling, weatherization and equipment assistance are out of scope. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml index 38fe034f805..835455bde67 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap.yaml @@ -4,7 +4,8 @@ # - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 # - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 -# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +# All eight literal source amounts; a matching 100 bill does not cap the regular matrix +# award. Eligibility and band are supplied only in this final-variable unit test. - name: Case 1, complete published propane schedule. period: 2026 absolute_error_margin: 0.01 @@ -21,7 +22,8 @@ output: de_liheap: [2_464, 2_108, 1_751, 1_043, 697, 502, 380, 339] -# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +# All eight literal source amounts; a matching 100 bill does not cap the regular matrix +# award. Eligibility and band are supplied only in this final-variable unit test. - name: Case 2, complete published fuel_oil schedule. period: 2026 absolute_error_margin: 0.01 @@ -38,7 +40,8 @@ output: de_liheap: [2_016, 1_724, 1_432, 853, 570, 411, 311, 278] -# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +# All eight literal source amounts; a matching 100 bill does not cap the regular matrix +# award. Eligibility and band are supplied only in this final-variable unit test. - name: Case 3, complete published electricity schedule. period: 2026 absolute_error_margin: 0.01 @@ -56,7 +59,8 @@ output: de_liheap: [1_391, 1_190, 988, 588, 394, 283, 215, 192] -# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +# All eight literal source amounts; a matching 100 bill does not cap the regular matrix +# award. Eligibility and band are supplied only in this final-variable unit test. - name: Case 4, complete published natural_gas schedule. period: 2026 absolute_error_margin: 0.01 @@ -73,7 +77,8 @@ output: de_liheap: [1_126, 963, 800, 476, 318, 229, 174, 155] -# REQ-011/012: all eight literal source amounts; matching bill100 does not cap the regular matrix award. Eligibility and band supplied only in this final-variable unit test. +# All eight literal source amounts; a matching 100 bill does not cap the regular matrix +# award. Eligibility and band are supplied only in this final-variable unit test. - name: Case 5, complete published other schedule. period: 2026 absolute_error_margin: 0.01 @@ -90,7 +95,8 @@ output: de_liheap: [726, 621, 516, 307, 205, 148, 112, 100] -# REQ-011/012: oil/kerosene share a column; wood and coal use OTHER. Bill100 establishes responsibility without capping payment. +# Oil and kerosene share a column; wood and coal use OTHER. A 100 bill establishes +# responsibility without capping payment. - name: Case 6, kerosene fuel uses its published shared schedule. period: 2026 absolute_error_margin: 0.01 @@ -128,7 +134,8 @@ de_liheap_income_band: 1 de_liheap: 2_016 -# REQ-011/012: oil/kerosene share a column; wood and coal use OTHER. Bill100 establishes responsibility without capping payment. +# Oil and kerosene share a column; wood and coal use OTHER. A 100 bill establishes +# responsibility without capping payment. - name: Case 7, wood fuel uses its published shared schedule. period: 2026 absolute_error_margin: 0.01 @@ -166,7 +173,8 @@ de_liheap_income_band: 1 de_liheap: 726 -# REQ-011/012: oil/kerosene share a column; wood and coal use OTHER. Bill100 establishes responsibility without capping payment. +# Oil and kerosene share a column; wood and coal use OTHER. A 100 bill establishes +# responsibility without capping payment. - name: Case 8, coal fuel uses its published shared schedule. period: 2026 absolute_error_margin: 0.01 @@ -204,7 +212,8 @@ de_liheap_income_band: 1 de_liheap: 726 -# REQ-012: tax-free annual child support supplies adjusted source example income; published whole-dollar boundary31,935/31,936 separates588/394 electric benefits. +# Tax-free annual child support supplies the source example's adjusted income; the +# published whole-dollar boundary 31,935/31,936 separates the 588 and 394 electric benefits. - name: Case 9, three person source example at income 31935. period: 2026 absolute_error_margin: 0.01 @@ -259,7 +268,8 @@ de_liheap_income_band: 4 de_liheap: 588 -# REQ-012: tax-free annual child support supplies adjusted source example income; published whole-dollar boundary31,935/31,936 separates588/394 electric benefits. +# Tax-free annual child support supplies the source example's adjusted income; the +# published whole-dollar boundary 31,935/31,936 separates the 588 and 394 electric benefits. - name: Case 10, three person source example at income 31936. period: 2026 absolute_error_margin: 0.01 @@ -314,7 +324,7 @@ de_liheap_income_band: 5 de_liheap: 394 -# REQ-009/011: full-rent household with bundled heat uses ELECTRIC band5 independent of building fuel. +# A full-rent household with bundled heat uses ELECTRIC band 5, independent of building fuel. - name: Case 11, ordinary heat in rent selects electricity even with natural_gas fuel. period: 2026 absolute_error_margin: 0.01 @@ -365,7 +375,7 @@ de_liheap_income_band: 5 de_liheap: 394 -# REQ-009/011: full-rent household with bundled heat uses ELECTRIC band5 independent of building fuel. +# A full-rent household with bundled heat uses ELECTRIC band 5, independent of building fuel. - name: Case 12, ordinary heat in rent selects electricity even with unspecified fuel. period: 2026 absolute_error_margin: 0.01 @@ -416,7 +426,8 @@ de_liheap_income_band: 5 de_liheap: 394 -# REQ-010: monthly rent679 exactly is flat236; above679 goes to ordinary gas band1 amount1,126. Annual rent is tenant share. +# Monthly rent of exactly 679 gets the flat 236; above 679 goes to the ordinary gas band 1 +# amount of 1,126. Annual rent is the tenant share. - name: Case 13, subsidized separate heat with annual tenant rent 8148. period: 2026 absolute_error_margin: 0.01 @@ -451,7 +462,8 @@ output: de_liheap: 236 -# REQ-010: monthly rent679 exactly is flat236; above679 goes to ordinary gas band1 amount1,126. Annual rent is tenant share. +# Monthly rent of exactly 679 gets the flat 236; above 679 goes to the ordinary gas band 1 +# amount of 1,126. Annual rent is the tenant share. - name: Case 14, subsidized separate heat with annual tenant rent 8148.12. period: 2026 absolute_error_margin: 0.01 @@ -486,7 +498,8 @@ output: de_liheap: 1_126 -# REQ-010: monthly rent679 exactly is flat236; above679 goes to ordinary gas band1 amount1,126. Annual rent is tenant share. +# Monthly rent of exactly 679 gets the flat 236; above 679 goes to the ordinary gas band 1 +# amount of 1,126. Annual rent is the tenant share. - name: Case 15, subsidized separate heat with annual tenant rent 8160. period: 2026 absolute_error_margin: 0.01 @@ -521,7 +534,8 @@ output: de_liheap: 1_126 -# REQ-010: pre-subsidy12,000 minus housing assistance3,852=tenant rent8,148=679/month; apply flat236. +# Pre-subsidy 12,000 minus housing assistance 3,852 = tenant rent 8,148 = 679 a month; the +# flat 236 applies. - name: Case 16, rent ceiling uses tenant share after housing assistance. period: 2026 absolute_error_margin: 0.01 @@ -557,7 +571,7 @@ rent: 8_148 de_liheap: 236 -# REQ-004/009: subsidized heat-in-rent excluded; current plan has no nominal SNAP payment. +# Subsidized heat in rent is excluded; the current plan has no nominal SNAP payment. - name: Case 17, subsidized bundled heat has no regular or nominal SNAP award. period: 2026 absolute_error_margin: 0.01 @@ -595,7 +609,8 @@ de_liheap_eligible: false de_liheap: 0 -# REQ-004/012: tax-free VA represents countable income; inclusive size1 ceiling39,342 pays OTHER band8 amount100. SNAP never bypasses income ceiling. +# Tax-free VA benefits represent countable income; the inclusive size 1 ceiling of 39,342 +# pays the OTHER band 8 amount of 100. SNAP never bypasses the income ceiling. - name: Case 18, other fuel at annual adjusted income 39342. period: 2026 absolute_error_margin: 0.01 @@ -635,7 +650,8 @@ de_liheap_countable_income: 39_342 de_liheap: 100 -# REQ-004/012: tax-free VA represents countable income; inclusive size1 ceiling39,342 pays OTHER band8 amount100. SNAP never bypasses income ceiling. +# Tax-free VA benefits represent countable income; the inclusive size 1 ceiling of 39,342 +# pays the OTHER band 8 amount of 100. SNAP never bypasses the income ceiling. - name: Case 19, other fuel at annual adjusted income 39343. period: 2026 absolute_error_margin: 0.01 @@ -675,7 +691,8 @@ de_liheap_countable_income: 39_343 de_liheap: 0 -# REQ-003/014: gross21,000 minus supplied payroll1,000=20,000. Use qualified size1 and full ELECTRIC band5 amount394; no additional one-third reduction. +# Gross 21,000 minus supplied payroll 1,000 = 20,000. Qualified size 1 takes the full +# ELECTRIC band 5 amount of 394, with no additional one-third reduction. - name: Case 20, two nonqualified parents and citizen child retain all income without share reduction. period: 2026 absolute_error_margin: 0.01 @@ -729,7 +746,8 @@ de_liheap_income_band: 5 de_liheap: 394 -# REQ-007: student25,000 excluded; size2 income16,000 exceeds band2 maximum12,990 but is within band3 maximum19,421; gas800. +# The student's 25,000 is excluded; size 2 income of 16,000 exceeds the band 2 maximum of +# 12,990 but is within the band 3 maximum of 19,421; gas pays 800. - name: Case 21, dependent student exclusion affects income but not benefit household size. period: 2026 absolute_error_margin: 0.01 @@ -779,7 +797,8 @@ de_liheap_income_band: 3 de_liheap: 800 -# REQ-006/012: gross10,000 minus existing withholding helper1,000=9,000; size1 band2 gas963. Helper is estimated withholding, not observed payroll data. +# Gross 10,000 minus the withholding helper's 1,000 = 9,000; size 1 band 2 gas pays 963. +# The helper is estimated withholding, not observed payroll data. - name: Case 22, given payroll deductions change income interval. period: 2026 absolute_error_margin: 0.01 @@ -817,7 +836,8 @@ de_liheap_income_band: 2 de_liheap: 963 -# REQ-013: both households have zero income and gas heat; elder/disability/young-child priority creates no payment supplement. +# Both households have zero income and gas heat; elder, disability and young-child +# priority creates no payment supplement. - name: Case 23, priority household characteristics do not add benefit dollars. period: 2026 absolute_error_margin: 0.01 @@ -892,7 +912,8 @@ de_liheap_income_band: [1, 1] de_liheap: [1_126, 1_126] -# REQ-001: separate household/SPM/tax entities for DE/CT/MD; CT and MD rows have no Delaware award or unguarded matrix lookup. +# Separate household, SPM and tax entities for DE, CT and MD; CT and MD rows have no +# Delaware award or unguarded matrix lookup. - name: Case 24, mixed state batch isolates Delaware variables. period: 2026 absolute_error_margin: 0.01 @@ -979,7 +1000,7 @@ de_liheap_eligible: [true, false, false] de_liheap: [1_126, 0, 0] -# REQ-012: the published size-six band-seven maximum is $87,634. +# The published size-six band-seven maximum is $87,634. # A post-2018 alimony recipient with no employment has no payroll withholding. # At the boundary natural gas pays $174; the next dollar moves to $155. - name: Case 25, size six natural gas payment at adjusted income 87,634. @@ -1023,7 +1044,7 @@ de_liheap_eligible: true de_liheap: 174 -# REQ-012: the published size-six band-seven maximum is $87,634. +# The published size-six band-seven maximum is $87,634. # A post-2018 alimony recipient with no employment has no payroll withholding. # At the boundary natural gas pays $174; the next dollar moves to $155. - name: Case 26, size six natural gas payment at adjusted income 87,635. @@ -1067,9 +1088,9 @@ de_liheap_eligible: true de_liheap: 155 -# Plan excludes the earner's income; source matrix size2 band5 pays gas318. -# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. -- name: Excluded minor payroll does not lower support income, Wilmington false. +# The plan excludes the earner's income; source matrix size 2 band 5 pays gas 318. +# The parent's 26,000 support stays countable despite taxes on 20,000 of excluded wages. +- name: Case 27, excluded minor payroll does not lower support income, Wilmington false. period: 2026 absolute_error_margin: 0.01 input: @@ -1081,7 +1102,7 @@ child: age: 17 immigration_status: CITIZEN - employment_income: 20_000 + employment_income_before_lsr: 20_000 is_full_time_college_student: false is_tax_unit_dependent: true tax_units: @@ -1107,9 +1128,9 @@ de_liheap_income_band: 5 de_liheap: 318 -# Plan excludes the earner's income; source matrix size2 band5 pays gas318. -# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. -- name: Excluded minor payroll does not lower support income, Wilmington true. +# The plan excludes the earner's income; source matrix size 2 band 5 pays gas 318. +# The parent's 26,000 support stays countable despite taxes on 20,000 of excluded wages. +- name: Case 28, excluded minor payroll does not lower support income, Wilmington true. period: 2026 absolute_error_margin: 0.01 input: @@ -1121,7 +1142,7 @@ child: age: 17 immigration_status: CITIZEN - employment_income: 20_000 + employment_income_before_lsr: 20_000 is_full_time_college_student: false is_tax_unit_dependent: true tax_units: @@ -1147,9 +1168,9 @@ de_liheap_income_band: 5 de_liheap: 318 -# Plan excludes the earner's income; source matrix size2 band5 pays gas318. -# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. -- name: Excluded dependent full-time college student payroll does not lower support income, Wilmington false. +# The plan excludes the earner's income; source matrix size 2 band 5 pays gas 318. +# The parent's 26,000 support stays countable despite taxes on 20,000 of excluded wages. +- name: Case 29, excluded dependent full-time college student payroll does not lower support income, Wilmington false. period: 2026 absolute_error_margin: 0.01 input: @@ -1161,7 +1182,7 @@ child: age: 21 immigration_status: CITIZEN - employment_income: 20_000 + employment_income_before_lsr: 20_000 is_full_time_college_student: true is_tax_unit_dependent: true tax_units: @@ -1187,9 +1208,9 @@ de_liheap_income_band: 5 de_liheap: 318 -# Plan excludes the earner's income; source matrix size2 band5 pays gas318. -# The parent's26,000 support stays countable despite taxes on20,000 excluded wages. -- name: Excluded dependent full-time college student payroll does not lower support income, Wilmington true. +# The plan excludes the earner's income; source matrix size 2 band 5 pays gas 318. +# The parent's 26,000 support stays countable despite taxes on 20,000 of excluded wages. +- name: Case 30, excluded dependent full-time college student payroll does not lower support income, Wilmington true. period: 2026 absolute_error_margin: 0.01 input: @@ -1201,7 +1222,7 @@ child: age: 21 immigration_status: CITIZEN - employment_income: 20_000 + employment_income_before_lsr: 20_000 is_full_time_college_student: true is_tax_unit_dependent: true tax_units: @@ -1228,7 +1249,7 @@ de_liheap: 318 # Recurring IRA receipts exceed the published one-person income ceiling. -- name: Recurring IRA income above the limit prevents regular heating assistance. +- name: Case 31, recurring IRA income above the limit prevents regular heating assistance. period: 2026 absolute_error_margin: 0.01 input: @@ -1250,9 +1271,9 @@ de_liheap: 0 # Separate-filer minor wages are excluded by the plan, regardless of dependency. -# The published two-person band5 starts above25,852 and pays natural gas318. +# The published two-person band 5 starts above 25,852 and pays natural gas 318. # No tax, receipt or LIHEAP intermediate overrides are supplied. -- name: Excluded wages of a minor filing separately do not reduce countable support. +- name: Case 32, excluded wages of a minor filing separately do not reduce countable support. period: 2026 absolute_error_margin: 0.01 input: @@ -1265,7 +1286,7 @@ age: 17 immigration_status: CITIZEN is_tax_unit_dependent: false - employment_income: 10000 + employment_income_before_lsr: 10000 tax_units: parent_tax: members: @@ -1300,8 +1321,8 @@ de_liheap: 318 -# Military retirement is separate from pension_income. The state ceiling is -#39,342. Net SSA40,000-PartB2,400=37,600 reaches the final gas-band amount155. +# Military retirement is separate from pension_income. The state ceiling is 39,342. +# Net Social Security 40,000 - Part B 2,400 = 37,600 reaches the final gas-band amount of 155. # Supplied zero paycheck withholding isolates these income rules; this is an # existing proxy input, not an added deduction or a new medical-premium input. - name: Case 33, military retirement and net Social Security reach the final award. @@ -1326,12 +1347,12 @@ de_liheap_eligible: [false, true] de_liheap: [0, 155] -# Tenant rent is annual. The flat236 applies at/below679/month when heat is -# separately paid, including solar-primary households with an electric bill. -# Unsubsidized or over-rent-ceiling solar has no invented matrix price, but its -# supported heating responsibility remains eligible. No bill/NONE/bundled -# subsidized heat still fails the independent responsibility/housing gates. -- name: Case 34, solar supplemental heat reaches only the supported flat award. +# No Delaware source lists solar heat; it is read as electric. Tenant rent is +# annual. The flat 236 applies at or below 679 a month when heat is separately +# paid. Unsubsidized and over-ceiling solar households with an electric bill take +# the Electric band 1 amount of 1,391. No bill, NONE and bundled subsidized heat +# still fail the responsibility and housing gates. +- name: Case 34, solar with an electric bill takes the electric column or the flat award. period: 2026 input: state_code: [DE, DE, DE, DE, DE, DE, DE] @@ -1348,7 +1369,7 @@ de_liheap_household_size: [1, 1, 1, 1, 1, 1, 1] de_liheap_countable_income: [0, 0, 0, 0, 0, 0, 0] de_liheap_eligible: [true, true, false, false, false, true, true] - de_liheap: [236, 0, 0, 0, 0, 0, 236] + de_liheap: [236, 1_391, 0, 0, 0, 1_391, 236] # The family's potential DE TANF entitlement is not received when take-up is # false. No categorical bypass is added; the ordinary income test still applies. @@ -1378,11 +1399,11 @@ de_liheap_eligible: true de_liheap: 1_126 -# Actual25qualified members use2025FPG15,650+24*5,500=147,650 and strict -#110%floor162,415. The ordinary state limit remains142,995. Nontaxable support -#150,000 is above that ceiling but below federal protection, reaching the -#supported last-band gas award155. Exact162,415 is unprotected. Each adult has -#their own tax unit; no household-size or eligibility intermediate is forced. +# The 25 qualified members use the 2025 guideline 15,650 + 24 x 5,500 = 147,650 and the +# strict 110% floor of 162,415. The ordinary state limit remains 142,995. Nontaxable +# support of 150,000 is above that ceiling but below federal protection, reaching the +# last-band gas award of 155. Exactly 162,415 is unprotected. Each adult has their own +# tax unit; no household-size or eligibility intermediate is forced. - name: Case 36, large households retain the strict federal income protection. period: 2026 input: @@ -1665,3 +1686,43 @@ de_liheap_income_band: [8, 8] de_liheap_eligible: [true, false] de_liheap: [155, 0] + +# Public housing without a voucher is subsidized housing. Tenant rent of +# 600/month (7,200/year) is within the 679 ceiling, so separate gas heat gets the +# flat 236 instead of the ordinary gas matrix amount. +- name: Case 37, public housing with separate heat receives the subsidized flat award. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + rent: 7_200 + tax_units: + tax_unit: + members: [person1] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + receives_housing_assistance: false + housing_assistance: 0 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1] + state_code: DE + is_in_public_housing: true + output: + de_liheap_eligible: true + de_liheap: 236 + diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml index d31b680142e..b8d75879be1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_household_size.yaml @@ -3,7 +3,7 @@ # - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 # - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 -# REQ-002/003: historical manual section 426 includes all members income but only qualified members in benefit size. +# Historical manual section 426 includes all members' income but only qualified members in benefit size. - name: Case 1, citizens and qualified noncitizens count. period: 2026 input: @@ -51,7 +51,7 @@ output: de_liheap_household_size: 3 -# REQ-002/003: historical manual section 426 includes all members income but only qualified members in benefit size. +# Historical manual section 426 includes all members' income but only qualified members in benefit size. - name: Case 2, two nonqualified parents and citizen child count as one. period: 2026 input: @@ -99,7 +99,7 @@ output: de_liheap_household_size: 1 -# REQ-002/003: historical manual section 426 includes all members income but only qualified members in benefit size. +# Historical manual section 426 includes all members' income but only qualified members in benefit size. - name: Case 3, no qualified members yield zero. period: 2026 input: @@ -140,7 +140,7 @@ output: de_liheap_household_size: 0 -# REQ-002/007: section 429.2 excludes qualifying student income, not household membership. +# Section 429.2 excludes qualifying student income, not household membership. - name: Case 4, dependent college student remains a household member. period: 2026 input: diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml index ef753551777..1e2b518c8f3 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/de_liheap_income_band.yaml @@ -2,7 +2,7 @@ # Sources: # - https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 1, published band 1 maxima for all twelve sizes and next dollar. period: 2026 input: @@ -23,7 +23,7 @@ output: de_liheap_income_band: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 2, published band 2 maxima for all twelve sizes and next dollar. period: 2026 input: @@ -44,7 +44,7 @@ output: de_liheap_income_band: [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 3, published band 3 maxima for all twelve sizes and next dollar. period: 2026 input: @@ -65,7 +65,7 @@ output: de_liheap_income_band: [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 4, published band 4 maxima for all twelve sizes and next dollar. period: 2026 input: @@ -86,7 +86,7 @@ output: de_liheap_income_band: [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5] -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 5, published band 5 maxima for all twelve sizes and next dollar. period: 2026 input: @@ -107,7 +107,7 @@ output: de_liheap_income_band: [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6] -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 6, published band 6 maxima for all twelve sizes and next dollar. period: 2026 input: @@ -128,7 +128,7 @@ output: de_liheap_income_band: [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7] -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 7, published band 7 maxima for all twelve sizes and next dollar. period: 2026 input: @@ -149,7 +149,7 @@ output: de_liheap_income_band: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8] -# REQ-012: first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. +# The first 12 rows are sizes 1-12 at the published maxima; next 12 are one dollar above where another band exists. - name: Case 8, published band 8 maxima for all twelve sizes. period: 2026 input: @@ -164,7 +164,7 @@ output: de_liheap_income_band: [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8] -# REQ-012: three-person printed example assigns 31,936 to band 5. Cent case follows the approved whole-dollar maximum convention; source income rounding is unspecified. +# The three-person printed example assigns 31,936 to band 5. Cent case follows the approved whole-dollar maximum convention; source income rounding is unspecified. - name: Case 9, printed example crosses whole dollar boundary. period: 2026 input: diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml index 6ff5c07cad6..e6e6162d9d1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml @@ -4,7 +4,8 @@ # - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 # - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 -# REQ-004: first12 rows at published60% SMI ceiling; next12 one dollar above. No categorical income bypass. +# The first 12 rows sit at the published 60% SMI ceiling; the next 12 are one dollar above. +# No categorical income bypass. - name: Case 1, all twelve published limits are inclusive and next dollar is ineligible. period: 2026 input: @@ -28,7 +29,7 @@ de_liheap_eligible: [true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false] -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 2, direct gas with positive matching bill. period: 2026 input: @@ -41,7 +42,7 @@ output: de_liheap_eligible: true -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 3, known direct fuel with no bill. period: 2026 input: @@ -54,7 +55,7 @@ output: de_liheap_eligible: false -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 4, no heating despite reported fuel bills. period: 2026 input: @@ -67,7 +68,7 @@ output: de_liheap_eligible: false -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 5, unspecified direct fuel has no supported matrix column. period: 2026 input: @@ -80,8 +81,8 @@ output: de_liheap_eligible: false -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. -- name: Case 6, solar heating responsibility does not invent a matrix price. +# Membership, heating responsibility and housing gates; no asset test. +- name: Case 6, solar heat with an electric bill qualifies. period: 2026 input: state_code: DE @@ -94,7 +95,7 @@ output: de_liheap_eligible: true -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 7, ordinary heat in rent with unknown building fuel. period: 2026 input: @@ -108,7 +109,7 @@ output: de_liheap_eligible: true -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 8, subsidized heat in rent is excluded. period: 2026 input: @@ -123,7 +124,7 @@ output: de_liheap_eligible: false -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 9, no qualified household member. period: 2026 input: @@ -136,7 +137,7 @@ output: de_liheap_eligible: false -# REQ-003/004/009/011: membership, heating responsibility and housing gates; no asset test. +# Membership, heating responsibility and housing gates; no asset test. - name: Case 10, assets do not create an eligibility test. period: 2026 input: @@ -149,3 +150,18 @@ spm_unit_assets: 1_000_000 output: de_liheap_eligible: true + +# A subsidized gate also reads public housing, which ends bundled-heat eligibility +# without a voucher flag. +- name: Case 11, public housing with heat in rent is excluded. + period: 2026 + input: + state_code: DE + heating_type: NATURAL_GAS + de_liheap_household_size: 1 + de_liheap_countable_income: 0 + de_liheap_income_limit: 39_342 + heat_expense_included_in_rent: true + is_in_public_housing: true + output: + de_liheap_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml index 3e01adaf379..119260e3776 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.yaml @@ -2,7 +2,7 @@ # Sources: # - https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf -# REQ-004: literal FY2026 matrix 60% SMI limits, independent of inferred rounding convention. +# Literal FY2026 matrix 60% SMI limits, independent of inferred rounding convention. - name: Case 1, all twelve published household income limits. period: 2026 absolute_error_margin: 0.01 @@ -16,7 +16,7 @@ de_liheap_income_limit: [39_342, 51_448, 63_553, 75_659, 87_764, 99_869, 102_139, 104_409, 106_679, 108_948, 111_218, 113_488] -# REQ-003/004: positive qualified size is required. +# A positive qualified size is required. - name: Case 2, no qualified members have no income allowance. period: 2026 absolute_error_margin: 0.01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml index 07e198cc30f..cdc234e50d3 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income.yaml @@ -2,7 +2,8 @@ # Sources: # - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 -# REQ-005/006: person income10,000+3,000, TANF12x200=2,400, helper800+150+50=1,000 including state payroll100, city125; 15,400-1,000-125=14,275. +# Person income 10,000 + 3,000, TANF 12 x 200 = 2,400, helper 800 + 150 + 50 = 1,000 +# including state payroll 100, city 125; 15,400 - 1,000 - 125 = 14,275. - name: Case 1, TANF counts once and payroll helper includes state contributions once. period: 2026 absolute_error_margin: 0.01 @@ -61,7 +62,7 @@ spm_unit_paycheck_withholdings: 1_000 de_liheap_countable_income: 14_275 -# REQ-006: max(500-800,0)=0. +# max(500 - 800, 0) = 0. - name: Case 2, deductions cannot make household income negative. period: 2026 absolute_error_margin: 0.01 @@ -97,7 +98,7 @@ output: de_liheap_countable_income: 0 -# REQ-006: negative deduction is floored at zero, so500 remains500; refunds are not income. +# A negative deduction is floored at zero, so 500 remains 500; refunds are not income. - name: Case 3, negative tax total cannot increase income. period: 2026 absolute_error_margin: 0.01 @@ -133,7 +134,8 @@ output: de_liheap_countable_income: 500 -# REQ-003/006: nonqualified parent gross21,000 minus given withholding1,000 leaves20,000 for qualified size1. +# The nonqualified parent's gross 21,000 minus supplied withholding 1,000 leaves 20,000 +# for qualified size 1. - name: Case 4, income of members excluded from qualified size still counts. period: 2026 absolute_error_margin: 0.01 @@ -177,7 +179,7 @@ de_liheap_household_size: 1 de_liheap_countable_income: 20_000 -- name: Excluded child taxes, zero supplied deductions stay zero. +- name: Case 5, excluded child taxes, zero supplied deductions stay zero. period: 2026 absolute_error_margin: 0.01 input: @@ -212,7 +214,7 @@ output: de_liheap_countable_income: 26000 -- name: Excluded child taxes, remaining supplied deductions are retained. +- name: Case 6, excluded child taxes, remaining supplied deductions are retained. period: 2026 absolute_error_margin: 0.01 input: @@ -249,7 +251,7 @@ # Ongoing retirement receipts: pension 1,000 + taxable IRA 12,000 + exempt IRA 3,000. # Count the two aggregates once; one-time lump sums are not represented here. -- name: Recurring taxable and exempt retirement distributions count beside pensions. +- name: Case 7, recurring taxable and exempt retirement distributions count beside pensions. period: 2026 absolute_error_margin: 0.01 input: @@ -279,12 +281,12 @@ output: de_liheap_countable_income: 16_000 -# Counted income is15,900 support+10,000 interest in all four households. -# Shared DE withholding contract: (10,000-3,250 standard deduction) yields134.25. -# Excluded wages/business income and their payroll/AGI adjustments cannot reduce -# the25,765.75 remaining countable income. Federal tax is explicitly zero here -# to isolate the person-level state-tax deduction, not allocate federal liability. -- name: Excluded minor earnings preserve state tax on counted interest, including +# Manual 418 excludes a minor's interest as well as earnings, so counted income +# is the parent's 15,900 support in all four households. All of the minor's +# estimated state tax and payroll tax is removed, so wages, pre-tax wages and +# business adjustments cannot reduce it. Federal tax is explicitly zero here to +# isolate the person-level state-tax deduction, not allocate federal liability. +- name: Case 8, excluded minor income removes all of the minor's state tax, including pre-tax wages and business adjustments. period: 2026 absolute_error_margin: 0.02 @@ -452,7 +454,90 @@ in_wilmington: false output: de_liheap_countable_income: - - 25765.75 - - 25765.75 - - 25765.75 - - 25765.75 + - 15_900 + - 15_900 + - 15_900 + - 15_900 + +# Net business amounts are added as reported: wages 30,000 - loss 10,000 = 20,000. +- name: Case 9, a business loss offsets the same person's wages. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: DE + age: 40 + ssi: 0 + de_tanf: 0 + employment_income: 30_000 + self_employment_income: -10_000 + de_wilmington_earned_income_tax: 0 + spm_unit_paycheck_withholdings: 0 + output: + de_liheap_countable_income_person: 20_000 + de_liheap_countable_income: 20_000 + +# Manual 418.3 verifies self-employment against Form 1040 adjusted gross income, so +# one spouse's 40,000 loss offsets the other's 30,000 wages and the unit floors at 0. +- name: Case 10, a business loss offsets another member's wages and the unit floors at zero. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + ssi: 0 + employment_income: 30_000 + person2: + age: 40 + ssi: 0 + self_employment_income: -40_000 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + de_tanf: 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [30_000, -40_000] + de_liheap_countable_income: 0 + +# The minor's 20,000 of nonresident Wilmington earnings carries 20,000 x 1.25% = 250 +# of city tax. That tax is removed with the excluded earnings, so the parent's 26,000 +# of support stays whole. +- name: Case 11, Wilmington tax on an excluded member's nonresident earnings is removed. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + ssi: 0 + child_support_received: 26_000 + person2: + age: 17 + ssi: 0 + is_tax_unit_dependent: true + de_wilmington_nonresident_earnings: 20_000 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + de_tanf: 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + in_wilmington: false + output: + de_wilmington_earned_income_tax: 250 + de_liheap_countable_income: 26_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml index e984093d733..14af53ded81 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml @@ -3,7 +3,7 @@ # - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 # - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 -# REQ-005: 1,000+2,000+3,000+4,000+5,000+6,000+7,000=28,000. Historical section 418 classifies property rent as earned. +# 1,000 + 2,000 + 3,000 + 4,000 + 5,000 + 6,000 + 7,000 = 28,000. Historical section 418 classifies property rent as earned. - name: Case 1, adult earned sources including rents count. period: 2026 absolute_error_margin: 0.01 @@ -45,7 +45,7 @@ output: de_liheap_countable_income_person: 28_000 -# REQ-005: 100+200+...+1,200=7,800; SSI is an annual total for a monthly variable. Ordinary dividends feed the existing compatibility alias once. +# 100 + 200 + ... + 1,200 = 7,800; SSI is an annual total for a monthly variable. - name: Case 2, disjoint unearned income sources count. period: 2026 absolute_error_margin: 0.01 @@ -91,7 +91,8 @@ output: de_liheap_countable_income_person: 7_800 -# REQ-007: minor earned 13,000 excluded; 2,000 child support plus 1,000 SSA survivors counts. +# A minor's earned 13,000 is excluded; 2,000 of child support plus 1,000 of Social Security +# survivors counts. - name: Case 3, minor wages and rental income excluded but support and Social Security retained. period: 2026 absolute_error_margin: 0.01 @@ -138,7 +139,7 @@ output: de_liheap_countable_income_person: [0, 3_000] -# REQ-007: 10,000+1,800+1,200 earned plus 3,000 unearned=16,000 at age 18. +# 10,000 + 1,800 + 1,200 earned plus 3,000 unearned = 16,000 at age 18. - name: Case 4, earned income counts at eighteen. period: 2026 absolute_error_margin: 0.01 @@ -178,7 +179,7 @@ output: de_liheap_countable_income_person: 16_000 -# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +# Historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. - name: Case 5, dependent full time college student under twenty two excludes all income. period: 2026 absolute_error_margin: 0.01 @@ -224,7 +225,7 @@ output: de_liheap_countable_income_person: [0, 0] -# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +# Historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. - name: Case 6, dependent student at twenty two counts all income. period: 2026 absolute_error_margin: 0.01 @@ -270,7 +271,7 @@ output: de_liheap_countable_income_person: [0, 13_000] -# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +# Historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. - name: Case 7, nondependent college student counts income. period: 2026 absolute_error_margin: 0.01 @@ -319,7 +320,7 @@ output: de_liheap_countable_income_person: [0, 13_000] -# REQ-007: historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. +# Historical section 429.2 exempts all 13,000 only when full-time college, dependent and age <22. - name: Case 8, dependent who is not a full time college student counts income. period: 2026 absolute_error_margin: 0.01 @@ -365,7 +366,7 @@ output: de_liheap_countable_income_person: [0, 13_000] -# REQ-005/008: twelve monthly SSI awards of 500 contribute 6,000 annual income. +# Twelve monthly SSI awards of 500 contribute 6,000 annual income. - name: Case 9, monthly SSI aggregates across the entire year. period: 2026 absolute_error_margin: 0.01 @@ -411,7 +412,8 @@ output: de_liheap_countable_income_person: 6_000 -# REQ-005: pension components total3,000 (including classified survivor pension), SSA survivors1,000 and distinct non-SSA survivor benefit500 total4,500. +# Pension components of 3,000 (including the classified survivor pension), Social Security +# survivors of 1,000 and a distinct non-Social Security survivor benefit of 500 total 4,500. - name: Case 10, pension and Social Security survivor components are counted once. period: 2026 absolute_error_margin: 0.01 @@ -451,8 +453,9 @@ output: de_liheap_countable_income_person: 4_500 -# REQ-007: current plan unchecked categories override conflicting historical manual rules; only wages1,000 count. -- name: Case 11, current plan excludes cash gifts strike pay and lottery lump sums. +# Manual 416.2 counts strike benefits, which plan 1.9 leaves unchecked; the manual +# is followed. Annual gifts and lottery lump sums stay out. Wages 1,000 + strike 3,000. +- name: Case 11, strike pay counts; cash gifts and lottery lump sums do not. period: 2026 absolute_error_margin: 0.01 input: @@ -488,9 +491,9 @@ members: [person1] state_code: DE output: - de_liheap_countable_income_person: 1_000 + de_liheap_countable_income_person: 4_000 -# REQ-005: qualified200+nonqualified300=ordinary500; do not add the alias again. +# Qualified 200 + nonqualified 300 = ordinary 500, counted once. - name: Case 12, dividend components are counted once. period: 2026 absolute_error_margin: 0.01 @@ -546,3 +549,81 @@ output: total_unemployment_compensation: [1_200, 400, 0] de_liheap_countable_income_person: [1_200, 400, 1_000] + +# Manual 419.1 and 419.3: an adult's railroad retirement 6,000 and insurance +# disability payments 2,400 count (8,400). Manual 418: a minor keeps only child +# support 1,800, SSI 2,400 and Social Security survivors 3,000 (7,200); the +# minor's 500 of interest is excluded. +- name: Case 14, railroad and disability payments count; a minor keeps only support and Social Security benefits. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: + '2026': 0 + is_full_time_college_student: false + railroad_benefits: 6_000 + disability_benefits: 2_400 + person2: + age: 16 + immigration_status: CITIZEN + ssi: + '2026': 2_400 + is_full_time_college_student: false + child_support_received: 1_800 + social_security_survivors: 3_000 + taxable_interest_income: 500 + tax_units: + tax_unit: + members: [person1, person2] + de_wilmington_earned_income_tax: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_000 + de_tanf: + '2026': 0 + spm_unit_paycheck_withholdings: 0 + households: + household: + members: [person1, person2] + state_code: DE + output: + de_liheap_countable_income_person: [8_400, 7_200] + +# Manual 416.2 counts trusts and 416.1 counts other taxable income: 2,000 + 1,000. +# A minor's trust income stays out under manual 418. +- name: Case 15, trust and other taxable income count for adults only. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE] + age: [40, 16] + ssi: [0, 0] + de_tanf: [0, 0] + estate_income: [2_000, 2_000] + miscellaneous_income: [1_000, 0] + output: + de_liheap_countable_income_person: [3_000, 0] + +# Manual 419.1 lists railroad retirement among Social Security benefits, so Part B +# nets against their sum: 41,000 - 2,434.80; 6,000 + 6,000 - 2,400. A premium above +# 1,000 of railroad retirement cannot reduce the separate 1,000 pension. +- name: Case 16, Part B nets against Social Security and railroad retirement together. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: [DE, DE, DE] + age: [70, 70, 70] + ssi: [0, 0, 0] + de_tanf: [0, 0, 0] + railroad_benefits: [41_000, 6_000, 1_000] + social_security: [0, 6_000, 0] + taxable_pension_income: [0, 0, 1_000] + medicare_part_b_premium: [2_434.80, 2_400, 2_400] + output: + de_liheap_countable_income_person: [38_565.20, 9_600, 1_000] diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py index d221dd5ff0b..1f8fb57205c 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py @@ -9,7 +9,7 @@ class de_liheap(Variable): label = "Delaware LIHEAP regular heating assistance" defined_for = "de_liheap_eligible" reference = ( - "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf", + "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1", "https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=9", ) @@ -22,7 +22,9 @@ def formula(spm_unit, period, parameters): heat_in_rent = spm_unit("heat_expense_included_in_rent", period) matrix_amount = select( [ - heat_in_rent | (fuel == types.ELECTRICITY), + # No Delaware source lists solar heat. Solar is read as electric, + # as heating_expense reads its electric bill. + heat_in_rent | (fuel == types.ELECTRICITY) | (fuel == types.SOLAR), fuel == types.PROPANE, (fuel == types.FUEL_OIL) | (fuel == types.KEROSENE), fuel == types.NATURAL_GAS, @@ -37,7 +39,9 @@ def formula(spm_unit, period, parameters): ], default=0, ) - subsidized = spm_unit("receives_housing_assistance", period) + subsidized = spm_unit( + "receives_housing_assistance", period + ) | spm_unit.household("is_in_public_housing", period) # rent is the tenant's share after housing assistance, in annual units. rent = add(spm_unit, period, ["rent"]) flat_benefit = ( diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py index cb0a1162315..9db0cf4d3dd 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap_income_band.py @@ -7,7 +7,7 @@ class de_liheap_income_band(Variable): definition_period = YEAR label = "Delaware LIHEAP income band" defined_for = StateCode.DE - reference = "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf" + reference = "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1" def formula(spm_unit, period, parameters): rates = parameters( @@ -17,8 +17,8 @@ def formula(spm_unit, period, parameters): # Float32 can round a product just below a whole dollar up before floor # (e.g. size six, band seven). Preserve the printed whole-dollar bound. limit = spm_unit("de_liheap_income_limit", period).astype(np.float64) - # The published whole-dollar maximums reproduce all 96 cells. The - # source does not specify rounding applicant income containing cents. + # The published whole-dollar maximums reproduce all 96 cells and bind + # here, although matrix note 2 expresses the interval as a rounded percent. return select( [income <= np.floor(limit * rate) for rate in rates], list(range(1, len(rates) + 1)), diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py index d256f9fae31..44efdaf9db0 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py @@ -29,15 +29,16 @@ def formula(spm_unit, period, parameters): ) federal_floor = np.round(guideline * p.gov.hhs.liheap.fpg_floor, 2) heat_in_rent = spm_unit("heat_expense_included_in_rent", period) - subsidized = spm_unit("receives_housing_assistance", period) + subsidized = spm_unit( + "receives_housing_assistance", period + ) | spm_unit.household("is_in_public_housing", period) pays_for_heat = spm_unit("has_heating_expense", period) fuel = spm_unit("heating_type", period) types = fuel.possible_values known_fuel = (fuel != types.NONE) & (fuel != types.UNSPECIFIED) # Full-rent households use the electric column even if the building's - # fuel is unknown. Solar with a matching supplemental-electric bill may - # reach the fuel-independent subsidized flat award; its ordinary matrix - # price remains unsupported. + # fuel is unknown. Solar qualifies with an electric bill, which + # has_heating_expense reads for it. heating_responsibility = where( heat_in_rent, ~subsidized & (fuel != types.NONE), diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py index 65703e42496..d076e505a7f 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_income_limit.py @@ -1,5 +1,5 @@ from policyengine_us.model_api import * -from policyengine_us.variables.gov.hhs.hhs_smi import smi +from policyengine_us.variables.gov.hhs.hhs_smi import liheap_smi_limit class de_liheap_income_limit(Variable): @@ -9,16 +9,11 @@ class de_liheap_income_limit(Variable): unit = USD label = "Delaware LIHEAP annual income limit" defined_for = StateCode.DE - reference = "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf" + reference = "https://liheapch.acf.gov/docs/2026/benefits-matricies/CO_BenefitMatrix_Heating_2026.pdf#page=1" def formula(spm_unit, period, parameters): p = parameters(period).gov.states.de.dhss.liheap.eligibility - federal = parameters(period).gov.hhs.smi size = spm_unit("de_liheap_household_size", period) state = spm_unit.household("state_code_str", period) - # Rounding the four-person limit first and then truncating the adjusted - # limit reproduces all 12 FY2026 amounts. This order is inferred from - # the published table, not an express legal rounding instruction. - base = np.round(federal.amount[state] * p.smi_rate) - size_share = smi(size, state, period, parameters) / federal.amount[state] - return where(size > 0, np.floor(base * size_share), 0) + limit = liheap_smi_limit(size, state, p.smi_rate, period, parameters) + return where(size > 0, limit, 0) diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py index 65dae133ece..6b78c5e7176 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income.py @@ -35,50 +35,13 @@ def formula(spm_unit, period, parameters): "de_employee_state_payroll_tax", ], ) - # DE withholding is a Person estimate. Remove the excluded earnings' - # contribution to its AGI base, preserving tax on counted unearned - # income. IRS wages already exclude pre-tax payroll contributions. - taxable_earned = sum( - max_( - person( - "irs_employment_income" - if source == "employment_income" - else source, - period, - ), - 0, - ) - for source in p.sources.earned - ) - business_adjustments = add( - person, - period, - [ - "self_employment_tax_ald_person", - "self_employed_health_insurance_ald_person", - "self_employed_pension_contribution_ald_person", - ], - ) - earned_agi = where( - person("is_tax_unit_dependent", period), - 0, - max_(taxable_earned - business_adjustments, 0), - ) - remaining_agi = where( - student_exempt, - 0, - person("adjusted_gross_income_person", period) - earned_agi, - ) - state_tax = parameters(period).gov.states.de.tax.income - remaining_state_tax = state_tax.rate.calc( - max_(remaining_agi - state_tax.deductions.standard.amount["SINGLE"], 0) - ) + # DE withholding is a Person estimate. Excluded members' remaining + # countable income (child support, Social Security benefits) is not + # taxed, so all of their estimated state tax is removed. excluded_state_tax = where( - excluded_earner, - max_(person("de_withheld_income_tax", period) - remaining_state_tax, 0), - 0, + excluded_earner, max_(person("de_withheld_income_tax", period), 0), 0 ) - # Remove identifiable taxes on excluded earnings from the supplied + # Remove excluded members' identifiable taxes from the supplied # aggregate; keep any remaining deduction and never create a refund. withholding = max_( spm_unit("spm_unit_paycheck_withholdings", period) diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py index 00aed3b53bf..e84d0a52d84 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py @@ -11,24 +11,30 @@ class de_liheap_countable_income_person(Variable): reference = ( # PDF pages 5-7 "https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5", - # Historical manual sections 418 and 429.2. - # PDF pages 35-38,41-42 - "https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35", + # Historical manual sections 416, 418, 419 and 429.2. + # PDF pages 33,35-38,41-42 + "https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=33", ) def formula(person, period, parameters): p = parameters(period).gov.states.de.dhss.liheap.income age = person("age", period) earned = add(person, period, p.sources.earned) - social_security = person("social_security", period) + # Manual 419.1 groups railroad retirement with Social Security benefits, + # and plan 1.9 nets health deductions from them. Both sit in both + # unearned lists, so Part B nets once against their sum. + benefits = add(person, period, ["social_security", "railroad_benefits"]) part_b = person("medicare_part_b_premium", period) - net_social_security = max_(social_security - max_(part_b, 0), 0) - unearned = ( - add(person, period, p.sources.unearned) - - social_security - + net_social_security + benefit_adjustment = max_(benefits - max_(part_b, 0), 0) - benefits + adult_income = earned + add(person, period, p.sources.unearned) + # Manual 418 excludes minors' income except child support and Social + # Security benefits, which 419.1 defines to include SSI and railroad + # retirement. + minor_income = add(person, period, p.sources.minor_unearned) + income = ( + where(age >= p.earned_income_min_age, adult_income, minor_income) + + benefit_adjustment ) - income = where(age >= p.earned_income_min_age, earned, 0) + unearned # The historical manual excludes ALL income of dependent full-time # college students under 22. The FY2026 plan is silent on this rule. student_exempt = ( @@ -37,6 +43,8 @@ def formula(person, period, parameters): & (age < p.student_income_exclusion_age) ) # add() aggregates monthly SSI over the year. Net business income is - # used without another expense deduction. Pension-health withholding - # cannot be inferred from generic ordinary or payroll premiums. + # used without another expense deduction, and this person amount has no + # floor: manual 418.3 verifies self-employment against Form 1040 adjusted + # gross income, so a loss can offset other members' income. Pension-health + # withholding cannot be inferred from generic ordinary or payroll premiums. return where(student_exempt, 0, income) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 7d8c41658c6..09edb9134e3 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -1277,6 +1277,34 @@ candidates: note: 'The statute-first rule requires replacing age-60 eligibility if the literal boundary is confirmed; verify individual-return scope and intervening editions. Code not yet on main: de_elderly_or_disabled_income_exclusion_joint, de_elderly_or_disabled_income_exclusion_indiv.' +- id: us-de:liheap-income-floor-vs-smi-limit + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Can Delaware's 60% SMI heating limit exclude a household of 20 or more whose income is below the federal + 110% poverty-guideline floor? + sources: + - kind: statute + citation: 42 U.S.C. 8624(b)(2)(B) + url: https://www.law.cornell.edu/uscode/text/42/8624#b_2_B + - kind: plan + citation: Delaware FY2026 LIHEAP State Plan, section 2.1, p.9 + url: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=9 + readings: + statute: Income below 110% of the poverty guideline cannot by itself exclude the household. + other: The plan's 60% SMI limit falls below that floor from 20 members. + example: Twenty-five people with $150,000 exceed the $142,995 limit but are below the $162,415 floor (2025 guideline, + one-year lag), so they keep the last-band gas award of $155. + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py + - policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml + - policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/fpg_year_lag.yaml + state: unreviewed + note: PE-US applies the floor, rounded to cents with the statute's strict "less than" (de_liheap_eligible.py). - id: us-de:snap-child-support-exclusion program: snap years: From dc180f1ad992443aa362871b5abd18118ae1ebce Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 2 Nov 2026 11:58:33 -0500 Subject: [PATCH 5/7] Link the Delaware income floor candidate to its PR Co-Authored-By: Claude Opus 5.5 --- source_conflicts/candidates.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 0d05ac2d56b..9486ee52a1c 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -1866,6 +1866,8 @@ candidates: - policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py - policyengine_us/parameters/gov/hhs/liheap/fpg_floor.yaml - policyengine_us/parameters/gov/states/de/dhss/liheap/eligibility/fpg_year_lag.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10612 state: unreviewed note: PE-US applies the floor, rounded to cents with the statute's strict "less than" (de_liheap_eligible.py). - id: us-de:snap-child-support-exclusion From ab98aa9facdd367f3a2c48fc17e885a956a6cfb3 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 3 Nov 2026 16:44:02 -0500 Subject: [PATCH 6/7] Apply review fixes to Delaware LIHEAP Count military basic pay. Pin the minors' railroad entry and the fuel guards in eligibility, drop the redundant heat-in-rent test from the flat benefit, and fix two parameter descriptions. Record the plan-versus-manual income choices as us-de:liheap-plan-income-checklist. Move the registry entry next to DC. Co-Authored-By: Claude Opus 5.5 --- .../de/dhss/liheap/income/sources/earned.yaml | 4 ++ .../liheap/payment/subsidized_amount.yaml | 2 +- .../payment/subsidized_rent_ceiling.yaml | 2 +- policyengine_us/programs.yaml | 16 ++++---- .../eligibility/de_liheap_eligible.yaml | 16 ++++++++ .../de_liheap_countable_income_person.yaml | 12 +++--- .../gov/states/de/dhss/liheap/de_liheap.py | 7 +--- .../liheap/eligibility/de_liheap_eligible.py | 2 + source_conflicts/candidates.yaml | 39 +++++++++++++++++++ 9 files changed, 80 insertions(+), 20 deletions(-) diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml index 737d04093ab..3b4980cbedc 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml @@ -2,6 +2,10 @@ description: Delaware counts these earned income sources for adults under the Lo values: 2025-10-01: - employment_income + # Plan 1.9 checks "Wages" and manual 418.1 counts all gross wages and salaries. + # Basic pay is an input apart from employment_income; enter it in one of the + # two. The estimated taxes deduct nothing on it. + - military_basic_pay - self_employment_income - sstb_self_employment_income - farm_operations_income diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml index 62c484494d5..d1558914a71 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_amount.yaml @@ -1,4 +1,4 @@ -description: Delaware provides this flat Low Income Home Energy Assistance Program benefit to subsidized households paying separately for heat with tenant rent at or below the ceiling. +description: Delaware provides this flat benefit to subsidized tenants who pay for heat separately and whose rent is at or below the ceiling under the Low Income Home Energy Assistance Program. values: 2025-10-01: 236 metadata: diff --git a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml index 3d2ffd7cfca..51122a1524d 100644 --- a/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml +++ b/policyengine_us/parameters/gov/states/de/dhss/liheap/payment/subsidized_rent_ceiling.yaml @@ -1,4 +1,4 @@ -description: Delaware pays a flat Low Income Home Energy Assistance Program benefit to subsidized households paying separately for heat when monthly tenant rent does not exceed this amount. +description: Delaware limits the monthly tenant rent for the subsidized-housing flat benefit to this amount under the Low Income Home Energy Assistance Program. values: 2025-10-01: 679 metadata: diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 48fe7b11c4a..fe29cc90a16 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1065,6 +1065,14 @@ programs: full_name: DC Low Income Home Energy Assistance Program variable: dc_liheap_payment parameter_prefix: gov.states.dc.doee.liheap + - state: DE + status: partial + name: Delaware LIHEAP + full_name: Delaware Low Income Home Energy Assistance Program + variable: de_liheap + parameter_prefix: gov.states.de.dhss.liheap + verified_years: "2026" + notes: FY2026 regular heating matrix and the subsidized-housing flat award. Crisis, cooling, weatherization and equipment assistance are out of scope. - state: MA status: complete name: Massachusetts LIHEAP @@ -1314,14 +1322,6 @@ programs: parameter_prefix: gov.states.wy.dfs.lieap verified_years: "2026" notes: FY2026 regular heating from the published fuel cost standards. Crisis, cooling, weatherization and equipment assistance are out of scope. - - state: DE - status: partial - name: Delaware LIHEAP - full_name: Delaware Low Income Home Energy Assistance Program - variable: de_liheap - parameter_prefix: gov.states.de.dhss.liheap - verified_years: "2026" - notes: FY2026 regular heating matrix and the subsidized-housing flat award. Crisis, cooling, weatherization and equipment assistance are out of scope. # --- SSA programs --- - id: ssi diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml index e6e6162d9d1..38db8439ea2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.yaml @@ -165,3 +165,19 @@ is_in_public_housing: true output: de_liheap_eligible: false + +# has_heating_expense can be set directly, so the known-fuel guard still binds; without +# it the first two rows could reach de_liheap's flat $236 branch with no fuel column. +- name: Case 12, no heating or an unknown fuel stays out on the bill path and no heating in rent. + period: 2026 + input: + state_code: [DE, DE, DE, DE] + heating_type: [NONE, UNSPECIFIED, NATURAL_GAS, NONE] + gas_expense: [0, 0, 0, 0] + has_heating_expense: [true, true, true, false] + heat_expense_included_in_rent: [false, false, false, true] + de_liheap_household_size: [1, 1, 1, 1] + de_liheap_countable_income: [0, 0, 0, 0] + de_liheap_income_limit: [39_342, 39_342, 39_342, 39_342] + output: + de_liheap_eligible: [false, false, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml index 14af53ded81..2052c34fe69 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.yaml @@ -3,7 +3,7 @@ # - https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=5 # - https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=35 -# 1,000 + 2,000 + 3,000 + 4,000 + 5,000 + 6,000 + 7,000 = 28,000. Historical section 418 classifies property rent as earned. +# 1,000 + 500 + 2,000 + 3,000 + 4,000 + 5,000 + 6,000 + 7,000 = 28,500. Historical section 418 classifies property rent as earned. - name: Case 1, adult earned sources including rents count. period: 2026 absolute_error_margin: 0.01 @@ -17,6 +17,7 @@ is_full_time_college_student: false rent: 0 employment_income: 1_000 + military_basic_pay: 500 self_employment_income: 2_000 sstb_self_employment_income: 3_000 farm_operations_income: 4_000 @@ -43,7 +44,7 @@ members: [person1] state_code: DE output: - de_liheap_countable_income_person: 28_000 + de_liheap_countable_income_person: 28_500 # 100 + 200 + ... + 1,200 = 7,800; SSI is an annual total for a monthly variable. - name: Case 2, disjoint unearned income sources count. @@ -552,8 +553,8 @@ # Manual 419.1 and 419.3: an adult's railroad retirement 6,000 and insurance # disability payments 2,400 count (8,400). Manual 418: a minor keeps only child -# support 1,800, SSI 2,400 and Social Security survivors 3,000 (7,200); the -# minor's 500 of interest is excluded. +# support 1,800, SSI 2,400, Social Security survivors 3,000 and railroad retirement +# 1,500 (8,700); the minor's 500 of interest is excluded. - name: Case 14, railroad and disability payments count; a minor keeps only support and Social Security benefits. period: 2026 absolute_error_margin: 0.01 @@ -575,6 +576,7 @@ is_full_time_college_student: false child_support_received: 1_800 social_security_survivors: 3_000 + railroad_benefits: 1_500 taxable_interest_income: 500 tax_units: tax_unit: @@ -593,7 +595,7 @@ members: [person1, person2] state_code: DE output: - de_liheap_countable_income_person: [8_400, 7_200] + de_liheap_countable_income_person: [8_400, 8_700] # Manual 416.2 counts trusts and 416.1 counts other taxable income: 2,000 + 1,000. # A minor's trust income stays out under manual 418. diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py index 1f8fb57205c..5f8489b3692 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/de_liheap.py @@ -44,11 +44,8 @@ def formula(spm_unit, period, parameters): ) | spm_unit.household("is_in_public_housing", period) # rent is the tenant's share after housing assistance, in annual units. rent = add(spm_unit, period, ["rent"]) - flat_benefit = ( - subsidized - & ~heat_in_rent - & (rent <= p.subsidized_rent_ceiling * MONTHS_IN_YEAR) - ) + # Eligibility already bars subsidized heat in rent. + flat_benefit = subsidized & (rent <= p.subsidized_rent_ceiling * MONTHS_IN_YEAR) # Published matrix amounts already incorporate statewide heating-cost # evidence. No additional household bill cap or priority supplement # is imposed on the regular heating award in the verified sources. diff --git a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py index 44efdaf9db0..2f693554512 100644 --- a/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/de/dhss/liheap/eligibility/de_liheap_eligible.py @@ -35,6 +35,8 @@ def formula(spm_unit, period, parameters): pays_for_heat = spm_unit("has_heating_expense", period) fuel = spm_unit("heating_type", period) types = fuel.possible_values + # has_heating_expense can be set directly; a fuel the matrix cannot read + # must not reach the flat subsidized amount in de_liheap. known_fuel = (fuel != types.NONE) & (fuel != types.UNSPECIFIED) # Full-rent households use the electric column even if the building's # fuel is unknown. Solar qualifies with an electric bill, which diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 9486ee52a1c..9cce599f339 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -1870,6 +1870,45 @@ candidates: - https://github.com/PolicyEngine/policyengine-us/pull/10612 state: unreviewed note: PE-US applies the floor, rounded to cents with the statute's strict "less than" (de_liheap_eligible.py). +- id: us-de:liheap-plan-income-checklist + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Do strike benefits, insurance disability payments and minors' unearned income count for Delaware LIHEAP as + the manual provides or as the FY2026 plan checklist marks them? + sources: + - kind: manual + citation: DEAP Policies and Procedures Manual, sections 416, 416.2, 418 and 419.3, PDF pages 33, 35 and 37 + url: https://bidcondocs.delaware.gov/HSS/HSS_15027Liheap_MAN.pdf#page=33 + - kind: plan + citation: Delaware FY2026 LIHEAP State Plan, section 1.9, PDF pages 6-7 + url: https://liheapch.acf.gov/docs/2026/state-plans/DE_Plan_2026.pdf#page=6 + - kind: guidance + citation: Delaware LIHEAP RFP HSS-20-036 statement of work, which lists the manual as an applicable document and asks + for income documentation from members aged 18 and over not attending school, PDF pages 69 and 73 + url: https://bidcondocs.delaware.gov/HSS/HSS_20036Liheap_RFP.pdf#page=69 + readings: + statute: No statute is supplied; the manual counts strike benefits and disability payments made by an insurance + company to the individual, and excludes the income of members under 18 except child support and Social Security. + other: Plan 1.9 leaves "Strike Pay" and "Insurance payments made directly to the insured" unchecked. Its only + person-based exclusion, "Earned income of a child under the age of 18", is also unchecked, so a child's unearned + income of a checked type would count. + example: One adult with $20,000 of insurance disability payments and natural gas heat counts $20,000 and receives $318 + under the manual, and counts $0 and receives $1,126 under the plan. + pe_us: + follows: gap-fill + code: + - policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml + - policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/minor_unearned.yaml + - policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10612 + state: ruled + note: 'Ruled 2026-11-02 for strike pay and disability payments, and 2026-11-03 for minors: follow the manual over the + plan. The manual also fills what the plan does not list: trusts (estate_income, 416.2) and other + taxable income (miscellaneous_income, 416.1). Its sections carry 2011-2015 dates.' - id: us-de:snap-child-support-exclusion program: snap years: From f9902a6737b8a7e7b432cb6deac53338a9078be0 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 5 Nov 2026 11:42:25 -0500 Subject: [PATCH 7/7] Record the basis for the Delaware income ruling Writes the reasons into us-de:liheap-plan-income-checklist and lists earned.yaml, which holds the miscellaneous_income gap-fill. Co-Authored-By: Claude Opus 5.5 --- source_conflicts/candidates.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 9697f3c443e..ec76ca13294 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -2040,6 +2040,7 @@ candidates: pe_us: follows: gap-fill code: + - policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/earned.yaml - policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/unearned.yaml - policyengine_us/parameters/gov/states/de/dhss/liheap/income/sources/minor_unearned.yaml - policyengine_us/variables/gov/states/de/dhss/liheap/income/de_liheap_countable_income_person.py @@ -2047,8 +2048,10 @@ candidates: - https://github.com/PolicyEngine/policyengine-us/pull/10612 state: ruled note: 'Ruled 2026-11-02 for strike pay and disability payments, and 2026-11-03 for minors: follow the manual over the - plan. The manual also fills what the plan does not list: trusts (estate_income, 416.2) and other - taxable income (miscellaneous_income, 416.1). Its sections carry 2011-2015 dates.' + plan. Neither text is a statute. The statement of work lists the manual as an applicable document, and plan 1.9 is a + checkbox summary. On minors, manual 418 is the specific rule, and the statement of work asks for income documentation + from members aged 18 and over not attending school. The manual also fills what the plan does not list: trusts + (estate_income, 416.2) and other taxable income (miscellaneous_income, 416.1). Its sections carry 2011-2015 dates.' - id: us-de:snap-child-support-exclusion program: snap years: