Skip to content

Implement Maine PTFC unknown-utilities 15% rule (Schedule PTFC line 5c) - #9267

Merged
DTrim99 merged 6 commits into
PolicyEngine:mainfrom
DTrim99:fix/me-ptfc-utilities-in-rent-v2
Aug 25, 2026
Merged

Implement Maine PTFC unknown-utilities 15% rule (Schedule PTFC line 5c)#9267
DTrim99 merged 6 commits into
PolicyEngine:mainfrom
DTrim99:fix/me-ptfc-utilities-in-rent-v2

Conversation

@DTrim99

@DTrim99 DTrim99 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Surfaced by PolicyEngine/policyengine-taxsim#1126 (ME renter with rent that includes utilities).

Problem

Maine's property tax fairness credit treats 15% of rent as "rent constituting property taxes," after first excluding any heat/utilities/furniture included in the rent. Per 2022 Schedule PTFC/STFC line 5c: if the rent includes heat, utilities, furniture, or similar items and the amount is known, subtract it; if it includes them and the amount is not known, subtract 15% of rent paid (line 5a) instead; if it does not, subtract 0.

The old me_property_tax_fairness_credit_countable_rent formula only handled the known-amount case (via an SPMUnit-level utility_expense subtraction) and its comment noted the unknown-amount branch was "not implemented." So a filer whose rent includes utilities but who did not itemize a utility amount received no utility exclusion at all, overstating the countable rent (and the credit). The old code also subtracted the household's separately paid SPMUnit-level utility bills from rent, which has no basis on the form.

Fix

  • Implement the line-5c fallback: when the line-5b flag is true and the utility amount is unknown, deduct 15% of rent paid before applying the 15% rent-constituting-property-tax rate.
  • Reuse the existing generic utilities_included_in_rent boolean (a TaxUnit variable, already consumed by Michigan's home heating credit) as the line-5b gate, instead of adding a state-specific flag.
  • Add a new ME-specific dollar input me_property_tax_fairness_credit_utilities_in_rent_amount (TaxUnit, USD, default 0). A value of 0 means the amount is unknown and triggers the 15% estimate; a positive value is the known amount to subtract.
  • Add parameter gov.states.me.tax.income.credits.fairness.property_tax.rate.utilities_share_of_rent (0.15) for the unknown-amount utility fraction — kept separate from the coincidentally-equal line-5e rate.rent, and deliberately not citing §5219-KK for the 15% (the statute carries no unknown-amount estimate; that rule is form-instructions-only).
  • Clamp net rent at zero (max_(rent - utility_portion, 0)) so inconsistent input where the utility amount exceeds rent cannot drive countable rent negative and offset real_estate_taxes downstream.
  • Add countable-rent and end-to-end tests covering the full flag × amount branch matrix (not-included / known / unknown), the clamp, multi-person aggregation, the zero-sentinel boundary, temporal pins (2014/2024), and binding cap / phase-out / senior compositions.

Example

Rent $17,139 with utilities included, amount unknown: utility portion = 15% × 17,139 = 2,571; countable rent = 15% × (17,139 − 2,571) = 2,185, matching the Maine worksheet (previously PE used the full 15% × 17,139 = 2,571). The known-amount and utilities-not-included cases are unchanged.

@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (d8007aa) to head (b7066df).
⚠️ Report is 23 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #9267   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         3    +2     
  Lines           36        33    -3     
  Branches         2         0    -2     
=========================================
- Hits            36        33    -3     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@PavelMakarchuk PavelMakarchuk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation mechanics check out — all 34 tests in the ME PTFC suite pass on the branch, the new parameter loads with correct metadata, utilities_included_in_rent defaults to false so microsim defaults are unaffected, no partner contract tests are touched, and the worksheet math in the new test (127.5 = (1000 − 150) × 0.15) is internally consistent with the quoted form text.

Requesting changes for two findings on the rewritten formula, detailed inline:

  1. utility_expense is the wrong "amount known" discriminator — it's the household's general SNAP-style utility expense total, not the utility portion of rent, so the new 15% fallback only fires when the household reports zero utility expenses of any kind, and separately-paid utilities get subtracted from rent.
  2. No clamp when utilities exceed rent — countable rent can go negative and offsets real_estate_taxes downstream; line 5d on the form can never be negative.

Caveat: maine.gov was unreachable from the review environment, so the line-5c rule was verified against the PR's quoted form text and worksheet example rather than the form PDF itself.


Generated by Claude Code

@DTrim99

DTrim99 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

Fixes applied from @PavelMakarchuk's review

Both findings addressed and pushed (ME PTFC suite 36/36). Thanks for the catch — both were masked by the old tests.

F1 — wrong known/unknown discriminator (fixed)

You're right that utility_expense (the SPM-unit's general SNAP-style utility total) is the wrong signal for "is the utility portion of rent known?" — it made the line-5c 15% fallback unreachable for any household reporting utility expenses and subtracted separately-paid utilities from rent. Added a dedicated me_ptfc_utilities_included_in_rent (TaxUnit, USD, default 0) and rewired the split off the utilities_included_in_rent boolean + that amount:

  • not included in rent → no subtraction (full rent counts);
  • included & amount known (> 0) → subtract that amount;
  • included & amount unknown (0) → subtract the 15%-of-rent estimate (line 5c).

Your concrete case now resolves to the form's (12,000 − 1,800) × 0.15 = 1,530 instead of 1,710, and the separately-paid utility_expense is no longer subtracted.

F2 — clamp when utilities exceed rent (fixed)

net_rent is now max_(rent − utility_portion, 0), so countable rent can never go negative and offset real_estate_taxes downstream (line 5d ≥ 0). Your rent = 2,400 / utilities = 3,600 → −180 case now returns 0.

Tests

Appended two demonstrating cases that fail if either fix is reverted:

  • separately-paid-utilities (rent 12,000, included-amount unknown, general utility_expense 600) → 1,530 (would be 1,710 under the old discriminator);
  • utilities-exceed-rent (rent 2,400, included-amount 3,600) → 0 (would be −180 unclamped).

The existing known-amount case (1000 − 150) × 0.15 = 127.5 still passes. No parameter values changed (the 15% rates were already added by this PR).

🤖 Generated with Claude Code

@DTrim99
DTrim99 requested a review from PavelMakarchuk August 17, 2026 13:20
@PavelMakarchuk

Copy link
Copy Markdown
Collaborator

PR Review (follow-up)

Re-reviewed head bea2956 against the 2022 and 2023 Schedule PTFC/STFC instructions (line 5a–5e) and 36 M.R.S. §5219-KK.

🔴 Critical (Must Fix)

None.

🟡 Should Address

  1. Changelog type. changelog.d/me-ptfc-utilities-in-rent.fixed.md — the PR adds a new parameter (rate/utilities_included_in_rent.yaml) and a new input variable (me_ptfc_utilities_included_in_rent), which by repo convention is added (minor bump), not fixed. Rename to .added.md.

