diff --git a/changelog.d/ut-liheap-wave2b.added.md b/changelog.d/ut-liheap-wave2b.added.md new file mode 100644 index 00000000000..b3b62c2b0d6 --- /dev/null +++ b/changelog.d/ut-liheap-wave2b.added.md @@ -0,0 +1 @@ +Add Utah HEAT (ut_heat): 2026 regular heating benefit from energy-burden points and targeted supplements with the 150% federal poverty guideline income test. diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/burden_point_amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/burden_point_amount.yaml new file mode 100644 index 00000000000..5094f9abab0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/burden_point_amount.yaml @@ -0,0 +1,10 @@ +description: Utah pays this amount for each whole energy burden percentage point under the Home Energy Assistance Target program. +values: + 2026-03-01: 10 +metadata: + unit: currency-USD + period: year + label: Utah HEAT amount per energy burden percentage point + reference: + - title: Utah HEAT Benefit Calculation Worksheet, Section 2 + href: https://jobs.utah.gov/infosource/heatpolicy/assets/docs/Training/FY26/3.1.26%20Benefit%20Calculation%20Worksheet.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/fuel_credit.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/fuel_credit.yaml new file mode 100644 index 00000000000..127c6992744 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/fuel_credit.yaml @@ -0,0 +1,10 @@ +description: Utah adds this amount for primary propane, kerosene or fuel oil heating under the Home Energy Assistance Target program. +values: + 2023-03-01: 150 +metadata: + unit: currency-USD + period: year + label: Utah HEAT propane, kerosene or fuel oil credit + reference: + - title: Utah HEAT Manual, Section 605 Propane or Fuel Oil + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/605_Propane_or_Fuel_Oil.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/fuel_credit_types.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/fuel_credit_types.yaml new file mode 100644 index 00000000000..7f4e06c3bc6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/fuel_credit_types.yaml @@ -0,0 +1,21 @@ +description: Utah grants an additional benefit for these primary heating fuels under the Home Energy Assistance Target program. +values: + 2023-03-01: + - PROPANE + - KEROSENE + - FUEL_OIL +# Section 605 names propane and fuel oil. Table III groups kerosene with +# propane, and the March 2026 worksheet's fuel list (GAS, PROPANE, OIL, +# ELECTRICITY, COAL/STEAM, WOOD) has no kerosene entry, so a kerosene household +# is entered as propane or oil, both of which carry the credit. +metadata: + unit: list + period: year + label: Utah HEAT fuels receiving an additional benefit + reference: + - title: Utah HEAT Manual, Section 605 Propane or Fuel Oil + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/605_Propane_or_Fuel_Oil.htm + - title: Utah HEAT Manual, Section 609 Table III Monthly Energy Cost Standards + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/609_Table_III_Monthly_Energy_Cost_Standards.htm + - title: Utah HEAT Benefit Calculation Worksheet, effective March 1, 2026, Sheet2 fuel list + href: https://jobs.utah.gov/infosource/heatpolicy/assets/docs/Training/FY26/3.1.26%20Benefit%20Calculation%20Worksheet.xlsx diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/income_component.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/income_component.yaml new file mode 100644 index 00000000000..f13e657d873 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/income_component.yaml @@ -0,0 +1,10 @@ +description: Utah starts the income component at this amount before subtracting the poverty percentage under the Home Energy Assistance Target program. +values: + 2026-03-01: 250 +metadata: + unit: currency-USD + period: year + label: Utah HEAT initial income component + reference: + - title: Utah HEAT Benefit Calculation Worksheet, Section 1 + href: https://jobs.utah.gov/infosource/heatpolicy/assets/docs/Training/FY26/3.1.26%20Benefit%20Calculation%20Worksheet.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/maximum_burden.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/maximum_burden.yaml new file mode 100644 index 00000000000..15910949c48 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/maximum_burden.yaml @@ -0,0 +1,10 @@ +description: Utah caps the energy burden at this share of countable income under the Home Energy Assistance Target program. +values: + 2024-03-01: 0.25 +metadata: + unit: /1 + period: year + label: Utah HEAT maximum energy burden + reference: + - title: Utah HEAT Manual, Section 603 Energy Burden + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/603_Energy_Burden.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/monthly_energy_cost_standard.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/monthly_energy_cost_standard.yaml new file mode 100644 index 00000000000..795a809f7be --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/monthly_energy_cost_standard.yaml @@ -0,0 +1,37 @@ +description: Utah assigns these monthly energy cost standards by dwelling category and fuel under the Home Energy Assistance Target program. +HOUSE: + natural_gas: + 2023-03-01: 211 + propane: + 2023-03-01: 541 + fuel_oil: + 2023-03-01: 468 + electricity: + 2023-03-01: 287 + coal: + 2023-03-01: 92 + wood: + 2023-03-01: 343 +APARTMENT: + natural_gas: + 2023-03-01: 161 + propane: + 2023-03-01: 408 + fuel_oil: + 2023-03-01: 354 + electricity: + 2023-03-01: 218 + coal: + 2023-03-01: 71 + wood: + 2023-03-01: 260 +# Section 609 groups kerosene with propane and other/steam with coal. +metadata: + unit: currency-USD + period: month + label: Utah HEAT monthly energy cost standard + breakdown: + - ut_heat_dwelling_type + reference: + - title: Utah HEAT Manual, Section 609 Table III Monthly Energy Cost Standards + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/609_Table_III_Monthly_Energy_Cost_Standards.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/rounding_increment.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/rounding_increment.yaml new file mode 100644 index 00000000000..ebdd655d611 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/rounding_increment.yaml @@ -0,0 +1,12 @@ +description: Utah rounds the poverty and energy burden ratios in increments of this share under the Home Energy Assistance Target program. +values: + 2024-03-01: 0.01 +metadata: + unit: /1 + period: year + label: Utah HEAT ratio rounding increment + reference: + - title: Utah HEAT Manual, Section 602 Percent of Poverty + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/602_Percent_of_Poverty.htm + - title: Utah HEAT Manual, Section 603 Energy Burden + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/603_Energy_Burden.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/amount.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/amount.yaml new file mode 100644 index 00000000000..0f12eff0104 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/amount.yaml @@ -0,0 +1,10 @@ +description: Utah adds this amount once for a household containing an eligible target group member under the Home Energy Assistance Target program. +values: + 2025-03-01: 150 +metadata: + unit: currency-USD + period: year + label: Utah HEAT target group credit + reference: + - title: Utah HEAT Manual, Section 604 Target Groups + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_600/Obsolete_604_(3_1_25_to_9_30_26)_Target_Groups.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/child_age.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/child_age.yaml new file mode 100644 index 00000000000..3ddfc8597a3 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/child_age.yaml @@ -0,0 +1,10 @@ +description: Utah includes eligible children below this age in the target group under the Home Energy Assistance Target program. +values: + 2025-03-01: 6 +metadata: + unit: year + period: year + label: Utah HEAT target group child age + reference: + - title: Utah HEAT Manual, Section 604 Target Groups + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_600/Obsolete_604_(3_1_25_to_9_30_26)_Target_Groups.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/elderly_age.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/elderly_age.yaml new file mode 100644 index 00000000000..916d262c0f8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/benefit/target/elderly_age.yaml @@ -0,0 +1,10 @@ +description: Utah includes eligible people of at least this age in the target group under the Home Energy Assistance Target program. +values: + 2025-03-01: 60 +metadata: + unit: year + period: year + label: Utah HEAT target group elderly age + reference: + - title: Utah HEAT Manual, Section 604 Target Groups + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_600/Obsolete_604_(3_1_25_to_9_30_26)_Target_Groups.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/adult_age.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/adult_age.yaml new file mode 100644 index 00000000000..d781d45cb34 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/adult_age.yaml @@ -0,0 +1,10 @@ +description: Utah requires an applicant of at least this age, except emancipated minors, under the Home Energy Assistance Target program. +values: + 2026-03-01: 18 +metadata: + unit: year + period: year + label: Utah HEAT minimum applicant age + reference: + - title: Utah HEAT Manual, Section 202 Eligibility Standards + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_200/Obsolete_202_(03_01_26_to_09_30_26)_Eligibility_Standards.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/conditional_statuses.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/conditional_statuses.yaml new file mode 100644 index 00000000000..99df48a035f --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/conditional_statuses.yaml @@ -0,0 +1,12 @@ +description: Utah requires an additional eligible criterion for these qualified immigration statuses under the Home Energy Assistance Target program. +values: + 2025-10-01: + - CONDITIONAL_ENTRANT + - PAROLED_ONE_YEAR +metadata: + unit: list + period: year + label: Utah HEAT immigration statuses requiring an additional criterion + reference: + - title: Utah HEAT Manual, Section 203-2B Qualified and Eligible Non-Citizens + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/203_Citizenship_and_Non-Citizenship_Requirements/203-2B_Qualified_and_Eligible_Non-Citizens.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/eligible_statuses.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/eligible_statuses.yaml new file mode 100644 index 00000000000..dc12d6ac819 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/eligible_statuses.yaml @@ -0,0 +1,18 @@ +description: Utah treats these observable citizenship or immigration statuses as eligible without an additional waiting period under the Home Energy Assistance Target program. +values: + 2025-10-01: + - CITIZEN + - LEGAL_PERMANENT_RESIDENT + - REFUGEE + - ASYLEE + - DEPORTATION_WITHHELD + - CUBAN_HAITIAN_ENTRANT +metadata: + unit: list + period: year + label: Utah HEAT eligible citizenship and immigration statuses + reference: + - title: Utah HEAT Manual, Section 203-1 US Citizenship + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/203_Citizenship_and_Non-Citizenship_Requirements/203-1_US_Citizenship.htm + - title: Utah HEAT Manual, Section 203-2B Qualified and Eligible Non-Citizens + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/203_Citizenship_and_Non-Citizenship_Requirements/203-2B_Qualified_and_Eligible_Non-Citizens.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/waiting_period.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/waiting_period.yaml new file mode 100644 index 00000000000..cfa9e6a1a79 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/immigration/waiting_period.yaml @@ -0,0 +1,10 @@ +description: Utah treats this many cumulative years in qualified immigration status as an eligible criterion under the Home Energy Assistance Target program. +values: + 2025-10-01: 5 +metadata: + unit: year + period: year + label: Utah HEAT qualified immigration waiting period + reference: + - title: Utah HEAT Manual, Section 203-2B Eligible Non-Citizens + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/203_Citizenship_and_Non-Citizenship_Requirements/203-2B_Qualified_and_Eligible_Non-Citizens.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/income_limit.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/income_limit.yaml new file mode 100644 index 00000000000..14b8941fa6d --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/eligibility/income_limit.yaml @@ -0,0 +1,14 @@ +description: Utah limits countable income to this share of the federal poverty guideline under the Home Energy Assistance Target program. +values: + 2026-03-01: 1.5 +metadata: + unit: /1 + period: year + label: Utah HEAT income limit as a share of the poverty guideline + reference: + - title: Utah HEAT Manual, Section 608 Table II Federal Poverty Level Monthly Income Limits + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/608_Table_II_Federal_Poverty_Level_(FPL)_Monthly_Income_Limits.htm + - title: Utah FY2026 LIHEAP State Plan, Section 2.1 + href: https://liheapch.acf.gov/docs/2026/state-plans/UT_Plan_2026.pdf#page=8 + - title: Utah Admin. Code R982-403-1 + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-1 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/income/child_income_age.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/child_income_age.yaml new file mode 100644 index 00000000000..3f28dcdee24 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/child_income_age.yaml @@ -0,0 +1,15 @@ +description: Utah excludes all income of children below this age under the Home Energy Assistance Target program. +values: + 2025-03-01: 18 +# Section 405 excludes earned and unearned income of a child; R982-403-5(1) +# excludes the earned income of an unemancipated household member (candidate +# us-ut:heat-child-unearned-income). +metadata: + unit: year + period: year + label: Utah HEAT child income exclusion age + reference: + - title: Utah HEAT Manual, Section 405 Income Exclusions + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_405_(3_1_25_to_9_30_26)_Income_Exclusions.htm + - title: Utah Admin. Code R982-403-5(1) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-5 diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/income/earned_income_disregard.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/earned_income_disregard.yaml new file mode 100644 index 00000000000..5e465a74fb0 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/earned_income_disregard.yaml @@ -0,0 +1,19 @@ +description: Utah excludes this share of earned income from countable income under the Home Energy Assistance Target program. +values: + 2022-06-14: 0.2 +# R982-403-6(2) applies the disregard to self-employment income after the +# cost of doing business; the business inputs are already net amounts. +# Worksheet cell C8 ("20% disregard") is B8*0.2, and TOTAL INCOME B11 is +# B8+B9-C8-B10. The worksheet's print area is A1:B67, so the PDF copy omits +# column C. +metadata: + unit: /1 + period: year + label: Utah HEAT earned income disregard rate + reference: + - title: Utah Admin. Code R982-403-6 + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-6 + - title: Utah HEAT Benefit Calculation Worksheet, effective March 1, 2026, cells C8 and B11 + href: https://jobs.utah.gov/infosource/heatpolicy/assets/docs/Training/FY26/3.1.26%20Benefit%20Calculation%20Worksheet.xlsx + - title: Utah HEAT Manual, Section 204 Eligibility with Ineligible Resident + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/204_Eligibility_with_Ineligible_Resident.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/income/earned_income_sources.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/earned_income_sources.yaml new file mode 100644 index 00000000000..fb4a1b46aa9 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/earned_income_sources.yaml @@ -0,0 +1,35 @@ +description: Utah uses these earned income sources under the Home Energy Assistance Target program. +values: + 2024-10-01: + - employment_income + # R982-403-4(2)(a): "wages, including military base pay"; section 403 + # counts military pay as earned income. Basic pay entered here should not + # also be included in employment_income, or it is counted twice. + - military_basic_pay + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - partnership_s_corp_income + # Section 403 treats rental income as self-employment. R982-403-4(2)(k) + # makes rent earned when the client manages the property and + # R982-403-3(2)(m) makes it unearned otherwise; the inputs do not + # identify who manages the property, so all rent is earned here. + - rental_income + - farm_rent_income +# The business inputs are current net amounts and do not reconstruct HEAT +# business expenses or isolate disallowed prior-period losses. Section 404 +# counts passive S corporation income as unearned, which +# partnership_s_corp_income does not separate. +metadata: + unit: list + period: year + label: Utah HEAT earned income sources + reference: + - title: Utah Admin. Code R982-403-4(2) + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-4 + - title: Utah Admin. Code R982-403-8 + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-8 + - title: Utah HEAT Manual, Section 403 Earned Income + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/400_Income_Standards/403_Earned_Income.htm + - title: Utah HEAT Manual, Section 404 Self-Employment + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/400_Income_Standards/404_Self-Employment/404_Self-Employment.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/income/student_income_age.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/student_income_age.yaml new file mode 100644 index 00000000000..d11eb3e2b07 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/student_income_age.yaml @@ -0,0 +1,10 @@ +description: Utah excludes all income of children remaining in secondary school below this age under the Home Energy Assistance Target program. +values: + 2025-03-01: 19 +metadata: + unit: year + period: year + label: Utah HEAT student income exclusion age + reference: + - title: Utah HEAT Manual, Section 405 Income Exclusions + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_405_(3_1_25_to_9_30_26)_Income_Exclusions.htm diff --git a/policyengine_us/parameters/gov/states/ut/dwf/heat/income/unearned_income_sources.yaml b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/unearned_income_sources.yaml new file mode 100644 index 00000000000..dea5449aedd --- /dev/null +++ b/policyengine_us/parameters/gov/states/ut/dwf/heat/income/unearned_income_sources.yaml @@ -0,0 +1,46 @@ +description: Utah counts these unearned income sources under the Home Energy Assistance Target program. +values: + 2024-10-01: + - social_security + - ssi + - railroad_benefits + - pension_income + - military_retirement_income + - retirement_distributions + - survivor_benefits + - veterans_benefits + - total_unemployment_compensation + - workers_compensation + - disability_benefits + - strike_benefits + - financial_assistance + - alimony_income + - child_support_received + # Trust payments, which R982-403-3(2)(h) counts. + - estate_income + - gambling_winnings +# R982-403-5(12) excludes interest and dividend income, and plan item 1.9 +# leaves "Interest, dividends, or royalties" unchecked, so ordinary dividends +# are not listed. The cash contribution input represents private gifts. +# Section 405 exempts TANF/FEP/GA, financial payments made by the Department +# of Workforce Services and financial assistance from other government +# agencies, so the Utah state supplement (ut_ssp) is not listed either +# (candidate us-ut:heat-tanf-dws-payments). Section 405 also exempts ordinary +# bank interest, educational aid and enumerated nonrecurring receipts. +# Existing inputs do not separately represent adoption payments, passive +# royalties or foster-child elections. +metadata: + unit: list + period: year + label: Utah HEAT unearned income sources + reference: + - title: Utah Admin. Code R982-403-3 + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-3 + - title: Utah Admin. Code R982-403-5 + href: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-5 + - title: Utah HEAT Manual, Section 402 Unearned Income + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/400_Income_Standards/402_Unearned_Income.htm + - title: Utah HEAT Manual, Section 405 Income Exclusions + href: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_405_(3_1_25_to_9_30_26)_Income_Exclusions.htm + - title: Utah FY2026 LIHEAP State Plan, Section 1.9 + href: https://liheapch.acf.gov/docs/2026/state-plans/UT_Plan_2026.pdf#page=6 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 681d557eb61..95a3b4aadd9 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1170,6 +1170,14 @@ programs: variable: tx_ceap parameter_prefix: gov.states.tx.tdhca.ceap notes: Models the 150% FPG income limit, the alternative 60% SMI limit from the FY2024 state plan (applied through 2024), benefit amounts, and categorical eligibility through TANF enrollment, SNAP eligibility, and SSI receipt. Not modeled - net rather than gross gambling winnings, the Medicare premium deduction from counted Social Security, and the exclusion of means-tested veterans' pensions from counted income (10 TAC 6.4(c)) + - state: UT + status: partial + name: Utah HEAT + full_name: Utah Home Energy Assistance Target Program + variable: ut_heat + parameter_prefix: gov.states.ut.dwf.heat + verified_years: "2026" + notes: Regular heating under the rules effective March 1, 2026, including the target-group and propane, kerosene or fuel oil supplements. Crisis, cooling, weatherization and equipment assistance are out of scope. - state: VA status: partial name: Virginia EAP diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat.yaml new file mode 100644 index 00000000000..b5c6214bfec --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat.yaml @@ -0,0 +1,1801 @@ +# Sources: Utah HEAT manual sections 602-605 and 609; FY2026 plan pages 8-9. +# The annual 2026 period represents the March 2026 snapshot. +# Countable earnings take the 20% disregard of Utah Admin. Code R982-403-6. + +# Income component 250 + zero-income burden 250. +- name: "Case 1, zero income yields the ordinary gas award." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 500 + +# 250+250+150 target+150 propane=800. +- name: "Case 2, targeted propane household reaches the highest formula award." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: PROPANE + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 800 + +# Wages 15,960 x 0.8 = 12,768; I 1064, P 1330; Q 80 => 170; +# gas burden round(19.83)=20; 170+200=370. +- name: "Case 3, gas house with wages at the poverty guideline after the earnings disregard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 370 + ut_heat_countable_income: 12_768 + ut_heat_household_size: 1 + ut_heat_income_limit: 23_940 + +# I 1064 (15,960 x 0.8 / 12); Q 80 => 170; apartment 161/1064*100 rounds 15; +# 170+150=320. +- name: "Case 4, gas apartment uses its lower cost standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 320 + +# Wages 29,925 x 0.8 = 23,940, I 1995; Q 150; 211/1995*100 rounds 11; 100+110=210. +- name: "Case 5, income at the inclusive one person limit." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 29_925 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 210 + +# Wages 29,925.15 x 0.8 = 23,940.12; monthly 1995.01 exceeds 1995, so the +# household is ineligible and receives 0. +- name: "Case 6, countable income twelve cents above the annual limit is ineligible." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 29_925.15 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 0 + +# Wages 15,972 x 0.8 = 12,777.60; I 1064.80; ceil(100*1064.80/1330)=ceil(80.06)=81 +# => 169; burden round(19.82)=20; 169+200=369. +- name: "Case 7, poverty percentage rounds upward." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_972 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 369 + +# Wages 42,600 x 0.8 = 34,080; I 2840, P 2277, Q 125; 100*71/2840=2.5=>3; 125+30=155. +- name: "Case 8, energy burden rounds half upward." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 42_600 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: COAL + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 155 + +# Wages 42,600.60 x 0.8 = 34,080.48; I 2840.04; Q 125; burden just below 2.5=>2; +# 125+20=145. +- name: "Case 9, energy burden just below the half point rounds down." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 42_600.60 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: COAL + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 145 + +# Size 14, P 7484; wages 168,375 x 0.8 = 134,700, I 11225; Q 150 => income +# 250-150=100. Coal apartment 71/11225*100 rounds to burden 1 => 10. +# Section 607 adds the components with no floor: 100+10=110. +- name: "Case 10, large household at the income limit receives the unfloored formula amount." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 168_375 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person4: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person5: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person6: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person7: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person8: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person9: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person10: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person11: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person12: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person13: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person14: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + heating_type: COAL + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: UT + output: + ut_heat: 110 + ut_heat_household_size: 14 + ut_heat_income_limit: 134_700 + +# Zero income 500 plus one 150 target credit. +- name: "Case 11, target credit begins at age sixty." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 650 + +# Age 59 is below 60. +- name: "Case 12, age fifty nine alone gives no target credit." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 59 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 500 + +# Child 5 is below 6; target credit once. +- name: "Case 13, eligible child under six gives one target credit." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person2: + age: 5 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat: 650 + +# Child 6 is outside under 6 category. +- name: "Case 14, child at six gives no young child target credit." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person2: + age: 6 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat: 500 + +# Older, disabled and young members trigger one 150 credit. +- name: "Case 15, multiple target members give only one credit." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + immigration_status: CITIZEN + ssi: 0 + is_disabled: true + person2: + age: 5 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat: 650 + +# Disability target independent of age. +- name: "Case 16, disabled adult gives target credit." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + is_disabled: true + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 650 + +# Ineligible resident excluded from size and target credit. +- name: "Case 17, ineligible older resident gives no target credit." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person2: + age: 65 + immigration_status: UNDOCUMENTED + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat: 500 + ut_heat_household_size: 1 + +# Size 1; adult income 15960 counts; 310 base+150 eligible child. +- name: "Case 18, eligible child supports mixed status household." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + pension_income: 15_960 + person2: + age: 5 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat: 460 + ut_heat_household_size: 1 + ut_heat_countable_income: 15_960 + +# Nonsubsidized heat-in-rent uses regular standard; no actual-bill cap. +- name: "Case 19, ordinary heat in rent qualifies without a direct bill." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + rent: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + heat_expense_included_in_rent: true + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 500 + +# Actual expense establishes responsibility; standards determine grant. +- name: "Case 20, small direct heating bill does not cap the scheduled award." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 500 + +# Wages 25,500 x 0.8 = 20,400; 20,400-2,400-2,040=15,960; I 1330; 150+160=310. +- name: "Case 21, medical and child support deductions reach exact poverty." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 25_500 + other_medical_expenses: 2_400 + child_support_expense: 2_040 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 310 + ut_heat_countable_income: 15_960 + +# Countable income floors at 0; 250+250+150 target+150 propane=800. +- name: "Case 22, negative net business income does not inflate the award." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + immigration_status: CITIZEN + ssi: 0 + self_employment_income: -10_000 + spm_units: + spm_unit: + members: [person1] + heating_type: PROPANE + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat: 800 + ut_heat_countable_income: 0 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 211, rounded burden 9. +# Fuel addition 0; 144+90=234. +- name: "Case 23, natural gas house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 234 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 161, rounded burden 7. +# Fuel addition 0; 144+70=214. +- name: "Case 24, natural gas apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 214 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 541, rounded burden 23. +# Fuel addition 150; 144+230+150=524. +- name: "Case 25, propane house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: PROPANE + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 524 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 408, rounded burden 17. +# Fuel addition 150; 144+170+150=464. +- name: "Case 26, propane apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: PROPANE + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 464 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 541, rounded burden 23. +# Kerosene shares propane's standard and its addition. +# Fuel addition 150; 144+230+150=524. +- name: "Case 27, kerosene house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: KEROSENE + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 524 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 408, rounded burden 17. +# Kerosene shares propane's standard and its addition. +# Fuel addition 150; 144+170+150=464. +- name: "Case 28, kerosene apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: KEROSENE + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 464 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 468, 468/2400*100=19.5 rounds +# half upward to burden 20. +# Fuel addition 150; 144+200+150=494. +- name: "Case 29, fuel oil house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: FUEL_OIL + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 494 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 354, rounded burden 15. +# Fuel addition 150; 144+150+150=444. +- name: "Case 30, fuel oil apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: FUEL_OIL + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 444 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 287, rounded burden 12. +# Fuel addition 0; 144+120=264. +- name: "Case 31, electricity house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: ELECTRICITY + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 264 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 218, rounded burden 9. +# Fuel addition 0; 144+90=234. +- name: "Case 32, electricity apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: ELECTRICITY + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 234 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 92, rounded burden 4. +# Fuel addition 0; 144+40=184. +- name: "Case 33, coal house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: COAL + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 184 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 71, rounded burden 3. +# Fuel addition 0; 144+30=174. +- name: "Case 34, coal apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: COAL + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 174 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 92, rounded burden 4. +# Fuel addition 0; 144+40=184. +- name: "Case 35, other house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: OTHER + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 184 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 71, rounded burden 3. +# Fuel addition 0; 144+30=174. +- name: "Case 36, other apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: OTHER + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 174 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 343, rounded burden 14. +# Fuel addition 0; 144+140=284. +- name: "Case 37, wood house standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: WOOD + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 284 + +# Size 3, P 2277, I 2400 (36,000 x 0.8 / 12), Q 106 => income 144; standard 260, rounded burden 11. +# Fuel addition 0; 144+110=254. +- name: "Case 38, wood apartment standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: WOOD + heating_expense: 1_200 + ut_heat_dwelling_type: APARTMENT + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat: 254 + +# Separate ordinary gas, targeted propane, mixed-status young-child, and no-heating cases in one vector. +# Unit 1 matches Case 3 (wages 15,960 x 0.8 = 12,768: 370); unit 3 counts the +# undocumented parent's pension in full (unearned: 310 + 150 = 460); unit 4 has +# no heating and no electric bill, so no energy source (section 208). +- name: "Case 39, mixed households preserve separate formulas and eligibility." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + employment_income: 15_960 + ssi: 0 + person2: + age: 60 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: UNDOCUMENTED + pension_income: 15_960 + ssi: 0 + person4: + age: 5 + immigration_status: CITIZEN + ssi: 0 + person5: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + spm_unit2: + members: [person2] + heating_type: PROPANE + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + spm_unit3: + members: [person3, person4] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + spm_unit4: + members: [person5] + heating_type: NONE + pre_subsidy_electricity_expense: 0 + ut_heat_dwelling_type: HOUSE + households: + household1: + members: [person1] + state_code: UT + household2: + members: [person2] + state_code: UT + household3: + members: [person3, person4] + state_code: UT + household4: + members: [person5] + state_code: UT + output: + ut_heat: [370, 800, 460, 0] + ut_heat_household_size: [1, 1, 1, 1] + ut_heat_countable_income: [12_768, 0, 15_960, 0] + ut_heat_eligible: [true, true, true, false] + +# Section 407 and R982-403-7(1)(b) deduct health insurance premiums. A nonzero +# direct premium input replaces the components; otherwise non-Medicare premiums +# and the modeled Part B premium for an enrollee count. Cases 40-43 supply no +# Medicare Savings Program coverage, so the modeled Part B premium is +# 202.90 x 12 = 2,434.80. +# Source: Utah HEAT section 407, effective March 1 through September 30, 2026. +# Award arithmetic uses sections 602-604 and the March 2026 gas-house standard of 211. + +# The reported 2,400 replaces the modeled 2,434.80: 18,360 - 2,400 = 15,960; +# I=1,330, P=1,330, income points=150, burden=160, age credit=150; award=460. +- name: "Case 40, a reported premium replaces the modeled Part B premium." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + immigration_status: "CITIZEN" + pension_income: 18_360 + ssi: 0 + medicare_enrolled: true + health_insurance_premiums: 2_400 + health_insurance_premiums_without_medicare_part_b: 0 + msp_part_b_premium_coverage: 0 + spm_units: + spm_unit1: + members: ["person1"] + heating_type: "NATURAL_GAS" + gas_expense: 1_000 + heat_expense_included_in_rent: false + ut_fep: 0 + ut_heat_dwelling_type: "HOUSE" + households: + household1: + members: ["person1"] + state_code: "UT" + output: + medicare_part_b_premium: 2_434.80 + medical_expense_health_insurance_premiums: 2_400 + ut_heat_countable_income: 15_960 + ut_heat: 460 + +# 18,360 - (1,200 + 2,434.80) - 600 = 14,125.20; I=1,177.10, +# ceil(100*I/1,330)=ceil(88.50)=89 => 161; 211/1,177.10=17.93 => 18 => 180; +# 161+180+150=491. +- name: "Case 41, non-Medicare premiums, the modeled Part B premium and other medical expenses all count." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + immigration_status: "CITIZEN" + pension_income: 18_360 + ssi: 0 + medicare_enrolled: true + health_insurance_premiums: 0 + health_insurance_premiums_without_medicare_part_b: 1_200 + other_medical_expenses: 600 + msp_part_b_premium_coverage: 0 + spm_units: + spm_unit1: + members: ["person1"] + heating_type: "NATURAL_GAS" + gas_expense: 1_000 + heat_expense_included_in_rent: false + ut_fep: 0 + ut_heat_dwelling_type: "HOUSE" + households: + household1: + members: ["person1"] + state_code: "UT" + output: + medicare_part_b_premium: 2_434.80 + ut_heat_countable_income: 14_125.20 + ut_heat: 491 + +# The 1,200 direct aggregate replaces 1,200 + 2,434.80 of components: +# 18,360 - 1,200 aggregate - 600 other medical = 16,560; I=1,380; 146+150+150=446. +- name: "Case 42, a positive premium aggregate prevents component double counting." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + immigration_status: "CITIZEN" + pension_income: 18_360 + ssi: 0 + medicare_enrolled: true + health_insurance_premiums: 1_200 + health_insurance_premiums_without_medicare_part_b: 1_200 + other_medical_expenses: 600 + msp_part_b_premium_coverage: 0 + spm_units: + spm_unit1: + members: ["person1"] + heating_type: "NATURAL_GAS" + gas_expense: 1_000 + heat_expense_included_in_rent: false + ut_fep: 0 + ut_heat_dwelling_type: "HOUSE" + households: + household1: + members: ["person1"] + state_code: "UT" + output: + medicare_part_b_premium: 2_434.80 + medical_expense_health_insurance_premiums: 1_200 + ut_heat_countable_income: 16_560 + ut_heat: 446 + +# 18,360 - 2,434.80 = 15,925.20; I=1,327.10, ceil(100*I/1,330)=ceil(99.78)=100 +# => 150; 211/1,327.10=15.90 => 16 => 160; 150+160+150=460. +- name: "Case 43, Medicare enrollment deducts the modeled Part B premium." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + immigration_status: "CITIZEN" + pension_income: 18_360 + ssi: 0 + medicare_enrolled: true + health_insurance_premiums: 0 + health_insurance_premiums_without_medicare_part_b: 0 + msp_part_b_premium_coverage: 0 + spm_units: + spm_unit1: + members: ["person1"] + heating_type: "NATURAL_GAS" + gas_expense: 1_000 + heat_expense_included_in_rent: false + ut_fep: 0 + ut_heat_dwelling_type: "HOUSE" + households: + household1: + members: ["person1"] + state_code: "UT" + output: + medicare_part_b_premium: 2_434.80 + ut_heat_countable_income: 15_925.20 + ut_heat: 460 + +# Section 402 counts UI payments. The state UI formula gives 764 per week for +# 14 weeks: 10,696. Wages 15,000 x 0.8 = 12,000; 12,000 + 10,696 = 22,696, +# within the 23,940 limit. I=1,891.33, ceil(142.21)=143 => 107; +# 211/1,891.33=11.16 => 11 => 110; 107+110=217. +- name: "Case 44, modeled unemployment compensation counts as unearned income." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + employment_income: 15_000 + ut_ui_base_period_wages: 40_000 + ut_ui_high_quarter_wages: 20_000 + ut_ui_quarters_with_wages: 4 + ut_ui_weeks_unemployed: 20 + ut_ui_gross_weekly_earnings: 0 + ut_ui_weekly_hours_worked: 0 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household1: + members: [person1] + state_code: UT + output: + ut_ui: 10_696 + total_unemployment_compensation: 10_696 + ut_heat_countable_income: 22_696 + ut_heat_income_limit: 23_940 + ut_heat: 217 + +# Sections 402/404: each source is floored at zero, so neither an estate loss +# nor a current business loss offsets other income. +# Both households: 15,000 x 0.8 + 12,000 = 24,000, above the 23,940 limit. +- name: "Case 45, neither estate losses nor business losses erase wages and pensions." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + employment_income: 15_000 + pension_income: 12_000 + estate_income: -12_000 + person2: + age: 40 + immigration_status: CITIZEN + employment_income: 15_000 + pension_income: 12_000 + self_employment_income: -12_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + spm_unit2: + members: [person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household1: + members: [person1] + state_code: UT + household2: + members: [person2] + state_code: UT + output: + ut_heat_countable_income: [24_000, 24_000] + ut_heat: [0, 0] + +# Section 407 permits household-paid, unreimbursed medical premiums. Pretax +# payroll premiums are disjoint from the alternative nonpretax aggregate/components. +# 24,000 x 0.8 = 19,200; less 1,200 pretax = 18,000; monthly 1,500: +# 250 - 113 + 140 = 277. +# 19,200 - 1,200 pretax - 1,200 aggregate = 16,800; monthly 1,400: +# 250 - 106 + 150 = 294. +- name: "Case 46, pretax premiums are deducted once alongside reported nonpretax premiums." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + employment_income: 24_000 + pre_tax_health_insurance_premiums: 1_200 + health_insurance_premiums: 0 + health_insurance_premiums_without_medicare_part_b: 0 + person2: + age: 40 + immigration_status: CITIZEN + employment_income: 24_000 + pre_tax_health_insurance_premiums: 1_200 + health_insurance_premiums: 1_200 + health_insurance_premiums_without_medicare_part_b: 1_200 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + spm_unit2: + members: [person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household1: + members: [person1] + state_code: UT + household2: + members: [person2] + state_code: UT + output: + ut_heat_countable_income: [18_000, 16_800] + ut_heat: [277, 294] + +# Section 602 rounds poverty percentages upward. Wages of 399 give countable +# income 399 x 0.8 = 319.20, exactly 2% of 15,960; a cent of wages below or +# above gives 319.192 or 319.208, so the ceilings are 2, 2, 3. Section 603's +# burden component is capped at 250, giving awards 498, 498, 497. +- name: "Case 47, exact poverty percentages and neighboring cents retain their correct ceilings." + period: 2026 + absolute_error_margin: 0.001 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + employment_income: 398.99 + person2: + age: 40 + immigration_status: CITIZEN + employment_income: 399 + person3: + age: 40 + immigration_status: CITIZEN + employment_income: 399.01 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + spm_unit2: + members: [person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + spm_unit3: + members: [person3] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household1: + members: [person1] + state_code: UT + household2: + members: [person2] + state_code: UT + household3: + members: [person3] + state_code: UT + output: + ut_heat_countable_income: [319.192, 319.20, 319.208] + ut_heat: [498, 498, 497] + +# Sections 401/402 count ordinary DoD retirement pay separately from pensions +# and VA benefits. A veteran retiring after 20 years receives 36,000 per year, +# above the one-person 23,940 income limit; no ordinary heating award is due. +- name: "Case 48, ordinary military retirement pay counts toward heating eligibility." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + is_veteran: true + years_in_military: 20 + military_retirement_pay: 36_000 + pension_income: 0 + veterans_benefits: 0 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household1: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 36_000 + ut_heat_income_limit: 23_940 + ut_heat_eligible: false + ut_heat: 0 + +# Section 402 counts pensions and annuities as unearned income; section 405 +# exempts no uniformed-services survivor annuity. A surviving spouse aged 70 +# receives a 26,000 Survivor Benefit Plan annuity. Medicare Savings Program +# countable income of 26,000 / 12 - 20 = 2,146.67 a month exceeds the QI limit +# of 1,795.50, so the enrollee pays the 2,434.80 Part B premium, which is +# deducted: 26,000 - 2,434.80 = 23,565.20, within the 23,940 limit. +# I=1,963.77, ceil(147.65)=148 => 102; 211/1,963.77=10.74 => 11 => 110; +# 102+110+150 age credit=362. +- name: "Case 49, military survivor annuity counts as income for a Medicare enrollee." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + immigration_status: CITIZEN + military_retirement_pay_survivors: 26_000 + spm_units: + spm_unit1: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household1: + members: [person1] + state_code: UT + output: + military_retirement_income: 26_000 + medicare_part_b_premium: 2_434.80 + ut_heat_countable_income: 23_565.20 + ut_heat_income_limit: 23_940 + ut_heat_eligible: true + ut_heat: 362 + +# Section 407 and R982-403-7(1)(b): an enrollee's Part B premium is a +# deductible health insurance premium. Medicare Savings Program countable +# income is 24,500 / 12 - 20 = 2,021.67 a month, above the QI limit of +# 1,330 x 1.35 = 1,795.50, so the enrollee pays 202.90 x 12 = 2,434.80. +# 24,500 - 2,434.80 = 22,065.20, within the 23,940 limit. I=1,838.77, +# ceil(138.25)=139 => 111; 211/1,838.77=11.48 => 11 => 110; +# 111+110+150 age credit=371. +- name: "Case 50, a Social Security retiree's modeled Part B premium is deducted." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + immigration_status: CITIZEN + ssi: 0 + social_security_retirement: 24_500 + medicare_enrolled: true + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + msp_part_b_premium_coverage: 0 + medicare_part_b_premium: 2_434.80 + ut_heat_countable_income: 22_065.20 + ut_heat_income_limit: 23_940 + ut_heat: 371 + +# R982-403-4(2)(a) and section 403 count military base pay as earned income: +# 30,000 x 0.8 = 24,000, within the size-2 limit of 32,460. +# P=ceil(21,640 / 12)=1,804; I=2,000, ceil(110.86)=111 => 139; +# 211/2,000=10.55 => 11 => 110; 139+110=249. +- name: "Case 51, military basic pay is earned income subject to the disregard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + immigration_status: CITIZEN + ssi: 0 + is_military: true + military_basic_pay: 30_000 + person2: + age: 30 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_household_size: 2 + ut_heat_countable_income: 24_000 + ut_heat_income_limit: 32_460 + ut_heat: 249 + +# R982-403-5(12) excludes interest and dividend income, and plan item 1.9 +# leaves dividends unchecked, so only the 15,000 pension counts (with the +# dividends, 24,000 would exceed the 23,940 limit). I=1,250, +# ceil(93.98)=94 => 156; 211/1,250=16.88 => 17 => 170; 156+170=326. +- name: "Case 52, ordinary dividends do not count toward heating eligibility." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 50 + immigration_status: CITIZEN + ssi: 0 + pension_income: 15_000 + ordinary_dividend_income: 9_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_200 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 15_000 + ut_heat: 326 + +# Plan item 1.1 and section 207: HEAT is one benefit a program year covering +# heating and cooling, and section 603 takes the standard for the household's +# primary energy source. A home with no heating that pays an electric bill +# uses the electricity house standard of 287 (3,444 a year). +# Wages 15,960 x 0.8 = 12,768; I=1,064, Q 80 => 170; 287/1,064=26.97 => 27, +# capped at 25 => 250; 170+250=420. +- name: "Case 53, a home with no heating that pays an electric bill uses the electricity standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + spm_units: + spm_unit: + members: [person1] + heating_type: NONE + pre_subsidy_electricity_expense: 900 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_energy_cost_standard: 3_444 + ut_heat_eligible: true + ut_heat_countable_income: 12_768 + ut_heat: 420 + +# A solar home is taken as grid-tied with electric supplemental heat, so it +# uses the electricity house standard of 287 (3,444 a year), as Case 31 does: +# size 3, I=2,400 (36,000 x 0.8 / 12), Q 106 => 144; 287/2,400=11.96 => 12 +# => 120; 144+120=264. +- name: "Case 54, solar heating uses the electricity standard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 36_000 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: SOLAR + pre_subsidy_electricity_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat_energy_cost_standard: 3_444 + ut_heat: 264 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_countable_income.yaml new file mode 100644 index 00000000000..7863e7546bf --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_countable_income.yaml @@ -0,0 +1,728 @@ +# Sources: Utah Admin. Code R982-403, Utah HEAT sections 401-407 and archived +# March 2026 sections 405/407. +# R982-403-6 and the March 2026 worksheet (cell C8) disregard 20% of earned +# income, including net self-employment and rental income (section 403). +# Prior-period business-loss reconstruction remains outside scope. + +# R982-403-6(1): 18,000 x (1 - 0.2) = 14,400. +- name: "Case 1, twenty percent of gross earnings is disregarded." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 18_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 14_400 + +# Exclusion covers earned and unearned child income; 15,960 x 0.8 = 12,768. +- name: "Case 2, all income of a seventeen year old is excluded." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + person2: + age: 17 + immigration_status: CITIZEN + ssi: 1_200 + employment_income: 12_000 + pension_income: 2_400 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 12_768 + +# Age 18 remains in school; 15,960 x 0.8 = 12,768. +- name: "Case 3, eighteen year old secondary student income is excluded." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + person2: + age: 18 + immigration_status: CITIZEN + ssi: 0 + is_in_secondary_school: true + employment_income: 12_000 + pension_income: 2_400 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 12_768 + +# (15,960 + 12,000) x 0.8 + 2,400 = 24,768; the exclusion ends when the person +# is not in school. +- name: "Case 4, eighteen year old out of school income counts." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + person2: + age: 18 + immigration_status: CITIZEN + ssi: 0 + is_in_secondary_school: false + is_in_k12_school: false + employment_income: 12_000 + pension_income: 2_400 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 24_768 + +# The student exception ends after 18; (15,960 + 12,000) x 0.8 = 22,368. +- name: "Case 5, nineteen year old student income counts." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + person2: + age: 19 + immigration_status: CITIZEN + ssi: 0 + is_in_secondary_school: true + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 22_368 + +# Support received is parent income. +- name: "Case 6, parent child support counts despite child income exclusion." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + child_support_received: 3_600 + person2: + age: 10 + immigration_status: CITIZEN + ssi: 0 + employment_income: 12_000 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 3_600 + +# Count income of all age-eligible members; section 204 allows the disregard on +# the ineligible resident's earnings too: (12,000 + 6,000) x 0.8 = 14,400. +- name: "Case 7, income of ineligible resident counts." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 12_000 + person2: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + employment_income: 6_000 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 14_400 + +# DWS government assistance and ordinary bank interest are exempt. +- name: "Case 8, FEP general assistance and bank interest are excluded." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + general_assistance: 12_000 + interest_income: 1_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + ut_fep: 6_000 + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 0 + +# R982-403-5(12) excludes dividend income and plan item 1.9 leaves dividends +# unchecked; the 2,400 of recurring cash contributions counts. +- name: "Case 9, cash contributions count but ordinary dividends do not." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + ordinary_dividend_income: 1_200 + financial_assistance: 2_400 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 2_400 + +# Annual SSI input 2400=200/month; count gross SSA and pension income. +- name: "Case 10, gross social security SSI and pension count once." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 2_400 + social_security: 12_000 + pension_income: 3_600 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 18_000 + +# 1200+2400+3600+4800. +- name: "Case 11, supported unearned benefit sources count." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + unemployment_compensation: 1_200 + workers_compensation: 2_400 + veterans_benefits: 3_600 + alimony_income: 4_800 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 12_000 + +# Section 403 treats rental income as self-employment, so both supplied net +# amounts are earned income: (12,000 + 3,600) x 0.8 = 12,480. +- name: "Case 12, net business and rental income are earned income subject to the disregard." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + self_employment_income: 12_000 + rental_income: 3_600 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 12_480 + +# Rental income counts only when positive; a rental loss does not offset +# earnings: 15,960 x 0.8 = 12,768. +- name: "Case 13, negative rent does not offset earnings." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + rental_income: -6_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 12_768 + +# 20,400 x 0.8 = 16,320, less paid medical 2,400 and child support 2,040 = 11,880. +- name: "Case 14, medical and support payments are deductible." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 20_400 + other_medical_expenses: 2_400 + child_support_expense: 2_040 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 11_880 + +# Medical payment by an excluded member is allowed; that member's income also +# counts: (15,960 + 6,000) x 0.8 - 6,000 = 11,568. +- name: "Case 15, medical payments by ineligible member remain deductible." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + person2: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + employment_income: 6_000 + other_medical_expenses: 6_000 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 11_568 + +# The supplied generic premium 1,200 takes precedence over the component +# fallback 3,600: 18,000 x 0.8 - 1,200 = 13,200. +- name: "Case 16, reported premiums are not counted twice." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 18_000 + health_insurance_premiums: 1_200 + health_insurance_premiums_without_medicare_part_b: 3_600 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 13_200 + +# 18,000 x 0.8 - 1,200 - 840 = 12,360; a person under 65 has no Medicare premium. +- name: "Case 17, supplied non Medicare premiums are the fallback." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 18_000 + health_insurance_premiums: 0 + health_insurance_premiums_without_medicare_part_b: 1_200 + other_medical_expenses: 840 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 12_360 + +# Qualifying alimony paid outside the unit: 18,400 x 0.8 - 2,440 = 12,280. +- name: "Case 18, alimony paid is deductible." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 18_400 + alimony_expense: 2_440 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 12_280 + +# Countable income is nonnegative: 1,000 x 0.8 - 2,400 floors at 0. +- name: "Case 19, deductions floor countable income at zero." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 1_000 + other_medical_expenses: 2_400 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 0 + +# Enumerated deductions do not include ordinary child care: 15,960 x 0.8 = 12,768. +- name: "Case 20, childcare is not a general qualified deduction." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + childcare_expenses: 2_400 + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 12_768 + +# Each earned source is floored at zero: (15,960 + 0) x 0.8 = 12,768; +# prior-period loss reconstruction unavailable. +- name: "Case 21, current net business loss does not offset other income." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + self_employment_income: -3_960 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 12_768 + +# Section 407 and R982-403-7(1)(b) deduct health insurance premiums. A nonzero +# direct premium input replaces the components; otherwise non-Medicare premiums +# and the modeled Part B premium for an enrollee (net of Medicare Savings +# Program coverage) count, and any Part A premium is added once. +# Source: Utah HEAT section 407, effective March 1 through September 30, 2026. + +# No direct premium and no Medicare Savings Program coverage, so the modeled +# Part B premium is 202.90 x 12 = 2,434.80. +# 18,360 - (1,200 + 2,434.80) - 600 = 14,125.20. +- name: "Case 22, a zero direct premium falls back to non-Medicare premiums plus the modeled Part B premium." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + immigration_status: "CITIZEN" + pension_income: 18_360 + ssi: 0 + medicare_enrolled: true + health_insurance_premiums: 0 + health_insurance_premiums_without_medicare_part_b: 1_200 + other_medical_expenses: 600 + msp_part_b_premium_coverage: 0 + spm_units: + spm_unit1: + members: ["person1"] + heating_type: "NATURAL_GAS" + gas_expense: 1_000 + heat_expense_included_in_rent: false + ut_fep: 0 + ut_heat_dwelling_type: "HOUSE" + households: + household1: + members: ["person1"] + state_code: "UT" + output: + medicare_part_b_premium: 2_434.80 + medical_expense_health_insurance_premiums: 3_634.80 + ut_heat_countable_income: 14_125.20 + +# A retiree with 35 quarters of covered work pays the reduced Part A premium: +# 311 x 12 = 3,732. Medicare Savings Program countable income is +# 18,360 / 12 - 20 = 1,510 a month: above the QMB limit of 1,330 (no Part A +# coverage) but within the SLMB limit of 1,330 x 1.2 = 1,596 with no assets, +# so the program pays the 2,434.80 Part B premium. +# 18,360 - 3,732 - 0 = 14,628. +- name: "Case 23, a Part A premium is deducted and Medicare Savings Program coverage leaves no Part B premium." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 68 + immigration_status: CITIZEN + pension_income: 18_360 + ssi: 0 + medicare_enrolled: true + medicare_quarters_of_coverage: 35 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 1_000 + heat_expense_included_in_rent: false + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + medicare_part_a_premium: 3_732 + msp_part_b_premium_coverage: 2_434.80 + medicare_part_b_premium: 0 + ut_heat_countable_income: 14_628 + +# Every earned and unearned list entry not exercised elsewhere, for an adult. +# Earned: (5,000 SSTB self-employment + 2,500 farm operations + 2,000 +# partnership/S corporation + 1,000 farm rent) x 0.8 = 8,400. +# Unearned: 1,200 railroad + 2,400 retirement distributions + 3,600 survivor +# + 4,800 disability + 600 strike + 300 gambling + 1,800 estate = 14,700. +# 8,400 + 14,700 = 23,100. +- name: "Case 24, remaining earned and unearned income sources count." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 50 + immigration_status: CITIZEN + ssi: 0 + sstb_self_employment_income: 5_000 + farm_operations_income: 2_500 + partnership_s_corp_income: 2_000 + farm_rent_income: 1_000 + railroad_benefits: 1_200 + retirement_distributions: 2_400 + survivor_benefits: 3_600 + disability_benefits: 4_800 + strike_benefits: 600 + gambling_winnings: 300 + estate_income: 1_800 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_countable_income: 23_100 + +# Section 405 excludes the income of an 18-year-old still in school; K-12 +# enrollment qualifies as well as secondary school: 15,960 x 0.8 = 12,768. +- name: "Case 25, eighteen year old K-12 student income is excluded." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 15_960 + person2: + age: 18 + immigration_status: CITIZEN + ssi: 0 + is_in_k12_school: true + is_in_secondary_school: false + employment_income: 12_000 + pension_income: 2_400 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_countable_income: 12_768 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_eligible.yaml new file mode 100644 index 00000000000..83517c343ff --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_eligible.yaml @@ -0,0 +1,440 @@ +# Sources: Utah HEAT manual sections 202-204, 208 and March 2026 section 608. +# The annual 2026 period represents the March 2026 snapshot. + +# Wages 29,925 x 0.8 = 23,940; monthly income 1995 equals published 150% limit. +- name: "Case 1, inclusive income limit." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 29_925 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: true + +# Wages 29,925.15 x 0.8 = 23,940.12; monthly income 1995.01 exceeds limit. +- name: "Case 2, income just above limit." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + employment_income: 29_925.15 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: false + +# Requires adult 18+; emancipation unavailable. +- name: "Case 3, no adult member." + period: 2026 + input: + people: + person1: + age: 17 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: false + +# Adult threshold is inclusive 18. +- name: "Case 4, adult age eighteen." + period: 2026 + input: + people: + person1: + age: 18 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: true + +# At least one eligible person. +- name: "Case 5, no qualified member." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: false + +# An eligible child can qualify unit; the adult need not be eligible. +- name: "Case 6, citizen child with ineligible adult." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + person2: + age: 5 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_eligible: true + +# Utah residence required. +- name: "Case 7, wrong state." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: ID + output: + ut_heat_eligible: false + +# NONE affirmatively denotes no home heat; with no electric bill the home is +# not connected to an energy source (section 208) and has no energy cost +# standard. Case 53 in ut_heat.yaml covers a NONE household with a bill. +- name: "Case 8, no heating source and no electric bill." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NONE + pre_subsidy_electricity_expense: 0 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_energy_cost_standard: 0 + ut_heat_eligible: false + +# No supplied responsibility. +- name: "Case 9, no energy costs or rent responsibility." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + pre_subsidy_electricity_expense: 0 + heat_expense_included_in_rent: false + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: false + +# Households supplying own firewood are eligible. +- name: "Case 10, self supplied firewood qualifies." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: WOOD + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: true + +# Indirect energy responsibility. +- name: "Case 11, ordinary heat in rent." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + rent: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + heat_expense_included_in_rent: true + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: true + +# Utility costs are wholly covered. +- name: "Case 12, subsidized rent with all utilities covered." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + heat_expense_included_in_rent: true + pre_subsidy_electricity_expense: 0 + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: false + +# Separately paid utility in addition to subsidized rent. +- name: "Case 13, subsidized rent with separately paid electricity." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + heat_expense_included_in_rent: true + pre_subsidy_electricity_expense: 600 + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: true + +# Subsidized housing does not itself bar utility responsibility. +- name: "Case 14, subsidized household directly pays heating." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + receives_housing_assistance: true + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: true + +# Section 208 and plan item 2.3: public housing counts as subsidized housing, +# and heat included in subsidized rent is not a household energy cost. +- name: "Case 15, public housing with heat in rent and no utility bill." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + heat_expense_included_in_rent: true + pre_subsidy_electricity_expense: 0 + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: UT + is_in_public_housing: true + output: + ut_heat_eligible: false + +# A public housing tenant who pays an electric bill directly is responsible for +# an energy cost (section 208). +- name: "Case 16, public housing with a separately paid electric bill." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + heat_expense_included_in_rent: true + pre_subsidy_electricity_expense: 600 + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: UT + is_in_public_housing: true + output: + ut_heat_eligible: true + +# The household reports paying for heat without a bill amount; the heating-cost +# flag alone establishes responsibility (section 208). Case 9 is the same +# household without the flag. +- name: "Case 17, reported heating costs without a bill amount qualify." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + pre_subsidy_electricity_expense: 0 + heat_expense_included_in_rent: false + has_heating_expense: true + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible: true + +# Case 11 with no heating type reported. Heat in unsubsidized rent makes the +# household responsible for an energy cost, but an unspecified fuel has no +# energy cost standard, so the household is not eligible. +- name: "Case 18, heat in rent with no heating type reported." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + rent: 12_000 + spm_units: + spm_unit: + members: [person1] + heating_type: UNSPECIFIED + heating_expense: 0 + ut_heat_dwelling_type: HOUSE + heat_expense_included_in_rent: true + receives_housing_assistance: false + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_energy_cost_standard: 0 + ut_heat_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_eligible_person.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_eligible_person.yaml new file mode 100644 index 00000000000..fe2a4448e7f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_eligible_person.yaml @@ -0,0 +1,510 @@ +# Source: Utah HEAT section 203-2B, effective October 1, 2025. +# LPR is separately eligible; parole/conditional entry needs an eligible criterion. +# Service exceptions use actual marital, tax and family relationships. + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 1, citizen." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + years_since_us_entry: 0 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 2, recent permanent resident." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: LEGAL_PERMANENT_RESIDENT + ssi: 0 + years_since_us_entry: 0 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 3, refugee." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: REFUGEE + ssi: 0 + years_since_us_entry: 0 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 4, asylee." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: ASYLEE + ssi: 0 + years_since_us_entry: 0 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 5, deportation withheld." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: DEPORTATION_WITHHELD + ssi: 0 + years_since_us_entry: 0 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 6, Cuban Haitian entrant." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CUBAN_HAITIAN_ENTRANT + ssi: 0 + years_since_us_entry: 0 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 7, parole below five years." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 4.99 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: false + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 8, parole at five years." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 5 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 9, conditional entrant below five years." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CONDITIONAL_ENTRANT + ssi: 0 + years_since_us_entry: 4.99 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: false + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 10, conditional entrant at five years." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CONDITIONAL_ENTRANT + ssi: 0 + years_since_us_entry: 5 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 11, undocumented resident." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + years_since_us_entry: 10 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: false + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 12, DACA recipient." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: DACA + ssi: 0 + years_since_us_entry: 10 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: false + +# Section 203-2 B qualified and eligible categories, including the explicit LPR exception. +- name: "Case 13, TPS recipient." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: TPS + ssi: 0 + years_since_us_entry: 10 + is_veteran: false + is_military: false + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: false + +# The qualifying veteran exception has no time limit. +- name: "Case 14, recent parolee who is a veteran." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 0 + is_veteran: true + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# An actual marital-unit connection; no synthetic SPM-wide veteran flag. +- name: "Case 15, actual spouse of veteran qualifies without five years." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + is_veteran: true + is_tax_unit_head: true + person2: + age: 38 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 0 + is_tax_unit_spouse: true + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + marital_units: + marital_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + output: + ut_heat_eligible_person: [true, true] + +# Share an SPM unit and household but have separate family, tax, and marital units. +- name: "Case 16, unrelated veteran does not confer immigration eligibility." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + is_veteran: true + is_tax_unit_head: true + person2: + age: 38 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 0 + is_tax_unit_head: true + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + families: + family1: + members: [person1] + family2: + members: [person2] + output: + ut_heat_eligible_person: [true, false] + +# Section 203-2B: active-duty service is an eligible criterion for a parolee +# with no time in qualified status. +- name: "Case 17, recent parolee on active duty qualifies." + period: 2026 + input: + people: + person1: + age: 30 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 0 + is_veteran: false + is_military: true + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_eligible_person: true + +# Section 203-2B extends the service criterion to a veteran's dependent child. +# The 10-year-old is a dependent in the veteran's tax unit and qualifies; the +# 25-year-old child files a separate return, is not a dependent, and has no +# qualifying service or five years in status, so does not. +- name: "Case 18, a veteran's dependent child qualifies but a non-dependent adult child does not." + period: 2026 + input: + people: + person1: + age: 45 + immigration_status: CITIZEN + ssi: 0 + is_veteran: true + is_tax_unit_head: true + person2: + age: 10 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 0 + person3: + age: 25 + immigration_status: PAROLED_ONE_YEAR + ssi: 0 + years_since_us_entry: 0 + is_tax_unit_head: true + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + marital_unit3: + members: [person3] + tax_units: + tax_unit1: + members: [person1, person2] + tax_unit2: + members: [person3] + output: + ut_heat_eligible_person: [true, true, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_household_size.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_household_size.yaml new file mode 100644 index 00000000000..eec29338b43 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_household_size.yaml @@ -0,0 +1,61 @@ +# Source: Utah HEAT section 204; exclude ineligible persons from household size. + +# Only the eligible child and refugee count. +- name: "Case 1, only qualified members enter size." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + person2: + age: 5 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: TPS + ssi: 0 + person4: + age: 40 + immigration_status: REFUGEE + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3, person4] + state_code: UT + output: + ut_heat_household_size: 2 + +# No eligible member. +- name: "Case 2, no eligible members gives zero size." + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + ssi: 0 + person2: + age: 40 + immigration_status: DACA + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_household_size: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_income_limit.yaml new file mode 100644 index 00000000000..ebe4566ad8a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/dwf/heat/ut_heat_income_limit.yaml @@ -0,0 +1,237 @@ +# Source: Utah HEAT section 608 and the March 1, 2026 poverty table. +# Annual thresholds are 1.5 * (15,960 + 5,680 * (eligible members - 1)). + +# 1.5*(15960+5680*(size-1)); above 14 published monthly increment 710. +- name: "Case 1, published March limit for 1 eligible members." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1] + state_code: UT + output: + ut_heat_income_limit: 23_940 + +# 1.5*(15960+5680*(size-1)); above 14 published monthly increment 710. +- name: "Case 2, published March limit for 2 eligible members." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2] + state_code: UT + output: + ut_heat_income_limit: 32_460 + +# 1.5*(15960+5680*(size-1)); above 14 published monthly increment 710. +- name: "Case 3, published March limit for 3 eligible members." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3] + state_code: UT + output: + ut_heat_income_limit: 40_980 + +# 1.5*(15960+5680*(size-1)); above 14 published monthly increment 710. +- name: "Case 4, published March limit for 14 eligible members." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person4: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person5: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person6: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person7: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person8: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person9: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person10: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person11: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person12: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person13: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person14: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: UT + output: + ut_heat_income_limit: 134_700 + +# 1.5*(15960+5680*(size-1)); above 14 published monthly increment 710. +- name: "Case 5, published March limit for 15 eligible members." + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person2: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person3: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person4: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person5: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person6: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person7: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person8: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person9: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person10: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person11: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person12: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person13: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person14: + age: 40 + immigration_status: CITIZEN + ssi: 0 + person15: + age: 40 + immigration_status: CITIZEN + ssi: 0 + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15] + heating_type: NATURAL_GAS + heating_expense: 1_200 + ut_heat_dwelling_type: HOUSE + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14, person15] + state_code: UT + output: + ut_heat_income_limit: 143_220 diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_eligible.py b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_eligible.py new file mode 100644 index 00000000000..ca70a4fa5d7 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_eligible.py @@ -0,0 +1,54 @@ +from policyengine_us.model_api import * + + +class ut_heat_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Utah HEAT regular heating assistance eligibility" + defined_for = StateCode.UT + reference = ( + "https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_200/Obsolete_202_(03_01_26_to_09_30_26)_Eligibility_Standards.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_200/Obsolete_208_(03_01_26_to_09_30_26)_Vulnerability.htm", + "https://liheapch.acf.gov/docs/2026/state-plans/UT_Plan_2026.pdf#page=8", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.dwf.heat.eligibility + has_adult = spm_unit.any(spm_unit.members("age", period) >= p.adult_age) + size = spm_unit("ut_heat_household_size", period) + income = spm_unit("ut_heat_countable_income", period) + limit = spm_unit("ut_heat_income_limit", period) + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + subsidized = spm_unit( + "receives_housing_assistance", period + ) | spm_unit.household("is_in_public_housing", period) + directly_paid = ( + spm_unit("has_heating_expense", period) + | (spm_unit("heating_expense", period) > 0) + | (spm_unit("pre_subsidy_electricity_expense", period) > 0) + ) + fuel = spm_unit("heating_type", period) + own_wood = fuel == fuel.possible_values.WOOD + responsible = directly_paid | (heat_in_rent & ~subsidized) | own_wood + housing_eligible = ~subsidized | directly_paid + # A household with no heating (NONE) has a standard, and so + # qualifies, only when it pays an electric bill; one with no bill is + # not connected to an energy source (section 208). UNSPECIFIED has no + # standard. + supported_fuel = spm_unit("ut_heat_energy_cost_standard", period) > 0 + # The annual potential award assumes no prior seasonal payment or + # disqualifying utility credit balance. Emancipation, institutions, + # tribal duplicate assistance and special RV rules are unobserved. + # Self-supplied firewood qualifies without a bill. Subsidized housing + # requires a separately paid utility; subsidies alone are not expenses. + # The existing heating-cost flag can supply that separate obligation + # when the primary fuel bill does not capture it. + return ( + (size > 0) + & has_adult + & (income <= limit) + & responsible + & housing_eligible + & supported_fuel + ) diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_eligible_person.py b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_eligible_person.py new file mode 100644 index 00000000000..8736f27a7a4 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_eligible_person.py @@ -0,0 +1,36 @@ +from policyengine_us.model_api import * + + +class ut_heat_eligible_person(Variable): + value_type = bool + entity = Person + definition_period = YEAR + label = "Meets the Utah HEAT citizenship or immigration requirement" + defined_for = StateCode.UT + reference = "https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/203_Citizenship_and_Non-Citizenship_Requirements/203-2B_Qualified_and_Eligible_Non-Citizens.htm" + + def formula(person, period, parameters): + p = parameters(period).gov.states.ut.dwf.heat.eligibility.immigration + status = person("immigration_status", period).decode_to_str() + eligible_status = np.isin(status, p.eligible_statuses) + conditional_status = np.isin(status, p.conditional_statuses) + waited = person("years_since_us_entry", period) >= p.waiting_period + served = person("is_veteran", period) | person("is_military", period) + # Marital units identify spouses; tax-unit roles and the child link + # identify dependent children. Unrelated household members do not confer + # the exception. Supply these units/links explicitly for complex families. + self_or_spouse_served = person.marital_unit.any(served) + dependent_child = person("is_tax_unit_dependent", period) & person( + "is_child_of_tax_head", period + ) + parent_served = person.tax_unit.any( + served & person("is_tax_unit_head_or_spouse", period) + ) + military_connection = self_or_spouse_served | (dependent_child & parent_served) + # The existing service flags do not distinguish honorable discharge or + # full-time active duty from National Guard service. The entry clock + # stands for years in qualified status, not merely physical presence. + # COFA, trafficking, battered and special Afghan/Ukrainian statuses are + # not separately observable. LPR is expressly eligible in section 203-2B; + # SNAP's broader waiting-period and child-age rules are not imported. + return eligible_status | (conditional_status & (waited | military_connection)) diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_household_size.py b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_household_size.py new file mode 100644 index 00000000000..7960734ad38 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_household_size.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class ut_heat_household_size(Variable): + value_type = int + entity = SPMUnit + definition_period = YEAR + label = "Utah HEAT eligible household size" + defined_for = StateCode.UT + reference = "https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/204_Eligibility_with_Ineligible_Resident.htm" + # SPM units approximate the shared residence and energy-cost unit. Temporary + # guests, absences, shared custody and the foster-child election are unobserved. + adds = ["ut_heat_eligible_person"] diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_income_limit.py b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_income_limit.py new file mode 100644 index 00000000000..078cd3ccbd0 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/eligibility/ut_heat_income_limit.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class ut_heat_income_limit(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Utah HEAT annual income limit" + defined_for = StateCode.UT + reference = "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/608_Table_II_Federal_Poverty_Level_(FPL)_Monthly_Income_Limits.htm" + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.dwf.heat.eligibility + # The published 150% column uses unrounded annual FPG, rather than + # multiplying the upward-rounded monthly 100% benefit denominator. + return spm_unit("ut_heat_fpg", period) * p.income_limit diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/income/ut_heat_countable_income.py b/policyengine_us/variables/gov/states/ut/dwf/heat/income/ut_heat_countable_income.py new file mode 100644 index 00000000000..5db7f77b495 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/income/ut_heat_countable_income.py @@ -0,0 +1,73 @@ +from policyengine_us.model_api import * + + +class ut_heat_countable_income(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Utah HEAT annual countable household income" + defined_for = StateCode.UT + reference = ( + "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-2", + "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-6", + "https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-7", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_401_(10_1_24_to_9_30_26)_Income.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/400_Income_Standards/402_Unearned_Income.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/400_Income_Standards/403_Earned_Income.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/400_Income_Standards/404_Self-Employment/404_Self-Employment.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_405_(3_1_25_to_9_30_26)_Income_Exclusions.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_407_(3_1_26_to_9_30_26)_Qualified_Deductions.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/204_Eligibility_with_Ineligible_Resident.htm", + "https://jobs.utah.gov/infosource/heatpolicy/assets/docs/Training/FY26/3.1.26%20Benefit%20Calculation%20Worksheet.xlsx", + "https://liheapch.acf.gov/docs/2026/state-plans/UT_Plan_2026.pdf#page=6", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.dwf.heat.income + person = spm_unit.members + age = person("age", period) + in_school = person("is_in_k12_school", period) | person( + "is_in_secondary_school", period + ) + excluded_child = (age < p.child_income_age) | ( + (age < p.student_income_age) & in_school + ) + # Annual inputs approximate the preceding eligibility month. All + # otherwise countable adult income counts regardless of immigration. + # Each source is floored at zero, so a business or rental loss does + # not offset other income. R982-403-6 disregards 20% of earned income, + # including self-employment income after business costs; section 204 + # and the March 2026 worksheet (cell C8) apply the same disregard. + earned = 0 + for source in p.earned_income_sources: + earned = earned + max_(person(source, period), 0) + unearned = 0 + for source in p.unearned_income_sources: + unearned = unearned + max_(person(source, period), 0) + counted = earned * (1 - p.earned_income_disregard) + unearned + income = spm_unit.sum(where(excluded_child, 0, counted)) + # Child support belongs on the receiving parent. TANF/FEP/GA, ordinary + # bank interest, educational aid and exempt nonrecurring receipts are + # excluded. Broad inputs cannot isolate all exempt gifts, settlements, + # combat pay, third-party payments, or cash withdrawals from trusts. + # Section 407 and R982-403-7(1)(b) count health insurance premiums as + # medical expenses. The premium aggregate takes a nonzero direct + # premium input, or else non-Medicare premiums plus the modeled Part B + # premium for enrollees net of Medicare Savings Program coverage; Part A + # and pretax payroll premiums are added once each. + medical = spm_unit.sum( + max_(person("medical_expense_health_insurance_premiums", period), 0) + + max_(person("pre_tax_health_insurance_premiums", period), 0) + + person("medicare_part_a_premium", period) + + max_(person("other_medical_expenses", period), 0) + ) + support_paid = add( + spm_unit, period, ["child_support_expense", "alimony_expense"] + ) + # Reported medical costs approximate qualified uncompensated payments. + # Self-employed premiums must be included only once. Support to an + # included child, payment timing and medical-purpose restrictions are + # not identified by these inputs. The seasonal equipment deduction is + # outside the heating-bill scope. + return max_(income - medical - max_(support_paid, 0), 0) diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat.py b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat.py new file mode 100644 index 00000000000..9af75fd2d54 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat.py @@ -0,0 +1,79 @@ +from policyengine_us.model_api import * + + +class ut_heat(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Utah Home Energy Assistance Target regular heating benefit" + defined_for = "ut_heat_eligible" + reference = ( + "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/602_Percent_of_Poverty.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/603_Energy_Burden.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_600/Obsolete_604_(3_1_25_to_9_30_26)_Target_Groups.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/605_Propane_or_Fuel_Oil.htm", + # PDF pages 8-9. + "https://liheapch.acf.gov/docs/2026/state-plans/UT_Plan_2026.pdf#page=8", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.dwf.heat.benefit + annual_income = spm_unit("ut_heat_countable_income", period) + income = annual_income.astype(float) / MONTHS_IN_YEAR + poverty = np.ceil( + spm_unit("ut_heat_fpg", period).astype(float) / MONTHS_IN_YEAR + ) + lower_poverty_percentage = np.floor( + np.divide( + income / p.rounding_increment, + poverty, + out=np.zeros_like(income), + where=poverty > 0, + ) + ) + # Compare integer percentage boundaries at stored annual-income precision. + poverty_boundary = ( + lower_poverty_percentage * poverty * p.rounding_increment * MONTHS_IN_YEAR + ).astype(annual_income.dtype) + # Sections 602/603 require numeric rounding, not merely the stale + # XLSX's zero-decimal display. Percentage-point size is the policy's + # rounding increment; 0.5 implements nearest-whole, ties upward. + income_points = ( + p.income_component + - lower_poverty_percentage + - (annual_income > poverty_boundary) + ) + standard = spm_unit("ut_heat_energy_cost_standard", period) / MONTHS_IN_YEAR + burden_percentage = np.divide( + standard / p.rounding_increment, + income, + out=np.zeros_like(income), + where=income > 0, + ) + burden_points = np.floor(burden_percentage + 0.5) + capped_burden = min_(burden_points, p.maximum_burden / p.rounding_increment) + burden_component = where( + income > 0, + capped_burden * p.burden_point_amount, + p.maximum_burden / p.rounding_increment * p.burden_point_amount, + ) + person = spm_unit.members + age = person("age", period) + target_member = person("ut_heat_eligible_person", period) & ( + (age < p.target.child_age) + | (age >= p.target.elderly_age) + | person("is_disabled", period) + ) + target_credit = spm_unit.any(target_member) * p.target.amount + fuel = spm_unit("heating_type", period) + fuel_credit = np.isin(fuel.decode_to_str(), p.fuel_credit_types) * p.fuel_credit + # Kerosene shares propane's cost standard and its addition: the March + # 2026 worksheet has no kerosene fuel, so a kerosene household is + # entered as propane or oil. No actual-expense cap applies. + # Funding-dependent extra supplements and equipment/crisis are excluded. + # Section 607 and the March 2026 worksheet add the components with no + # floor or ceiling. Plan section 2.6 reports $140 and $800 as estimated + # benefit levels; $800 is the formula's maximum and $140 its one-person + # minimum, so larger households can receive less. + return income_points + burden_component + target_credit + fuel_credit diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_dwelling_type.py b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_dwelling_type.py new file mode 100644 index 00000000000..b4efd92e2f0 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_dwelling_type.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class UtHeatDwellingType(Enum): + APARTMENT = "Apartment, condominium, townhouse, or small trailer home" + HOUSE = "House, mobile home, basement apartment, or duplex" + + +class ut_heat_dwelling_type(Variable): + value_type = Enum + entity = SPMUnit + possible_values = UtHeatDwellingType + default_value = UtHeatDwellingType.HOUSE + definition_period = YEAR + label = "Utah HEAT dwelling category" + defined_for = StateCode.UT + reference = "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/609_Table_III_Monthly_Energy_Cost_Standards.htm" diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_energy_cost_standard.py b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_energy_cost_standard.py new file mode 100644 index 00000000000..20ff981e3ac --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_energy_cost_standard.py @@ -0,0 +1,58 @@ +from policyengine_us.model_api import * + + +class ut_heat_energy_cost_standard(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Utah HEAT annual energy cost standard" + defined_for = StateCode.UT + reference = ( + "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/609_Table_III_Monthly_Energy_Cost_Standards.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/603_Energy_Burden.htm", + "https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_200/Obsolete_207_(01_01_25_to_09_30_26)_Eligible_Households-copy.htm", + "https://liheapch.acf.gov/docs/2026/state-plans/UT_Plan_2026.pdf#page=4", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.ut.dwf.heat.benefit + dwelling = spm_unit("ut_heat_dwelling_type", period) + standard = p.monthly_energy_cost_standard[dwelling] + fuel = spm_unit("heating_type", period) + fuels = fuel.possible_values + # HEAT is one benefit a program year covering heating and cooling + # (plan item 1.1, section 207), and section 603 takes the standard for + # the household's primary energy source. A home with no heating that + # pays an electric bill therefore uses the electricity standard. Solar + # homes are taken as grid-tied with electric supplemental heat, as + # heating_expense reads their electricity bill. + electric_without_heating = (fuel == fuels.NONE) & ( + spm_unit("pre_subsidy_electricity_expense", period) > 0 + ) + monthly_standard = select( + [ + fuel == fuels.NATURAL_GAS, + (fuel == fuels.PROPANE) | (fuel == fuels.KEROSENE), + fuel == fuels.FUEL_OIL, + (fuel == fuels.ELECTRICITY) + | (fuel == fuels.SOLAR) + | electric_without_heating, + (fuel == fuels.COAL) | (fuel == fuels.OTHER), + fuel == fuels.WOOD, + ], + [ + standard.natural_gas, + standard.propane, + standard.fuel_oil, + standard.electricity, + standard.coal, + standard.wood, + ], + # UNSPECIFIED has no verified schedule; zero denotes unsupported + # model coverage, not a legal zero-cost standard. A NONE household + # with no electric bill is not connected to an energy source + # (section 208) and never qualifies. + default=0, + ) + return monthly_standard * MONTHS_IN_YEAR diff --git a/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_fpg.py b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_fpg.py new file mode 100644 index 00000000000..fc794371401 --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/dwf/heat/ut_heat_fpg.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class ut_heat_fpg(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Federal poverty guideline for the Utah HEAT household" + defined_for = StateCode.UT + reference = "https://jobs.utah.gov/infosource/heatpolicy/Policy/600_Payment_Calculation/608_Table_II_Federal_Poverty_Level_(FPL)_Monthly_Income_Limits.htm" + + def formula(spm_unit, period, parameters): + size = spm_unit("ut_heat_household_size", period) + state_group = spm_unit.household("state_group_str", period) + # Annual 2026 represents the March 2026 snapshot: current-year FPG. + # Application dates and the March/October transitions are not observed. + # Parameter backfilling does not verify other historical or future years. + amount = fpg(max_(size, 1), state_group, period, parameters, year_lag=0) + return where(size > 0, amount, 0) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index dfbda8868e1..f6e80f64bf4 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -6728,6 +6728,132 @@ candidates: state: open note: 'PE-US follows the regulation; resolve the pending conflict with the information letter. Code not yet on main: tx_ssi_state_supplement.' +- id: us-ut:heat-child-unearned-income + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Does Utah HEAT count a child's unearned income, as Utah Admin. Code R982-403-5(1) implies by excluding only + an unemancipated member's earned income, or exclude all income of children, as manual section 405 does? + sources: + - kind: regulation + citation: Utah Admin. Code R982-403-5(1), effective June 14, 2022 (the linked Cornell LII copy carries + the 2014 wording, unchanged in substance for this provision) + url: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-5 + - kind: manual + citation: Utah HEAT Manual section 405, effective March 1, 2025 to September 30, 2026 + url: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_405_(3_1_25_to_9_30_26)_Income_Exclusions.htm + readings: + statute: No statute is supplied; R982-403-5(1) excludes the "earned income of an unemancipated household member", + so a child's unearned income, such as Social Security survivor benefits, counts under R982-403-3. + other: Manual section 405 reads "Do not count any income of a child (earned or unearned), 17 years old or younger. + Do not count income of an 18 year old unless they have dropped out of school or graduated." + example: A parent aged 35 with $12,000 annual wages and a child aged 10 with $6,000 of Social Security survivor + benefits, heating a house with natural gas, receive $455 under the manual (monthly countable income $800 after + the earned income disregard) versus $337 under the rule (monthly $1,300). + pe_us: + follows: conflicting-source + code: + - policyengine_us/parameters/gov/states/ut/dwf/heat/income/child_income_age.yaml + - policyengine_us/parameters/gov/states/ut/dwf/heat/income/student_income_age.yaml + - policyengine_us/variables/gov/states/ut/dwf/heat/income/ut_heat_countable_income.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10344 + state: open + note: PE-US follows manual section 405 and excludes all income of members younger than 18 and of 18-year-olds in + secondary school (child_income_age.yaml, student_income_age.yaml, ut_heat_countable_income.py). R982-403 is a + current rule with its next five-year review due June 17, 2027, so decide whether it governs over the manual. +- id: us-ut:heat-earned-income-disregard + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Does Utah HEAT disregard 20% of earned income, as Utah Admin. Code R982-403-6 provides, or count earned + income in full, as the retired manual section 406 implies? + sources: + - kind: regulation + citation: Utah Admin. Code R982-403-2 and R982-403-6, effective June 14, 2022 (the linked Cornell LII + copy carries the 2014 wording, unchanged in substance for these provisions) + url: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-6 + - kind: manual + citation: Utah HEAT Manual section 204, effective October 1, 2024 + url: https://jobs.utah.gov/infosource/heatpolicy/Policy/200_Program_Standards/204_Eligibility_with_Ineligible_Resident.htm + - kind: worksheet + citation: Utah HEAT Benefit Calculation Worksheet, effective March 1, 2026, cells C8 and B11 + url: https://jobs.utah.gov/infosource/heatpolicy/assets/docs/Training/FY26/3.1.26%20Benefit%20Calculation%20Worksheet.xlsx + - kind: calculator + citation: Utah FY2026 LIHEAP benefit matrix workbook, cells C8 and B11 + url: https://liheapch.acf.gov/docs/2026/benefits-matricies/UT_BenefitMatrix_2026.xlsx + - kind: manual + citation: Utah HEAT Manual section 401, effective October 1, 2024 to September 30, 2026 + url: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_401_(10_1_24_to_9_30_26)_Income.htm + - kind: manual + citation: Utah HEAT Manual section 406, income disregards obsolete September 30, 2023 + url: https://jobs.utah.gov/infosource/heatpolicy/Policy/400_Income_Standards/406_No_Longer_Applicable.htm + readings: + statute: No statute is supplied; R982-403-2 makes countable income "gross income minus exclusions, disregards, and + deductions", and R982-403-6 disregards 20% of earned income, including self-employment earned income after the + cost of doing business. Manual section 204 ("Allow the 20% disregard on the earned income of all household + members"), the March 2026 worksheet (C8 = B8*0.2, "20% disregard"; B11 = B8+B9-C8-B10) and the FY2026 workbook + apply the same disregard. + other: Manual section 406 marks income disregards no longer applicable from September 30, 2023, and sections 401 + and 603 describe countable income as gross income minus exclusions and deductions without naming a disregard. + example: A one-person household with $27,000 annual wages heating a house with natural gas receives $234 with the + disregard (monthly $1,800) and $0 without it (monthly $2,250 exceeds the $1,995 limit). + pe_us: + follows: statute + code: + - policyengine_us/parameters/gov/states/ut/dwf/heat/income/earned_income_disregard.yaml + - policyengine_us/variables/gov/states/ut/dwf/heat/income/ut_heat_countable_income.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10344 + state: unreviewed + note: PE-US follows R982-403-6, manual section 204 and the March 2026 worksheet and disregards 20% of earned income + after per-source zero floors (earned_income_disregard.yaml, ut_heat_countable_income.py). The worksheet PDF prints + only A1:B67, so its disregard column C does not appear there. The open question is whether retired section 406 + signals a practice of counting earnings in full; no current DWS source applies one. +- id: us-ut:heat-tanf-dws-payments + program: liheap + years: + from: 2026 + to: 2026 + type: federal-fiscal + question: Does Utah HEAT count TANF and other financial payments made by the Department of Workforce Services, as + Utah Admin. Code R982-403-3(2)(l) and (n) list them, or exclude them, as manual section 405 and plan item 1.9 do? + sources: + - kind: regulation + citation: Utah Admin. Code R982-403-3(2)(l) and (n), effective June 14, 2022 (the linked Cornell LII + copy carries the 2014 wording, unchanged in substance for these provisions) + url: https://www.law.cornell.edu/regulations/utah/Utah-Admin-Code-R982-403-3 + - kind: manual + citation: Utah HEAT Manual section 405, effective March 1, 2025 to September 30, 2026 + url: https://jobs.utah.gov/infosource/heatpolicy/Policy/Obsolete_Policy/Obsolete_400/Obsolete_405_(3_1_25_to_9_30_26)_Income_Exclusions.htm + - kind: plan + citation: Utah FY2026 LIHEAP State Plan, item 1.9 + url: https://liheapch.acf.gov/docs/2026/state-plans/UT_Plan_2026.pdf#page=6 + readings: + statute: No statute is supplied; R982-403-3(2) lists "(l) financial payments made by the Department" and "(n) + Temporary Assistance to Needy Families" as countable unearned income. + other: Manual section 405 excludes "Temporary Assistance to Needy Families (TANF), Family Employment Program (FEP), + General Assistance (GA), Transitional Cash Assistance, financial payments made by the Department of Workforce + Services, or other financial assistance from non-profits / other government agencies", and plan item 1.9 leaves + TANF and General Assistance benefits unchecked. + example: A parent aged 30 with $12,000 annual wages, $4,800 of Family Employment Program cash assistance and a child + aged 4, heating a house with natural gas, receives $605 under the manual and plan (monthly countable income $800 + after the earned income disregard) versus $513 under the rule (monthly $1,200). + pe_us: + follows: conflicting-source + code: + - policyengine_us/parameters/gov/states/ut/dwf/heat/income/unearned_income_sources.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10344 + state: open + note: PE-US follows manual section 405 and plan item 1.9, so unearned_income_sources.yaml lists neither tanf nor the + Utah state supplement (ut_ssp, which adds ut_dws_ssp, a Department of Workforce Services payment, and ut_dhhs_ssp, + another agency payment that section 405 excludes in the same item). R982-403 is a current rule with its next + five-year review due June 17, 2027, so decide whether it governs over the manual and plan. - id: us-va:ag-entry-month-spouse-at-home program: ssi-state-supplement years: