Repository navigation
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # policyengine_us/programs.yaml
PR Review: Add Minnesota EAP Primary Heat benefitPR #10433 (author: hua7450), head
The PR has no comments or reviews yet, and it touches no partner test file. Path prefixes:
Sources read for this review:
SummaryWhat is right. The published FFY2026 and FFY2027 values are encoded correctly:
There are no critical findings and three should-address items:
There are also six suggestions:
Status.
Critical (must fix)None. Should addressS1. Railroad retirement annuities are counted gross of the Medicare premium, while Social Security and pensions are counted net
S2. Twenty income and cost entries, and one eligibility branch, have no test that would fail if they were dropped
S3. The
|
DTrim99
left a comment
There was a problem hiding this comment.
All 40 limit cells (50% SMI, with the 110% FPG floor from size 19), both workbooks' pay-share constants and formulas, all 112 backup-matrix cells and the heat-in-rent and subsidized paths check out, 22 expectations hand-check, and MSA is correctly excluded. Three should-address items: (1) railroad_benefits are counted gross of Part B while SS and pensions are netted, though RRB withholds Part B (a $38k railroad retiree gets $0 instead of $216); (2) many entries are unpinned (6/7 earned, 9/12 unearned, tanf/GA, 3/7 energy-cost sources, the public-housing branch); (3) the smi_rate description is off-template. Six suggestions. Full report in the comment above.
Apply DTrim99's round 1 review: tests that pin every income source, the rule and documentation fixes, and source-conflict candidates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…into mn-liheap-wave1d # Conflicts: # policyengine_us/programs.yaml # source_conflicts/candidates.yaml
|
Thanks, David. Round 1 is in
The PR body and TheAxiomFoundation/rulespec-us#1894 now describe this head. The Axiom issue adds the RRB page to its sources, rewrites interpretation 9, adds companion test 14 (railroad $216, PERA with Part A $408) and gives the new case counts. I did not run the tests locally; CI passed every check at |
PR Review (round 2): Add Minnesota EAP Primary Heat benefitPR #10433 (author: hua7450), head
The PR still touches no partner test file. Path prefixes:
SummaryAll three should-address items are fixed, and a test pins each fix.
Suggestions.
New findings. No critical or should. One small housekeeping suggestion (N-G1). The fix adds no unpinned branch and removes no test. Its comments trip neither the #10287 ratchet nor any other guard on the tree merged with current Status.
0 critical, 0 should and 2 suggestions are open. Prior findings
New findingsCritical: none. Should address: none.
Suggestions:
VerifiedHand-checks of every new expectation (2026, FFY26 size-1 limit 37,428):
Merge resolutions (both blocks checked):
Guards on the tree merged with current
Housekeeping:
AxiomValid:
CI33 pass, 0 fail, 0 pending. I re-checked
Branch
0 critical, 0 should and 2 suggestions (G6 and N-G1) are open at this head. The coverage-line conflict must be resolved before merge, keeping AK and adding MN. Verdict: APPROVE |
DTrim99
left a comment
There was a problem hiding this comment.
Approving round 2: 0 critical, 0 should. All three round-1 shoulds are fixed and pinned. Full report in the comment above. Branch note: AK #10341 merged, so programs.yaml conflicts again; keep AK and add MN in the coverage line before landing.
# Conflicts: # policyengine_us/programs.yaml
Adds Minnesota's Energy Assistance Program (EAP) Primary Heat benefit for FFY2026 and FFY2027, administered by the Minnesota Department of Commerce. The model counts citizens and eligible noncitizens in household size (ineligible members' income still counts), tests countable income against 50% of state median income with the federal 110% poverty floor, and pays a share of the household's total annual energy cost that falls linearly as income rises. The result is rounded and held between $200 and $1,400. Primary Heat is Minnesota's single regular benefit and is based on all home energy costs, including non-heating electricity. Crisis, Energy Related Repair and weatherization are out of scope.
Fixes #10423
Regulatory authority
Eligibility
defined_for = StateCode.MNmn_eap_household_sizesumsis_citizen_or_legal_immigrant; size 0 is ineligiblemn_eap_income_limit= 12 x max(floor(50% of size-adjusted SMI / 12), floor(110% of prior-year FPG / 12)); reproduces all 40 published monthly cells (FFY26, FFY27)heating_typeis required, #9754), not a Minnesota ruleheating_typeUNSPECIFIEDorNONEpays $0, including for own-payers and subsidized tenants, whose cost does not depend on the fuelCountable income
is_in_k12_school) are excludedpfml_benefitscounted from FFY2026: the FFY26 manual counts gross cash receipts with no Paid Leave exclusion, Paid Leave began January 1, 2026, and the FFY27 manual lists it as countablemedicare_part_a_premium+medicare_part_b_premium, subtracted once from each person's combined amount and floored at zero (PERA example). Part A is $0 with 40 or more quarters of coverage (the default), so it lowers income only for an enrollee who buys Part A, such as a PERA retiree without Social SecuritytanfBenefit
pre_subsidy_electricity_expense, gas, fuel oil, propane, wood, coal, other fuel). Unsubsidized heat-in-rent households use the backup matrix (average annual energy cost by main fuel and housing type, 7 fuels x 8 housing types per year). Subsidized heat-in-rent households use their electric cost (Manual FFY26 p.117-119, 125-126).mn_eap_housing_type(Apartment, Duplex, Triplex, Fourplex, Townhouse, House, Mobile home, Other; default House) selects the backup-matrix column. Oil (fuel oil and kerosene), propane, natural gas and electricity rows are selected throughheating_type; the steam, district heating and metered propane rows are stored as published, but no existing input selects them.Not modeled
heating_typevalue or matrix row; benefit $0. A steam or district-heat tenant entersOTHERand gets $0, although the matrix has Steam and District Heating rowspension_incomecarries them and counts them with pensionsPlan item 1.9 (pages 6-7) and the manual differ on three income boxes. The plan checks funds received for the care of a foster child, which the manual excludes (p.92). It leaves earned income of a child under 18 unchecked, while the manual counts minors' earnings unless they are K-12 students aged 19 or under (p.91). It also leaves insurance payments made directly to the insured unchecked, while the manual counts workers' compensation and wage-replacement disability pay (p.91, 99). The model follows the manual, and
source_conflicts/candidates.yamlrecords the difference asus-mn:liheap-plan-income-checklist.Earlier years are unverified estimates through parameter backfilling. The pay-share constants appear only in the Appendix 4A calculator; the FFY27 manual calls the calculator an optional estimating tool, while eHEAT, the system of record, is not public. The size-21+ limit follows the federal floor because the manual table stops at size 20.
The stale note on the shared
pfml_benefitsinput saying it is used only for Massachusetts CCFA is removed, since Minnesota now reads it.Microsimulation:
heating_type, the per-fuel bills andmn_eap_housing_typeare not in current datasets; callers must supply them.Test plan
41 YAML cases in 7 files:
mn_eap.yaml9,mn_eap_household_size.yaml1,eligibility/mn_eap_eligible.yaml6,eligibility/mn_eap_income_limit.yaml2,income/mn_eap_countable_income.yaml11,payment/mn_eap_energy_cost.yaml6 andpayment/mn_eap_pay_share.yaml6. The five cases added in this round (countable income Cases 10 and 11, eligibility Case 6, energy cost Case 6 andmn_eapCase 9) were hand-derived and not run locally; CI validates them. The cases cover:income limits at sizes 0, 1, 4, 18, 19 and 21 for both years, and the exact-limit boundary;
countable income: a self-employment loss, an ineligible member's wages, the student exclusion at 19 and 20, Social Security and pension net of Part B, railroad retirement net of Part B, a PERA pension net of Part A and Part B, every earned and unearned list source with a distinct amount, retirement withdrawals at age 59 and exactly 59 1/2, the $50 and $100 thresholds, SSI, veterans benefits, TANF, child support excluded, Paid Leave counted in FFY2026;
energy cost across fuels, the sum of fuel oil, coal and other fuel bills, backup-matrix cells for both years, kerosene on the oil row, subsidized heat in rent, public housing with heat in rent and no electric bill (ineligible), wood with heat in rent;
pay share at zero income, above the slope end, Appendix 4A Calculator row 2 for both years, Qualified Eligibility for SSI-only, General Assistance-only and MFIP-only households;
the $200 floor, the $1,400 ceiling, half-up rounding (including a $658.50 tie that rounds to $659), and two end-to-end households (2026 and 2027).
YAML tests with expected values from the manuals and Appendix 4A
ruff formatCI passes (program tests, registry and code-health checks)
Changelog fragment in
changelog.d/axiom: TheAxiomFoundation/rulespec-us#1894 queued
🤖 Generated with Claude Code