🟢 Suggestions

  1. Naming / documentationme_ptfc_utilities_included_in_rent.py: the sibling family is me_property_tax_fairness_credit_*; consider the long form for consistency. Either way, add documentation stating that 0 means "amount unknown" (triggers the 15% estimate), since a known $0 is indistinguishable from unknown at ..._countable_rent.py:26.
  2. Referencesutilities_included_in_rent.yaml:9-12: also cite the 2023 line-5c instruction text (p.2) and a pre-2022 form to support the 2014-01-01 start (only 2022/2023 forms are cited; rate/rent.yaml already cites 2021).
  3. Tests — add an integration case in me_property_tax_fairness_credit.yaml (rent with unknown utilities → credit) and a boundary where the known utility amount equals rent (→ 0 countable rent).

Validation Summary

Check Result
Regulatory Accuracy 0 issues — line 5c: if utilities included and amount known, subtract it; if unknown, subtract 15% of gross rent (5a); 5d = 5a − 5c; 5e = 5d × 15%. Code matches exactly, incl. the "included AND unknown" condition
Reference Quality 0 issues (1 suggestion) — 2022 p.2 / 2023 p.1 corroborate 15%
Code Patterns 0 issues — vectorized where/max_, TaxUnit level matches caller, non-ME users of utilities_included_in_rent (MI home heating) unaffected, input defaults 0 so microsim unchanged
Test Coverage 0 blocking gaps (1 suggestion) — not-included / known / unknown / unknown+separate utilities / known > rent clamp all covered
CI Status Passing, codecov 100%
Prior review Both items (F1 discriminator, F2 clamp) addressed in bea2956

Verdict: APPROVE once the changelog type is added.

@DTrim99

DTrim99 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up review addressed — thanks @PavelMakarchuk

All items from your 2026-08-18 follow-up applied (ME PTFC suite 38/38).

Should

  • Changelog type → renamed me-ptfc-utilities-in-rent.fixed.md to .added.md (the PR adds a new parameter and input variable, so added is right).

