diff --git a/changelog.d/fix-mt-rebate-wiring.fixed.md b/changelog.d/fix-mt-rebate-wiring.fixed.md new file mode 100644 index 00000000000..76f6ec3aa65 --- /dev/null +++ b/changelog.d/fix-mt-rebate-wiring.fixed.md @@ -0,0 +1 @@ +Correct the Montana 2021 income tax rebate's reported value outside its eligibility year: without the 2022 sunset the amount backdates forward, so the variable reported a phantom rebate in 2022 and later. Montana income tax is unaffected, as the non-refundable credit list already excludes the rebate from 2022. diff --git a/policyengine_us/parameters/gov/states/mt/tax/income/credits/rebate/amount.yaml b/policyengine_us/parameters/gov/states/mt/tax/income/credits/rebate/amount.yaml index 323de1b3ef6..21df70439f9 100644 --- a/policyengine_us/parameters/gov/states/mt/tax/income/credits/rebate/amount.yaml +++ b/policyengine_us/parameters/gov/states/mt/tax/income/credits/rebate/amount.yaml @@ -11,11 +11,16 @@ metadata: SINGLE: 2021-01-01: 1_250 + 2022-01-01: 0 HEAD_OF_HOUSEHOLD: 2021-01-01: 1_250 + 2022-01-01: 0 JOINT: 2021-01-01: 2_500 + 2022-01-01: 0 SURVIVING_SPOUSE: 2021-01-01: 2_500 + 2022-01-01: 0 SEPARATE: - 2021-01-01: 1_250 + 2021-01-01: 1_250 + 2022-01-01: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.yaml b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.yaml index ce17b615090..738e667816b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.yaml @@ -1,23 +1,42 @@ +# The rebate is keyed to the 2021 tax year (MCA 15-30-2191(1)); it was paid out +# in 2023 but is booked in the eligibility year. All active-year cases therefore +# run at period 2021. Cases at 2022 and 2023 guard the year-scoping added by +# amount.yaml's `2022-01-01: 0` entries: without them, backdating fills the 2021 +# amounts forward and every Montana filer receives a phantom rebate credit. + - name: Single filer receives the full single rebate - period: 2023 + period: 2021 input: - filing_status: SINGLE - state_code: MT + people: + person1: + age: 45 + employment_income: 50_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MT output: - mt_income_tax_rebate: 1_250 + mt_income_tax_rebate: [1_250] - name: Joint filers split the per-return rebate across each spouse's column - period: 2023 + period: 2021 + absolute_error_margin: 0.01 input: people: person1: - is_tax_unit_head: true + age: 45 + employment_income: 60_000 person2: - is_tax_unit_spouse: true + age: 45 + marital_units: + marital_unit: + members: [person1, person2] tax_units: tax_unit: members: [person1, person2] - filing_status: JOINT households: household: members: [person1, person2] @@ -25,11 +44,98 @@ output: # $2,500 per-return cap split $1,250 per spouse (sums to $2,500, not $5,000) mt_income_tax_rebate: [1_250, 1_250] + # End to end: 2,518.22 pre-credit - 2,500 pooled rebate = 18.22 + mt_income_tax: 18.22 + +- name: Rebate cannot drive liability below zero (MCA 15-30-2191(2)) + period: 2021 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + employment_income: 20_000 + person2: + age: 45 + marital_units: + marital_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MT + output: + # The statutory "lesser of the amount or the liability" cap is enforced by + # the ordered credit application, not by the rebate variable: the full + # $2,500 is reported, but the joint path floors at zero, so a household + # whose pre-credit liability is only $252.40 keeps $252.40 of benefit and + # no more. (mt_income_tax itself goes to -33.81 here from the refundable + # Montana EITC, which is unrelated to the rebate.) + mt_income_tax_rebate: [1_250, 1_250] + mt_income_tax_before_non_refundable_credits_joint: 252.40 + mt_income_tax_before_refundable_credits_joint: 0 -- name: Not in Montana +- name: No rebate outside Montana + period: 2021 + input: + people: + person1: + age: 45 + employment_income: 50_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: AR + output: + mt_income_tax_rebate: [0] + +- name: No phantom rebate value in 2022 + period: 2022 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + employment_income: 50_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MT + output: + # This is the discriminating assertion: without amount.yaml's 2022 + # zeroing, backdating fills the 2021 amount forward and this reads + # 1_250. Montana tax is NOT affected either way, because + # credits/non_refundable.yaml already drops mt_income_tax_rebate from + # the list at 2022-01-01 - so the defect is the variable's reported + # value, which mis-feeds consumers such as the TAXSIM srebate + # comparison, not the tax outcome. mt_income_tax and + # mt_non_refundable_credits are pinned here as unchanged controls. + mt_income_tax_rebate: [0] + mt_non_refundable_credits: [0] + mt_income_tax: 2_246.00 + +- name: No rebate in 2023, the year the rebate was actually paid out period: 2023 input: - filing_status: JOINT - state_code: AR + people: + person1: + age: 45 + employment_income: 50_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: MT output: - mt_income_tax_rebate: 0 + mt_income_tax_rebate: [0] diff --git a/policyengine_us/variables/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.py b/policyengine_us/variables/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.py index ae19961fc22..7d18397af19 100644 --- a/policyengine_us/variables/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.py +++ b/policyengine_us/variables/gov/states/mt/tax/income/credits/rebate/mt_income_tax_rebate.py @@ -14,6 +14,17 @@ class mt_income_tax_rebate(Variable): # It applies once per return (MCA 15-30-2191(1)), so joint filers split # the per-return cap across each spouse's column ($1,250 each) to avoid # double-counting when the person-level non-refundable credits are pooled. + # + # MCA 15-30-2191(2) caps the rebate at the lesser of the filing-status + # amount or the 2021 income tax liability reported on line 20 of Form 2 + # (tax after non-refundable credits). That cap is NOT applied here: the + # ordered non-refundable credit application already floors each path at + # zero, so the effective rebate is line-20-capped per filing + # configuration in both the indiv and joint paths. Capping this + # person-level amount against each spouse's own column would instead + # under-pay a one-earner couple electing the joint column, which the + # statute and the DOR rebate report (May 2024, pp. 6, 10-11) grant + # min($2,500, joint line 20). def formula(person, period, parameters): p = parameters(period).gov.states.mt.tax.income.credits.rebate filing_status = person.tax_unit("filing_status", period)