From 449696c1c57770f0bf6b4fca8f59242e0d3c4d74 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 12 Oct 2026 06:02:12 -0400 Subject: [PATCH 1/6] 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 --- ...erly-credit-government-assistance.fixed.md | 1 + .../gross_income_sources.yaml | 31 ++ ...r_renter_credit_government_assistance.yaml | 282 ++++++++++++++++++ 3 files changed, 314 insertions(+) create mode 100644 changelog.d/mt-elderly-credit-government-assistance.fixed.md create mode 100644 policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml diff --git a/changelog.d/mt-elderly-credit-government-assistance.fixed.md b/changelog.d/mt-elderly-credit-government-assistance.fixed.md new file mode 100644 index 00000000000..27b553487f9 --- /dev/null +++ b/changelog.d/mt-elderly-credit-government-assistance.fixed.md @@ -0,0 +1 @@ +Montana's elderly homeowner/renter credit now counts SSI, TANF and workers' compensation received by household members in gross household income (MCA 15-30-2337(9)(a)(vi); Schedule 2EC line 16). 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 7c3c2184cdf..61a193e098d 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 @@ -26,6 +26,22 @@ metadata: href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2024_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=47 - title: 2025 Montana Form 2 instructions, Schedule 2EC, line 8, refundable credits received href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2025_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=45 + - title: MCA 15-30-2337(9)(a)(vi), cash public assistance and relief + href: https://mca.legmt.gov/bills/mca/title_0150/chapter_0300/part_0230/section_0370/0150-0300-0230-0370.html + - title: MCA 15-30-2337(9)(a)(vi) as in effect in 2016 (archived) + href: https://web.archive.org/web/20161231130526/http://leg.mt.gov/bills/mca/title_0150/chapter_0300/part_0230/section_0370/0150-0300-0230-0370.html + - title: 2016 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief + href: https://taxsim.nber.org/historical_state_tax_forms/MT/2016/Form_2_booklet_2016.pdf#page=74 + - title: 2017 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief + href: https://taxsim.nber.org/historical_state_tax_forms/MT/2017/Form%202%202017%20Booklet.pdf#page=64 + - title: 2022 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 8, disability benefits including SSI payments and workers' compensation + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2022_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=48 + - title: 2023 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 8, disability benefits including SSI payments and workers' compensation + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2023_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=52 + - title: 2024 Montana Form 2 instructions, Schedule 2EC, line 16, government assistance + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2024_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=48 + - title: 2025 Montana Form 2 instructions, Schedule 2EC, line 16, government assistance + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2025_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=46 values: 2009-01-01: @@ -43,6 +59,15 @@ values: - 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 + # Government assistance (Schedule 2EC line 16 from 2024; "disability + # benefits including ... SSI payments and workers' compensation" and + # "cash public assistance and relief" in earlier instructions). TANF is + # held for the SPM unit; tanf_person is each member's per capita share, + # so the household sum counts the unit's TANF once. LIEAP and SNAP are + # not cash public assistance (2014-2017 Form 2EC instructions). + - ssi + - tanf_person + - workers_compensation # Refundable credits received (2023 schedule line 7, Schedule 2EC line 8 # from 2024): Montana's refundable credits other than this credit, # and this credit as received during the year (ARM 42.4.301(2)(c)). @@ -60,6 +85,9 @@ values: - child_support_received - strike_benefits - general_assistance + - ssi + - tanf_person + - workers_compensation - mt_refundable_credits_before_renter_credit - mt_elderly_homeowner_or_renter_credit_received - mt_elderly_homeowner_or_renter_credit_federal_refundable_credits @@ -76,6 +104,9 @@ values: - child_support_received - strike_benefits - general_assistance + - ssi + - tanf_person + - workers_compensation - mt_refundable_credits_before_renter_credit - mt_elderly_homeowner_or_renter_credit_received - mt_elderly_homeowner_or_renter_credit_federal_refundable_credits diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml new file mode 100644 index 00000000000..82bc6942c0f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml @@ -0,0 +1,282 @@ +# Government assistance in gross household income: SSI, TANF and workers' +# compensation. § 15-30-2337(9)(a) counts "all nontaxable income, including +# but not limited to ... (vi) cash public assistance and relief". 2024 and +# 2025 Schedule 2EC line 16: "This includes veteran's compensation benefits, +# supplemental security income (SSI) payments, worker's compensation, and any +# other government assistance received during the year." The 2014-2023 +# instructions list "Disability benefits including, but not limited to, +# veteran's disability, SSI payments and workers' compensation", and the +# 2014-2017 instructions add "Cash public assistance and relief - Do not +# include LIEAP ... or SNAP". + +- name: 2024 Schedule 2EC worked case, the claimant's SSI counts on line 16 + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 15_000 + ssi: 6_000 + real_estate_taxes: 1_200 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # Line 5 pensions 15_000; line 16 SSI 6_000; line 18 = 21_000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: 21_000 + # Line 19 12_600; line 20 = 8_400; line 21 = 0.039 (8_000 to 8_999); + # line 22 = 8_400 x 0.039 = 327.60. + mt_elderly_homeowner_or_renter_credit_net_household_income: 327.60 + # Line 23 = 1_200; line 26 = 1_200; line 27 = 1_200 - 327.60 = 872.40; + # line 28 = 872.40 (under 1_150); line 29 = 100%; line 30 = 872.40. + # Without the SSI, line 18 = 15_000, line 22 = 2_400 x 0.006 = 14.40 and + # the credit would be the 1_150 cap. + mt_elderly_homeowner_or_renter_credit: 872.40 + +- name: 2025 Schedule 2EC worked case, a household member's workers' compensation counts on line 17 + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + taxable_pension_income: 18_000 + real_estate_taxes: 1_500 + person2: + age: 45 + workers_compensation: 9_000 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_name: MT + output: + # The claimant's adult son lives in the household and files his own + # return. Line 5 pensions 18_000; line 17 his workers' compensation, a + # line 16 item for another member, 9_000; line 18 = 27_000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [18_000, 9_000] + # Line 20 = 27_000 - 12_600 = 14_400; line 21 = 0.05; line 22 = 720. + mt_elderly_homeowner_or_renter_credit_net_household_income: [720, 0] + # Line 27 = 1_500 - 720 = 780; line 28 = 780; line 29 = 100%; line 30 = + # 780. Without his workers' compensation, line 18 = 18_000, line 22 = + # 5_400 x 0.028 = 151.20 and the credit would be the 1_150 cap. + mt_elderly_homeowner_or_renter_credit: [780, 0] + +- name: 2024 Schedule 2EC worked case, TANF in a shared SPM unit counts once across two returns + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 20_000 + real_estate_taxes: 1_500 + person2: + age: 30 + person3: + age: 5 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + tanf: 4_800 + households: + household: + members: [person1, person2, person3] + state_name: MT + output: + # The claimant's daughter and granddaughter live with her; the daughter + # files her own return and receives 4_800 of TANF. Line 5 pensions + # 20_000; line 17 the TANF 4_800; line 18 = 24_800. The model holds TANF + # for the SPM unit and counts each member's per capita share + # (tanf_person, 1_600 each), so the household total counts it once. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [21_600, 1_600, 1_600] + # Line 20 = 24_800 - 12_600 = 12_200; line 21 = 0.05; line 22 = 610. + mt_elderly_homeowner_or_renter_credit_net_household_income: [610, 0, 0] + # Line 27 = 1_500 - 610 = 890; line 28 = 890; line 29 = 100%; line 30 = + # 890. Without the TANF, line 18 = 20_000, line 22 = 7_400 x 0.035 = 259 + # and the credit would be the 1_150 cap. Counting the whole 4_800 for + # each of the three members would give line 18 = 34_400 and a credit of + # 1_500 - 1_090 = 410. + mt_elderly_homeowner_or_renter_credit: [890, 0, 0] + +- name: 2024 Schedule 2EC worked case, Montana TANF paid to a separate SPM unit counts on line 17 + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 20_000 + real_estate_taxes: 1_500 + person2: + age: 30 + person3: + age: 5 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + spm_units: + spm_unit1: + members: [person1] + spm_unit2: + members: [person2, person3] + mt_tanf: 4_800 + households: + household: + members: [person1, person2, person3] + state_name: MT + output: + # The same household with the daughter's family in its own SPM unit and + # the payment entered as Montana TANF (ARM 37.78), which tanf sums with + # the other states' programs. Line 17 = 4_800; line 18 = 24_800. + tanf: [0, 4_800] + mt_elderly_homeowner_or_renter_credit_gross_household_income: [20_000, 2_400, 2_400] + # Line 22 = (24_800 - 12_600) x 0.05 = 610; line 27 = 890; line 30 = 890. + mt_elderly_homeowner_or_renter_credit_net_household_income: [610, 0, 0] + mt_elderly_homeowner_or_renter_credit: [890, 0, 0] + +- name: 2023 Elderly Homeowner/Renter Credit Schedule worked case, workers' compensation and a spouse's SSI count on line 8 + period: 2023 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 66 + taxable_pension_income: 14_000 + workers_compensation: 6_000 + real_estate_taxes: 1_000 + person2: + age: 64 + ssi: 5_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_name: MT + output: + # Joint return. Line 1 federal AGI 14_000; line 8 "Disability benefits + # including, but not limited to, veteran's disability, SSI payments, and + # workers' compensation": 6_000 + 5_000 = 11_000; line 10 = 25_000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [20_000, 5_000] + # Line 11 12_600; line 12 = 12_400; line 13 = 0.05; line 14 = 620. + mt_elderly_homeowner_or_renter_credit_net_household_income: [620, 0] + # Line 15 = 1_000; line 18 = 1_000; line 19 = 1_000 - 620 = 380; line 20 + # = 380; line 21 = 100%; line 22 = 380. Without either amount, line 10 = + # 14_000, line 12 = 1_400 at a 0 rate and the credit would be 1_000. + mt_elderly_homeowner_or_renter_credit: [380, 0] + +- name: 2017 Form 2EC worked case, a household member's SSI counts in gross household income + period: 2017 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 15_000 + real_estate_taxes: 1_000 + person2: + age: 40 + # 2017 federal benefit rate: 735 a month. + ssi: 8_820 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_name: MT + output: + # The claimant's adult son receives SSI. Gross Household Income + # Worksheet: line 6 pensions 15_000; line 7 income of other household + # members, his SSI 8_820 ("Disability benefits including ... SSI + # payments"); line 8 = 23_820, Form 2EC line 1. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [15_000, 8_820] + # Line 2 6_300; line 3 = 17_520; line 4 = 0.05; line 5 = 876. + mt_elderly_homeowner_or_renter_credit_net_household_income: [876, 0] + # Line 6 = 1_000; line 9 = 1_000; line 10 = 1_000 - 876 = 124; line 11 = + # 124 (under 1_000); line 12 = 100%; line 13 = 124. Without his SSI, line + # 1 = 15_000, line 5 = 8_700 x 0.039 = 339.30 and the credit 660.70. + mt_elderly_homeowner_or_renter_credit: [124, 0] + +- name: 2016 Form 2EC worked case, cash public assistance received by another household member counts + period: 2016 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 12_000 + real_estate_taxes: 900 + person2: + age: 30 + person3: + age: 5 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + spm_units: + spm_unit1: + members: [person1] + spm_unit2: + members: [person2, person3] + tanf: 5_400 + households: + household: + members: [person1, person2, person3] + state_name: MT + output: + # Gross Household Income Worksheet line 7, "Alimony, cash public + # assistance, unemployment", for the daughter's 5_400 of TANF; line 9 = + # 12_000 + 5_400 = 17_400, Form 2EC line 1. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [12_000, 2_700, 2_700] + # Line 2 6_300; line 3 = 11_100; line 4 = 0.048; line 5 = 532.80. + mt_elderly_homeowner_or_renter_credit_net_household_income: [532.80, 0, 0] + # Line 6 = 900; line 10 = 900 - 532.80 = 367.20; line 11 = 367.20; line + # 12 = 100%; line 13 = 367.20. Without the TANF, line 1 = 12_000, line 5 + # = 5_700 x 0.028 = 159.60 and the credit 740.40. + mt_elderly_homeowner_or_renter_credit: [367.20, 0, 0] + +- name: SNAP is not cash public assistance and does not count + period: 2017 + input: + people: + person1: + age: 70 + taxable_pension_income: 15_000 + spm_units: + spm_unit: + members: [person1] + snap: 1_800 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # 2017 Form 2EC instructions: "Cash, public assistance and relief - Do + # not include LIEAP (Low Income Energy Assistance Program) or SNAP". + mt_elderly_homeowner_or_renter_credit_gross_household_income: 15_000 From 50786d8acade21d20adeddc445c45747222309d5 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 12 Oct 2026 06:09:21 -0400 Subject: [PATCH 2/6] 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 --- ...mt_elderly_credit_government_assistance.py | 307 ++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 policyengine_us/tests/test_mt_elderly_credit_government_assistance.py diff --git a/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py b/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py new file mode 100644 index 00000000000..6a366428122 --- /dev/null +++ b/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py @@ -0,0 +1,307 @@ +"""Property tests: government assistance in the Montana elderly +homeowner/renter credit. + +MCA 15-30-2337(9)(a) counts "all nontaxable income, including but not +limited to ... (vi) cash public assistance and relief", and (4) counts "all +income received by all individuals of a household". The 2024 Schedule 2EC +line 16 names "supplemental security income (SSI) payments, worker's +compensation, and any other government assistance"; line 17 carries the same +items for the other members of the household. + +The model holds SSI and workers' compensation per person and TANF per SPM +unit, which it spreads over the unit's members (tanf_person). For a claimant +aged 62 or older (taxable pension, SSI, workers' compensation, property tax, +rent) living with another adult (SSI, workers' compensation) and a child, +whose SPM unit receives TANF, in four arrangements: + + A. one return, the other adult and the child the claimant's dependents, and + one SPM unit; + B. two returns (the claimant's, and the other adult's with the child) and + one SPM unit; + C. two returns and two SPM units, the TANF going to the other adult's; + D. as C, with more of one kind of assistance; + +1. The household's gross household income is the pension plus every + member's SSI and workers' compensation plus the TANF, once, in A, B and C. +2. So the claimant's credit is the same in A, B and C, and nobody else + claims. +3. The credit equals an independent reading of Schedule 2EC lines 18 to 30, + is between zero and the cap, and is zero at $45,000 or more (line 29). +4. More assistance never raises the credit (D against C). + +No one has earned income, so no refundable credit enters line 8. The model +computes in single precision, so comparisons allow one cent or eight float32 +spacings at the household's total income, whichever is larger. +""" + +import numpy as np +import pytest + +from policyengine_us import Simulation + +YEAR = 2024 +CAP = 1_150 +INCOME_LIMIT = 45_000 +TOLERANCE = 0.01 +ARRANGEMENTS = "ABCD" +# 2024 Schedule 2EC, line 19. +EXCLUSION = 12_600 +# Household Income Reduction Table (line 21): lower bounds and rates. +REDUCTION_TABLE = [ + (0, 0), + (2_000, 0.006), + (3_000, 0.016), + (4_000, 0.024), + (5_000, 0.028), + (6_000, 0.032), + (7_000, 0.035), + (8_000, 0.039), + (9_000, 0.042), + (10_000, 0.045), + (11_000, 0.048), + (12_000, 0.05), +] +# Credit Multiplier Table (line 29): lower bounds of line 18 and percentages. +MULTIPLIER_TABLE = [ + (0, 1), + (35_000, 0.4), + (37_501, 0.3), + (40_001, 0.2), + (42_501, 0.1), + (45_000, 0), +] +EXTRA_KINDS = ["claimant_ssi", "member_workers_compensation", "tanf"] + + +def amounts(c, arrangement): + """The case's assistance amounts, with D's extra amount added.""" + a = { + "claimant_ssi": c["claimant_ssi"], + "claimant_workers_compensation": c["claimant_workers_compensation"], + "member_ssi": c["member_ssi"], + "member_workers_compensation": c["member_workers_compensation"], + "tanf": c["tanf"], + } + if arrangement == "D": + a[c["extra_kind"]] += c["extra"] + return a + + +def build_situation(cases): + people, tax_units, marital_units, spm_units, families, households = ( + {}, + {}, + {}, + {}, + {}, + {}, + ) + for i, c in enumerate(cases): + for arrangement in ARRANGEMENTS: + key = f"{arrangement}{i}" + a = amounts(c, arrangement) + claimant, member, child = ( + f"claimant_{key}", + f"member_{key}", + f"child_{key}", + ) + people[claimant] = { + "age": {YEAR: c["claimant_age"]}, + "taxable_pension_income": {YEAR: c["pension"]}, + "ssi": {YEAR: a["claimant_ssi"]}, + "workers_compensation": {YEAR: a["claimant_workers_compensation"]}, + "real_estate_taxes": {YEAR: c["property_tax"]}, + "rent": {YEAR: c["rent"]}, + "is_tax_unit_dependent": {YEAR: False}, + } + people[member] = { + "age": {YEAR: c["member_age"]}, + "ssi": {YEAR: a["member_ssi"]}, + "workers_compensation": {YEAR: a["member_workers_compensation"]}, + "is_tax_unit_dependent": {YEAR: arrangement == "A"}, + } + people[child] = { + "age": {YEAR: c["child_age"]}, + "is_tax_unit_dependent": {YEAR: True}, + } + if arrangement == "A": + tax_units[f"tax_unit_{key}"] = {"members": [claimant, member, child]} + else: + tax_units[f"tax_unit_{key}"] = {"members": [claimant]} + tax_units[f"tax_unit_{key}_member"] = {"members": [member, child]} + if arrangement in "AB": + spm_units[f"spm_unit_{key}"] = { + "members": [claimant, member, child], + "tanf": {YEAR: a["tanf"]}, + } + else: + spm_units[f"spm_unit_{key}"] = { + "members": [claimant], + "tanf": {YEAR: 0}, + } + spm_units[f"spm_unit_{key}_member"] = { + "members": [member, child], + "tanf": {YEAR: a["tanf"]}, + } + for person in (claimant, member, child): + marital_units[f"marital_unit_{person}"] = {"members": [person]} + families[f"family_{key}"] = {"members": [claimant, member, child]} + households[f"household_{key}"] = { + "members": [claimant, member, child], + "state_code": {YEAR: "MT"}, + } + return { + "people": people, + "tax_units": tax_units, + "marital_units": marital_units, + "spm_units": spm_units, + "families": families, + "households": households, + } + + +def calculate(cases): + """Household totals of gross household income and the credit, and the + other members' credits, as arrays indexed [arrangement, case].""" + simulation = Simulation(situation=build_situation(cases)) + n, k = len(cases), len(ARRANGEMENTS) + + def by_household(variable): + values = simulation.calculate(variable, YEAR, map_to="household") + return np.asarray(values).reshape(n, k).T + + person_credit = np.asarray( + simulation.calculate("mt_elderly_homeowner_or_renter_credit", YEAR) + ).reshape(n, k, 3) + return { + "gross_household_income": by_household( + "mt_elderly_homeowner_or_renter_credit_gross_household_income" + ), + "credit": by_household("mt_elderly_homeowner_or_renter_credit"), + # The other adult's and the child's credits. + "others_credit": person_credit[:, :, 1:].transpose(1, 0, 2), + } + + +def expected_gross_household_income(c, arrangement): + """2024 Schedule 2EC line 18: line 5 pension and line 16 assistance for + the claimant, line 17 the other members' assistance, the TANF once.""" + return c["pension"] + sum(amounts(c, arrangement).values()) + + +def lookup(table, amount): + rate = 0 + for lower, value in table: + if amount >= lower: + rate = value + return rate + + +def expected_credit(c, gross_household_income): + """2024 Schedule 2EC lines 19 to 30 for a claimant who owns or rents.""" + line_20 = max(gross_household_income - EXCLUSION, 0) + line_22 = line_20 * lookup(REDUCTION_TABLE, line_20) + line_26 = c["property_tax"] + 0.15 * c["rent"] + line_27 = max(line_26 - line_22, 0) + line_28 = min(line_27, CAP) + return line_28 * lookup(MULTIPLIER_TABLE, gross_household_income) + + +def tolerance(amount): + return max(TOLERANCE, 8 * float(np.spacing(np.float32(abs(amount))))) + + +def assert_properties(cases): + result = calculate(cases) + ghi, credit = result["gross_household_income"], result["credit"] + for i, c in enumerate(cases): + for j, arrangement in enumerate(ARRANGEMENTS): + expected = expected_gross_household_income(c, arrangement) + tol = tolerance(expected) + # 1. Every member's assistance counts, the TANF once. + assert ghi[j, i] == pytest.approx(expected, abs=tol), (arrangement, c) + # 3. The schedule, the bounds and the income limit. + assert credit[j, i] == pytest.approx( + expected_credit(c, expected), abs=tol + ), (arrangement, c) + assert -tol <= credit[j, i] <= CAP + tol, (arrangement, c) + if expected >= INCOME_LIMIT: + assert credit[j, i] == 0, (arrangement, c) + # 2. The arrangement does not change the credit, and only the + # claimant claims. + tol = tolerance(expected_gross_household_income(c, "D")) + assert credit[1, i] == pytest.approx(credit[0, i], abs=tol), c + assert credit[2, i] == pytest.approx(credit[0, i], abs=tol), c + assert np.all(result["others_credit"][:, i] == 0), c + # 4. More assistance never raises the credit. + assert credit[3, i] <= credit[2, i] + tol, c + + +def test_worked_example(): + """2024 Schedule 2EC: line 5 pension 20,000; line 16 the claimant's SSI + 3,000; line 17 the other adult's SSI 2,000 and workers' compensation + 1,000 and the TANF 1,800; line 18 = 27,800; line 22 = (27,800 - 12,600) + x 0.05 = 760; line 27 = 1,500 - 760 = 740; line 30 = 740 in A, B and C. + D adds 8,000 of TANF: line 18 = 35,800; line 22 = 1,160; line 27 = 340; + line 29 = 40%; line 30 = 136.""" + case = { + "claimant_age": 70, + "pension": 20_000, + "claimant_ssi": 3_000, + "claimant_workers_compensation": 0, + "property_tax": 1_500, + "rent": 0, + "member_age": 35, + "member_ssi": 2_000, + "member_workers_compensation": 1_000, + "child_age": 6, + "tanf": 1_800, + "extra_kind": "tanf", + "extra": 8_000, + } + result = calculate([case]) + assert result["gross_household_income"][:, 0] == pytest.approx( + [27_800, 27_800, 27_800, 35_800], abs=TOLERANCE + ) + assert result["credit"][:, 0] == pytest.approx( + [740, 740, 740, 136], abs=TOLERANCE + ) + assert_properties([case]) + + +try: + import hypothesis + import hypothesis.strategies as st +except ImportError: # pragma: no cover + hypothesis = None + +if hypothesis is not None: + # Each example builds a Simulation; on a loaded runner input generation + # can trip the too_slow health check, which says nothing about the model. + SLOW = [hypothesis.HealthCheck.too_slow] + + def amount(high): + return st.one_of(st.just(0), st.integers(min_value=1, max_value=high)) + + @st.composite + def case(draw): + return { + "claimant_age": draw(st.integers(min_value=62, max_value=90)), + "pension": draw(amount(40_000)), + "claimant_ssi": draw(amount(12_000)), + "claimant_workers_compensation": draw(amount(15_000)), + "property_tax": draw(st.integers(min_value=0, max_value=4_000)), + "rent": draw(amount(12_000)), + "member_age": draw(st.integers(min_value=18, max_value=61)), + "member_ssi": draw(amount(12_000)), + "member_workers_compensation": draw(amount(15_000)), + "child_age": draw(st.integers(min_value=0, max_value=17)), + "tanf": draw(amount(10_000)), + "extra_kind": draw(st.sampled_from(EXTRA_KINDS)), + "extra": draw(st.integers(min_value=1, max_value=20_000)), + } + + @hypothesis.settings(max_examples=15, deadline=None, suppress_health_check=SLOW) + @hypothesis.given(st.lists(case(), min_size=1, max_size=8)) + def test_properties(cases): + assert_properties(cases) From b662ed12cf0b28e8a50e27e54166fb494add1f66 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 12 Oct 2026 06:09:40 -0400 Subject: [PATCH 3/6] Format the Montana government assistance property tests Co-Authored-By: Claude Opus 5.5 --- .../tests/test_mt_elderly_credit_government_assistance.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py b/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py index 6a366428122..00870adc9cc 100644 --- a/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py +++ b/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py @@ -263,9 +263,7 @@ def test_worked_example(): assert result["gross_household_income"][:, 0] == pytest.approx( [27_800, 27_800, 27_800, 35_800], abs=TOLERANCE ) - assert result["credit"][:, 0] == pytest.approx( - [740, 740, 740, 136], abs=TOLERANCE - ) + assert result["credit"][:, 0] == pytest.approx([740, 740, 740, 136], abs=TOLERANCE) assert_properties([case]) From 8718317e69bcac94882258c103f20a728619ea8e Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 12 Oct 2026 07:03:14 -0400 Subject: [PATCH 4/6] 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 --- ..._homeowner_or_renter_credit_gross_household_income.yaml | 7 +++++++ .../tests/test_mt_elderly_credit_dependent_deductions.py | 2 ++ .../tests/test_mt_elderly_credit_household_members.py | 3 +++ .../tests/test_mt_elderly_credit_rebate_receipts.py | 2 ++ 4 files changed, 14 insertions(+) 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 ec00f8c2fad..e1ca3dc39ce 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 @@ -8,6 +8,9 @@ child_support_received: 3_000 strike_benefits: 2_000 general_assistance: 1_000 + # These amounts would make the model compute SSI, which also counts; + # its own cases are in the government assistance test file. + ssi: 0 tax_units: tax_unit: members: [person1] @@ -117,6 +120,8 @@ people: person1: age: 70 + # No SSI for the claimant, so the case isolates the dependent's income. + ssi: 0 person2: age: 17 employment_income: 25_000 @@ -144,6 +149,8 @@ people: person1: age: 70 + # No SSI for the claimant, so the case isolates the dependent's income. + ssi: 0 person2: age: 16 employment_income: 10_000 diff --git a/policyengine_us/tests/test_mt_elderly_credit_dependent_deductions.py b/policyengine_us/tests/test_mt_elderly_credit_dependent_deductions.py index 90736451eca..819ce2ce5ff 100644 --- a/policyengine_us/tests/test_mt_elderly_credit_dependent_deductions.py +++ b/policyengine_us/tests/test_mt_elderly_credit_dependent_deductions.py @@ -31,6 +31,8 @@ def build_situation(cases, year): "age": {year: 70}, "taxable_pension_income": {year: case["pension"]}, "early_withdrawal_penalty": {year: case["parent_penalty"]}, + # No computed SSI; it has its own tests (government assistance). + "ssi": {year: 0}, "is_tax_unit_dependent": {year: False}, "mt_refundable_credits_before_renter_credit": {year: 0}, "mt_elderly_homeowner_or_renter_credit_received": {year: 0}, diff --git a/policyengine_us/tests/test_mt_elderly_credit_household_members.py b/policyengine_us/tests/test_mt_elderly_credit_household_members.py index d1c1fff15ef..343bd2529a1 100644 --- a/policyengine_us/tests/test_mt_elderly_credit_household_members.py +++ b/policyengine_us/tests/test_mt_elderly_credit_household_members.py @@ -69,6 +69,9 @@ def build_situation(cases): "social_security_retirement": {YEAR: c["claimant_ss"]}, "real_estate_taxes": {YEAR: c["property_tax"]}, "rent": {YEAR: c["rent"]}, + # The model would compute SSI for a claimant with little + # income; SSI has its own tests (government assistance). + "ssi": {YEAR: 0}, } people[member] = { "age": {YEAR: c["member_age"]}, diff --git a/policyengine_us/tests/test_mt_elderly_credit_rebate_receipts.py b/policyengine_us/tests/test_mt_elderly_credit_rebate_receipts.py index 9f44d62671b..09470be0d6f 100644 --- a/policyengine_us/tests/test_mt_elderly_credit_rebate_receipts.py +++ b/policyengine_us/tests/test_mt_elderly_credit_rebate_receipts.py @@ -35,6 +35,8 @@ def build_situation(cases, year, with_receipts): }, "mt_refundable_credits_before_renter_credit": {year: 0}, "mt_elderly_homeowner_or_renter_credit_received": {year: 0}, + # No computed SSI; it has its own tests. + "ssi": {year: 0}, } if arrangement == "C": people[name][ From 87cef23a7db280d1e36c7e40bf4d721c44ec3d7f Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 12 Oct 2026 07:17:17 -0400 Subject: [PATCH 5/6] 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 --- ...erly-credit-government-assistance.fixed.md | 2 +- .../gross_income_sources.yaml | 50 ++- ...mt_elderly_homeowner_or_renter_credit.yaml | 298 ++++++++++++++++++ ...r_renter_credit_government_assistance.yaml | 282 ----------------- ..._renter_credit_gross_household_income.yaml | 23 ++ ...mt_elderly_credit_government_assistance.py | 34 +- 6 files changed, 370 insertions(+), 319 deletions(-) delete mode 100644 policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml diff --git a/changelog.d/mt-elderly-credit-government-assistance.fixed.md b/changelog.d/mt-elderly-credit-government-assistance.fixed.md index 27b553487f9..5c1b0d95f6f 100644 --- a/changelog.d/mt-elderly-credit-government-assistance.fixed.md +++ b/changelog.d/mt-elderly-credit-government-assistance.fixed.md @@ -1 +1 @@ -Montana's elderly homeowner/renter credit now counts SSI, TANF and workers' compensation received by household members in gross household income (MCA 15-30-2337(9)(a)(vi); Schedule 2EC line 16). +Montana's elderly homeowner/renter credit now counts SSI, TANF, workers' compensation and guaranteed income payments received by household members in gross household income (MCA 15-30-2337(9)(a); Schedule 2EC line 16). 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 61a193e098d..14a8ead4344 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 @@ -4,44 +4,32 @@ metadata: period: year label: Montana elderly homeowner or renter credit gross income sources reference: - - title: HB191 (2021), section 1(9), all nontaxable income - href: https://archive.legmt.gov/bills/2021/HB0199/HB0191_X.pdf#page=2 - - title: Montana 2022 Form2 Individual Income Tax Instructions, Page47, Gross Household Income - href: https://revenuefiles.mt.gov/files/Forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2022_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=47 + - title: MCA 15-30-2337(9)(a), all nontaxable income, including (vi) cash public assistance and relief + href: https://mca.legmt.gov/bills/mca/title_0150/chapter_0300/part_0230/section_0370/0150-0300-0230-0370.html + - title: MCA 15-30-2337(9)(a) (2009), the same definition + href: https://archive.legmt.gov/bills/2009/mca/15/30/15-30-2337.htm - title: 2022 Montana Code Annotated, Title 15, Chapter 30, Part 23, 15-30-2337 (9) href: https://law.justia.com/codes/montana/2022/title-15/chapter-30/part-23/section-15-30-2337/ - - title: 2024 Montana Individual Income Tax Return - href: https://revenuefiles.mt.gov/files/Forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2024_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=46 + - title: HB191 (2021), section 1(9), all nontaxable income + href: https://archive.legmt.gov/bills/2021/HB0199/HB0191_X.pdf#page=2 - title: ARM 42.4.301(2) as in effect 8/20/2004 to 11/9/2017 ("elderly homeowner/renter credit refunds received") href: https://rules.mt.gov/api/policy-library-public/collections/aec52c46-128e-4279-9068-8af5d5432d74/policies/c90ea93a-03a2-4605-a0f8-f2f3760198bf/document/788508cc-8418-41c8-926d-3dfb11af3fd6 - title: ARM 42.4.301(2) as in effect 11/10/2017 to 9/6/2024 ("federal refundable credits received" and "any state refundable credits received") href: https://rules.mt.gov/api/policy-library-public/collections/aec52c46-128e-4279-9068-8af5d5432d74/policies/c90ea93a-03a2-4605-a0f8-f2f3760198bf/document/297c7a8d-f6f4-4b70-a7b7-fe1cedee53e7 - title: ARM 42.4.301(2) as in effect from 9/7/2024 ("federal refundable tax credits received" and "any state refundable tax credits received") href: https://rules.mt.gov/api/policy-library-public/collections/aec52c46-128e-4279-9068-8af5d5432d74/policies/c90ea93a-03a2-4605-a0f8-f2f3760198bf/document/768c8344-24ee-4950-9d5e-9d8fc97ec0f7 - - title: 2017 Montana Form 2EC instructions, Gross Household Income Worksheet, item 4 ("Any federal or state refundable credits including the 2EC credit") - href: https://taxsim.nber.org/historical_state_tax_forms/MT/2017/Form%202%202017%20Booklet.pdf#page=65 - - title: 2023 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 7, refundable credits received - href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2023_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=51 - - title: 2024 Montana Form 2 instructions, Schedule 2EC, line 8, refundable credits received - href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2024_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=47 - - title: 2025 Montana Form 2 instructions, Schedule 2EC, line 8, refundable credits received - href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2025_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=45 - - title: MCA 15-30-2337(9)(a)(vi), cash public assistance and relief - href: https://mca.legmt.gov/bills/mca/title_0150/chapter_0300/part_0230/section_0370/0150-0300-0230-0370.html - - title: MCA 15-30-2337(9)(a)(vi) as in effect in 2016 (archived) - href: https://web.archive.org/web/20161231130526/http://leg.mt.gov/bills/mca/title_0150/chapter_0300/part_0230/section_0370/0150-0300-0230-0370.html - - title: 2016 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief + - title: 2016 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief (PDF p.74) href: https://taxsim.nber.org/historical_state_tax_forms/MT/2016/Form_2_booklet_2016.pdf#page=74 - - title: 2017 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief + - title: 2017 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief; Gross Household Income Worksheet, items 4 and 5 (PDF pp.64-65) href: https://taxsim.nber.org/historical_state_tax_forms/MT/2017/Form%202%202017%20Booklet.pdf#page=64 - - title: 2022 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 8, disability benefits including SSI payments and workers' compensation - href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2022_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=48 - - title: 2023 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 8, disability benefits including SSI payments and workers' compensation - href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2023_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=52 - - title: 2024 Montana Form 2 instructions, Schedule 2EC, line 16, government assistance - href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2024_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=48 - - title: 2025 Montana Form 2 instructions, Schedule 2EC, line 16, government assistance - href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2025_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=46 + - title: 2022 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, gross household income; line 8, disability benefits including SSI payments and workers' compensation (PDF pp.47-48) + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2022_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=47 + - title: 2023 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 7, refundable credits received; line 8, disability benefits including SSI payments and workers' compensation (PDF pp.51-52) + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2023_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=51 + - title: 2024 Montana Form 2 instructions, Schedule 2EC, gross household income; line 8, refundable credits received; line 16, government assistance (PDF pp.46-48) + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2024_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=46 + - title: 2025 Montana Form 2 instructions, Schedule 2EC, line 8, refundable credits received; line 16, government assistance (PDF pp.45-46) + href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2025_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=45 values: 2009-01-01: @@ -68,6 +56,10 @@ values: - ssi - tanf_person - workers_compensation + # Guaranteed income pilot payments are outside federal AGI here, and + # (9)(a) counts all nontaxable income; a government-funded pilot is also + # "any other government assistance" (Schedule 2EC line 16). + - gi_cash_assistance # Refundable credits received (2023 schedule line 7, Schedule 2EC line 8 # from 2024): Montana's refundable credits other than this credit, # and this credit as received during the year (ARM 42.4.301(2)(c)). @@ -88,6 +80,7 @@ values: - ssi - tanf_person - workers_compensation + - gi_cash_assistance - mt_refundable_credits_before_renter_credit - mt_elderly_homeowner_or_renter_credit_received - mt_elderly_homeowner_or_renter_credit_federal_refundable_credits @@ -107,6 +100,7 @@ values: - ssi - tanf_person - workers_compensation + - gi_cash_assistance - mt_refundable_credits_before_renter_credit - mt_elderly_homeowner_or_renter_credit_received - mt_elderly_homeowner_or_renter_credit_federal_refundable_credits 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 472a0218dd0..9b786fcce4f 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 @@ -327,6 +327,304 @@ mt_elderly_homeowner_or_renter_credit_net_household_income: [870, 0] mt_elderly_homeowner_or_renter_credit: [1_130, 0] +# Government assistance in gross household income. § 15-30-2337(9)(a) +# counts "all nontaxable income, including but not limited to ... (vi) cash +# public assistance and relief". 2024 and 2025 Schedule 2EC line 16 names +# SSI payments, workers' compensation "and any other government assistance"; +# the 2014-2023 instructions list "Disability benefits including, but not +# limited to, veteran's disability, SSI payments and workers' compensation". + +- name: 2024 Schedule 2EC worked case, the claimant's SSI counts on line 16 + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 15_000 + ssi: 6_000 + real_estate_taxes: 1_200 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # Line 5 pensions 15_000; line 16 SSI 6_000; line 18 = 21_000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: 21_000 + # Line 19 12_600; line 20 = 8_400; line 21 = 0.039 (8_000 to 8_999); + # line 22 = 8_400 x 0.039 = 327.60. + mt_elderly_homeowner_or_renter_credit_net_household_income: 327.60 + # Line 23 = 1_200; line 26 = 1_200; line 27 = 1_200 - 327.60 = 872.40; + # line 28 = 872.40 (under 1_150); line 29 = 100%; line 30 = 872.40. + # Without the SSI, line 18 = 15_000, line 22 = 2_400 x 0.006 = 14.40 and + # the credit would be the 1_150 cap. + mt_elderly_homeowner_or_renter_credit: 872.40 + + +- name: 2025 Schedule 2EC worked case, a household member's workers' compensation counts on line 17 + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 72 + taxable_pension_income: 18_000 + real_estate_taxes: 1_500 + person2: + age: 45 + workers_compensation: 9_000 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_name: MT + output: + # The claimant's adult son lives in the household and files his own + # return. Line 5 pensions 18_000; line 17 his workers' compensation, a + # line 16 item for another member, 9_000; line 18 = 27_000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [18_000, 9_000] + # Line 20 = 27_000 - 12_600 = 14_400; line 21 = 0.05; line 22 = 720. + mt_elderly_homeowner_or_renter_credit_net_household_income: [720, 0] + # Line 27 = 1_500 - 720 = 780; line 28 = 780; line 29 = 100%; line 30 = + # 780. Without his workers' compensation, line 18 = 18_000, line 22 = + # 5_400 x 0.028 = 151.20 and the credit would be the 1_150 cap. + mt_elderly_homeowner_or_renter_credit: [780, 0] + + +- name: 2024 Schedule 2EC worked case, a household member's guaranteed income payments count on line 17 + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 16_000 + real_estate_taxes: 1_200 + person2: + age: 35 + gi_cash_assistance: 6_000 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_name: MT + output: + # The claimant's daughter files her own return and receives 6_000 from a + # guaranteed income pilot, which is outside federal AGI. § 15-30-2337(9)(a) + # counts "all nontaxable income", and line 16 counts "any other + # government assistance". Line 5 = 16_000; line 17 = 6_000; line 18 = + # 22_000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [16_000, 6_000] + # Line 20 = 9_400; line 21 = 0.042; line 22 = 394.80. + mt_elderly_homeowner_or_renter_credit_net_household_income: [394.80, 0] + # Line 27 = 1_200 - 394.80 = 805.20; line 28 = 805.20; line 29 = 100%; + # line 30 = 805.20. Without the payments, line 18 = 16_000, line 22 = + # 3_400 x 0.016 = 54.40 and the credit 1_145.60. + mt_elderly_homeowner_or_renter_credit: [805.20, 0] + + +- name: 2024 Schedule 2EC worked case, TANF in a shared SPM unit counts once across two returns + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 20_000 + real_estate_taxes: 1_500 + person2: + age: 30 + person3: + age: 5 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + spm_units: + spm_unit: + members: [person1, person2, person3] + tanf: 4_800 + households: + household: + members: [person1, person2, person3] + state_name: MT + output: + # The claimant's daughter and granddaughter live with her; the daughter + # files her own return and receives 4_800 of TANF. Line 5 pensions + # 20_000; line 17 the TANF 4_800; line 18 = 24_800. The model holds TANF + # for the SPM unit and counts each member's per capita share + # (tanf_person, 1_600 each), so the household total counts it once. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [21_600, 1_600, 1_600] + # Line 20 = 24_800 - 12_600 = 12_200; line 21 = 0.05; line 22 = 610. + mt_elderly_homeowner_or_renter_credit_net_household_income: [610, 0, 0] + # Line 27 = 1_500 - 610 = 890; line 28 = 890; line 29 = 100%; line 30 = + # 890. Without the TANF, line 18 = 20_000, line 22 = 7_400 x 0.035 = 259 + # and the credit would be the 1_150 cap. Counting the whole 4_800 for + # each of the three members would give line 18 = 34_400 and a credit of + # 1_500 - 1_090 = 410. + mt_elderly_homeowner_or_renter_credit: [890, 0, 0] + + +- name: 2024 Schedule 2EC worked case, Montana TANF paid to a separate SPM unit counts on line 17 + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 20_000 + real_estate_taxes: 1_500 + person2: + age: 30 + person3: + age: 5 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + spm_units: + spm_unit1: + members: [person1] + spm_unit2: + members: [person2, person3] + mt_tanf: 4_800 + households: + household: + members: [person1, person2, person3] + state_name: MT + output: + # The same household with the daughter's family in its own SPM unit and + # the payment entered as Montana TANF (ARM 37.78), which tanf sums with + # the other states' programs. Line 17 = 4_800; line 18 = 24_800. + tanf: [0, 4_800] + mt_elderly_homeowner_or_renter_credit_gross_household_income: [20_000, 2_400, 2_400] + # Line 22 = (24_800 - 12_600) x 0.05 = 610; line 27 = 890; line 30 = 890. + mt_elderly_homeowner_or_renter_credit_net_household_income: [610, 0, 0] + mt_elderly_homeowner_or_renter_credit: [890, 0, 0] + + +- name: 2023 Elderly Homeowner/Renter Credit Schedule worked case, workers' compensation and a spouse's SSI count on line 8 + period: 2023 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 66 + taxable_pension_income: 14_000 + workers_compensation: 6_000 + real_estate_taxes: 1_000 + person2: + age: 64 + ssi: 5_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_name: MT + output: + # Joint return. Line 1 federal AGI 14_000; line 8 "Disability benefits + # including, but not limited to, veteran's disability, SSI payments, and + # workers' compensation": 6_000 + 5_000 = 11_000; line 10 = 25_000. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [20_000, 5_000] + # Line 11 12_600; line 12 = 12_400; line 13 = 0.05; line 14 = 620. + mt_elderly_homeowner_or_renter_credit_net_household_income: [620, 0] + # Line 15 = 1_000; line 18 = 1_000; line 19 = 1_000 - 620 = 380; line 20 + # = 380; line 21 = 100%; line 22 = 380. Without either amount, line 10 = + # 14_000, line 12 = 1_400 at a 0 rate and the credit would be 1_000. + mt_elderly_homeowner_or_renter_credit: [380, 0] + + +- name: 2017 Form 2EC worked case, a household member's SSI counts in gross household income + period: 2017 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 15_000 + real_estate_taxes: 1_000 + person2: + age: 40 + # 2017 federal benefit rate: 735 a month. + ssi: 8_820 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_name: MT + output: + # The claimant's adult son receives SSI. Gross Household Income + # Worksheet: line 6 pensions 15_000; line 7 income of other household + # members, his SSI 8_820 ("Disability benefits including ... SSI + # payments"); line 8 = 23_820, Form 2EC line 1. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [15_000, 8_820] + # Line 2 6_300; line 3 = 17_520; line 4 = 0.05; line 5 = 876. + mt_elderly_homeowner_or_renter_credit_net_household_income: [876, 0] + # Line 6 = 1_000; line 9 = 1_000; line 10 = 1_000 - 876 = 124; line 11 = + # 124 (under 1_000); line 12 = 100%; line 13 = 124. Without his SSI, line + # 1 = 15_000, line 5 = 8_700 x 0.039 = 339.30 and the credit 660.70. + mt_elderly_homeowner_or_renter_credit: [124, 0] + + +- name: 2016 Form 2EC worked case, cash public assistance received by another household member counts + period: 2016 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + taxable_pension_income: 12_000 + real_estate_taxes: 900 + person2: + age: 30 + person3: + age: 5 + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + spm_units: + spm_unit1: + members: [person1] + spm_unit2: + members: [person2, person3] + tanf: 5_400 + households: + household: + members: [person1, person2, person3] + state_name: MT + output: + # Gross Household Income Worksheet: line 8 pensions 12_000; the + # daughter's 5_400 of TANF, cash public assistance (line 7), as income of + # another household member (line 9); line 10 = 17_400, Form 2EC line 1. + mt_elderly_homeowner_or_renter_credit_gross_household_income: [12_000, 2_700, 2_700] + # Line 2 6_300; line 3 = 11_100; line 4 = 0.048; line 5 = 532.80. + mt_elderly_homeowner_or_renter_credit_net_household_income: [532.80, 0, 0] + # Line 6 = 900; line 10 = 900 - 532.80 = 367.20; line 11 = 367.20; line + # 12 = 100%; line 13 = 367.20. Without the TANF, line 1 = 12_000, line 5 + # = 5_700 x 0.028 = 159.60 and the credit 740.40. + mt_elderly_homeowner_or_renter_credit: [367.20, 0, 0] + - name: 2024 Schedule 2EC worked case, a dependent's wages move the credit into the 40 percent band period: 2024 absolute_error_margin: 0.01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml deleted file mode 100644 index 82bc6942c0f..00000000000 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/elderly_homeowner_or_renter/mt_elderly_homeowner_or_renter_credit_government_assistance.yaml +++ /dev/null @@ -1,282 +0,0 @@ -# Government assistance in gross household income: SSI, TANF and workers' -# compensation. § 15-30-2337(9)(a) counts "all nontaxable income, including -# but not limited to ... (vi) cash public assistance and relief". 2024 and -# 2025 Schedule 2EC line 16: "This includes veteran's compensation benefits, -# supplemental security income (SSI) payments, worker's compensation, and any -# other government assistance received during the year." The 2014-2023 -# instructions list "Disability benefits including, but not limited to, -# veteran's disability, SSI payments and workers' compensation", and the -# 2014-2017 instructions add "Cash public assistance and relief - Do not -# include LIEAP ... or SNAP". - -- name: 2024 Schedule 2EC worked case, the claimant's SSI counts on line 16 - period: 2024 - absolute_error_margin: 0.01 - input: - people: - person1: - age: 70 - taxable_pension_income: 15_000 - ssi: 6_000 - real_estate_taxes: 1_200 - tax_units: - tax_unit: - members: [person1] - households: - household: - members: [person1] - state_name: MT - output: - # Line 5 pensions 15_000; line 16 SSI 6_000; line 18 = 21_000. - mt_elderly_homeowner_or_renter_credit_gross_household_income: 21_000 - # Line 19 12_600; line 20 = 8_400; line 21 = 0.039 (8_000 to 8_999); - # line 22 = 8_400 x 0.039 = 327.60. - mt_elderly_homeowner_or_renter_credit_net_household_income: 327.60 - # Line 23 = 1_200; line 26 = 1_200; line 27 = 1_200 - 327.60 = 872.40; - # line 28 = 872.40 (under 1_150); line 29 = 100%; line 30 = 872.40. - # Without the SSI, line 18 = 15_000, line 22 = 2_400 x 0.006 = 14.40 and - # the credit would be the 1_150 cap. - mt_elderly_homeowner_or_renter_credit: 872.40 - -- name: 2025 Schedule 2EC worked case, a household member's workers' compensation counts on line 17 - period: 2025 - absolute_error_margin: 0.01 - input: - people: - person1: - age: 72 - taxable_pension_income: 18_000 - real_estate_taxes: 1_500 - person2: - age: 45 - workers_compensation: 9_000 - tax_units: - tax_unit1: - members: [person1] - tax_unit2: - members: [person2] - households: - household: - members: [person1, person2] - state_name: MT - output: - # The claimant's adult son lives in the household and files his own - # return. Line 5 pensions 18_000; line 17 his workers' compensation, a - # line 16 item for another member, 9_000; line 18 = 27_000. - mt_elderly_homeowner_or_renter_credit_gross_household_income: [18_000, 9_000] - # Line 20 = 27_000 - 12_600 = 14_400; line 21 = 0.05; line 22 = 720. - mt_elderly_homeowner_or_renter_credit_net_household_income: [720, 0] - # Line 27 = 1_500 - 720 = 780; line 28 = 780; line 29 = 100%; line 30 = - # 780. Without his workers' compensation, line 18 = 18_000, line 22 = - # 5_400 x 0.028 = 151.20 and the credit would be the 1_150 cap. - mt_elderly_homeowner_or_renter_credit: [780, 0] - -- name: 2024 Schedule 2EC worked case, TANF in a shared SPM unit counts once across two returns - period: 2024 - absolute_error_margin: 0.01 - input: - people: - person1: - age: 70 - taxable_pension_income: 20_000 - real_estate_taxes: 1_500 - person2: - age: 30 - person3: - age: 5 - tax_units: - tax_unit1: - members: [person1] - tax_unit2: - members: [person2, person3] - spm_units: - spm_unit: - members: [person1, person2, person3] - tanf: 4_800 - households: - household: - members: [person1, person2, person3] - state_name: MT - output: - # The claimant's daughter and granddaughter live with her; the daughter - # files her own return and receives 4_800 of TANF. Line 5 pensions - # 20_000; line 17 the TANF 4_800; line 18 = 24_800. The model holds TANF - # for the SPM unit and counts each member's per capita share - # (tanf_person, 1_600 each), so the household total counts it once. - mt_elderly_homeowner_or_renter_credit_gross_household_income: [21_600, 1_600, 1_600] - # Line 20 = 24_800 - 12_600 = 12_200; line 21 = 0.05; line 22 = 610. - mt_elderly_homeowner_or_renter_credit_net_household_income: [610, 0, 0] - # Line 27 = 1_500 - 610 = 890; line 28 = 890; line 29 = 100%; line 30 = - # 890. Without the TANF, line 18 = 20_000, line 22 = 7_400 x 0.035 = 259 - # and the credit would be the 1_150 cap. Counting the whole 4_800 for - # each of the three members would give line 18 = 34_400 and a credit of - # 1_500 - 1_090 = 410. - mt_elderly_homeowner_or_renter_credit: [890, 0, 0] - -- name: 2024 Schedule 2EC worked case, Montana TANF paid to a separate SPM unit counts on line 17 - period: 2024 - absolute_error_margin: 0.01 - input: - people: - person1: - age: 70 - taxable_pension_income: 20_000 - real_estate_taxes: 1_500 - person2: - age: 30 - person3: - age: 5 - tax_units: - tax_unit1: - members: [person1] - tax_unit2: - members: [person2, person3] - spm_units: - spm_unit1: - members: [person1] - spm_unit2: - members: [person2, person3] - mt_tanf: 4_800 - households: - household: - members: [person1, person2, person3] - state_name: MT - output: - # The same household with the daughter's family in its own SPM unit and - # the payment entered as Montana TANF (ARM 37.78), which tanf sums with - # the other states' programs. Line 17 = 4_800; line 18 = 24_800. - tanf: [0, 4_800] - mt_elderly_homeowner_or_renter_credit_gross_household_income: [20_000, 2_400, 2_400] - # Line 22 = (24_800 - 12_600) x 0.05 = 610; line 27 = 890; line 30 = 890. - mt_elderly_homeowner_or_renter_credit_net_household_income: [610, 0, 0] - mt_elderly_homeowner_or_renter_credit: [890, 0, 0] - -- name: 2023 Elderly Homeowner/Renter Credit Schedule worked case, workers' compensation and a spouse's SSI count on line 8 - period: 2023 - absolute_error_margin: 0.01 - input: - people: - person1: - age: 66 - taxable_pension_income: 14_000 - workers_compensation: 6_000 - real_estate_taxes: 1_000 - person2: - age: 64 - ssi: 5_000 - tax_units: - tax_unit: - members: [person1, person2] - households: - household: - members: [person1, person2] - state_name: MT - output: - # Joint return. Line 1 federal AGI 14_000; line 8 "Disability benefits - # including, but not limited to, veteran's disability, SSI payments, and - # workers' compensation": 6_000 + 5_000 = 11_000; line 10 = 25_000. - mt_elderly_homeowner_or_renter_credit_gross_household_income: [20_000, 5_000] - # Line 11 12_600; line 12 = 12_400; line 13 = 0.05; line 14 = 620. - mt_elderly_homeowner_or_renter_credit_net_household_income: [620, 0] - # Line 15 = 1_000; line 18 = 1_000; line 19 = 1_000 - 620 = 380; line 20 - # = 380; line 21 = 100%; line 22 = 380. Without either amount, line 10 = - # 14_000, line 12 = 1_400 at a 0 rate and the credit would be 1_000. - mt_elderly_homeowner_or_renter_credit: [380, 0] - -- name: 2017 Form 2EC worked case, a household member's SSI counts in gross household income - period: 2017 - absolute_error_margin: 0.01 - input: - people: - person1: - age: 70 - taxable_pension_income: 15_000 - real_estate_taxes: 1_000 - person2: - age: 40 - # 2017 federal benefit rate: 735 a month. - ssi: 8_820 - tax_units: - tax_unit1: - members: [person1] - tax_unit2: - members: [person2] - households: - household: - members: [person1, person2] - state_name: MT - output: - # The claimant's adult son receives SSI. Gross Household Income - # Worksheet: line 6 pensions 15_000; line 7 income of other household - # members, his SSI 8_820 ("Disability benefits including ... SSI - # payments"); line 8 = 23_820, Form 2EC line 1. - mt_elderly_homeowner_or_renter_credit_gross_household_income: [15_000, 8_820] - # Line 2 6_300; line 3 = 17_520; line 4 = 0.05; line 5 = 876. - mt_elderly_homeowner_or_renter_credit_net_household_income: [876, 0] - # Line 6 = 1_000; line 9 = 1_000; line 10 = 1_000 - 876 = 124; line 11 = - # 124 (under 1_000); line 12 = 100%; line 13 = 124. Without his SSI, line - # 1 = 15_000, line 5 = 8_700 x 0.039 = 339.30 and the credit 660.70. - mt_elderly_homeowner_or_renter_credit: [124, 0] - -- name: 2016 Form 2EC worked case, cash public assistance received by another household member counts - period: 2016 - absolute_error_margin: 0.01 - input: - people: - person1: - age: 70 - taxable_pension_income: 12_000 - real_estate_taxes: 900 - person2: - age: 30 - person3: - age: 5 - tax_units: - tax_unit1: - members: [person1] - tax_unit2: - members: [person2, person3] - spm_units: - spm_unit1: - members: [person1] - spm_unit2: - members: [person2, person3] - tanf: 5_400 - households: - household: - members: [person1, person2, person3] - state_name: MT - output: - # Gross Household Income Worksheet line 7, "Alimony, cash public - # assistance, unemployment", for the daughter's 5_400 of TANF; line 9 = - # 12_000 + 5_400 = 17_400, Form 2EC line 1. - mt_elderly_homeowner_or_renter_credit_gross_household_income: [12_000, 2_700, 2_700] - # Line 2 6_300; line 3 = 11_100; line 4 = 0.048; line 5 = 532.80. - mt_elderly_homeowner_or_renter_credit_net_household_income: [532.80, 0, 0] - # Line 6 = 900; line 10 = 900 - 532.80 = 367.20; line 11 = 367.20; line - # 12 = 100%; line 13 = 367.20. Without the TANF, line 1 = 12_000, line 5 - # = 5_700 x 0.028 = 159.60 and the credit 740.40. - mt_elderly_homeowner_or_renter_credit: [367.20, 0, 0] - -- name: SNAP is not cash public assistance and does not count - period: 2017 - input: - people: - person1: - age: 70 - taxable_pension_income: 15_000 - spm_units: - spm_unit: - members: [person1] - snap: 1_800 - tax_units: - tax_unit: - members: [person1] - households: - household: - members: [person1] - state_name: MT - output: - # 2017 Form 2EC instructions: "Cash, public assistance and relief - Do - # not include LIEAP (Low Income Energy Assistance Program) or SNAP". - mt_elderly_homeowner_or_renter_credit_gross_household_income: 15_000 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 e1ca3dc39ce..442caea56f2 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 @@ -89,6 +89,29 @@ # income: (20_000 - 12_600) * 0.035 = 259, allocated to the head. mt_elderly_homeowner_or_renter_credit_net_household_income: [259, 0] +- name: SNAP is not cash public assistance and does not count + period: 2017 + input: + people: + person1: + age: 70 + taxable_pension_income: 15_000 + spm_units: + spm_unit: + members: [person1] + snap: 1_800 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: MT + output: + # 2017 Form 2EC instructions: "Cash, public assistance and relief - Do + # not include LIEAP (Low Income Energy Assistance Program) or SNAP". + mt_elderly_homeowner_or_renter_credit_gross_household_income: 15_000 + - name: A dependent's wages count in gross household income period: 2024 input: diff --git a/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py b/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py index 00870adc9cc..aaf5fa438f5 100644 --- a/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py +++ b/policyengine_us/tests/test_mt_elderly_credit_government_assistance.py @@ -8,11 +8,12 @@ compensation, and any other government assistance"; line 17 carries the same items for the other members of the household. -The model holds SSI and workers' compensation per person and TANF per SPM -unit, which it spreads over the unit's members (tanf_person). For a claimant -aged 62 or older (taxable pension, SSI, workers' compensation, property tax, -rent) living with another adult (SSI, workers' compensation) and a child, -whose SPM unit receives TANF, in four arrangements: +The model holds SSI, workers' compensation and guaranteed income payments +per person and TANF per SPM unit, which it spreads over the unit's members +(tanf_person). For a claimant aged 62 or older (taxable pension, SSI, +workers' compensation, property tax, rent) living with another adult (SSI, +workers' compensation, guaranteed income payments) and a child, whose SPM +unit receives TANF, in four arrangements: A. one return, the other adult and the child the claimant's dependents, and one SPM unit; @@ -22,7 +23,8 @@ D. as C, with more of one kind of assistance; 1. The household's gross household income is the pension plus every - member's SSI and workers' compensation plus the TANF, once, in A, B and C. + member's SSI, workers' compensation and guaranteed income payments plus + the TANF, once, in A, B and C. 2. So the claimant's credit is the same in A, B and C, and nobody else claims. 3. The credit equals an independent reading of Schedule 2EC lines 18 to 30, @@ -32,6 +34,12 @@ No one has earned income, so no refundable credit enters line 8. The model computes in single precision, so comparisons allow one cent or eight float32 spacings at the household's total income, whichever is larger. + +YAML cases (mt_elderly_homeowner_or_renter_credit.yaml) pin fixed worked +examples. This file adds what they cannot: randomized amounts across +arrangements that must agree, an independent Schedule 2EC reference for the +credit, and monotonicity. Each example is one small Simulation on the shared +tax-benefit system. """ import numpy as np @@ -70,7 +78,12 @@ (42_501, 0.1), (45_000, 0), ] -EXTRA_KINDS = ["claimant_ssi", "member_workers_compensation", "tanf"] +EXTRA_KINDS = [ + "claimant_ssi", + "member_workers_compensation", + "member_gi_cash_assistance", + "tanf", +] def amounts(c, arrangement): @@ -80,6 +93,7 @@ def amounts(c, arrangement): "claimant_workers_compensation": c["claimant_workers_compensation"], "member_ssi": c["member_ssi"], "member_workers_compensation": c["member_workers_compensation"], + "member_gi_cash_assistance": c["member_gi_cash_assistance"], "tanf": c["tanf"], } if arrangement == "D": @@ -118,6 +132,7 @@ def build_situation(cases): "age": {YEAR: c["member_age"]}, "ssi": {YEAR: a["member_ssi"]}, "workers_compensation": {YEAR: a["member_workers_compensation"]}, + "gi_cash_assistance": {YEAR: a["member_gi_cash_assistance"]}, "is_tax_unit_dependent": {YEAR: arrangement == "A"}, } people[child] = { @@ -185,7 +200,8 @@ def by_household(variable): def expected_gross_household_income(c, arrangement): """2024 Schedule 2EC line 18: line 5 pension and line 16 assistance for - the claimant, line 17 the other members' assistance, the TANF once.""" + the claimant, line 17 the other members' assistance and guaranteed income + payments, the TANF once.""" return c["pension"] + sum(amounts(c, arrangement).values()) @@ -254,6 +270,7 @@ def test_worked_example(): "member_age": 35, "member_ssi": 2_000, "member_workers_compensation": 1_000, + "member_gi_cash_assistance": 0, "child_age": 6, "tanf": 1_800, "extra_kind": "tanf", @@ -293,6 +310,7 @@ def case(draw): "member_age": draw(st.integers(min_value=18, max_value=61)), "member_ssi": draw(amount(12_000)), "member_workers_compensation": draw(amount(15_000)), + "member_gi_cash_assistance": draw(amount(12_000)), "child_age": draw(st.integers(min_value=0, max_value=17)), "tanf": draw(amount(10_000)), "extra_kind": draw(st.sampled_from(EXTRA_KINDS)), From f9d8d64b535b8200c8f94dddfe74bd7acb34a9d9 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 12 Oct 2026 15:37:33 -0400 Subject: [PATCH 6/6] 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 --- .../gross_income_sources.yaml | 12 ++++++------ .../tests/test_mt_elderly_credit_one_claimant.py | 4 ++++ 2 files changed, 10 insertions(+), 6 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 14a8ead4344..fb84aef0128 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 @@ -18,17 +18,17 @@ metadata: href: https://rules.mt.gov/api/policy-library-public/collections/aec52c46-128e-4279-9068-8af5d5432d74/policies/c90ea93a-03a2-4605-a0f8-f2f3760198bf/document/297c7a8d-f6f4-4b70-a7b7-fe1cedee53e7 - title: ARM 42.4.301(2) as in effect from 9/7/2024 ("federal refundable tax credits received" and "any state refundable tax credits received") href: https://rules.mt.gov/api/policy-library-public/collections/aec52c46-128e-4279-9068-8af5d5432d74/policies/c90ea93a-03a2-4605-a0f8-f2f3760198bf/document/768c8344-24ee-4950-9d5e-9d8fc97ec0f7 - - title: 2016 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief (PDF p.74) + - title: 2016 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief href: https://taxsim.nber.org/historical_state_tax_forms/MT/2016/Form_2_booklet_2016.pdf#page=74 - - title: 2017 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief; Gross Household Income Worksheet, items 4 and 5 (PDF pp.64-65) + - title: "2017 Montana Form 2EC instructions, Part II, disability benefits including SSI payments and workers' compensation, and cash public assistance and relief; Gross Household Income Worksheet, items 4 and 5 #page 64-65" href: https://taxsim.nber.org/historical_state_tax_forms/MT/2017/Form%202%202017%20Booklet.pdf#page=64 - - title: 2022 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, gross household income; line 8, disability benefits including SSI payments and workers' compensation (PDF pp.47-48) + - title: "2022 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, gross household income; line 8, disability benefits including SSI payments and workers' compensation #page 47-48" href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2022_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=47 - - title: 2023 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 7, refundable credits received; line 8, disability benefits including SSI payments and workers' compensation (PDF pp.51-52) + - title: "2023 Montana Form 2 instructions, Elderly Homeowner/Renter Credit Schedule, line 7, refundable credits received; line 8, disability benefits including SSI payments and workers' compensation #page 51-52" href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2023_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=51 - - title: 2024 Montana Form 2 instructions, Schedule 2EC, gross household income; line 8, refundable credits received; line 16, government assistance (PDF pp.46-48) + - title: "2024 Montana Form 2 instructions, Schedule 2EC, gross household income; line 8, refundable credits received; line 16, government assistance #page 46-48" href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2024_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=46 - - title: 2025 Montana Form 2 instructions, Schedule 2EC, line 8, refundable credits received; line 16, government assistance (PDF pp.45-46) + - title: "2025 Montana Form 2 instructions, Schedule 2EC, line 8, refundable credits received; line 16, government assistance #page 45-46" href: https://revenue.mt.gov/files/forms/Montana-Individual-Income-Tax-Return-Form-2-Instructions/2025_Montana_Individual_Income_Tax_Return_Form_2_Instructions.pdf#page=45 values: diff --git a/policyengine_us/tests/test_mt_elderly_credit_one_claimant.py b/policyengine_us/tests/test_mt_elderly_credit_one_claimant.py index d1dc874a300..ae224c8dea5 100644 --- a/policyengine_us/tests/test_mt_elderly_credit_one_claimant.py +++ b/policyengine_us/tests/test_mt_elderly_credit_one_claimant.py @@ -68,6 +68,10 @@ def build_situation(households): "taxable_pension_income": {YEAR: adult["pension"]}, "taxable_interest_income": {YEAR: adult["interest"]}, "social_security_retirement": {YEAR: adult["social_security"]}, + # The model would compute SSI for an adult with + # little income; SSI has its own tests (government + # assistance), so the reference leaves it out. + "ssi": {YEAR: 0}, "is_tax_unit_dependent": {YEAR: False}, } unit_members.append(person)