diff --git a/changelog.d/fix-vt-retirement-exemption-ss-gate.fixed.md b/changelog.d/fix-vt-retirement-exemption-ss-gate.fixed.md new file mode 100644 index 00000000000..7bef4e93f15 --- /dev/null +++ b/changelog.d/fix-vt-retirement-exemption-ss-gate.fixed.md @@ -0,0 +1 @@ +- Fix the Vermont retirement-income exemption eligibility gate to use the Social Security phase-out threshold for Social Security filers. diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_retirement_income_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_retirement_income_exemption.yaml index 8759e0439af..8bfb094e813 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_retirement_income_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_retirement_income_exemption.yaml @@ -180,3 +180,54 @@ state_code: VT output: vt_retirement_income_exemption: 500 # Partial qualified (halfway between $70k and $80k) + +# Integration tests: eligibility gate must use the Social Security phase-out +# threshold (not the CSRS threshold) for Social Security filers in the 2025 +# partial band. Resolves policyengine-taxsim #999 (single) and #1000 (joint). +- name: VT single SS filer in 2025 partial band gets partial exemption (taxsim #999) + absolute_error_margin: 0.1 + period: 2025 + input: + people: + person1: + age: 74 + employment_income: 29_333.33 + taxable_interest_income: 3.64 + social_security_retirement: 25_742.70 + unemployment_compensation: 10_880 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_name: VT + output: + tax_unit_taxable_social_security: 20_725.08 + vt_retirement_income_exemption_eligible: true + vt_retirement_income_exemption: 8_497.28 + vt_income_tax: 1_281.20 + +- name: VT joint SS filers in 2025 partial band get partial exemption (taxsim #1000) + period: 2025 + input: + people: + person1: + age: 77 + employment_income: 52_380.95 + taxable_interest_income: 29.15 + social_security_retirement: 27_581.46 + person2: + age: 77 + marital_units: + marital_unit: + members: [person1, person2] + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_name: VT + output: + vt_retirement_income_exemption_eligible: true diff --git a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_retirement_income_exemption_eligible.py b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_retirement_income_exemption_eligible.py index a8a217d8921..09558e39661 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_retirement_income_exemption_eligible.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_retirement_income_exemption_eligible.py @@ -21,9 +21,7 @@ def formula(tax_unit, period, parameters): # or other eligible retirement systems to determine eligibility filing_status = tax_unit("filing_status", period) agi = tax_unit("adjusted_gross_income", period) - p = parameters( - period - ).gov.states.vt.tax.income.agi.retirement_income_exemption.csrs.reduction + p = parameters(period).gov.states.vt.tax.income.agi.retirement_income_exemption # One of the retirement income should be greater than 0 retirement_income = add( tax_unit, @@ -35,8 +33,34 @@ def formula(tax_unit, period, parameters): ], ) retirement_income_qualified = retirement_income > 0 + # Determine which retirement system the filer uses, mirroring the + # main exemption formula, so the eligibility gate uses the matching + # phase-out threshold (Social Security thresholds differ from CSRS + # under 2025 law, S.51). + tax_unit_taxable_social_security = tax_unit( + "tax_unit_taxable_social_security", period + ) + vt_military_retirement_pay_exclusion = tax_unit( + "vt_military_retirement_pay_exclusion", period + ) + vt_csrs_retirement_pay_exclusion = tax_unit( + "vt_csrs_retirement_pay_exclusion", period + ) + larger_retirement_income = max_( + tax_unit_taxable_social_security, + vt_military_retirement_pay_exclusion, + ) + chosen_retirement_income = max_( + larger_retirement_income, vt_csrs_retirement_pay_exclusion + ) + use_ss = tax_unit_taxable_social_security == chosen_retirement_income + reduction_end = where( + use_ss, + p.social_security.reduction.end[filing_status], + p.csrs.reduction.end[filing_status], + ) # The agi should below threshold - agi_qualified = agi < p.end[filing_status] + agi_qualified = agi < reduction_end # Both qualified then the filer is qualified for vermont retirement # income exemption return retirement_income_qualified & agi_qualified