From 204a75c3666efe491f1b436b47e8eb5b81bdb929 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 1 Jun 2026 00:23:21 -0400 Subject: [PATCH 1/4] Fix MT Elderly Homeowner/Renter Credit eligibility cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #8547 - Apply the multiplier phase-out to the tax-unit-aggregated gross household income, not the per-person value, per § 15-30-2337(4). - Add the untaxed portion of Social Security to the gross household income sources so all SS is counted per § 15-30-2337(9)(a)(viii). - Add an integration test for a joint filer above the $45,000 cap. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../fix-mt-ehrc-household-income.fixed.md | 1 + ...mt_elderly_homeowner_or_renter_credit.yaml | 23 +++++++++++++++++++ .../mt_elderly_homeowner_or_renter_credit.py | 8 +++++-- ...or_renter_credit_gross_household_income.py | 13 ++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 changelog.d/fix-mt-ehrc-household-income.fixed.md diff --git a/changelog.d/fix-mt-ehrc-household-income.fixed.md b/changelog.d/fix-mt-ehrc-household-income.fixed.md new file mode 100644 index 00000000000..94e8059efd0 --- /dev/null +++ b/changelog.d/fix-mt-ehrc-household-income.fixed.md @@ -0,0 +1 @@ +Apply the Montana Elderly Homeowner/Renter Credit multiplier to household-level gross income and include the full Social Security amount. diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml index 8a9b3d29202..7815791d890 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml @@ -92,6 +92,29 @@ # 1000+ 9000*0.15 - (43000-12600)*0.05 = 830 # 830*10% = 83 mt_elderly_homeowner_or_renter_credit: [83, 0, 0] +- name: MT EHRC denied when household income exceeds $45,000 due to SS + period: 2025 + input: + people: + head: + age: 75 + employment_income: 20_000 + taxable_interest_income: 5_280 + social_security_retirement: 51_792 + rent: 17_139 + spouse: + age: 75 + employment_income: 10_000 + tax_units: + tax_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_name: MT + output: + mt_elderly_homeowner_or_renter_credit: 0 + - name: Integration test period: 2022 absolute_error_margin: 0.01 diff --git a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py index 3053a934490..d233f4ad92c 100644 --- a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py +++ b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.py @@ -13,9 +13,13 @@ def formula(person, period, parameters): p = parameters( period ).gov.states.mt.tax.income.credits.elderly_homeowner_or_renter - gross_household_income = person( - "mt_elderly_homeowner_or_renter_credit_gross_household_income", + # § 15-30-2337(4) defines gross household income at the household + # (tax-unit) level, so the multiplier phase-out must be applied to + # the aggregated amount rather than each person's share. + gross_household_income = add( + person.tax_unit, period, + ["mt_elderly_homeowner_or_renter_credit_gross_household_income"], ) # Get net_household_income and allocate it to the head head = person("is_tax_unit_head", period) diff --git a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py index fa446410695..e4a6976f246 100644 --- a/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py +++ b/policyengine_us/variables/gov/states/mt/tax/income/credits/mt_elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.py @@ -8,5 +8,16 @@ class mt_elderly_homeowner_or_renter_credit_gross_household_income(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MT + reference = "https://law.justia.com/codes/montana/2022/title-15/chapter-30/part-23/section-15-30-2337/" - adds = "gov.states.mt.tax.income.credits.elderly_homeowner_or_renter.gross_income_sources" + def formula(person, period, parameters): + p = parameters( + period + ).gov.states.mt.tax.income.credits.elderly_homeowner_or_renter + sources = add(person, period, p.gross_income_sources) + # AGI only captures the taxable portion of Social Security; add the + # untaxed portion so all SS is counted per § 15-30-2337(9)(a)(viii). + social_security = person("social_security", period) + taxable_social_security = person("taxable_social_security", period) + untaxed_social_security = max_(social_security - taxable_social_security, 0) + return sources + untaxed_social_security From a41c48def70a434295b4b853dfa47578d265f17b Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 1 Jun 2026 00:29:22 -0400 Subject: [PATCH 2/4] Add MT EHRC edge-case tests for review findings - Multiplier uses household-aggregated GHI (per-person GHI under threshold; tax-unit sum lands in phase-out bracket). - Credit = 0 at exactly $45,000 GHI boundary. - Full untaxed Social Security counted in the gross household income variable. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...mt_elderly_homeowner_or_renter_credit.yaml | 41 +++++++++++++++++++ ..._renter_credit_gross_household_income.yaml | 18 ++++++++ 2 files changed, 59 insertions(+) create mode 100644 policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml index 7815791d890..be8cdec579d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit.yaml @@ -92,6 +92,47 @@ # 1000+ 9000*0.15 - (43000-12600)*0.05 = 830 # 830*10% = 83 mt_elderly_homeowner_or_renter_credit: [83, 0, 0] +- name: Multiplier uses household-aggregated gross income, not per-person + period: 2022 + input: + people: + person1: + rent: 9_000 + real_estate_taxes: 1_500 + mt_elderly_homeowner_or_renter_credit_gross_household_income: 22_000 + mt_elderly_homeowner_or_renter_credit_net_household_income: 700 + mt_elderly_homeowner_or_renter_credit_eligible: true + person2: + rent: 9_000 + real_estate_taxes: 0 + mt_elderly_homeowner_or_renter_credit_gross_household_income: 22_000 + mt_elderly_homeowner_or_renter_credit_net_household_income: 0 + mt_elderly_homeowner_or_renter_credit_eligible: true + tax_units: + tax_unit: + members: [person1, person2] + output: + # Each person's gross household income is under the $35,000 threshold + # (multiplier 1.0 per-person), but the tax-unit sum is $44,000 which + # falls in the 0.1 multiplier bracket. capped credit = $1,150 * 0.1 = $115. + mt_elderly_homeowner_or_renter_credit: [115, 0] + +- name: MT EHRC zero at exactly the $45,000 gross household income threshold + period: 2022 + input: + people: + person1: + rent: 9_000 + real_estate_taxes: 1_500 + mt_elderly_homeowner_or_renter_credit_gross_household_income: 45_000 + mt_elderly_homeowner_or_renter_credit_net_household_income: 0 + mt_elderly_homeowner_or_renter_credit_eligible: true + tax_units: + tax_unit: + members: [person1] + output: + mt_elderly_homeowner_or_renter_credit: 0 + - name: MT EHRC denied when household income exceeds $45,000 due to SS period: 2025 input: diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml new file mode 100644 index 00000000000..cbe5f2f1af2 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml @@ -0,0 +1,18 @@ +- name: Untaxed Social Security is fully counted in gross household income + period: 2025 + input: + people: + person1: + age: 75 + social_security_retirement: 30_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # § 15-30-2337(9)(a)(viii) requires all SS to be counted, even the + # portion excluded from federal AGI. + mt_elderly_homeowner_or_renter_credit_gross_household_income: 30_000 From 84f0f4f8165efe9cbe2a13f79264fbda95424210 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 1 Jun 2026 00:37:06 -0400 Subject: [PATCH 3/4] =?UTF-8?q?Expand=20MT=20EHRC=20gross=20income=20sourc?= =?UTF-8?q?es=20to=20match=20=C2=A7=2015-30-2337(9)(a)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add veterans_benefits, child_support_received, strike_benefits, and general_assistance to the statutory list of nontaxable income items counted toward gross household income, covering items (i), (iv), (v), and (vi). Add a test asserting they are all summed. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../gross_income_sources.yaml | 16 +++++++++----- ..._renter_credit_gross_household_income.yaml | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml b/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml index 6a2de2109e5..141d60a40af 100644 --- a/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml +++ b/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml @@ -3,7 +3,7 @@ metadata: unit: list period: year label: Montana elderly homeowner or renter credit gross income sources - reference: + reference: - title: Montana 2022 Form2 Individual Income Tax Instructions, Page47, Gross Household Income href: https://mtrevenue.gov/wp-content/uploads/dlm_uploads/2022/12/Form-2-2022-Instructions.pdf#page=47 - title: 2022 Montana Code Annotated, Title 15, Chapter 30, Part 23, 15-30-2337 (9) @@ -14,11 +14,17 @@ metadata: values: 2009-01-01: - adjusted_gross_income_person # Line 1: Federal adjusted gross income - - tax_exempt_interest_income # Line 2: Exempt interest + - tax_exempt_interest_income # Line 2: Exempt interest; § 15-30-2337(9)(a)(vii) - taxable_ira_distributions # Line 3: IRA distribution reported # Requests 4a from 1040, which includes Roth IRA distributions. - tax_exempt_ira_distributions - - pension_income # Line 4: Pensions and annuities + - pension_income # Line 4: Pensions and annuities; § 15-30-2337(9)(a)(i) + - veterans_benefits # § 15-30-2337(9)(a)(i) – veterans' disability benefits + - child_support_received # § 15-30-2337(9)(a)(iv) – support money + - strike_benefits # § 15-30-2337(9)(a)(v) – nontaxable strike benefits + - general_assistance # § 15-30-2337(9)(a)(vi) – cash public assistance - mt_refundable_credits_before_renter_credit # Line 7: Refundable credits -# exclude the renter credit from the gross income computation -# due to a potential circular reference +# Social Security under § 15-30-2337(9)(a)(viii) is added separately in +# mt_elderly_homeowner_or_renter_credit_gross_household_income.py because the +# untaxed portion is computed as social_security - taxable_social_security. +# The renter credit itself is excluded to avoid a circular reference. diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml index cbe5f2f1af2..cee870a82af 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_gross_household_income.yaml @@ -1,3 +1,24 @@ +- name: Statutory nontaxable income sources are counted + period: 2025 + input: + people: + person1: + age: 75 + veterans_benefits: 5_000 + child_support_received: 3_000 + strike_benefits: 2_000 + general_assistance: 1_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # § 15-30-2337(9)(a)(i), (iv), (v), (vi). Sum: 5,000 + 3,000 + 2,000 + 1,000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: 11_000 + - name: Untaxed Social Security is fully counted in gross household income period: 2025 input: From 2bc36878c3969ac570dfd448bb044e9380dda3fa Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 1 Jun 2026 00:58:40 -0400 Subject: [PATCH 4/4] Fix MT EHRC pension and IRA double-count Federal AGI already includes the taxable portion of pension and IRA distributions (via taxable_pension_income and taxable_retirement_distributions). The gross income sources list was adding pension_income and taxable_ira_distributions on top of AGI, causing the taxable portions to be counted twice. Replace pension_income with tax_exempt_pension_income and drop taxable_ira_distributions; the existing tax_exempt_ira_distributions still captures the Roth portion not in AGI. Verified: a single MT filer with \$10,000 taxable pension or taxable IRA distribution now produces \$10,000 of gross household income (was \$20,000). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../gross_income_sources.yaml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml b/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml index 141d60a40af..538b7b2585d 100644 --- a/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml +++ b/policyengine_us/parameters/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/gross_income_sources.yaml @@ -13,12 +13,16 @@ metadata: values: 2009-01-01: - - adjusted_gross_income_person # Line 1: Federal adjusted gross income - - tax_exempt_interest_income # Line 2: Exempt interest; § 15-30-2337(9)(a)(vii) - - taxable_ira_distributions # Line 3: IRA distribution reported - # Requests 4a from 1040, which includes Roth IRA distributions. + - adjusted_gross_income_person # Federal AGI baseline; covers taxable + # pensions, IRA, wages, interest, dividends, etc. + - tax_exempt_interest_income # § 15-30-2337(9)(a)(vii) + # AGI already includes taxable IRA distributions via + # taxable_retirement_distributions; only the tax-exempt portion + # (Roth distributions) is added back here. - tax_exempt_ira_distributions - - pension_income # Line 4: Pensions and annuities; § 15-30-2337(9)(a)(i) + # AGI already includes taxable pension income; only the tax-exempt + # portion is added back here per § 15-30-2337(9)(a)(i). + - tax_exempt_pension_income - veterans_benefits # § 15-30-2337(9)(a)(i) – veterans' disability benefits - child_support_received # § 15-30-2337(9)(a)(iv) – support money - strike_benefits # § 15-30-2337(9)(a)(v) – nontaxable strike benefits