Skip to content

Limit the Montana elderly homeowner/renter credit to one claimant per household (MCA 15-30-2341(1)) - #9900

Merged
MaxGhenis merged 15 commits into
mainfrom
fix-mt-ehrc-one-claimant-per-household
Oct 12, 2026
Merged

MaxGhenis merged 15 commits into
mainfrom
fix-mt-ehrc-one-claimant-per-household

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Montana's elderly homeowner/renter credit allows one claim per household, but the model paid every eligible tax unit in a household.

  • MCA 15-30-2341(1): "Only one claimant per household in a claim period under the provisions of 15-30-2337 through 15-30-2341 is entitled to relief."
  • The 2024 and 2025 Schedule 2EC attestation (2025 Form 2 p. 10): "I am the only member of my household claiming this credit".
  • The 2024 instructions (PDF p. 7) added the household count "to … verify that only one credit is claimed per household".
  • The 2025 instructions (PDF p. 45): "If filing jointly and both spouses qualify for the credit, enter the spouse listed as the taxpayer on page 1 as the claimant."

mt_elderly_homeowner_or_renter_credit_eligible checks only that the tax unit's head or spouse is 62 or older, and a comment in ..._net_household_income.py said "Only one claim is allowed per household" without enforcing it. Since #9882, gross household income is summed over the whole PolicyEngine household. So two eligible tax units in one household each computed a credit on the full household income, and both were paid.

Includes the stacked household-income and historical deduction corrections from #9882 and #9877. This round merges current main to incorporate #10004's deductible-mortgage-interest corrections alongside the care-deduction wiring.

Example: 2024, two elderly siblings filing separately in one household

Sibling 1 is 66, has a $10,000 pension and pays $4,800 of rent. Sibling 2 is 70, has a $15,000 pension and pays $7,200 of rent.

2024 Schedule 2EC line Sibling 1 Sibling 2
18 Gross household income (both pensions) 25,000 25,000
20 = 18 − 12,600 12,400 12,400
22 Net household income (× 0.05) 620 620
25 Rent × 15% 720 1,080
27 = 26 − 22 100 460
30 Credit (× 100%) 100 460
Pre-limit credit 100 460
Paid after 0 460

In the stacked model, the household receives $560 before the claimant limit and $460 after it.

Which member claims

Neither the statute nor the Department of Revenue's implementing rule, ARM 42.4.302 ("IMP: 15-30-2340, 15-30-2341, 50-5-101"), says which eligible member is the claimant. I chose the tax unit whose credit is largest.

  • Every eligible tax unit in a household has the same gross household income (line 18), net household income (line 22) and credit multiplier (line 29).
  • Their credits differ through line 26: property tax billed plus 15% of rent. Selection ranks the computed pre-limit credit after the contribution, cap and multiplier; ties at zero or the cap use member order. A renter paying $6,000 (line 26 = 900) loses to an owner billed $1,000 (line 26 = 1,000) when their resulting credits differ.
  • The model assumes the household chooses the largest credit. If two members both reach the $1,150 cap, either gives the same amount, and member order decides.
  • Whose costs count is a separate, pre-existing model choice, which this PR does not change. The model counts each tax unit's own property tax and rent. That follows the form's wording: line 23 is "the property tax you were billed", line 24 is "the rent that you paid", and the instructions (2025 PDF p. 47) say "Your rent is only the amount of money that you paid to occupy your home".
    • The statute defines both amounts for the homestead instead. §2337(10): "'Property tax billed' means taxes levied against the homestead". §2337(5): "'Gross rent' means the total rent ... actually paid ... by the renter or lessee for the right of occupancy of the homestead".
    • Under that reading, the one claimant would count the household's whole property tax and rent. In the sibling example above that is 1,800 − 620 = 1,180, capped at 1,150, instead of 460.
    • The law supports more than one reading, so I queued it for Max as decision d1035. A follow-up task implements the ruling.

Alternatives I rejected:

  • The oldest member, as Utah's ut_homeowner_renter_relief_selected_claimant does. With costs counted per tax unit, the oldest member may have no property tax or rent and a $0 credit. That would deny the household a credit the law allows one of its members.
  • Whoever is billed the property tax or pays the rent. When only one member holds housing costs and has a positive credit, that member has the largest credit. It gives no answer when members split the rent; the largest-credit rule still does.

get_rank ranks the candidates in each household 0, 1, 2, ..., so exactly one has rank 0. Its stable sort gives a tie to the first tax unit in member order. A joint return is one tax unit and one claim. The model already held that credit on the tax unit head, which stands in for "the spouse listed as the taxpayer".

Changes

  • New mt_elderly_homeowner_or_renter_credit_pre_one_claimant (Person): the existing Schedule 2EC computation moved from mt_elderly_homeowner_or_renter_credit, with this round's correction to the multiplier lookup for negative household AGI. It is nonzero only on an eligible tax unit's head.
  • New mt_elderly_homeowner_or_renter_credit_selected_claimant (TaxUnit, defined_for = StateCode.MT). It ranks eligible tax unit heads within person.household by that credit, largest first, using person.get_rank, the same pattern as Utah's selected claimant. It is vectorized and has no loops or Python branching on arrays.
  • mt_elderly_homeowner_or_renter_credit = pre-limit credit × the tax unit's selection. Its name and defined_for are unchanged, so mt_refundable_credits and state_property_tax_credits need no change.
  • The stale comment in ..._net_household_income.py now points at the selection variable.
  • The one-claimant limit applies in every year the model covers (its elderly credit parameters start in 2009, when §2341 took its current number), so it needs no parameter. The section was amended in 1983, 1989, 1997, 2009 and 2015. I have not checked the pre-2009 wording of subsection (1).