Suggestions

  • Documentationme_ptfc_utilities_included_in_rent now documents that 0 means the amount is unknown (which triggers the 15%-of-gross-rent line-5c estimate), so a known $0 is distinguishable in intent from unknown. Kept the me_ptfc_ name (you'd flagged the long-form as optional).
  • References → added the 2014 Schedule PTFC line-5c form (14_1040_sched_ptfc, p.2 — "multiply line 5a by 15%") to support the 2014-01-01 start, alongside the existing 2022/2023 forms. No value or start-date change.
  • Tests → added an integration case (ME household, rent $6,000 with utilities included but amount unknown → line-5c estimate $900 → countable rent 0.15 × (6000 − 900) = 765 → credit 765, vs 900 without the estimate) and a boundary case where the known utility amount equals rent → net rent clamps to 0 → countable rent 0.

CI/codecov should stay green. Let me know if you'd prefer the long-form variable rename after all.

Fixed with Claude Code assistance.

@PavelMakarchuk PavelMakarchuk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review (complete:review-pr — re-review after 8/18 commits)

Both findings from my 8/16 review are genuinely fixed, verified against the form text extracted mechanically (2022 Schedule PTFC/STFC p. 2; 2014 instructions p. 4; 36 M.R.S. §5219-KK(1)(E)):

  1. Discriminator ✓ — the new dedicated me_ptfc_utilities_included_in_rent input replaces utility_expense (the SPM-unit separately-paid utilities aggregate, which the form's line 5c does not mean). Countable-rent Case 4 is a regression guard that inverts if the old discriminator returns.
  2. Negative clamp ✓ — max_(rent - utility_portion, 0), with boundary tests at equal-to-rent and exceeding-rent.

The line 5c implementation reproduces all three form branches exactly — "If line 5b is yes and you know the amount… enter that amount… If yes, and you do not know the amount paid, multiply line 5a by 15% (.15)… If line 5b is no, enter '0'" — and the 0.15 is parameterized separately from the line-5e rent rate with correct page anchors for 2014/2022/2023 (the 2014-01-01 start date checks out against the 2014 form). All six countable-rent cases plus the end-to-end credit case (765) recompute correctly by hand; the full ME credits suite (125 tests) passes on the branch. Microsim-safe: utilities_included_in_rent is imputed nowhere, so defaults are unaffected. CI green.

🟡 Should address (non-blocking, but №1 is worth settling before merge since it's a public API name)

  1. Variable name breaks the folder convention — every sibling spells out me_property_tax_fairness_credit_*; me_ptfc_ has no precedent in the repo, and renaming a user-facing input after release is a breaking API change. Suggest me_property_tax_fairness_credit_utilities_included_in_rent_amount (the _amount suffix also disambiguates from the boolean utilities_included_in_rent).
  2. Parameter description — leads with a subordinate clause and uses "gross rent" in the opposite sense from the statute's term of art (§5219-KK(1)(E) defines "gross rent" as rent exclusive of utility charges, i.e. line 5d, not 5a). Suggest e.g. "Maine excludes this share of the rent paid as utilities included in rent when the amount is not known under the property tax fairness credit."

🟢 Suggestions

  • Add the mirror-image test: utilities_included_in_rent: false with a nonzero amount → no exclusion (guards the included * gate, form's "If line 5b is no" branch).
  • Label/description say "heat or utilities"; the form covers "heat, utilities, furniture, or similar items" — broaden the wording.
  • Test-name labels "(F1…)"/"(F2…)" are session-internal identifiers; the comment bodies are excellent, just reword the labels.
  • The clamp comment ("Line 5d (5a − 5c) can never be negative") slightly overstates the form — it's a defensive guard against user input where 5c exceeds 5a.
  • Drive-by while the folder is open: sibling rate/rent.yaml has label: …income rate — copy-paste error for the rent rate.

Validation summary

Check Result
Regulatory accuracy 0 issues (all three 5c branches match the form verbatim)
Reference quality Anchors verified for all three form years; 2014 start corroborated
Code patterns Clean (vectorized, parameterized, correct entities); naming nit above
Test coverage 6 unit + 1 end-to-end recompute correctly; 125-test suite passes
CI Passing (full suite)

@PavelMakarchuk

Copy link
Copy Markdown
Collaborator

PR 9267 — ME Property Tax Fairness Credit: Schedule PTFC/STFC line 5c utilities-in-rent rule

Program Review

Program: Maine Property Tax Fairness Credit (36 M.R.S. §5219-KK) — implements Schedule PTFC/STFC line 5c: when rent includes heat/utilities/furniture and the amount is known, subtract it; when unknown, subtract a 15% estimate of rent; when not included, subtract nothing. New 0.15 parameter, new dollar-amount input variable, rewritten countable-rent formula (drops an erroneous SPMUnit-level utility_expense subtraction), tests, changelog.

Source Documents

# Document Link Pages
1 2022 Form 1040ME Schedule PTFC/STFC (line 5c on file p. 2) https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/22_1040me_sched_pstfc_ff.pdf 4 (all rendered; p. 2 re-rendered at 600 DPI)
2 2014 Form 1040ME Schedule PTFC (line 5c on file p. 2) https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/14_1040_sched%20ptfc_download.pdf 4 (all rendered)
3 2023 Form 1040ME Schedule PTFC/STFC (line 5c moved to file p. 1) https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/23_1040me_sched_pstfc_ff.pdf 4 (all rendered; p. 1 re-rendered at 600 DPI)
4 36 M.R.S. §5219-KK (statute, HTML → text) https://legislature.maine.gov/statutes/36/title36sec5219-KK.html n/a (text-extracted)

Verification-phase supplements: 2013 Schedule PTFC (NBER mirror, ext-1) and 2016/2019/2021/2024/2025 Schedule PTFC/STFC forms (ext-2 continuity sample) — text-extracted, not rendered.

  • Year: 2014– (parameter effective date); tests use period 2022
  • Scope: PR changes only
  • Reviewed head SHA: b008eae
  • Mode: full

Critical

None. The three line-5c branches, the 0.15 value, the 5c → 5d → 5e ordering, the 2014-01-01 effective date, and all three reference page anchors match the extracted sources; every formula branch has at least one passing test; CI is passing.


Should

A1 — Wording understates the form's scope and misuses "gross rent" (VERIFIED mismatch, documentation-only; value 0.15 correct)

  • policyengine_us/parameters/gov/states/me/tax/income/credits/fairness/property_tax/rate/utilities_included_in_rent.yaml:1,7 (description, label)
  • policyengine_us/variables/gov/states/me/tax/income/credits/fairness/property_tax_fairness_credit/me_ptfc_utilities_included_in_rent.py:8,11 (label, documentation)
  • .../me_property_tax_fairness_credit_countable_rent.py:21-22 (comment)
  • changelog.d/me-ptfc-utilities-in-rent.added.md:1

Confirmed by verifier at 600 DPI against the 2022 form (p. 2) and 2023 form (p. 1), plus the 2014 text layer (p. 2): all three forms say "heat, utilities, furniture, or similar items" (statute §5219-KK(1)(E) is broader still: "utilities, services, furniture, furnishings or personal property appliances"). The repo strings say "heat or utilities" / "utilities" throughout. Classified as documentation, not a value mismatch — the formula reads only the parameter's numeric value, which is correct.

Second wording defect at the same loci: the description, variable documentation, and changelog all apply 15% to "gross rent", but §5219-KK(1)(E) defines gross rent as the figure exclusive of utility charges — i.e. the post-line-5c amount, the base of the sibling rate/rent.yaml. Because both parameters are 0.15, the current wording makes two legally distinct rates on different bases read as the same rule. Fix together: broaden every string to the form's own terms and replace "gross rent" with "rent paid (Schedule PTFC/STFC line 5a)"; also reshape the parameter description to the convention ([State] [verb] …; sibling rate/rent.yaml:1 shows the target shape) and note in the countable-rent formula that the generic boolean utilities_included_in_rent serves as a narrower-named proxy for line 5b.

A2 — Naming: me_ptfc_ abbreviation breaks the folder convention and the name reads as the adjacent boolean

  • .../me_ptfc_utilities_included_in_rent.py:4 (class name)
  • .../me_property_tax_fairness_credit_countable_rent.py:16,20 (both names two lines apart)
  • .../rate/utilities_included_in_rent.yaml (filename)

All eight sibling variables spell out me_property_tax_fairness_credit_*; me_ptfc_ appears nowhere else in the repo. The new USD-amount variable is character-for-character the existing bool utilities_included_in_rent (variables/household/expense/housing/utilities_included_in_rent.py:4) with a state prefix, and the two are read on adjacent lines. The parameter path compounds it: rent * p.rate.utilities_included_in_rent reads as multiplying by a flag — three same-named things of three types in one formula. Recommend me_property_tax_fairness_credit_utilities_in_rent_amount (or ..._line_5c_amount) and a rate filename that names what it scales (e.g. rate/utilities_share_of_rent.yaml). Flagged independently by regulatory, code, and reference validators.

A3 — Two mutation-guard tests missing for the exact bug being fixed (downgraded from the edge-case checker's "critical")

policyengine_us/tests/policy/baseline/gov/states/me/tax/income/credits/property_tax_fairness_credit/me_property_tax_fairness_credit_countable_rent.yaml

Severity call: no branch of the new formula has zero coverage — Case 1 exercises included=false (branch 3), Case 2 the known branch, Cases 3–4 the unknown branch, Cases 5–6 the clamp — so per canonical rules these are mutation-coverage gaps on a tested variable, SHOULD not CRITICAL. They are the two highest-value additions:

  1. Gate mirror: no case has utilities_included_in_rent: false with a nonzero me_ptfc_utilities_included_in_rent; dropping the included * multiplier entirely passes all six existing cases. The form is explicit: "If line 5b is no, enter '0' on line 5c." Add rent 1_000 / false / amount 400 → 150 (ungated would give 90).
  2. Known-branch utility_expense guard: Case 4 pins the removed utility_expense subtraction only in the unknown branch; reintroducing it inside the known branch passes every current case. Add rent 12_000 / true / amount 1_200 / heating_cooling_expense: 600 → 1_620 (regression would give 1_530).

A4 — Additional coverage gaps on the new formula

Same test files. Six gaps, none merge-blocking individually: (a) multi-person rent aggregation — every case is a one-person unit, so a head-only rent read is invisible (add JOINT, 6_000+4_000 → 1_275); (b) renter and owner combined — me_property_tax_fairness_credit_countable_rent_property_tax is never computed with both addends nonzero anywhere in the repo (add rent 4_000 + real_estate_taxes 200 → credit 710); (c) zero rent with utilities included, both sub-branches (known-amount case is the only zero-minuend clamp firing: max(0−500,0)=0); (d) the > 0 discriminator boundary — a $1 known amount jumps countable rent 127.5 → 149.85, a real cliff created by the zero sentinel, worth pinning against a future >= 0/!= 0 edit; (e) negative recorded amount (falls into the estimate branch today; != 0 would inflate the credit); (f) the default-input path (rent only, nothing set → plain 15% of rent), which is what the entire microdata population takes; (g) an end-to-end known-amount credit case (credit Case 4 covers only the unknown branch, amount 1_000 on rent 6_000 → 750). Ready-to-paste YAML for all of these is in pr9267-review-tests.md.

A5 — Test hygiene: missing error margins (real flakiness risk) and review-round jargon baked into permanent files

  • me_property_tax_fairness_credit_countable_rent.yaml (all 6 cases), me_property_tax_fairness_credit.yaml Case 4 — no absolute_error_margin. The values run 0.15 twice through float32 (Case 4: 12_000 → 1_530) and 0.15 is not exactly representable; the convention requires absolute_error_margin: 0.01 on currency outputs (the sibling ..._base_cap.yaml already sets one).
  • me_property_tax_fairness_credit_countable_rent.yaml:34,46-48,50 — "F1 discriminator", "F2 non-negative clamp", "old buggy discriminator", "this case inverts if F1 is reverted" are this review thread's internal finding IDs; meaningless to the next reader. Rename in domain terms (e.g. "Case 4, utilities included with amount unknown; separately-paid utility expenses are ignored."). Minor: Case 4's name says utility_expenses but the input is heating_cooling_expense; Case 1's name is ungrammatical ("utilities did not include in rent"); names lack the convention's trailing period and several exceed 90 chars.

A6 — Line 5d clamp comment asserts a form rule that is not printed, and Cases 5/6 encode the clamp's own output as the expectation

.../me_property_tax_fairness_credit_countable_rent.py:32-33 — the comment "Line 5d (5a - 5c) can never be negative" presents form text that does not exist: all three form years say only "Line 5a minus line 5c" (verified across the full line-5 block and instructions in the 2014/2022/2023 extracts). The clamp is a sound modelling guard — in the unknown branch 5d = 0.85 × 5a ≥ 0, and in the known branch 5c is by construction a component of 5a — so reword to state that rationale ("clamp guards inconsistent user input") instead of asserting a form rule. Correspondingly, me_property_tax_fairness_credit_countable_rent.yaml:50-70 (Cases 5–6, amount > rent and amount = rent → 0) derive their expectations from the clamp under review, not from any external ground truth (CLAUDE.md evidence rule 4 circularity). Keep the cases but annotate them as invalid-input guards, not Maine-published results.


Suggestions

S1 — Zero-as-"unknown" sentinel: document the convention and the default-path behavior

.../me_ptfc_utilities_included_in_rent.py:11, .../me_property_tax_fairness_credit_countable_rent.py:26. included_amount > 0 makes a genuinely known $0 indistinguishable from "unknown" (arguably impossible per the instruction, so benign); a separate ..._amount_known boolean would make the three branches explicit. Also note in the PR description that any record with the flag true and no amount now takes the 15% estimate instead of the old utility_expense subtraction — a default-driven change whose population-level reach is nil today (see xref result below) but which activates for household/API users.

S2 — Add the statute for the utilities-exclusion authority, and a comment recording why §5219-KK is not cited for the 15%

.../rate/utilities_included_in_rent.yaml:8-14. The form-only citation set is correct (verified: §5219-KK contains no unknown-amount estimate; its only 15% is the line-5e rate) — do not "fix" it by citing the statute for this value. But a one-line YAML comment recording that the omission is intentional would stop a future reviewer from adding the wrong-15% citation, and the statute URL could be added for the underlying exclusion concept, matching the sibling rate/rent.yaml.

S3 — documentation field on the new variable

.../me_ptfc_utilities_included_in_rent.py:11. The model-development reference says use reference, never documentation; ~20% of existing variables carry it, so this is convention drift, not a defect. Consider moving the sentinel explanation into the formula comment where it is acted on.

S4 — Period variation and the two-indistinguishable-0.15s note

All seven new/edited cases are period: 2022. One repeat of the unknown branch in 2014 and/or 2024 would pin the parameter's 2014-01-01 start and continuity. Separately, p.rate.utilities_included_in_rent and p.rate.rent are both 0.15, so no baseline YAML case can distinguish them — add a one-line comment at the top of the countable-rent test file so a future reader does not assume the tests pin them separately. Avoid any known-amount case where amount = 0.15 × rent (both branches coincide; proves nothing).

S5 — Minor polish

Comment volume in the formula (nine comment lines for eight code lines; lines 21–25 restate the where below them); amount_known could be inlined; changelog fragment type .added under a fix/ branch (defensible — the fragment covers a new user-facing input — flagged only because they disagree); me_ptfc_utilities_included_in_rent: 0 in Case 1 restates the default; trailing blank line at end of me_property_tax_fairness_credit.yaml.

S6 — Consider a generic household-level amount input

.../me_ptfc_utilities_included_in_rent.py:4. The dollar amount of utilities bundled into rent is not Maine-specific; the sibling boolean lives at variables/household/expense/housing/ and is already consumed by Michigan's home heating credit. A shared input would avoid a second state-only user-facing field later. Design preference, not a defect.

S7 — Pre-existing nits noticed in passing (outside PR scope)

.../rate/rent.yaml: (a) label reads "Maine property tax fairness credit income rate" though it holds the line-5e rent rate; (b) its "2024 Form 1040ME… Line 5(e)" reference href points at the 2023 file. Neither is touched by this PR; fix opportunistically.


Confirmed correct (highlights)

  • Three line-5c branches match the form exactly (known amount / 15% estimate / zero), in all three cited years, verified on rendered page images and at 600 DPI for 2022/2023.
  • 0.15 value verified 8 form-years deep: PR-cited 2014/2022/2023 plus continuity sample 2016/2019/2021/2024/2025 (ext-2: CONTINUITY CONFIRMED, identical operative wording throughout) — the single 2014-01-01: 0.15 entry stands on unusually strong evidence.
  • 2014-01-01 start date is correct (ext-1 investigated and cleared): ext-1 showed a TY2013 Schedule PTFC with the same 15% estimate existed — but under the predecessor credit, 36 M.R.S. §5219-II, a materially different program (25%-of-rent base, 40% credit, $300/$400 caps) that PE does not model; the modeled §5219-KK credit applies "for tax years beginning on or after January 1, 2014" and every sibling parameter uses the same 2014-01-01 start. A pre-2014 model of the §5219-II credit would be a separate feature, not a fix to this parameter.
  • Form-only citation for the 15% estimate is the right call: §5219-KK supplies the line-5e rate and the utilities exclusion but no estimation rule; citing it here would corroborate the wrong 15%. All four page anchors verified against actual file pages (2023's layout move to p. 1 correctly reflected).
  • Dropping utility_expense is a genuine fix: the old code subtracted the household's separately paid SPMUnit-level utility bills from rent — no basis on the form, plus a cross-entity aggregation bug — and its own comment conceded the unknown-amount case was unimplemented.
  • Microsimulation reach checked and cleared (xref-1: REJECTED): neither utilities_included_in_rent nor the new input is imputed anywhere in policyengine-us-data (CPS/ECPS/ACS/PUF); defaults hold for 100% of records, so this PR cannot move population-level ME PTFC results.
  • All seven test expectations independently re-derived against the 2022 form's 5c→5d→5e sequence and the benefit-base/cap parameters (integration case: 900 → 5_100 → 765, cap $1,000 non-binding). Code patterns clean: fully vectorized, fully parameterized (separate parameter correctly created rather than reusing the coincidentally equal rate/rent), correct entity/period usage, ruff clean, changelog fragment present.

PDF Audit Summary

Category Count
Confirmed correct (repo value = PDF) 13 (+5 continuity form-years via ext-2)
Mismatches verified 1 (wording-scope only, value correct → A1)
Mismatches rejected 0
Cross-reference checks 1 (microsim imputation — REJECTED, cleared)
External-document checks 2 (ext-1 TY2013 — cleared with reasoning above; ext-2 continuity — CONFIRMED)
Unmodeled program features 1 (§5219-KK(1)(E) assessor arm's-length rent adjustment; not modelable from microdata)
Pre-existing (outside PR scope) 2 (rent.yaml label misnomer; 2024 reference href → 2023 file → S7)

Validation Summary

Validator Result
Regulatory PASS — 0 critical; 3 should, 6 suggestions (consolidated above)
Reference 4/4 citations corroborated with correct page anchors; effective date corroborated twice; form-only 15% citation confirmed correct
Code PASS — 0 critical; naming/wording advisories consolidated (A1, A2); 10 pattern checks clean; ruff clean
Tests All 7 expectations verified; 2 mutation gaps downgraded from critical per policy (every branch has coverage) → A3; further gaps → A4; margin/jargon hygiene → A5
PDF audit 13 matches, 1 wording-only mismatch across 12 rendered pages + 2 at 600 DPI
Verifiers mismatch-1 CONFIRMED (doc-only); xref-1 REJECTED; ext-1 cleared (predecessor program, not an error); ext-2 continuity CONFIRMED
CI Passing YES (all checks pass)

Branch Status

The branch is 347 commits behind base (3 ahead). Rebase recommended before merge. Staleness did not affect any finding: all findings were verified against the PR snapshot at head SHA b008eae.

Review Severity: COMMENT

Zero critical findings. The value, mechanics, effective date, references, and formula are all verified correct against three cited form years, five additional sampled years, and the statute; the six SHOULD items are documentation wording, naming, and test-coverage improvements on a substantively correct fix.

Next Steps

Run the fix-pr workflow against this report: apply A1's wording broadening and gross-rent correction, A2's renames, A3's two mutation-guard tests, then the remaining A-items (coverage cases, margins, jargon scrub, clamp-comment reword) and any S-items worth taking; rebase on base and re-run CI.

DTrim99 and others added 4 commits August 24, 2026 09:23
Maine's property tax fairness credit computes rent constituting property
taxes as 15% of rent, after excluding any heat/utilities included in the
rent. Schedule PTFC/STFC line 5c provides that when the rent includes
utilities but the amount is not known, 15% of gross rent is treated as
the utility portion. me_property_tax_fairness_credit_countable_rent
previously left that fallback unimplemented, so a filer whose rent
includes utilities but who did not itemize a utility amount received no
utility exclusion. Add the 15% fallback and a parameter for the fraction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ator and clamp

- F1: the known/unknown split for the utility portion of rent was keyed on the
  household's general utility_expense (SNAP-style total), making the line-5c 15%
  fallback unreachable whenever any utility expense was reported and subtracting
  separately-paid utilities from rent. Add a dedicated me_ptfc_utilities_included_in_rent
  amount and drive the split off the utilities_included_in_rent boolean + that amount:
  not included -> no subtraction; included & known -> subtract it; included & unknown
  -> subtract the 15%-of-rent estimate.
- F2: clamp net rent with max_(rent - utility_portion, 0) so countable rent can never
  go negative and offset real_estate_taxes downstream (Schedule PTFC line 5d >= 0).
- Tests: add a separately-paid-utilities case (1,530, inverts if F1 reverted) and a
  utilities-exceed-rent clamp case (0). ME PTFC suite 36/36.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…(ME PTFC)

- Changelog: rename me-ptfc-utilities-in-rent.fixed.md -> .added.md (the PR adds a new
  parameter and input variable, so 'added' per repo convention).
- Documentation: me_ptfc_utilities_included_in_rent now documents that 0 means the amount
  is unknown (triggers the 15%-of-gross-rent line-5c estimate), disambiguating a known $0.
- References: utilities_included_in_rent.yaml adds the 2014 Schedule PTFC line-5c form
  (supports the 2014-01-01 start) alongside the 2022/2023 forms. No value/date change.
- Tests: integration case (rent with unknown utilities -> line-5c estimate -> positive
  credit) and a known-amount-equals-rent boundary (-> 0 countable rent). ME PTFC suite 38/38.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…, add coverage (ME PTFC)

- A2: rename me_ptfc_utilities_included_in_rent -> me_property_tax_fairness_credit_utilities_in_rent_amount
  and rate/utilities_included_in_rent.yaml -> rate/utilities_share_of_rent.yaml (spelled-out sibling
  convention; the amount no longer reads as the adjacent utilities_included_in_rent boolean).
- A1: broaden 'heat or utilities' -> 'heat, utilities, furniture, or similar items'; replace 'gross rent'
  with 'rent paid (Schedule PTFC/STFC line 5a)' (gross rent is the utilities-exclusive base per 5219-KK(1)(E)).
- A6: reword the line-5d clamp comment to the modelling rationale (guards inconsistent input), not unprinted form text.
- A3/A4: mutation-guard tests (gate mirror; known-branch utility_expense guard) + coverage (multi-person,
  renter+owner, zero rent, >0 boundary, negative amount, default path, e2e known-amount credit).
- A5: absolute_error_margin on all cases; rename review-jargon case names to domain terms.
- S2/S3/S5/S7: statute-not-cited-for-15% note; move sentinel doc into the formula comment; comment/style
  polish; fix pre-existing rate/rent.yaml label + 2024 reference href.

No parameter value changed (0.15 intact). ME PTFC suite 50/50.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DTrim99
DTrim99 force-pushed the fix/me-ptfc-utilities-in-rent-v2 branch from b008eae to e5a551c Compare August 24, 2026 13:27
@DTrim99

DTrim99 commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up review addressed — thanks @PavelMakarchuk

Applied all six SHOULD items and the actionable suggestions from your 2026-08-23 review (ME PTFC suite 50/50, rebased on main). No parameter value changed (0.15 intact).

Should

  • A2 (naming) — renamed the variable me_ptfc_utilities_included_in_rentme_property_tax_fairness_credit_utilities_in_rent_amount (spelled-out sibling convention) and the parameter rate/utilities_included_in_rent.yamlrate/utilities_share_of_rent.yaml (names what it scales). It no longer reads as the adjacent utilities_included_in_rent boolean.
  • A1 (wording) — broadened "heat or utilities" → "heat, utilities, furniture, or similar items" (the form's terms), and replaced "gross rent" with "rent paid (Schedule PTFC/STFC line 5a)" across the param description/label, variable label, formula comment, and changelog — since §5219-KK(1)(E) defines gross rent as exclusive of utilities. Reshaped the param description to the [State] [verb] … convention.
  • A6 — reworded the line-5d clamp comment to the modelling rationale (guards inconsistent input; unknown branch 0.85×5a ≥ 0, known branch 5c is a component of 5a) rather than asserting unprinted form text.
  • A3 — added the two mutation guards: the gate mirror (utilities_included_in_rent: false + amount 400 → 150, not 90) and the known-branch utility_expense guard (rent 12k / amount 1,200 / heating_cooling 600 → 1,620, not 1,530).
  • A4 — added the coverage cases: multi-person JOINT aggregation (1,275), renter+owner combined (credit 710), zero-rent both sub-branches, the >0 sentinel boundary ($1 → 149.85), negative amount → estimate branch, the default rent-only path (15% of rent), and an e2e known-amount credit case (750).
  • A5absolute_error_margin: 0.01 on every case; renamed the "F1/F2/discriminator" review-jargon case names to domain terms (and fixed the utility_expenses-vs-heating_cooling name, the ungrammatical name, trailing periods, ≤90 chars).

Suggestions

  • S2 — noted in the parameter that §5219-KK is intentionally not cited for the 15% (the statute has no unknown-amount estimate), so a future reviewer won't add the wrong citation. S3 — moved the zero-as-unknown sentinel explanation out of documentation into the formula comment. S4 — added 2014 and 2024 unknown-branch pins + a header note that both 0.15 rates can't be distinguished by baseline cases. S5 — trimmed the formula comments, inlined amount_known, dropped the redundant default-restating input, removed the trailing blank line. S7 — fixed the pre-existing rate/rent.yaml label ("income rate" → rent rate) and the mislabeled 2024→2023 reference.

Not applied — S6 (make it a generic household-level input): that conflicts with A2's state-specific rename you (and three validators) asked for, and you flagged it as "design preference, not a defect," so I kept the state-specific variable. Happy to revisit if you'd prefer the shared-input direction instead.

Also annotated Cases 5/6 (amount ≥ rent → 0) as invalid-input clamp guards rather than Maine-published results, per your circularity note.

Fixed with Claude Code assistance.

@DTrim99
DTrim99 requested a review from PavelMakarchuk August 24, 2026 14:30

@PavelMakarchuk PavelMakarchuk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Program Review

PR #9267 — Implement Maine PTFC unknown-utilities 15% rule (Schedule PTFC line 5c)

Re-review triggered by the post-approval commit e5a551c1 (2026-08-24), which landed after the
2026-08-22 approval and touched all 9 files.

Source Documents

  • PDF: 2014 Schedule PTFC, 2021/2022/2023 Schedule PTFC/STFC, plus 2024 and 2025 Schedule
    PTFC
    collected during this review; 36 M.R.S. §5219-KK (statute HTML)
  • Year: 2014+ (parameter starts 2014-01-01); tests use 2014, 2022, 2024
  • Scope: PR changes only
  • Reviewed head SHA: e5a551c
  • Mode: full

Verdict on the post-approval rename — SOUND

e5a551c1 deleted the ME-specific discriminator you had verified
(me_ptfc_utilities_included_in_rent + utilities_included_in_rent.yaml) and replaced it with the
pre-existing generic utilities_included_in_rent boolean plus a new ME-specific dollar-amount input.
Checked and sound on every dimension that mattered:

  • Entity is exact, not approximate. Despite living in variables/household/expense/housing/,
    utilities_included_in_rent is a TaxUnit boolean — the same entity as the ME credit chain — so
    tax_unit("utilities_included_in_rent", period) needs no aggregation and introduces no ambiguity.
  • No cross-program interference. Repo-wide grep: its only other consumers are the Michigan home
    heating credit (mi_standard_home_heating_credit.py:32,
    mi_alternate_home_heating_credit_eligible.py:16), both MI-gated. SNAP utility allowances and
    LIHEAP do not read it — they use utility_expense, has_heating_cooling_expense, and
    heat_expense_included_in_rent. The ME formula no longer touches utility_expense, which SNAP
    keeps using untouched.
  • No stale references to the deleted variable or parameter remain anywhere in the tree.
  • The negative-net-rent clamp survives at head: net_rent = max_(rent - utility_portion, 0),
    boundary-tested by Cases 5, 6, and 10.
  • Reuse over duplication is the right call — this is the pattern the standards ask for.

Critical (Must Fix)

None.

Should Address

  • [A1] me_property_tax_fairness_credit_countable_rent.py:19the overlapping sibling flag
    heat_expense_included_in_rent is not linked, so a heat-only household silently misses line 5b.

    variables/household/expense/housing/heat_expense_included_in_rent.py (SPMUnit bool, used by MA/IL
    LIHEAP) covers a subset of the line-5b concept ("heat, utilities, furniture, or similar items"). A
    household modeled as heat_expense_included_in_rent: true / utilities_included_in_rent: false
    a perfectly natural LIHEAP setup where the landlord provides heat only — answers line 5b "Yes" on
    the real form, but the formula sees included = False and counts full rent, overstating the
    credit. This is the one genuine gap the rename introduces: the deleted ME-specific variable had
    the same blind spot only when left unset, but its ME-specific name invited a direct answer to the
    ME question. At minimum document the relationship; OR-ing the two flags is a fuller fix but needs
    care with the SPMUnit→TaxUnit mapping, so it's a design call rather than a prescription.
  • [A2] me_property_tax_fairness_credit_utilities_in_rent_amount.pythe 0-as-unknown
    sentinel is undocumented on the input variable itself.
    The semantics live only in a comment in
    me_property_tax_fairness_credit_countable_rent.py:20-24. An app/API consumer introspecting this
    input will read 0 as "$0 of utilities in rent" and instead get a 15% deduction. Put the sentinel
    in the variable's own label or documentation.
    On substance the sentinel is form-faithful: a filer who genuinely pays $0 toward heat/utilities
    has rent that "does not include an amount paid" for those items, i.e. line 5b = No, representable
    by leaving the flag false — so the known-$0 vs unknown conflation has no materially wrong
    reachable state, and defaulting to the estimate when the flag is true with no amount is exactly
    the form's instruction.
  • [A3] No end-to-end case composes the new rule with a nonzero income phase-out or a binding
    cap
    . All three new full-pipeline cases (credit file Cases 4–6) use zero income, so the 4%
    phase-out never composes with the new countable-rent value; the existing
    me_property_tax_fairness_credit_base_cap.yaml cases that do exercise phase-out and cap inject
    me_property_tax_fairness_credit_countable_rent_property_tax directly, bypassing the changed
    formula. Either scenario closes it:
    cap binds — single, age 40, rent 60_000, utilities_included_in_rent: true, amount 0 →
    countable = 0.15 × (60_000 − 9_000) = 7_650 → min(2_200, 7_650) → capped at 1_000;
    phase-out binds — same household, rent 12_000 (countable 1_530) plus employment income,
    asserting me_sales_and_property_tax_fairness_credit_income alongside the credit.
  • [A4] changelog.d/me-ptfc-utilities-in-rent.added.md — filename does not match the branch.
    Convention is <branch-name>.<type>.md; branch is fix/me-ptfc-utilities-in-rent-v2, so the
    sanitized name is fix-me-ptfc-utilities-in-rent-v2.added.md. Towncrier only needs uniqueness so
    it builds fine, but the name/branch link is broken. The .added type is correct despite the
    fix/ prefix — the PR introduces a new rule, parameter, and input variable.
  • [A5] The PR body is stale versus head. It still names the deleted parameter
    utilities_included_in_rent (0.15) rather than utilities_share_of_rent, and describes the
    pre-rename discriminator design. Worth refreshing before merge so the record matches e5a551c1.

Suggestions

  • [S1] me_property_tax_fairness_credit_countable_rent.py:16 — the comment calls
    utilities_included_in_rent a "generic household boolean". It is a TaxUnit variable (it just
    lives in the household/ folder). The plumbing is right; only the wording is wrong.
  • [S2] The generic flag's label ("Whether utilities are included in rent payments") is narrower
    than line 5b, which asks about "heat, utilities, furniture, or similar items". Broadening it would
    also read correctly for MI's usage.
  • [S3] Now actionable — a real 2024/2025 form reference exists. The verification pass located
    and read both editions (see PDF Audit Summary). If you want form-year coverage extended:
    https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/24_Form%201040ME_Sch%20PTFC_ff.pdf#page=1
    and …/25_1040me_sch_ptfc_fillable.pdf#page=1 — both carry lines 5c and 5e on file page 1.
  • [S4] Pre-existing, same bug class this PR just fixed one file over.
    parameters/.../property_tax/rate/income.yaml:17-18 still carries the mislabeled duplicate that
    the PR correctly removed from rent.yaml: an entry titled "2024 Form 1040ME … Line 10" whose href
    is byte-identical to the retained 2023 entry (23_1040me_sched_pstfc_ff.pdf#page=2). Outside this
    PR's diff, but it is a one-line fix in a sibling file, and S3's real 2024 URL would replace it
    properly.
  • [S5] utilities_share_of_rent.yaml:4-8 — the comment opens "§5219-KK is intentionally NOT
    cited for this 15%", yet §5219-KK(1)(E) is the first entry in the reference list. The intent
    (cited for the utilities-exclusion concept, not the 15% value) is clear from the rest, but the
    first sentence reads as a contradiction. Suggest: "§5219-KK(1)(E) is cited only for the
    utilities-exclusion concept, not for the 15% value: …".
  • [S6] rent.yaml:7 — pre-existing statute title has a truncation artifact: "§5219-KK. Property
    tax fairness credit for tax (1) (E)". The 2021/2022 titles also carry trailing spaces and omit
    the "Line 5(e)" specificity the 2023 entry has. One-word cleanup while the file is open.
  • [S7] utilities_share_of_rent.yaml:4-8 — the sourcing-rationale comment sits between values:
    and metadata:; conventional placement is above the block it explains. Cosmetic.
  • [S8] Rate-coincidence blind spot (already acknowledged in the test file header): rate.rent
    and rate.utilities_share_of_rent are both 0.15 in every year, so swapping the two parameter
    references in the formula would pass the entire suite. The header correctly bans known-amount
    cases where amount = 0.15 × rent. Nothing more is testable at baseline; add a discriminating case
    if the rates ever diverge.
  • [S9] Senior (age ≥ 65, 1_500–2_000 cap) and veteran interactions are covered only via direct
    countable_rent_property_tax inputs. Low risk since the new rule is upstream and orthogonal, but
    one senior end-to-end case would seal the composition.
  • [S10] Credit-file Case 4's name lacks the trailing period its siblings use.

PDF Audit Summary

12 matches, 0 mismatches. No page offset in any edition (physical page N == #page=N), confirmed
visually at 300 DPI for the three cited anchors.

  • Line 5c unknown-utilities 15% rule — verbatim in all six editions: 2014 #page=2, 2021
    #page=2, 2022 #page=2, 2023 #page=1, and (collected during this review) 2024 #page=1 and
    2025 #page=1: "If yes, and you do not know the amount paid, multiply line 5a by 15% (.15)…
    If line 5b is no, enter '0' on line 5c." Instruction pages (p. 4 of every edition) restate it:
    "If your landlord cannot provide the amount…, multiply the amount on line 5a by 15%."
  • Line 5e rent rate 15% — "Multiply line 5d by 15% (.15)" in all six editions, matching
    rate/rent.yaml.
  • Statute — §5219-KK(1)(E): "'Rent constituting property taxes' means 15% of the gross rent
    actually paid", and gross rent is "exclusive of charges for any utilities, services, furniture,
    furnishings or personal property appliances furnished by the landlord".
  • The parameter comment's central claim is verified: grep -c "15%" on the statute text = 1
    — the sub-§1(E) rent rate only. The statute contains no unknown-amount estimate; that 15% is
    form-instructions-only. So deliberately not citing §5219-KK for the value is correct, and citing
    it for the utilities-exclusion concept pinpoints the right paragraph (the gross-rent definition
    lives inside (1)(E) itself; there is no separate paragraph).
  • 2014-01-01 start date corroborated — statute header "For tax years beginning on or after
    January 1, 2014" (PL 2013, c. 551), and the 2014 edition already carries both 15% rules.
  • Dropped 2024 reference lost nothing — the removed rent.yaml entry was titled "2024 Form
    1040ME…" but its href was byte-identical to the retained 2023 entry, i.e. a mislabeled duplicate.
    Removing it improves accuracy. (The same duplicate survives in income.yaml — see S4.)

Verification item closed. The one open flag from the verification queue was that the constant
0.15 was evidenced only for 2014/2021/2022/2023, while test Case 16 asserts 2024 against the
parameter rather than a 2024 form. Both the 2024 and 2025 Schedule PTFC editions were downloaded and
read during consolidation: both carry the identical line-5c 15% rule and line-5e 15% rate. Case
16's 2024 assertion is now backed by an actual 2024 form, and continuity extends through 2025.

Hand-recomputed test expectations, all agreeing: Case 1 (5b no) 1000 × 0.15 = 150; Case 2 (known 50)
950 × 0.15 = 142.5; Case 3 (unknown) 5c = 150, 850 × 0.15 = 127.5; Case 9 (joint, 6000+4000) 5c =
1500, 8500 × 0.15 = 1275; Case 12 (known 1) 999 × 0.15 = 149.85; credit Cases 4/5/6 → 765 / 710 / 750.

Validation Summary

Check Result
Regulatory Accuracy Pass — matches §5219-KK and the 2014–2025 form instructions; post-approval rename verified sound; 0 critical
Reference Quality Pass — 0 critical, 0 should-address; every href fetched and every #page= anchor verified against the actual file page
Code Patterns Pass — parameterized 15%, clean where()/max_ vectorization, correct entity handling, reuses rather than duplicates the flag; 0 critical
Formatting Pass with nit — changelog fragment present and correctly typed, filename/branch mismatch (A4)
Test Coverage Strong — 16 unit cases covering the full flag × amount branch matrix, sentinel, clamp, aggregation, defaults, and 2014/2024 temporal pins, all with discriminating values; one end-to-end composition gap (A3)
PDF Value Audit Pass — 12 matches, 0 mismatches, across six form editions
Microsim Safety Pass — flag defaults false and amount defaults 0, so population runs take the unchanged full-rent path; zero change to population-level PTFC, pinned by Case 14
CI Status Pass — all 33 checks (run 32732780945)

Review Severity: APPROVE

No critical findings. The post-approval rename that triggered this re-review is a genuine
improvement — it reuses an existing correctly-entitied variable instead of adding a state-specific
duplicate — and the negative-rent clamp you'd previously verified survives intact. The unit test
suite is unusually thorough.

A1 (the unlinked heat_expense_included_in_rent sibling) is the one item with real modeling
consequence and is worth a follow-up; A5 (stale PR body) is worth fixing before merge so the record
matches the code.

DTrim99 and others added 2 commits August 25, 2026 09:39
Applies all Should-Address and Suggestion items from PavelMakarchuk's
2026-08-25 re-review of the ME PTFC line-5c fix. No parameter values or
formula logic changed.

- A1/S1: document the sibling heat_expense_included_in_rent flag (not OR'd
  in; deferred as a cross-entity design call) and correct the
  utilities_included_in_rent comment to describe it as a TaxUnit variable.
- A2: put the 0-as-"amount unknown" sentinel on the input variable's own
  label and documentation, not only in the formula comment.
- A3/S9: add end-to-end cases composing the unknown-amount estimate with a
  binding non-senior cap (1000), a binding income phase-out (730), and the
  senior cap band (2000).
- A4: rename changelog fragment to match the branch.
- S2: broaden the shared utilities_included_in_rent label to the form's
  "heat, utilities, furniture, or similar items".
- S3/S4: replace the mislabeled 2024 income-rate reference (duplicate 2023
  href) with the real 2024 Schedule PTFC URL, and add verified 2024/2025
  line-5c references to utilities_share_of_rent.
- S5/S7: reword and reposition the utilities_share_of_rent sourcing comment
  so it no longer contradicts the cited statute.
- S6: fix the truncated statute title in rate/rent.yaml.
- S10: add the missing trailing period to credit Case 4's name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YCwrSsGY7vPCpKYGfV1xRr
Applies the Should-Address and Suggestion items from PavelMakarchuk's
2026-08-25 re-review of the ME PTFC line-5c fix. No parameter values or
formula logic changed.

- A1/S1: document the sibling heat_expense_included_in_rent flag (not OR'd
  in; deferred as a cross-entity design call) and correct the
  utilities_included_in_rent comment to describe it as a TaxUnit variable.
- A2: put the 0-as-"amount unknown" sentinel on the input variable's own
  label and documentation, not only in the formula comment.
- A3/S9: add end-to-end cases composing the unknown-amount estimate with a
  binding non-senior cap (1000), a binding income phase-out (730), and the
  senior cap band (2000).
- S2: broaden the shared utilities_included_in_rent label to the form's
  "heat, utilities, furniture, or similar items".
- S3/S4: replace the mislabeled 2024 income-rate reference (duplicate 2023
  href) with the real 2024 Schedule PTFC URL, and add verified 2024/2025
  line-5c references to utilities_share_of_rent.
- S5/S7: reword and reposition the utilities_share_of_rent sourcing comment
  so it no longer contradicts the cited statute.
- S6: fix the truncated statute title in rate/rent.yaml.
- S10: add the missing trailing period to credit Case 4's name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YCwrSsGY7vPCpKYGfV1xRr
@DTrim99

DTrim99 commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up review addressed — thanks @PavelMakarchuk

Applied all Should-Address and Suggestion items from your 2026-08-25 re-review. No parameter value changed (the 0.15 rates are intact) and no formula logic changed — everything is documentation, references, labels, comments, and added tests.

Should Address

  • A1 — documented the sibling heat_expense_included_in_rent (SPMUnit) flag in the countable-rent formula: it overlaps line 5b but is not OR'd into the gate, so a heat-only household must set utilities_included_in_rent to answer 5b "Yes." I deferred OR-ing the two flags — as you noted, it's a cross-entity SPMUnit→TaxUnit change and a design call. Happy to take that as a follow-up if you'd prefer the fuller fix.
  • A2 — moved the 0 = amount unknown sentinel onto the input variable itself (its label and a new documentation string), so an app/API consumer introspecting me_property_tax_fairness_credit_utilities_in_rent_amount reads that 0 triggers the 15% estimate rather than "$0 of utilities."
  • A3 / S9 — added three end-to-end cases that compose the unknown-amount estimate with the parts that were previously bypassed: cap binds (single, age 40, rent 60k → countable 7,650 → cap 1,000), phase-out binds (single, age 40, rent 12k + income 20k → countable 1,530 − 4%·20k → 730), and a senior case (age 70, 2024, rent 60k → senior base 4,000 → senior cap 2,000).
  • A4 — renamed the changelog fragment to fix-me-ptfc-utilities-in-rent-v2.added.md to match the branch.
  • A5 — refreshed the PR body: it now names utilities_share_of_rent and describes the current reuse-the-generic-boolean + ME-amount-input design instead of the pre-rename discriminator.

Suggestions

  • S1 — corrected the "generic household boolean" comment to describe utilities_included_in_rent as a TaxUnit variable.
  • S2 — broadened the shared utilities_included_in_rent label to "heat, utilities, furniture, or similar items" (reads correctly for MI's usage too).
  • S3 / S4 — replaced the mislabeled 2024 reference in rate/income.yaml (its href was a byte-identical duplicate of the 2023 entry) with the real 2024 Schedule PTFC URL, and added the verified 2024 and 2025 line-5c references to utilities_share_of_rent.yaml.
  • S5 / S7 — reworded the utilities_share_of_rent sourcing comment so it no longer contradicts the cited §5219-KK(1)(E), and moved it above the values: block.
  • S6 — fixed the truncated statute title ("…for tax (1) (E)" → "…(1) (E)") in rate/rent.yaml.
  • S10 — added the missing trailing period to credit Case 4's name.
  • S8 — the two 0.15 rates still can't be distinguished at baseline; noted only, nothing further testable until/unless they diverge.

I couldn't run the suite locally (the pinned venv is on a broken 3.14-alpha numpy), so I hand-verified all three new end-to-end expectations against the actual benefit-base, cap, and 4% income-rate parameters and am relying on CI for confirmation.

Fixed with Claude Code assistance.

@DTrim99
DTrim99 merged commit 789ed7b into PolicyEngine:main Aug 25, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants