PolicyEngine / PolicyEngine/policyengine-us
VT: 2025 Act 71 lets the military retirement exclusion stack with the §5830e(a)-(c) election; model still forces a single max_() choice
- Dominant language
- Python
- Stars
- 162
- Forks
- 212
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 97
Description
Found while verifying #9136 against the enacted text of 2025 Act No. 71 (S.51). Related: #9069, #9020, #9021, #8853.
## Problem
Act 71 (2025), Sec. 3 didn't just give U.S. military retirement/survivor income its own AGI thresholds in 32 V.S.A. § 5830e(d) — it also **removed the military exclusion from the elect-one-exclusion rule**. Subsection (e) as amended (verified against the enrolled act and the current Vermont Statutes Online codification, "amended … 2025, No. 71, § 3, eff. January 1, 2025"):
> (e)(1) Requirement to elect one exclusion. A taxpayer of this State who is eligible during the taxable year for more than one of the exclusions under subsections **(a), (b), and (c)** of this section shall elect only one of the exclusions for which the taxpayer is eligible.
> (2) A taxpayer of this State who is eligible during the taxable year for the military retirement and survivor benefit exclusion under subsection (d) of this section **may elect that exclusion regardless of whether the taxpayer also elects an exclusion under subsections (a)–(c)** of this section.
The old language routing military through the (b) CSRS regime and the (e) election ("pursuant to subsection (b) … and shall be subject to the limitations under subsection (e)") was struck by the act.
But `vt_retirement_income_exemption` (and the mirrored logic in `vt_retirement_income_exemption_eligible`) still models a single election across all three:
```python
chosen_retirement_income = max_(
max_(tax_unit_taxable_social_security, vt_military_retirement_pay_exclusion),
vt_csrs_retirement_pay_exclusion,
)
```
## Effect (2025+)
A filer with **both** military retirement income and taxable Social Security (or CSRS/other-contributory pension income) is under-computed: the statute allows the (d) military exclusion **plus** one elected exclusion among (a)–(c); the model grants only `max_()` of them. Direction: model overtaxes affected filers. (#9136 fixed the severe single-source defects — double-phasing and the CSRS-end zeroing — but deliberately kept the election structure.)
## Suggested direction
For `military_retirement.income_based_structure.in_effect` years:
- `vt_retirement_income_exemption` = `vt_military_retirement_income_based_exemption` (self-phased on the $125k/$175k band) **+** the elected-one exclusion among (a) Social Security, (b) CSRS, (c) other-contributory (the latter two still subject to the (b) reduction band, SS to its own band).
- The election among (a)–(c) should compare **post-phase-out** outcomes rather than raw amounts — the current raw `max_()` can elect an option that the AGI gate then zeroes (e.g. a dual CSRS+SS case where the bands differ).
- `vt_retirement_income_exemption_eligible`'s CSRS-end AGI gate needs the same restructure (it should gate only the elected (a)–(c) component, never the (d) component — #9136 already bypasses it for the military-chosen case).
## Also in scope for the follow-up
1. **Citation fix:** two comments added in #9136 (the test-file header and `vt_retirement_income_exemption.py`) cite "Act 51 (2025)". S.51 was enacted as **Act No. 71 (2025)**; Act 51 of 2025 is S.59 (Open Meeting Law). The parameter files already cite the S.51 bill PDF correctly.
2. **Survivor benefits:** § 5830e(d) covers "U.S. military survivor benefit income … received by an eligible beneficiary." The model computes (d) from `military_retirement_pay`, whose documentation says it includes survivor benefits; confirm that's the intended input convention (a separate `military_retirement_pay_survivors` variable also exists and is used by some states).
Source: enrolled act, https://legislature.vermont.gov/Documents/2026/Docs/BILLS/S-0051/S-0051%20As%20Passed%20by%20Both%20House%20and%20Senate%20Official.pdf (Secs. 1–6 begin at p. 6; subsection (e) at pp. 10–11), cross-checked against https://legislature.vermont.gov/statutes/section/32/151/05830e.
Contributor guide
Research direction
Start in vt_retirement_income_exemption.py and the mirrored vt_retirement_income_exemption_eligible logic, then review the tests and citation changes from #9136. Verify the 2025 Act No. 71 rules for combining the military exclusion with one post-phase-out exclusion under subsections (a)–(c), and confirm the survivor-benefit input convention. Done means the affected calculations and tests reflect the statute and the Act 51 citations are corrected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100