Tests

  • mt_elderly_homeowner_or_renter_credit.yaml, five new cases:
    • two eligible siblings (above);
    • one eligible tax unit and a younger member with larger rent: [100, 0];
    • a 2025 joint couple who both qualify: one 1,150 claim, [1_150, 0];
    • equal credits: exactly one 280 claim, [280, 0];
    • two households: each claims, [1_150, 900].
  • Six legacy cases never set a state and only input mt_elderly_homeowner_or_renter_credit_eligible. They now place their household in Montana; their expected values are unchanged.
  • New mt_elderly_homeowner_or_renter_credit_selected_claimant.yaml, nine cases:
    • order-independence;
    • a tie;
    • an ineligible unit with a larger amount;
    • no eligible unit;
    • three units;
    • per-household selection;
    • a joint couple;
    • only tax unit heads are ranked (another member's amount does not count);
    • a non-Montana household.
  • New mt_elderly_homeowner_or_renter_credit_pre_one_claimant.yaml: three tax units, one of them under 62. Its line-27 amounts are [0, 210, 0].
  • New policyengine_us/tests/test_mt_elderly_credit_one_claimant.py: a worked example plus a derandomized Hypothesis test of the invariants below. Two explicit examples are pinned: a tie at the cap, and an owner against a renter who pays more but has the smaller line 26. Random households have one to three tax units, single or joint, with any mix of ages, pension, interest, Social Security, property tax and rent. Each household is built in both tax-unit orders, and the results are compared against a reference written from the Schedule 2EC lines.
  • Mutation checks:
    • Ranking by +credit (the smallest claim wins) or selecting every candidate fails both the worked example and the Hypothesis test on its own.
    • Dropping the head filter (candidate = eligible) fails selected-claimant Case 8.

Why a Python test as well as YAML. The YAML cases pin specific households. The Hypothesis test checks invariants over random households. It also runs a differential: each household is built in both tax-unit orders, and an independent reference written from the Schedule 2EC lines is compared with the model. YAML cannot express either. It follows #9882's test_mt_elderly_credit_household_members.py:

  • It reads parameters from the shared policyengine_us.system.system instead of building a model.

  • It builds one small Simulation per example, 15 examples plus one worked example.

  • It runs in the Rest "remaining" group (239 s in the Makefile's timing note).

  • Local measurement on macOS at load average about 377, so wall times are inflated:

    Run Wall time CPU time Peak RSS
    Importing the model and one calculation 68 s 16.2 s 744 MB
    This test file alone 108 s 23.0 s 924 MB

    That is about 7 CPU-seconds more than an import, and pytest reported 22.9 s. I have no Linux CI measurement yet.

Previous-round validation, run locally one file at a time (before this review round):

  • The four existing MT credit YAML files and the two new ones pass: 21, 3, 3, 7, 9 and 1 cases.
  • test_mt_elderly_credit_one_claimant.py (2 tests) and Count household members' income in Montana's elderly homeowner/renter credit #9882's test_mt_elderly_credit_household_members.py (2 tests) pass.
  • These code-health tests pass: test_reference_urls, test_known_dead_reference_urls, test_no_concatenated_reference_urls, test_rest_python_groups, test_no_builtin_sum_over_entity_calls and test_no_in_place_writes_to_cached_arrays.
  • A scan of every YAML test found no other Montana case with two or more tax units in one household.

Invariants

These are property-tested over the generated 2024 domain: one to three single or joint tax units, using pension, interest, Social Security and housing costs:

  1. Each tax unit's pre-limit credit equals the Schedule 2EC reference.
  2. The household's credit equals the largest pre-limit credit among its tax units, so it never exceeds the $1,150 cap of a single claim.
  3. At most one tax unit per household is paid. Exactly one is selected if any tax unit is eligible, and none otherwise.
  4. Each tax unit is paid nothing or its whole pre-limit credit, and the selected one is paid in full.
  5. The household's credit does not depend on the order of its tax units.

Hub microsimulation impact (current head)

A real microsimulation on the default dataset, main at the merge base 42076211f5 against this PR's head bfcf454cc5, for 2025 and 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.

Output 2025 change 2026 change 2025 records changed (weighted) 2026 records changed (weighted)
mt_elderly_homeowner_or_renter_credit +0 +0 0 (0) 0 (0)
mt_elderly_homeowner_or_renter_credit_gross_household_income +0 +0 0 (0) 0 (0)
mt_income_tax +0 +0 0 (0) 0 (0)
household_net_income +0 +0 0 (0) 0 (0)
state_income_tax +0 +0 0 (0) 0 (0)
income_tax +0 +0 0 (0) 0 (0)
household_benefits +0 +0 0 (0) 0 (0)

Comparison files are in fixes/9900-impact/ on the hub host.

Hub microsimulation impact (before #9915 merged)

These earlier impact numbers were measured before #9915 merged on 2026-10-11. They do not describe the merged head below. The hub will rerun the impact comparison.

A real microsimulation on the default dataset, main at the merge base 41220ad346 against this PR's head 261e65b1ba, for 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.

Output 2026 change 2026 records changed (weighted)
mt_elderly_homeowner_or_renter_credit -3.30M 8 (3,778)
mt_elderly_homeowner_or_renter_credit_gross_household_income +1.07bn 147 (81,899)
mt_income_tax +3.30M 8 (3,778)
household_net_income -3.30M 8 (3,778)
state_income_tax +3.30M 8 (3,778)
income_tax +0 0 (0)
household_benefits +0 0 (0)

Comparison files are in fixes/9900-impact/ on the hub host.

Hub microsimulation impact

Claimant-limit-only measurement: $0 in 2024 at the previously measured head. The existing same-run comparison at 98d3742c35 on populace_us_2024 compares the pre-limit and paid credit. Both incorporate the stacked household-income and deduction fixes, so it isolates only the claimant limit. It does not measure the whole PR against merge base bab1a47c6046a5f74a51f250e2ffaee171dc90e0, or against current main. The stacked income corrections, historical deduction years, this round's dependent AGI adjustments, and the negative-total multiplier correction remain unquantified. The hub must supply that full impact comparison; no microsimulation was run in this round.

2024 Value
Elderly credit before the limit $7,587,384
Elderly credit after the limit $7,587,384
Change $0
Households with an eligible tax unit 168,749
Households with two or more eligible tax units 11,183 (10 records)
Households paid more than one claim before 0
Records whose credit changed 0

All 10 sample households with two or more eligible tax units have gross household income from $46,768 to $466,767. That is at or above the $45,000 cutoff, so every one of their credits is already $0. The limit binds for households the sparse sample does not contain, such as the elderly siblings above. Only 14 Montana records have a positive credit. No other year was measured; historical deduction effects and the full branch impact cannot be inferred from these records.

Review round 2

Reproduced P2 on the exact reviewed head: the 2023 $20,000-pension claimant with $12,000 rent and a dependent earning $10,000 of self-employment profit received $930 instead of $965.323875. The correction preserves the dependent's permitted, person-attributable non-loss federal AGI adjustments while continuing to exclude losses. 2023 instructions, PDF pp. 51–52 start with each member's AGI and add back losses. Hand arithmetic from 2023 Schedule SE, p. 1: 10,000 × .9235 × .153 / 2 = 706.4775; household income 29,293.5225; credit 1,800 − (29,293.5225 − 12,600) × .05 = 965.323875. The YAML regression and expanded Hypothesis cases cover earned income, SE health/pension adjustments and early-withdrawal penalties, including negative member AGI. Derived assertions now cover TAXSIM property-tax credit, multi-tax-unit Montana income tax, and a care-deduction phaseout crossing the standard-deduction threshold. P3's impact claim is scoped to the claimant limit, with the whole stacked-branch comparison explicitly left to the hub.

The expanded property test also reproduced a negative-total edge case: the existing multiplier lookup paid $0 at household incomes of −$325 and −$547, although both should receive the $319 housing-cost credit. The 2024 instructions, PDF p. 49 give a 100% multiplier for all income below $35,000. Floor only the multiplier lookup input, preserving signed household income and the full non-loss deductions. Worked regressions and pinned Hypothesis examples cover both cases and retain the monotonicity invariants. Hand arithmetic: 347 + 4,420 + 894 − 5,986 = −325; 347 − 894 = −547; both have zero household contribution after the $12,600 exclusion, so $319 × 100% = $319.

The expanded household-member file passes all 3 tests, retaining 15 derandomized generated examples and pinning the review case, SE-tax threshold, negative household totals, and a minor's separate return. The fixtures use main's validated explicit filer roles so that a minor filing separately is its return's head; the existing assertions verify the resulting dependency status.

Local cost measurements include interpreter/model setup. The original test file was run with the corrected pre-merge model; the expanded file includes merged main and all final corrections. These macOS runs include varying shared-machine load and model changes; Linux CI cost is unmeasured.

Household-member test file Wall time CPU time Peak RSS
Original, 2 tests 496.7 s 39.1 s 834 MB
Expanded, 3 tests 635.4 s 37.0 s 887 MB

Validation before the #9915 merge. CI at 261e65b1ba: all 26 checks passed (run 38085467718). Local runs (one file per process): 22 credit YAML cases, 3 itemization-choice YAML cases, 7 joint and 5 individual itemized-deduction cases, and the expanded household property file (3 tests) passed. An earlier run of that property file failed 1 of 3 before the last commit supplied explicit filer roles in its fixtures; the rerun passed. The local run stopped there when the build reached its time limit; the remaining merged mortgage fixture files were not re-run locally and are covered by CI. Ruff format/lint and the PR diff check against gh/main pass.

Validation after merging #9915

Merged gh/main at 42076211f50b73d4f31ab22a01eaf85682d56a47 into the approved head 261e65b1ba3eec8bd4e356c50a98f4734b4f72e3 with a plain merge commit. Merged head: da7c17e84416602056b239c77e5fbbe9704ba1f4.

All seven conflicts are resolved: retain #9900's maximum-credit selection, one payment per household, expanded household-member property tests, and negative-income multiplier correction; retain #9915's federal refundable credits, actual credit/rebate receipts, dependent-owned non-loss deductions, and positive federal-AGI allocation with zero shares when filer AGI is zero. Both PRs' YAML cases are preserved. Partner contract tests are unchanged.

A new combined Schedule 2EC regression counts pensions 25,000 plus federal refunds 800 plus actual elderly-credit receipts 100 plus rebate receipts 100: gross household income 26,000; contribution (26,000 - 12,600) * .05 = 670; pre-limit credits [720 - 670, 1,080 - 670] = [50, 410]; paid [0, 410]. The existing 2021 59.24 expectation and its EITC/EIP arithmetic are retained from #9915.

Local execution was attempted using the requested existing Python environment, one file in the foreground: mt_elderly_homeowner_or_renter_credit.yaml. Model startup exceeded 25 minutes without test output and was interrupted while loading parameter YAML (KeyboardInterrupt), per the requested cutoff. No test cases completed locally. The required inventory contains 28 Montana files (21 YAML and 7 Python); the remaining 27 files were not started. Execution validation therefore relies on CI for this merged head; no folders, full suites, or microsimulations ran locally.

CI at the merged head: run 38141521698. All 21 inventory YAML files passed (179 cases) in completed Baseline state shards 1 and 4; Montana's shard-4 batch passed 664 cases. Quick Feedback passed six changed files individually (46 tests), including both claimant Python files and all 28 credit YAML cases. PR validation and Household API Partners also passed. At this update, 24 checks have succeeded, two remain running, and none have failed. Rest Python is still running; test_mt_elderly_credit_dependent_deductions.py, test_mt_elderly_credit_rebate_receipts.py, test_mt_elderly_credit_refundable_credits.py, test_mt_federal_income_tax_deduction_allocation.py, and unit/test_mt_joint_agi_deductions_properties.py await that result.

make format (Ruff formatting and lint) and git diff --check gh/main pass. The earlier CI and microsimulation measurements above apply to their named pre-merge heads; the hub reruns impact for this merged head.

Methodology

  • Claimant: Retain maximum-credit selection as a proxy for explicit claimant designation. MCA §2341(1) requires one claimant but does not prescribe maximizing. Explicit designation is the alternative. This PR changes main by limiting the household to one payment; this round retains the reviewed selection rule.
  • Housing costs: Retain each tax unit's own costs, following Schedule 2EC lines 23–24, PDF p. 10 and rent instructions, PDF p. 47. Pooled homestead costs under §2337(5), (10) are an alternative that can change amounts. This cost basis is unchanged relative to main; decision d1035 remains for Max.
  • Federal tax attribution: Retain the reviewed current-year federal liability proxy allocated by positive federal AGI because spouse-specific payment inputs are unavailable. Actual withholding/payments or separately computed liability are alternatives. 2022 instructions, PDF pp. 33–34 prescribe payments and attribution to the earning spouse; they do not prescribe AGI proportions. This allocation, including zero shares when neither filer has positive federal AGI, is inherited from main, where it has been since Count refundable credits received in Montana's elderly homeowner/renter credit income #9915; this PR does not change federal tax attribution.
  • Dependent AGI: Preserve permitted non-loss adjustments that the existing model attributes to a person, instead of treating dependent gross income as AGI. Ignoring these adjustments is contradicted by §2337(9)(a) and the 2023 instructions. This treatment, including counting a dependent's gross income, is inherited from main, where it has been since Count refundable credits received in Montana's elderly homeowner/renter credit income #9915; this PR does not change it. Tax-unit-only adjustments, such as HSA contributions, cannot be assigned to a dependent's separate return with existing inputs; that pre-existing attribution limitation remains.
  • Negative total income: Apply the full multiplier below $35,000, including negative totals, as the instruction table explicitly directs and §2340(5) supports. The alternative is the existing lookup's zero for negative inputs. This round corrects both the reviewed head and main on this edge case; it does not floor gross household income or discard deductions.

Additional household-income invariants (Hypothesis, for the generated income sources and supported deductions): each member contributes AGI without losses plus nontaxable income; person-attributable non-loss adjustments reduce the total by their full modeled amount, with no zero floor on an individual contribution; dependent and separate-filer arrangements agree for a single capital-gain source when other refundable credits are absent. Mixed long-term gains and short-term losses retain their pre-existing treatment and are outside this equivalence assertion. Generated cases include positive SE income, bounded SE health/pension expenses, early-withdrawal penalties, capital losses, and Social Security. The existing claimant-selection invariants above remain covered.

Not changed

  • Bona fide lessees, tenants, roomers and boarders are outside the §2337(7)(b) household, but PolicyEngine's Household cannot identify them. As in Count household members' income in Montana's elderly homeowner/renter credit #9882, they count as household members, so the limit can apply to them.
  • Non-arm's-length rent between household members is not modeled. §2338(4) allows the department to adjust it.
  • Married couples living apart. ARM 42.4.302(3)(a) says they "are entitled to file and receive only one credit per year". A joint return is one tax unit and one claim here. A separated spouse filing in another tax unit is not linked to the other spouse, so that case is not limited.
  • Housing costs paid by other household members. Two gaps predate this PR; one follow-up task covers both:
    • The homestead reading of §2337(5) and (10), described above, is Max's decision d1035.
    • ARM 42.4.302(2)(b) lets a claimant use "property taxes billed ... as rent if the property occupied by the claimant is in a name other than the claimant." The model counts only each tax unit's own property tax and rent.
  • An elderly dependent as claimant. §2338(1) makes any individual aged 62 or older eligible to claim. The model's eligibility checks only the tax unit head and spouse, so an elderly dependent in someone else's tax unit cannot be the claimant. This predates this PR.

axiom: TheAxiomFoundation/rulespec-us#1512 queued (required output 8 names §2341's one-claimant limit; this PR's verbatim sources, review_finding addendum and companion cases are in this comment)

🤖 Generated with Claude Code

MaxGhenis and others added 6 commits October 6, 2026 07:08
… the forms

- Federal income tax deduction (through 2023): attribute federal tax to the
  spouse who earned the income and cap each spouse at $5,000, instead of
  prorating the jointly capped amount by Montana AGI (2022 Form 2
  instructions, Itemized Deductions Schedule, line 4).
- Child and dependent care expense deduction (through 2023): phase out on the
  couple's combined Montana AGI and split the result equally only for spouses
  filing separately on the same form; a single filer and a joint return take
  the whole deduction (Form 2441-M lines 3-7).
- Elderly homeowner/renter credit: count federal AGI without regard to losses
  (MCA 15-30-2337(9)(a); Form 2EC line 9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ions

Each spouse filing separately on the same form deducts their own federal
income tax up to $5,000, so both spouses itemize and Montana tax is 6,295.56.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…chedule

- A married person filing on a separate form (federal filing status
  SEPARATE) cannot take the child and dependent care expense deduction:
  "married couples shall file a joint return or file separately on the same
  form" (MCA 15-30-2131(1)(c)(vi)(A)); 2022 instructions, line 14.
- The 2023 credit schedule was the Elderly Homeowner/Renter Credit
  Schedule; it became Schedule 2EC in 2024.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MCA 15-30-2337(4) defines gross household income as "all income received
by all individuals of a household while they are members of the
household". The 2023 Elderly Homeowner/Renter Credit Schedule combines the
returns of "ALL members of the household" (lines 1-7 and 9) and has
non-filing members report their wages on line 8; the 2024 and 2025
Schedule 2EC put "Income received by other members of your household" on
line 17.

The model summed each person's federal AGI over the tax unit. A tax unit
dependent's federal AGI is zero (their income is on their own return), so
a dependent's wages and other income were left out, and household members
who file their own returns were never counted.

- Add dependent_gross_income to the gross income sources. It counts a
  dependent's gross income items, gains but not losses, and the taxable
  part of their Social Security; the formula now subtracts that part
  before adding the untaxed remainder, so the benefits count once.
- Sum gross household income over the household instead of the tax unit
  in the net household income and the credit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… tests

dependent_gross_income counts anyone who is not the head or spouse, while
irs_gross_income counts anyone who is not a dependent. A person with
neither role (a minor alone in a tax unit whose dependent flag is input as
false) was counted by both. Count dependent_gross_income in the formula
for tax unit dependents only, so the two paths split people exactly.

The property tests check, for random claimants and household members,
that gross household income is the Schedule 2EC total whether the other
member is a dependent or files their own return, that the credit is the
same either way, stays within its bounds, and never rises with income.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… household

MCA 15-30-2341(1): "Only one claimant per household in a claim period ...
is entitled to relief." Since gross household income now counts every
household member, two eligible tax units in one household (for example two
elderly siblings filing separately) each computed a credit on the same
household income and both were paid.

- mt_elderly_homeowner_or_renter_credit_pre_one_claimant holds the existing
  computation (Schedule 2EC lines 18-30) for every eligible tax unit.
- mt_elderly_homeowner_or_renter_credit_selected_claimant (TaxUnit) ranks the
  eligible tax unit heads within each household by that credit with
  get_rank and selects the largest; ties keep member order, so exactly one
  tax unit per household with an eligible one is selected.
- mt_elderly_homeowner_or_renter_credit pays only the selected tax unit.

Six legacy credit cases that never set a state now place their households in
Montana. Adds YAML cases (two eligible tax units, one eligible, a joint
couple, a tie, separate households) and property tests against a
Schedule 2EC reference.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Cite ARM 42.4.302, the rule implementing 15-30-2341, in the selected
  claimant's references; note that neither it nor the statute says which
  member claims.
- Restore the living-apart note in the net household income comment with
  its source (ARM 42.4.302(3)(a)), and say in the selection comment that a
  separated spouse in another tax unit is not linked, so that limit is not
  modeled.
- Selected-claimant Case 8 now fails if non-heads are ranked: a dependent's
  input amount larger than the other tax unit's no longer decides the
  selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Independent review (Opus) asked for text fixes only:
- The selection ranks by Schedule 2EC line 26 (property tax billed plus 15%
  of rent, before the cap), not by total housing cost; say so.
- Counting each tax unit's own property tax and rent follows the form's
  wording; the statute defines both for the homestead
  (MCA 15-30-2337(5), (10)). Name that reading as not modeled (queued for a
  ruling as decision d1035).
- Uniqueness of the selection comes from get_rank's ranks; its stable sort
  only breaks ties.
- Cite ARM 42.4.302 at Cornell, which shows the rule text.

The Hypothesis test is now derandomized and pins a tie at the cap and an
owner against a renter who pays more but has the smaller line 26.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ructions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 6 commits October 10, 2026 13:38
Retain refundable-credit and actual-receipt income rules, dependent-owned non-loss deductions, and federal-AGI tax allocation alongside maximum-credit claimant selection and the negative-income multiplier fix. Preserve both test sets and add a worked combined-credit regression.
The separate-filing allocation fragment duplicated the line released in
2.38.17, and the household-member income fragment repeated the
dependent and separate-filer income corrections released there too.
Keep one line per change this PR makes: the one-claimant limit and the
full multiplier for negative household income.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis MaxGhenis closed this Oct 11, 2026
@MaxGhenis MaxGhenis reopened this Oct 11, 2026
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Three items for this PR from the reviews of #9882, which I closed as superseded by #9915. They belong here because this PR rewrites the files involved, and keeping one writer per file avoids conflicts:

  1. test_mt_elderly_credit_household_members.py.
    • Set derandomize=True on the Hypothesis settings, as tests/core/test_dependent_above_the_line_deductions_invariants.py does. DTrim99's mutation check removed the is_tax_unit_dependent gate and ran 10 seeds: the property test missed the regression under 2 of the 10, so about one CI run in five.
    • Once Count a filer's gains without netted losses and Social Security once in Montana's elderly credit income #10139 lands, also draw short_term_capital_gains for the other member. Before then, arrangements A and B disagree whenever the draw nets a loss against a gain.
  2. mt_elderly_homeowner_or_renter_credit.py. The credit cites only the definitions section, §15-30-2337. Add the computation section, §15-30-2340 (cap and multiplier), and §15-30-2338(1)(d) (gross household income below $45,000).
  3. mt_elderly_homeowner_or_renter_credit_net_household_income.py, lines 21–22. The comment "Only one claim is allowed per household / married taxpayer who are living apart may qualify for only one credit per year" is stale: this PR enforces the first rule, and the second is not modeled.

#10139 touches only the gross household income formula, the trailing comment in gross_income_sources.yaml and appended YAML cases, so it should not conflict with this PR.

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

US + core hub merge audit, us#9900 at bfcf454cc5a31acfd77eba1c1710974054219b68 (squash): Limit the Montana elderly homeowner/renter credit to one claimant per household (MCA 15-30-2341(1)).

@MaxGhenis
MaxGhenis deleted the fix-mt-ehrc-one-claimant-per-household branch October 12, 2026 14:50
@DTrim99

DTrim99 commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Limit the Montana elderly homeowner/renter credit to one claimant per household (MCA 15-30-2341(1))

PR #9900 (author: MaxGhenis, head bfcf454cc5, 15 commits ahead of main and 41 behind).

Scope

Summary

When several tax units in one PolicyEngine household are eligible, the PR pays only the one with the largest credit. Before, each eligible unit computed a credit on the shared household income and every one of them was paid. The PR also fixes the multiplier lookup so that a negative gross household income gets 100% instead of 0%.

Both changes follow the law:

  • One claimant. MCA 15-30-2341(1): "Only one claimant per household in a claim period under the provisions of 15-30-2337 through 15-30-2341 is entitled to relief." The 2013 MCA has the same wording, so the limit covers every year the model's parameters reach (from 2009).
  • The multiplier. §15-30-2340(5) reduces the credit only "for a claimant whose household income is $35,000 or more but less than $45,000". The table in the 2024 instructions, PDF p. 49 gives "Less than $35,000 — 1.00 (100%)".

What I checked:

  • YAML tests: 77/77 pass, which is the 74 cases in the elderly credit folder plus the 3 in mt_tax_unit_itemizes.yaml. They pass on the extracted head tree and also on the tree that merges the head into current main. Both runs used policyengine-core 3.32.8, the CI minimum.
  • Python tests:
    • test_mt_elderly_credit_one_claimant.py: 2/2 pass, with 15 derandomized examples plus 2 pinned ones.
    • test_mt_elderly_credit_household_members.py: 3/3 pass.
  • Probes: 16 probe households on the head tree, plus a mutation check of the dependent gate.
  • Hand checks: 9 expectations.
  • CI and merge: CI is green (26/26), and the branch merges cleanly.

I found no critical or should-address issues:

  • The largest-credit rule is a reasonable modeling convention, and it is documented as one.
  • The enforcement is vectorized and deterministic.
  • In every household with an eligible tax unit, exactly one unit is paid, and it gets its whole credit.

#9882's S1 and S2 are still open on main. They arrived through #9915. They predate this PR and do not block it. The open PR #10139 fixes both. Details are in "Pre-existing on main" below.

Critical (must fix)

None.

Should address

None.

Suggestions

  1. Put the negative-income fix in the parameter, not the formula.
    • Where: mt_elderly_homeowner_or_renter_credit_pre_one_claimant.py:51-54, which floors the lookup input with p.multiplier.calc(max_(0, gross_household_income)).
    • Why it was needed: I confirmed on the head tree that multiplier.calc returns [0, 0, 0, 1] for [-547, -325, -1, 0]. The first bracket of multiplier.yaml starts at 0.
    • The repo pattern: the house rule is that the first threshold must be -.inf when negative inputs are valid. The parameter-patterns guidance says: "Starting a threshold at 0 silently drops negative-AGI filers into no bracket."
    • Fix: set the first threshold to -.inf (2009-01-01) and drop the max_. The result is identical, and any other caller of the parameter is then correct too. For example, reference() in test_mt_elderly_credit_one_claimant.py calls P.multiplier.calc(gross) without a floor.
  2. The items Max queued for this PR in his 2026-10-12 comment. The comment came after this head.
    • Citations. mt_elderly_homeowner_or_renter_credit.py now cites §2341. The computation moved to ..._pre_one_claimant.py, which cites §2337 and §2340. But no variable in the chain cites §15-30-2338(1)(d) ("must have less than $45,000 of gross household income"), which the 45,000 bracket implements. Add it to the pre-limit credit.
    • A comment that reads as enforced. mt_elderly_homeowner_or_renter_credit_net_household_income.py:21-24 still says "Married couples living apart may receive only one credit per year (ARM 42.4.302(3)(a))" as if the model enforces it. ..._selected_claimant.py:53-55 says correctly that it is not modeled. Add "(not modeled)", or point to that comment.
    • Already done: derandomize=True (test_mt_elderly_credit_household_members.py:365). The short_term_capital_gains draw waits for Count a filer's gains without netted losses and Social Security once in Montana's elderly credit income #10139.
  3. Clean up the PR body before merge.
  4. Comment, test and changelog polish.
    • ..._selected_claimant.py:43,49. Line 43 breaks the comment wrap mid-sentence ("The statute instead"), and line 49 is a 106-character comment line. Re-wrap them at 88.
    • mt_tax_unit_itemizes.yaml:46-48. The comment cites "2022 Form 2 instructions, PDF p. 35" for the standard deductions "max(min(.2 * 20,000, 5,090), 2,260)".
      • PDF p. 35 of the 2022 instructions is the line 14 child and dependent care text.
      • The worksheet is on the 2022 Form 2, PDF p. 7: "Multiply the amount on line 1 by 20% (0.20)", "If you are single or married filing separately, enter $5,090", and the minimum of "$2,260".
      • The expected values are right. Only the citation is wrong.
    • Changelog. changelog.d/fix-mt-ehrc-household-member-income.fixed.md reuses Count household members' income in Montana's elderly homeowner/renter credit #9882's branch name for the negative-income multiplier fix. Rename it, for example to fix-mt-ehrc-negative-income-multiplier.fixed.md, or fold it into the one-claimant fragment. This is optional, because towncrier does not care about the name.
  5. Axiom addendum.
  6. Optional tests.
    • A YAML case for the negative-income multiplier in mt_elderly_homeowner_or_renter_credit_pre_one_claimant.yaml. Today only the Python file pins it, so a YAML-only run of the folder misses it. Use the PR's second case: claimant 86 with $347 of Social Security and $319 of property tax; the member has an $894 early-withdrawal penalty. Gross household income is −547 and the credit is 319.
    • A YAML case where every eligible unit's credit is 0, for example gross household income ≥ 45,000. This pins that the first unit is selected and paid 0. My probe gives [0, 0] today.

Pre-existing on main (from #9882's review; not blocking this PR)

I checked both items on this head. ..._gross_household_income.py here is identical to main's.

S1: still open on main. A filer's short-term loss is still netted against their long-term gain. Head probe (2024): a claimant aged 70 with a $20,000 pension and $2,000 of property tax billed, and a household member aged 30 with LTCG +10,000 and STCG −4,000.

Arrangement Gross household income Net household income Credit Schedule 2EC
Member files their own return [20_000, 6_000] 670 1,150 30,000 → 1,130
Member is the claimant's dependent [20_000, 10_000] 870 1,130 30,000 → 1,130
The gain and loss are the claimant's own 26,000 670 1,150 30,000 → 1,130
  • The law: §2337(9)(a) counts "federal adjusted gross income, without regard to loss". The 2025 instructions, PDF p. 45, line 7, say "do not include any capital losses".
  • This PR's body and test docstring now qualify the claim correctly: "Mixed long-term gains and short-term losses retain their pre-existing treatment and are outside this equivalence assertion". The property test draws only long_term_capital_gains.

S2: still has no deterministic test on main. The gate itself works: a 16-year-old with $10,000 of wages, alone in a tax unit with is_tax_unit_dependent: false, gets role "neither" and gross household income [20_000, 10_000], and the credit is 1,130.

  • Mutation check:
    • I replaced is_tax_unit_dependent with "not head or spouse" in the gate, in scratch only. That is exactly the neither-role double count: the same probe then gives [20_000, 20_000] and a credit of 189.
    • All 74 YAML cases in the elderly credit folder still pass.
    • Both Python files that build dependents still pass: test_mt_elderly_credit_household_members.py and test_mt_elderly_credit_dependent_deductions.py.
  • This PR removes the remaining random coverage. Commit 261e65b1ba gives the property test's members explicit tax_unit_role_input roles (HEAD on their own return), so the test no longer reaches the neither-role branch at all. main's version reached it on some random seeds, about 8 seeds in 10 in my Count household members' income in Montana's elderly homeowner/renter credit #9882 mutation check. The explicit roles are the more realistic fixture, but they leave the gate unguarded.

Follow-up: #10139 (open, MaxGhenis, created 2026-10-12) fixes both items.

  • It fixes S1 in the gross household income formula.
  • It adds S2's deterministic YAML cases, the minor alone in a tax unit at both the gross household income level and the credit level.
  • I recommend merging it soon after this PR, then adding the short_term_capital_gains draw here, as Max's comment plans.
  • Expect a trivial conflict in the credit YAML, where both PRs append cases (see Branch status).

Verified correct

  • Law, researched first.
    • §15-30-2337:
      • (2) "'Claimant' means a person who is eligible to file a claim under 15-30-2338".
      • (7)(a) "'Household' means an association of persons who live in the same dwelling, sharing its furnishings, facilities, accommodations, and expenses".
    • §2338(1)(a) sets the age 62 test.
    • The 2024 and 2025 Schedule 2EC attestation reads "I am the only member of my household claiming this credit" (2024 Form 2, PDF p. 10; 2025 Form 2, PDF p. 10).
    • The 2024 instructions, PDF p. 7 say the household count was added to "verify that only one credit is claimed per household".
    • The 2023 instructions, PDF p. 51 say: "Only one claim is allowed per household, and married taxpayers who are living apart may qualify for only one credit per year."
    • The 2025 instructions, PDF p. 45 say: "If filing jointly and both spouses qualify for the credit, enter the spouse listed as the taxpayer on page 1 as the claimant." This sentence appears only in the 2025 instructions, and the joint-couple YAML case correctly uses 2025.
    • ARM 42.4.302:
      • It implements §§2340 and 2341.
      • (3)(a): "Married couples who are living apart are entitled to file and receive only one credit per year."
      • (2) lets property taxes billed count "as rent if the property occupied by the claimant is in a name other than the claimant".
  • The claimant rule is a reasonable convention, and it is documented as one.
    • Neither the statute, the ARM nor the forms say which eligible member claims. The household designates.
    • Every eligible unit in a household shares lines 18, 22 and 29, so their credits differ only through line 26 (property tax billed plus 15% of rent), the cap and the multiplier. Paying the largest credit models a household that files the best single claim.
    • The PR body ("Which member claims", "Methodology"), the formula comment and the changelog all say this is a modeling choice. They also disclose the statute's homestead reading of §2337(5) and (10) as an alternative (decision d1035).
    • Axiom ruling d1313 (2026-10-11) makes the claimant an input in RuleSpec and treats PolicyEngine's largest-credit pick as a simulation-side choice. That matches the PR.
    • Utah's ut_homeowner_renter_relief_selected_claimant uses the same get_rank pattern, ranked by age.
  • The enforcement mechanics (..._selected_claimant.py:56-64).
    • The candidates are tax unit heads that are eligible. The pre-limit credit is nonzero only on an eligible head, so each tax unit has at most one candidate.
    • person.get_rank(person.household, -credit, condition=candidate) ranks the candidates in each household as 0, 1, 2, …. Non-candidates are filled with inf and returned as −1, so exactly one candidate per household has rank 0.
    • policyengine-core's get_rank uses numpy.argsort(..., kind="stable") twice. I confirmed this in 3.32.8 and on core main. So ties go to the first unit in household member order, as the PR says.
    • credit = pre_one_claimant × selected pays the selected unit in full and pays everyone else 0, so no tax unit can be paid twice.
    • The code is fully vectorized, with no Python branching on arrays, and there is no circularity. The selection reads only the pre-limit credit, which never reads the paid credit.
  • Probes on the head tree (2024; all households in one simulation; outputs are pre-limit and paid credits).
Household Pre-limit Paid
PR example: siblings 66 and 70 on separate returns (pension 10k/15k, rent 4.8k/7.2k), both orders [100, 460] [0, 460] in both orders; mt_income_tax −460
Elderly couple filing jointly (70/66, pension 15k/10k, property tax 2,000) 1,150 on the head [1,150, 0]
Joint couple with the 7,200 rent on the spouse 460 on the head 460
Parent 70 (pension 15k, property tax 1,500) and child 40 (wages 20k, rent 6k), each filing [152, 0]: 35,000 → net 1,120 → 380 × 40% [152, 0]
Parent 80 (pension 10k, rent 3k) and child 63 (pension 8k, property tax 1,200), each filing [298.80, 1,048.80]: net 151.20 [0, 1,048.80]
First-listed unit aged 58 with rent 9,000, then a 70-year-old (pension 10k, rent 3k) [0, 435.60] [0, 435.60]
Three units: a joint couple 72/70 (property tax 900), a sibling 68 (rent 7k), an adult 30 (rent 12k) [641, 791, 0]: gross 20,000, net 259 [0, 791, 0]
Two units both at the 1,150 cap, both orders [1,150, 1,150] the first in member order; 1,150 total
Two eligible units, gross household income 50,000 [0, 0] [0, 0]
  • The multiplier commit (5b965e139a).
    • On the head tree, the lookup gives 1.0 for −547, −325, −1 and 0; 0.4 at 35,000; 0.1 at 44,999; and 0 at 45,000.
    • Because net household income is max_(G − 12,600, 0) × rate, a negative G contributes nothing, as a zero G would, so the household gets the full housing-cost credit. That is what §2340(5) gives below $35,000.
    • Signed income is otherwise preserved, so the PR adds no floor on gross household income.
  • The dependent AGI commit (10c7727dcf).
    • The code in the final diff is main's, from Count refundable credits received in Montana's elderly homeowner/renter credit income #9915. It subtracts the dependent's own person-level above-the-line deductions, excluding filer amounts recorded on dependents and loss_ald.
    • That follows §2337(9)(a)'s "federal adjusted gross income, without regard to loss" and the 2023 instructions' per-member AGI (PDF pp. 51-52).
    • This PR's 2023 YAML case checks it (credit.yaml:597): 10,000 × .9235 × .153 / 2 = 706.4775, so gross household income is 29,293.5225 and the credit is 1,800 − 834.676 = 965.32.
  • Callers (grep at head).
    • mt_elderly_homeowner_or_renter_credit keeps its name, entity and defined_for. It still feeds mt_refundable_credits and the TAXSIM state_property_tax_credits list.
    • The two new variables have no other callers.
    • Six legacy YAML cases needed a Montana household because the selection is defined_for = StateCode.MT. Their expected values are unchanged.
  • Code patterns.
    • There are no hard-coded policy values.
    • Entities and periods are correct: the selection is a TaxUnit bool, the credits are Person floats, and everything is YEAR.
    • The references are tuples with comments, and their anchors show what they cite:
      • 2024 Form 2 p. 10;
      • 2025 Form 2 p. 10;
      • 2025 instructions p. 45 (attestation, household, joint claimant);
      • 2025 instructions p. 47 ("can qualify as rent only"; "Your rent is only the amount of money that you paid to occupy your home");
      • 2024 instructions p. 49 (multiplier table).
    • Both property-test files set derandomize=True, so CI is reproducible.
  • Hand-checked expectations (all match).
    1. Siblings (credit.yaml:435): 25,000 − 12,600 = 12,400; × .05 = 620. Then 720 − 620 = 100 and 1,080 − 620 = 460. Paid [0, 460], and mt_income_tax is [0, −460] because 16,550 + 5,500 exceeds either pension.
    2. 2025 joint couple (:506): 2,000 − 620 = 1,380, capped at 1,150, held by the head.
    3. Equal credits (:534): 900 − 620 = 280 each. One is paid, to the first in member order.
    4. Two households (:564): 7,400 × .035 = 259, and 2,000 − 259 = 1,741, capped at 1,150. In the other household, 10,000 is under the exclusion, so its credit is 6,000 × .15 = 900.
    5. Pre-limit (pre_one_claimant.yaml): 30,000 gives 17,400 × .05 = 870. The credits are max(720 − 870, 0) = 0, 1,080 − 870 = 210, and 0 for the 40-year-old.
    6. Credits and receipts (credit.yaml:803): 10,000 + 500 + 60 + 20 = 10,580, and 15,000 + 300 + 40 + 80 = 15,420. The total of 26,000 gives a net of 670. The pre-limit credits are [50, 410], and only the 410 is paid.
    7. 2023 dependent self-employment: 965.323875 (above).
    8. Negative income (test_mt_elderly_credit_household_members.py:308): 347 + 4,420 + 894 − 5,986 = −325, and 347 − 894 = −547. Both pay the 319 property tax at 100%.
    9. Care phase-out (mt_tax_unit_itemizes.yaml:19):
      • 2022 Form 2441-M gives min(3,000, 2,400) − .5 × (20,000 − 18,000) = 1,400, so 700 to each spouse.
      • Itemized 4,650 + 700 + 700 = 6,050, which is less than the standard deductions 4,000 + 2,260 = 6,260, so the couple does not itemize.
  • Changelog.
  • Documented limitations. These predate the PR and are disclosed in the PR body:

Axiom line assessment

  • The line: axiom: TheAxiomFoundation/rulespec-us#1512 queued (required output 8 names §2341's one-claimant limit; …). The <rulespec issue> queued form is valid.
  • The issue: rulespec-us#1512 is OPEN and labelled pe-parity. It was updated 2026-10-12T12:17Z.
  • Coverage: required output 8 reads "Eligibility judgments covering §2338, with gross household income strictly below $45,000, and §2341's one-claimant and other limitations".
  • The addendum (comment 6019014199) adds:
    • verbatim §2341(1), §2337(2) and (7)(a), and §2340(1)-(2);
    • the attestation and instructions text, and ARM 42.4.302;
    • a review-finding paragraph;
    • six companion cases derived from the Schedule 2EC lines, not from PolicyEngine output;
    • properties to pin, and a methodology boundary.
  • Dispatch-readiness: it is dispatch-ready on the Add AMT parameters for 2020-2023 #1467 model.
  • Agreement: ruling d1313 (comment 6107998760) matches the PR's current behavior.
  • Caveat: the addendum predates the multiplier fix and the Count refundable credits received in Montana's elderly homeowner/renter credit income #9915 merge (Suggestion 5).

CI status

All green: gh pr checks 9900 shows 26/26 passing at head bfcf454cc5 (run 38170369268).

Branch status

Verdict: APPROVE

@DTrim99 DTrim99 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.

Approving: the one-claimant limit follows MCA 15-30-2341(1). The largest-credit pick is a reasonable, documented convention, the ranking is deterministic, and exactly one unit per household is paid. The negative-income multiplier fix matches § 2340(5), and the tests pass on the head and on the merge with main. Six optional suggestions in the comment above. Note: #9882's two should items from my earlier review reached main via #9915 and are still live there; #10139 fixes both and should merge next.

MaxGhenis added a commit that referenced this pull request Oct 12, 2026
#9900's one-claimant property test (now on main) builds claimants aged 65
or older with little income, for whom the model computes SSI, which gross
household income now counts; its reference leaves SSI out, so the builder
inputs none. Reference titles follow the repo format: no page in a
single-page title, and quoted titles ending in "#page N-M" for several.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
…ner/renter credit income (MCA 15-30-2337(9)(a)(vi)) (#10144)

* Count SSI, TANF and workers' compensation in Montana's elderly credit income

MCA 15-30-2337(9)(a) counts all nontaxable income, including (vi) cash
public assistance and relief. Schedule 2EC line 16 (2024, 2025) names SSI
and workers' compensation, and the 2014-2023 instructions list SSI
payments and workers' compensation as disability benefits. Add ssi,
tanf_person (the SPM unit's TANF per capita, so the household sum counts
it once) and workers_compensation to every period of the gross income
sources, with worked Schedule 2EC / Form 2EC cases for 2016-2025.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add property tests for government assistance in Montana's elderly credit

For a claimant, another adult and a child in four arrangements (one return
or two, one SPM unit or two, and more assistance), gross household income
adds every member's SSI and workers' compensation and the TANF once; the
credit matches an independent reading of Schedule 2EC lines 18 to 30, does
not depend on the arrangement, stays within the cap and never rises with
more assistance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Format the Montana government assistance property tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin SSI to zero in Montana elderly credit cases that test other income

Gross household income now counts SSI, and the model computes SSI for a
claimant aged 65 or older with little income (take-up defaults to true).
Three gross household income cases and three property-test builders are
about other items, so they now input no SSI; SSI has its own cases in the
government assistance tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Count guaranteed income payments; move the cases to variable-named files

Review follow-ups: gi_cash_assistance is outside federal AGI and
15-30-2337(9)(a) counts all nontaxable income (a government-funded pilot
is also "any other government assistance" on Schedule 2EC line 16), so it
joins every period of the sources. The worked cases move into
mt_elderly_homeowner_or_renter_credit.yaml (and the SNAP guard into the gross
household income file), with a guaranteed income case, the 2016 worksheet
total corrected to line 10 and the references consolidated to one per
document, with the 2009 MCA text for the 2009 period.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin SSI in the one-claimant property test; format reference titles

#9900's one-claimant property test (now on main) builds claimants aged 65
or older with little income, for whom the model computes SSI, which gross
household income now counts; its reference leaves SSI out, so the builder
inputs none. Reference titles follow the repo format: no page in a
single-page title, and quoted titles ending in "#page N-M" for several.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
… in Montana's elderly homeowner/renter credit income (#10163)

* Count SSI, TANF and workers' compensation in Montana's elderly credit income

MCA 15-30-2337(9)(a) counts all nontaxable income, including (vi) cash
public assistance and relief. Schedule 2EC line 16 (2024, 2025) names SSI
and workers' compensation, and the 2014-2023 instructions list SSI
payments and workers' compensation as disability benefits. Add ssi,
tanf_person (the SPM unit's TANF per capita, so the household sum counts
it once) and workers_compensation to every period of the gross income
sources, with worked Schedule 2EC / Form 2EC cases for 2016-2025.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add property tests for government assistance in Montana's elderly credit

For a claimant, another adult and a child in four arrangements (one return
or two, one SPM unit or two, and more assistance), gross household income
adds every member's SSI and workers' compensation and the TANF once; the
credit matches an independent reading of Schedule 2EC lines 18 to 30, does
not depend on the arrangement, stays within the cap and never rises with
more assistance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Format the Montana government assistance property tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin SSI to zero in Montana elderly credit cases that test other income

Gross household income now counts SSI, and the model computes SSI for a
claimant aged 65 or older with little income (take-up defaults to true).
Three gross household income cases and three property-test builders are
about other items, so they now input no SSI; SSI has its own cases in the
government assistance tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Count guaranteed income payments; move the cases to variable-named files

Review follow-ups: gi_cash_assistance is outside federal AGI and
15-30-2337(9)(a) counts all nontaxable income (a government-funded pilot
is also "any other government assistance" on Schedule 2EC line 16), so it
joins every period of the sources. The worked cases move into
mt_elderly_homeowner_or_renter_credit.yaml (and the SNAP guard into the gross
household income file), with a guaranteed income case, the 2016 worksheet
total corrected to line 10 and the references consolidated to one per
document, with the 2009 MCA text for the 2009 period.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Count disability benefits and unemployment compensation outside federal AGI in Montana's elderly credit income (WIP)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Test the 2020 cutoff above the band the federal test double subtracts; add changelog

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add a grid invariant test: disability benefits and unemployment compensation count once in every arrangement and year

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin SSI in the one-claimant property test; format reference titles

#9900's one-claimant property test (now on main) builds claimants aged 65
or older with little income, for whom the model computes SSI, which gross
household income now counts; its reference leaves SSI out, so the builder
inputs none. Reference titles follow the repo format: no page in a
single-page title, and quoted titles ending in "#page N-M" for several.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Name line 5 for disability pensions, describe the add-back's role edge, and test each list period's wiring

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Rename the add-back to mt_elderly_homeowner_or_renter_credit_unemployment_compensation_addback; supply Case 7's taxable allocation as an input

Both review rounds noted that the helper adds more than nontaxable compensation
for a person recorded as both a dependent and the head. Case 7 no longer pins
the federal exclusion's allocation, which #10175 changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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