diff --git a/changelog.d/wire-military-retirement-pay.fixed.md b/changelog.d/wire-military-retirement-pay.fixed.md new file mode 100644 index 00000000000..21a53dd2302 --- /dev/null +++ b/changelog.d/wire-military-retirement-pay.fixed.md @@ -0,0 +1,13 @@ +Wire military retirement pay and military retirement pay survivors to federal gross income (`irs_gross_income`), person `market_income`, household `market_income_sources`, SNAP unearned income, and SSI unearned income. Add new person-level `military_retirement_income` variable summing retiree and survivor pay. Update state tax calculations and exclusions across all affected states to conform with federal AGI inclusion and statutory state treatment: +- State military retirement and survivor subtractions added or updated in AR, AZ, CA, CO, CT, DC, DE, GA, HI, IA, ID, IL, IN, KS, KY, LA, MA, MD, ME, MI, MN, MO, ND, NE, NJ, NM, NY, OH, OK, OR, PA, RI, UT, VA, VT, WI, WV. +- Fix Georgia double-counting under O.C.G.A. § 48-7-27(a)(5)(E) and Rule 560-7-4-.02(3). +- Model California 2025–2029 military retirement and SBP exclusion under R&TC §§ 17132.9–17132.10. +- Model Indiana military retirement deduction under IC 6-3-2-4. +- Model DC survivor benefits exclusion for age 62+ under D.C. Code § 47-1803.02(a)(2)(N)(ii). +- Update Michigan retirement worksheets to account for military survivor benefits. +- Fix Pennsylvania Schedule SP eligibility income by excluding military retirement pensions while retaining survivor benefits per PA-40 SP instructions. +- Add military retirement and survivor pay back to total income for Massachusetts Senior Circuit Breaker credit under M.G.L. c. 62 § 6(k)(1). +- Prevent Maryland pension subtraction double-counting under § 10-209(d)(1) by measuring excess military income against the person's actual capped military subtraction under § 10-207(q). +- Fix New Jersey 529 deduction income eligibility test to evaluate NJ gross income (`nj_agi`) rather than federal AGI. +- Restrict subtractions and eligibility income calculations in DC, IN, PA, and WI to tax unit filers to prevent dependent income leakage, leaving out dependents' military amounts, PA dependents' alimony and tax-exempt interest, and WI dependents' state and local tax refunds. +- Update variable docstrings and references referencing IRC § 61(a)(10) and IRS Pubs 525/575. diff --git a/policyengine_us/parameters/gov/household/market_income_sources.yaml b/policyengine_us/parameters/gov/household/market_income_sources.yaml index b5c78f13734..bbf4153f1ca 100644 --- a/policyengine_us/parameters/gov/household/market_income_sources.yaml +++ b/policyengine_us/parameters/gov/household/market_income_sources.yaml @@ -15,6 +15,7 @@ values: - dividend_income - pension_income # Pension income includes annuities and endowment contracts + - military_retirement_income - debt_relief # Income from estates and trusts (Schedule E Part III), including income # in respect of a decedent received through an estate or trust. diff --git a/policyengine_us/parameters/gov/irs/gross_income/sources.yaml b/policyengine_us/parameters/gov/irs/gross_income/sources.yaml index d00f3b45950..69b959c1392 100644 --- a/policyengine_us/parameters/gov/irs/gross_income/sources.yaml +++ b/policyengine_us/parameters/gov/irs/gross_income/sources.yaml @@ -43,6 +43,9 @@ values: - taxable_alimony_income # Taxable state and local income tax refunds (Schedule 1 line 1 / IRC § 111). - salt_refund_income + # Military retirement pay and survivor benefit plan payments (IRC § 61, Form 1040 line 5b). + - military_retirement_income + metadata: unit: list diff --git a/policyengine_us/parameters/gov/ssa/ssi/income/sources/unearned.yaml b/policyengine_us/parameters/gov/ssa/ssi/income/sources/unearned.yaml index 31f8890c835..1d03fba2fd0 100644 --- a/policyengine_us/parameters/gov/ssa/ssi/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/ssa/ssi/income/sources/unearned.yaml @@ -10,6 +10,7 @@ values: - workers_compensation - total_unemployment_compensation - retirement_distributions + - military_retirement_income - gi_cash_assistance # (b) Alimony and support payments. - alimony_income diff --git a/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/individual.yaml b/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/individual.yaml index dd19f3cbf61..c92bd783ea2 100644 --- a/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/individual.yaml +++ b/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/individual.yaml @@ -15,7 +15,7 @@ values: - ar_taxable_capital_gains_indiv # Line 14 - taxable_ira_distributions # Line 16, or Lines 17A/17B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 17A/17B after age 59 1/2 - - military_retirement_pay # Line 17A/17B + - military_retirement_income # Line 17A/17B - taxable_pension_income # Line 17A/17B - taxable_disability_benefits # Line 17A/17B - rental_income # Line 18 @@ -41,7 +41,7 @@ values: - ar_taxable_capital_gains_indiv # Line 14 - taxable_ira_distributions # Line 16, or Lines 18A/18B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 18A/18B after age 59 1/2 - - military_retirement_pay # Line 17 (Lines 17A/17B on the 2018 form) + - military_retirement_income # Line 17 (Lines 17A/17B on the 2018 form) - taxable_pension_income # Line 18A/18B - taxable_disability_benefits # Line 18A/18B - rental_income # Line 19 @@ -61,7 +61,7 @@ values: - ar_taxable_capital_gains_indiv # Line 14 - taxable_ira_distributions # Line 16, or Lines 18A/18B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 18A/18B after age 59 1/2 - - military_retirement_pay # Line 17 + - military_retirement_income # Line 17 - taxable_pension_income # Line 18A/18B - taxable_disability_benefits # Line 18A/18B - rental_income # Line 19 @@ -80,7 +80,8 @@ values: - ar_taxable_capital_gains_indiv # Line 14 - taxable_ira_distributions # Line 16, or Lines 18A/18B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 18A/18B after age 59 1/2 - - military_retirement_pay # Line 17 + - military_retirement_income # Line 17 + - taxable_pension_income # Line 18A/18B - taxable_401k_distributions # Line 18A/18B - taxable_403b_distributions # Line 18A/18B diff --git a/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/joint.yaml b/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/joint.yaml index 811fe325ed5..ee92a779489 100644 --- a/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/joint.yaml +++ b/policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/joint.yaml @@ -15,7 +15,7 @@ values: - ar_taxable_capital_gains_joint # Line 14 - taxable_ira_distributions # Line 16, or Lines 17A/17B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 17A/17B after age 59 1/2 - - military_retirement_pay # Line 17A/17B + - military_retirement_income # Line 17A/17B - taxable_pension_income # Line 17A/17B - taxable_disability_benefits # Line 17A/17B - rental_income # Line 18 @@ -41,7 +41,7 @@ values: - ar_taxable_capital_gains_joint # Line 14 - taxable_ira_distributions # Line 16, or Lines 18A/18B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 18A/18B after age 59 1/2 - - military_retirement_pay # Line 17 (Lines 17A/17B on the 2018 form) + - military_retirement_income # Line 17 (Lines 17A/17B on the 2018 form) - taxable_pension_income # Line 18A/18B - taxable_disability_benefits # Line 18A/18B - rental_income # Line 19 @@ -61,7 +61,7 @@ values: - ar_taxable_capital_gains_joint # Line 14 - taxable_ira_distributions # Line 16, or Lines 18A/18B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 18A/18B after age 59 1/2 - - military_retirement_pay # Line 17 + - military_retirement_income # Line 17 - taxable_pension_income # Line 18A/18B - taxable_disability_benefits # Line 18A/18B - rental_income # Line 19 @@ -80,7 +80,8 @@ values: - ar_taxable_capital_gains_joint # Line 14 - taxable_ira_distributions # Line 16, or Lines 18A/18B after age 59 1/2 - taxable_roth_conversions # Line 16, or Lines 18A/18B after age 59 1/2 - - military_retirement_pay # Line 17 + - military_retirement_income # Line 17 + - taxable_pension_income # Line 18A/18B - taxable_401k_distributions # Line 18A/18B - taxable_403b_distributions # Line 18A/18B diff --git a/policyengine_us/parameters/gov/states/ca/tax/income/agi/military_retirement/agi_limit.yaml b/policyengine_us/parameters/gov/states/ca/tax/income/agi/military_retirement/agi_limit.yaml new file mode 100644 index 00000000000..7aab06e675f --- /dev/null +++ b/policyengine_us/parameters/gov/states/ca/tax/income/agi/military_retirement/agi_limit.yaml @@ -0,0 +1,38 @@ +description: California limits the military retirement and survivor benefit exclusion to filers with federal adjusted gross income at or below this amount, by filing status. +metadata: + unit: currency-USD + period: year + label: California military retirement and survivor benefit exclusion federal AGI limit + breakdown: + - filing_status + reference: + - title: Cal. Rev. & Tax. Code § 17132.9 + href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?sectionNum=17132.9.&lawCode=RTC + - title: Cal. Rev. & Tax. Code § 17132.10 + href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?sectionNum=17132.10.&lawCode=RTC + +SINGLE: + values: + 2021-01-01: 0 + 2025-01-01: 125_000 + 2030-01-01: 0 +JOINT: + values: + 2021-01-01: 0 + 2025-01-01: 250_000 + 2030-01-01: 0 +SEPARATE: + values: + 2021-01-01: 0 + 2025-01-01: 125_000 + 2030-01-01: 0 +HEAD_OF_HOUSEHOLD: + values: + 2021-01-01: 0 + 2025-01-01: 125_000 + 2030-01-01: 0 +SURVIVING_SPOUSE: + values: + 2021-01-01: 0 + 2025-01-01: 250_000 + 2030-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/ca/tax/income/agi/military_retirement/cap.yaml b/policyengine_us/parameters/gov/states/ca/tax/income/agi/military_retirement/cap.yaml new file mode 100644 index 00000000000..d3b86cb9841 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ca/tax/income/agi/military_retirement/cap.yaml @@ -0,0 +1,14 @@ +description: California caps the military retirement and survivor benefit exclusion at this amount per benefit category per return. +values: + 2021-01-01: 0 + 2025-01-01: 20_000 + 2030-01-01: 0 +metadata: + unit: currency-USD + period: year + label: California military retirement and survivor benefit exclusion cap + reference: + - title: Cal. Rev. & Tax. Code § 17132.9 + href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?sectionNum=17132.9.&lawCode=RTC + - title: Cal. Rev. & Tax. Code § 17132.10 + href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?sectionNum=17132.10.&lawCode=RTC diff --git a/policyengine_us/parameters/gov/states/ca/tax/income/agi/subtractions.yaml b/policyengine_us/parameters/gov/states/ca/tax/income/agi/subtractions.yaml index 85795b1a728..13260aaa4b0 100644 --- a/policyengine_us/parameters/gov/states/ca/tax/income/agi/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/ca/tax/income/agi/subtractions.yaml @@ -6,6 +6,13 @@ values: - us_govt_interest - salt_refund_income - ca_other_subtractions + 2025-01-01: + - taxable_social_security + - taxable_unemployment_compensation + - us_govt_interest + - salt_refund_income + - ca_military_retirement_exclusion + - ca_other_subtractions metadata: reference: diff --git a/policyengine_us/parameters/gov/states/co/tax/income/subtractions/pension/income_sources.yaml b/policyengine_us/parameters/gov/states/co/tax/income/subtractions/pension/income_sources.yaml index 073b63b2e52..4ba4d3f6e29 100644 --- a/policyengine_us/parameters/gov/states/co/tax/income/subtractions/pension/income_sources.yaml +++ b/policyengine_us/parameters/gov/states/co/tax/income/subtractions/pension/income_sources.yaml @@ -10,6 +10,7 @@ values: - keogh_distributions - taxable_roth_conversions - taxable_disability_benefits + - military_retirement_income # In 2022 the taxable social security is calculated separately. 2022-01-01: - taxable_pension_income @@ -20,6 +21,7 @@ values: - keogh_distributions - taxable_roth_conversions - taxable_disability_benefits + - military_retirement_income metadata: period: year unit: list diff --git a/policyengine_us/parameters/gov/states/ct/tax/income/subtractions/subtractions.yaml b/policyengine_us/parameters/gov/states/ct/tax/income/subtractions/subtractions.yaml index aea3a9f1f80..09d95c01cfc 100644 --- a/policyengine_us/parameters/gov/states/ct/tax/income/subtractions/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/ct/tax/income/subtractions/subtractions.yaml @@ -3,7 +3,8 @@ values: 2021-01-01: - us_govt_interest #ln 39 - ct_social_security_benefit_adjustment #ln 41 - - military_retirement_pay #ln 44 + - military_retirement_income #ln 44 + - ct_pension_annuity_subtraction #ln 48b - salt_refund_income #ln 38 diff --git a/policyengine_us/parameters/gov/states/dc/tax/income/subtractions/sources.yaml b/policyengine_us/parameters/gov/states/dc/tax/income/subtractions/sources.yaml index 8ba9d6dafad..0769b131ae3 100644 --- a/policyengine_us/parameters/gov/states/dc/tax/income/subtractions/sources.yaml +++ b/policyengine_us/parameters/gov/states/dc/tax/income/subtractions/sources.yaml @@ -21,3 +21,4 @@ values: - dc_disability_exclusion - us_govt_interest_person - salt_refund_income + - dc_survivor_benefits_subtraction diff --git a/policyengine_us/parameters/gov/states/dc/tax/income/subtractions/survivor_benefits/min_age.yaml b/policyengine_us/parameters/gov/states/dc/tax/income/subtractions/survivor_benefits/min_age.yaml new file mode 100644 index 00000000000..3c9930c9512 --- /dev/null +++ b/policyengine_us/parameters/gov/states/dc/tax/income/subtractions/survivor_benefits/min_age.yaml @@ -0,0 +1,10 @@ +description: District of Columbia limits the government survivor benefit exclusion to individuals who have reached at least this age by the end of the tax year. +values: + 2015-01-01: 62 +metadata: + label: DC minimum age for survivor benefits exclusion + unit: year + period: year + reference: + - title: D.C. Code § 47-1803.02(a)(2)(N)(ii) + href: https://code.dccouncil.gov/us/dc/council/code/sections/47-1803.02 diff --git a/policyengine_us/parameters/gov/states/de/tax/income/subtractions/exclusions/pension/income_sources.yaml b/policyengine_us/parameters/gov/states/de/tax/income/subtractions/exclusions/pension/income_sources.yaml index 68d01d3af09..74344c13e5e 100644 --- a/policyengine_us/parameters/gov/states/de/tax/income/subtractions/exclusions/pension/income_sources.yaml +++ b/policyengine_us/parameters/gov/states/de/tax/income/subtractions/exclusions/pension/income_sources.yaml @@ -6,6 +6,7 @@ values: - taxable_interest_income - rental_income - taxable_pension_income + - military_retirement_income - taxable_ira_distributions - taxable_401k_distributions - taxable_403b_distributions diff --git a/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/additional/amount.yaml b/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/additional/amount.yaml index 614e99cab0c..5461deca436 100644 --- a/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/additional/amount.yaml +++ b/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/additional/amount.yaml @@ -14,4 +14,5 @@ metadata: - title: 2025 IT-511 Individual Income Tax Booklet - Subtractions(2) href: https://dor.georgia.gov/document/document/2025-it-511-individual-income-tax-booklet/download#page=21 values: + 2021-01-01: 0 2022-01-01: 17_500 diff --git a/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/base.yaml b/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/base.yaml index f6204c1ae37..85a779bd1d5 100644 --- a/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/base.yaml +++ b/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/military_retirement/base.yaml @@ -14,4 +14,5 @@ metadata: - title: 2025 IT-511 Individual Income Tax Booklet - Subtractions(2) href: https://dor.georgia.gov/document/document/2025-it-511-individual-income-tax-booklet/download#page=21 values: + 2021-01-01: 0 2022-01-01: 17_500 diff --git a/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/retirement/sources.yaml b/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/retirement/sources.yaml index b40bfa87e32..a8ad771452e 100644 --- a/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/retirement/sources.yaml +++ b/policyengine_us/parameters/gov/states/ga/tax/income/agi/exclusions/retirement/sources.yaml @@ -28,3 +28,4 @@ values: - taxable_sep_distributions - keogh_distributions - taxable_roth_conversions + - military_retirement_pay_survivors diff --git a/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/subtractions.yaml b/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/subtractions.yaml index 241ecdea1a0..0d109beb922 100644 --- a/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/hi/tax/income/subtractions/subtractions.yaml @@ -2,12 +2,14 @@ description: Hawaii subtracts these sources from adjusted gross income. values: 2021-01-01: - taxable_pension_income # Line 13 + - military_retirement_income # Line 13 - taxable_social_security # Line 14 - hi_military_pay_exclusion # Line 15 - us_govt_interest # Line 18 - student_loan_interest_ald # Line 18 2025-01-01: - taxable_pension_income # Line 13 + - military_retirement_income # Line 13 - taxable_social_security # Line 14 - hi_military_pay_exclusion # Line 15 - us_govt_interest # Line 18 diff --git a/policyengine_us/parameters/gov/states/ia/tax/income/taxable_income/subtractions.yaml b/policyengine_us/parameters/gov/states/ia/tax/income/taxable_income/subtractions.yaml index 489df1799ab..2d9bbf5a97b 100644 --- a/policyengine_us/parameters/gov/states/ia/tax/income/taxable_income/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/ia/tax/income/taxable_income/subtractions.yaml @@ -1,28 +1,11 @@ description: Iowa subtracts these sources from taxable income on and after 2023. values: 2021-01-01: - # Line 1B - - us_govt_interest - # Dividends from federal securities - # Line 5B - - taxable_social_security - # Line 6B - - military_service_income - # Line 7B - - ia_pension_exclusion - # Railroad unemployment income - # Bonus Depreciation - # Iowa Health Insurance Deduction - # Iowa capital gains deduction - - ia_529_plan_subtraction - # Schedule 1 line 19b, code h (IA 2440) - - ia_disability_income_exclusion - 2024-01-01: # military_retirement_pay added in 2024. # Line 1B - us_govt_interest # Dividends from federal securities # Line 4B - - military_retirement_pay + - military_retirement_income # Line 5B - taxable_social_security # Line 6B diff --git a/policyengine_us/parameters/gov/states/id/tax/income/deductions/retirement_benefits/income_sources.yaml b/policyengine_us/parameters/gov/states/id/tax/income/deductions/retirement_benefits/income_sources.yaml index 156089394b4..e640086326a 100644 --- a/policyengine_us/parameters/gov/states/id/tax/income/deductions/retirement_benefits/income_sources.yaml +++ b/policyengine_us/parameters/gov/states/id/tax/income/deductions/retirement_benefits/income_sources.yaml @@ -2,7 +2,8 @@ description: Idaho counts the following income sources under the retirement bene values: 2021-01-01: - public_pension_income - - military_retirement_pay + - military_retirement_income + 2025-01-01: - public_pension_income metadata: diff --git a/policyengine_us/parameters/gov/states/il/tax/income/base/subtractions.yaml b/policyengine_us/parameters/gov/states/il/tax/income/base/subtractions.yaml index 0ec538b1f97..d5b497a05b3 100644 --- a/policyengine_us/parameters/gov/states/il/tax/income/base/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/il/tax/income/base/subtractions.yaml @@ -6,6 +6,7 @@ values: - taxable_pension_income - taxable_retirement_distributions - taxable_roth_conversions + - military_retirement_income - il_schedule_m_subtractions - il_529_plan_subtraction - salt_refund_income diff --git a/policyengine_us/parameters/gov/states/in/tax/income/deductions/deductions.yaml b/policyengine_us/parameters/gov/states/in/tax/income/deductions/deductions.yaml index 6727676faf2..f451e4b6ee0 100644 --- a/policyengine_us/parameters/gov/states/in/tax/income/deductions/deductions.yaml +++ b/policyengine_us/parameters/gov/states/in/tax/income/deductions/deductions.yaml @@ -13,6 +13,7 @@ values: - in_other_deductions - in_disability_retirement_deduction # IC 6-3-2-9 (code 602) - in_civil_service_annuity_deduction + - in_military_retirement_deduction 2023-01-01: # IC 6-3-2-6 @@ -41,6 +42,8 @@ values: - military_basic_pay # IC 6-3-2-3.7 - in_civil_service_annuity_deduction + # IC 6-3-2-4(a) + - in_military_retirement_deduction 2024-01-01: # IC 6-3-2-6 @@ -71,6 +74,8 @@ values: - in_healthcare_sharing_deduction # IC 6-3-2-3.7 - in_civil_service_annuity_deduction + # IC 6-3-2-4(a) + - in_military_retirement_deduction 2026-01-01: # IC 6-3-2-6 @@ -107,6 +112,8 @@ values: - in_auto_loan_interest_deduction # IC 6-3-2-3.7 - in_civil_service_annuity_deduction + # IC 6-3-2-4(a) + - in_military_retirement_deduction 2027-01-01: # IC 6-3-2-6 @@ -137,6 +144,8 @@ values: - in_healthcare_sharing_deduction # IC 6-3-2-3.7 - in_civil_service_annuity_deduction + # IC 6-3-2-4(a) + - in_military_retirement_deduction metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/in/tax/income/deductions/military_retirement/base.yaml b/policyengine_us/parameters/gov/states/in/tax/income/deductions/military_retirement/base.yaml new file mode 100644 index 00000000000..d540ef0ab04 --- /dev/null +++ b/policyengine_us/parameters/gov/states/in/tax/income/deductions/military_retirement/base.yaml @@ -0,0 +1,10 @@ +description: Indiana deducts up to this base amount of military retirement pay or survivor benefits. +values: + 2021-01-01: 6_250 +metadata: + label: Indiana military retirement deduction base amount + unit: currency-USD + period: year + reference: + - title: IC 6-3-2-4 + href: http://iga.in.gov/legislative/laws/2021/ic/titles/006#6-3-2-4 diff --git a/policyengine_us/parameters/gov/states/in/tax/income/deductions/military_retirement/excess_rate.yaml b/policyengine_us/parameters/gov/states/in/tax/income/deductions/military_retirement/excess_rate.yaml new file mode 100644 index 00000000000..74d36422834 --- /dev/null +++ b/policyengine_us/parameters/gov/states/in/tax/income/deductions/military_retirement/excess_rate.yaml @@ -0,0 +1,11 @@ +description: Indiana applies this deduction rate to military retirement benefits exceeding the base amount. +values: + 2021-01-01: 0.75 + 2022-01-01: 1 +metadata: + label: Indiana military retirement deduction excess rate + unit: /1 + period: year + reference: + - title: IC 6-3-2-4 + href: http://iga.in.gov/legislative/laws/2021/ic/titles/006#6-3-2-4 diff --git a/policyengine_us/parameters/gov/states/la/tax/income/exempt_income/sources.yaml b/policyengine_us/parameters/gov/states/la/tax/income/exempt_income/sources.yaml index 4c013831a8e..25639a27ac3 100644 --- a/policyengine_us/parameters/gov/states/la/tax/income/exempt_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/la/tax/income/exempt_income/sources.yaml @@ -4,7 +4,8 @@ values: - us_govt_interest # 01E # Louisiana State Employees’ Retirement Benefits 02E # Louisiana State Teachers’ Retirement Benefits 03E - - military_retirement_pay # 04E + - military_retirement_income # 04E + # Other Retirement Benefits 05E (federal civil service, municipal, etc.) # Proxy note: Schedule E exempts specific Louisiana state/municipal systems and federal # retirement systems (codes 02E, 03E, 05E). Out-of-state public pensions are not exempt. diff --git a/policyengine_us/parameters/gov/states/ma/tax/income/credits/senior_circuit_breaker/income/disallowed_deductions.yaml b/policyengine_us/parameters/gov/states/ma/tax/income/credits/senior_circuit_breaker/income/disallowed_deductions.yaml index 51a91ae417a..879ff14cb15 100644 --- a/policyengine_us/parameters/gov/states/ma/tax/income/credits/senior_circuit_breaker/income/disallowed_deductions.yaml +++ b/policyengine_us/parameters/gov/states/ma/tax/income/credits/senior_circuit_breaker/income/disallowed_deductions.yaml @@ -29,6 +29,7 @@ values: - ssi - ma_state_supplement - tanf + - military_retirement_income # In-kind under § 6(k)(1) item 2; see the note above before re-enabling. # - snap # - wic diff --git a/policyengine_us/parameters/gov/states/mi/tax/income/subtractions.yaml b/policyengine_us/parameters/gov/states/mi/tax/income/subtractions.yaml index 62d9a981878..7c40eb6b0c4 100644 --- a/policyengine_us/parameters/gov/states/mi/tax/income/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/mi/tax/income/subtractions.yaml @@ -2,7 +2,7 @@ description: Michigan subtracts these sources to federal adjusted gross income w values: 2017-01-01: - us_govt_interest # Line 10 - - military_retirement_pay # Line 11 + - military_retirement_income # Line 11 - taxable_social_security # Line 14 - military_service_income # Line 14 - section_22_income # Line 22 @@ -13,7 +13,8 @@ values: - salt_refund_income # Line 16 2026-01-01: - us_govt_interest # Line 10 - - military_retirement_pay # Line 11 + - military_retirement_income # Line 11 + - taxable_social_security # Line 14 - military_service_income # Line 14 - section_22_income # Line 22 diff --git a/policyengine_us/parameters/gov/states/mo/tax/income/subtractions/agi_subtractions.yaml b/policyengine_us/parameters/gov/states/mo/tax/income/subtractions/agi_subtractions.yaml index 9d81d585c0c..ed68d518c76 100644 --- a/policyengine_us/parameters/gov/states/mo/tax/income/subtractions/agi_subtractions.yaml +++ b/policyengine_us/parameters/gov/states/mo/tax/income/subtractions/agi_subtractions.yaml @@ -5,12 +5,14 @@ values: - us_govt_interest_person - mo_529_deduction - salt_refund_income # 143.121 RSMo / Form MO-A Line 9 + - military_retirement_pay # 143.121.3(12) RSMo / Form MO-A Line 10 2025-01-01: - mo_qualified_health_insurance_premiums - mo_capital_gains_subtraction_person - us_govt_interest_person - mo_529_deduction - salt_refund_income # 143.121 RSMo / Form MO-A Line 9 + - military_retirement_pay # 143.121.3(12) RSMo / Form MO-A Line 10 metadata: diff --git a/policyengine_us/parameters/gov/states/mt/tax/income/subtractions/subtractions.yaml b/policyengine_us/parameters/gov/states/mt/tax/income/subtractions/subtractions.yaml index af01c8b5b55..b65aa2ced80 100644 --- a/policyengine_us/parameters/gov/states/mt/tax/income/subtractions/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/mt/tax/income/subtractions/subtractions.yaml @@ -13,6 +13,9 @@ values: - mt_unemployment_compensation_subtraction - salt_refund_income # Form 2 Subtractions Schedule 2024-01-01: + # MCA 15-30-2120(3)(n) allows exempting up to 50% of military retirement pay + # (capped at MT earned income, (3)(n)(i)) and up to 50% of military survivor + # benefits regardless of other income ((3)(n)(ii), Form WMRE); not yet modeled. - mt_interest_exemption_person - mt_tuition_subtraction_person - mt_old_age_subtraction diff --git a/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/sources.yaml b/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/sources.yaml index b4baa1b3a2c..20e4b919f9f 100644 --- a/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/sources.yaml +++ b/policyengine_us/parameters/gov/states/nd/tax/income/taxable_income/subtractions/sources.yaml @@ -5,7 +5,7 @@ values: - nd_ltcg_subtraction # long-term capital gains - nd_qdiv_subtraction # qualified dividends - taxable_social_security - - military_retirement_pay + - military_retirement_income - nd_529_deduction - nd_stillborn_subtraction @@ -14,7 +14,7 @@ values: - nd_ltcg_subtraction # long-term capital gains - nd_qdiv_subtraction # qualified dividends - taxable_social_security - - military_retirement_pay + - military_retirement_income - nd_529_deduction - nd_stillborn_subtraction @@ -23,11 +23,12 @@ values: - nd_ltcg_subtraction # long-term capital gains - nd_qdiv_subtraction # qualified dividends - taxable_social_security - - military_retirement_pay + - military_retirement_income - military_service_income # military pay exclusion - nd_529_deduction - nd_stillborn_subtraction + metadata: unit: list period: year diff --git a/policyengine_us/parameters/gov/states/ne/tax/income/agi/subtractions/military_retirement/survivors_eligible.yaml b/policyengine_us/parameters/gov/states/ne/tax/income/agi/subtractions/military_retirement/survivors_eligible.yaml new file mode 100644 index 00000000000..9f4ee7d3302 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ne/tax/income/agi/subtractions/military_retirement/survivors_eligible.yaml @@ -0,0 +1,16 @@ +description: Nebraska includes military retirement survivor benefit payments in the military retirement subtraction starting in tax year 2022. +values: + 2015-01-01: false + 2022-01-01: true + +metadata: + label: Nebraska military retirement survivor benefits eligible + unit: bool + period: year + reference: + - title: Neb. Rev. Stat. § 77-2716(15) + href: https://nebraskalegislature.gov/laws/statutes.php?statute=77-2716 + - title: Form 1040N-MIL + href: https://revenue.nebraska.gov/sites/default/files/doc/f_1040n_mil.pdf#page=2 + - title: Nebraska Information Guide 8-364 + href: https://revenue.nebraska.gov/sites/default/files/doc/info/8-364.pdf#page=2 diff --git a/policyengine_us/parameters/gov/states/nj/tax/income/deductions/plan_529_contributions/income_limit.yaml b/policyengine_us/parameters/gov/states/nj/tax/income/deductions/plan_529_contributions/income_limit.yaml index 16ec3dd42f1..7212ce08dfa 100644 --- a/policyengine_us/parameters/gov/states/nj/tax/income/deductions/plan_529_contributions/income_limit.yaml +++ b/policyengine_us/parameters/gov/states/nj/tax/income/deductions/plan_529_contributions/income_limit.yaml @@ -1,6 +1,7 @@ -description: New Jersey limits the 529 plan contribution deduction to taxpayers with adjusted gross income at or below this amount. +description: New Jersey limits the 529 plan contribution deduction to taxpayers with gross income at or below this amount. metadata: - label: New Jersey 529 plan contribution deduction AGI limit + label: New Jersey 529 plan contribution deduction income limit + period: year unit: currency-USD reference: diff --git a/policyengine_us/parameters/gov/states/ny/tax/income/agi/subtractions/sources.yaml b/policyengine_us/parameters/gov/states/ny/tax/income/agi/subtractions/sources.yaml index e4c4eb10cd9..30ced102407 100644 --- a/policyengine_us/parameters/gov/states/ny/tax/income/agi/subtractions/sources.yaml +++ b/policyengine_us/parameters/gov/states/ny/tax/income/agi/subtractions/sources.yaml @@ -12,6 +12,7 @@ values: # local governments, or the federal government. Pensions from other states are not exempt. # PolicyEngine subtracts taxable_public_pension_income as an in-state/federal proxy. - taxable_public_pension_income + - military_retirement_income - ny_other_subtractions metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/pa/tax/income/forgiveness/eligibility_income_sources.yaml b/policyengine_us/parameters/gov/states/pa/tax/income/forgiveness/eligibility_income_sources.yaml index dc17bfc0a77..1e6f936e1f2 100644 --- a/policyengine_us/parameters/gov/states/pa/tax/income/forgiveness/eligibility_income_sources.yaml +++ b/policyengine_us/parameters/gov/states/pa/tax/income/forgiveness/eligibility_income_sources.yaml @@ -5,10 +5,11 @@ values: - alimony_income - tax_exempt_interest_income # non-taxable dividends and gains - # insurance proceeds and inheritances + # insurance proceeds and inheritances (Schedule SP line 4, includes survivor annuities) + - military_retirement_pay_survivors # gifts awards and prizes # non-PA income - # nontaxable military income + # nontaxable military income (military pension benefits excluded per PA-40 SP) # gain excluded from the sale of a residence # nontaxable education assistance # cash received for personal use outside your home diff --git a/policyengine_us/parameters/gov/states/pa/tax/income/nontaxable_income_sources.yaml b/policyengine_us/parameters/gov/states/pa/tax/income/nontaxable_income_sources.yaml index c129e29d75c..4f20466d5ad 100644 --- a/policyengine_us/parameters/gov/states/pa/tax/income/nontaxable_income_sources.yaml +++ b/policyengine_us/parameters/gov/states/pa/tax/income/nontaxable_income_sources.yaml @@ -8,6 +8,7 @@ values: - taxable_social_security - us_govt_interest - salt_refund_income + - military_retirement_income # Sick pay and disability benefits other than regular wages, including # third-party insurer payments, and disability distributions (61 Pa. # Code 101.6(c)(1)). Regular sick leave pay is in employment income. diff --git a/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/subtractions.yaml b/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/subtractions.yaml index 702508f7f68..ede4ccf4897 100644 --- a/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/subtractions.yaml @@ -12,7 +12,8 @@ values: - ri_tuition_saving_program_contribution_subtraction - ri_retirement_income_subtraction - us_govt_interest - - military_retirement_pay + - military_retirement_income + metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/sources.yaml b/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/sources.yaml index 07b706da34b..b9e9db7b587 100644 --- a/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/sources.yaml +++ b/policyengine_us/parameters/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/sources.yaml @@ -1,6 +1,11 @@ description: Rhode Island subtracts these retirement income sources from adjusted gross income under the individual income tax retirement income subtraction program. values: 2021-01-01: + - taxable_pension_income + - military_retirement_income + - taxable_401k_distributions + - taxable_403b_distributions + 2023-01-01: - taxable_pension_income - taxable_401k_distributions - taxable_403b_distributions diff --git a/policyengine_us/parameters/gov/states/wi/tax/income/subtractions/sources.yaml b/policyengine_us/parameters/gov/states/wi/tax/income/subtractions/sources.yaml index 9da38e69a4b..52608104212 100644 --- a/policyengine_us/parameters/gov/states/wi/tax/income/subtractions/sources.yaml +++ b/policyengine_us/parameters/gov/states/wi/tax/income/subtractions/sources.yaml @@ -6,6 +6,7 @@ values: - wi_capital_gain_loss_subtraction - wi_childcare_expense_subtraction - wi_retirement_income_subtraction + - military_retirement_income - us_govt_interest - wi_529_plan_deduction - salt_refund_income @@ -15,6 +16,7 @@ values: - tax_unit_taxable_social_security - wi_capital_gain_loss_subtraction - wi_retirement_income_subtraction + - military_retirement_income - us_govt_interest - wi_529_plan_deduction - salt_refund_income diff --git a/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/senior_citizen_disability_deduction/modification_sources.yaml b/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/senior_citizen_disability_deduction/modification_sources.yaml index 2d33df6161d..91c9f91fbe1 100644 --- a/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/senior_citizen_disability_deduction/modification_sources.yaml +++ b/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/senior_citizen_disability_deduction/modification_sources.yaml @@ -8,7 +8,8 @@ values: - us_govt_interest_person # Line 27 # certain federal law enforcement retirement Line 28 # West Virginia state or local police, deputy sheriff's or firemen's retirement Line 29 - - military_retirement_pay # Line 30 + - military_retirement_income # Line 30 + - wv_public_pension_subtraction_person # Line 31 - wv_social_security_benefits_subtraction_person # Line 32 diff --git a/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/subtractions.yaml b/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/subtractions.yaml index a3fe563b8fb..105706385bb 100644 --- a/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/subtractions.yaml +++ b/policyengine_us/parameters/gov/states/wv/tax/income/subtractions/subtractions.yaml @@ -2,8 +2,9 @@ description: West Virginia subtracts these sources from adjusted gross income. values: 2021-01-01: - us_govt_interest # Line 27 - - military_retirement_pay # Line 30 + - military_retirement_income # Line 30 - wv_public_pension_subtraction # Line 31 + - wv_social_security_benefits_subtraction # Line 32 - military_service_income # Line 34 - salt_refund_income # Line 36 diff --git a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml index 9484a2a732b..3bd809dbd21 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -68,6 +68,7 @@ values: - social_security - survivor_benefits - retirement_distributions + - military_retirement_income # Assume all rental income meets this criteria (rest is earned): # "gross income minus the cost of doing business derived from rental # property in which a household member is not actively engaged in the diff --git a/policyengine_us/tests/code_health/test_ar_gross_income_source_line_comments.py b/policyengine_us/tests/code_health/test_ar_gross_income_source_line_comments.py index c4715375f0c..1d31d0d74ee 100644 --- a/policyengine_us/tests/code_health/test_ar_gross_income_source_line_comments.py +++ b/policyengine_us/tests/code_health/test_ar_gross_income_source_line_comments.py @@ -45,7 +45,7 @@ "ar_taxable_capital_gains": "14", "taxable_ira_distributions": "16", "taxable_roth_conversions": "16", - "military_retirement_pay": "17A/17B", + "military_retirement_income": "17A/17B", "taxable_pension_income": "17A/17B", "taxable_disability_benefits": "17A/17B", "rental_income": "18", @@ -66,7 +66,7 @@ "ar_taxable_capital_gains": "14", "taxable_ira_distributions": "16", "taxable_roth_conversions": "16", - "military_retirement_pay": "17", + "military_retirement_income": "17", "taxable_pension_income": "18A/18B", "taxable_401k_distributions": "18A/18B", "taxable_403b_distributions": "18A/18B", diff --git a/policyengine_us/tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/irs_gross_income/military_retirement_pay.yaml b/policyengine_us/tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/irs_gross_income/military_retirement_pay.yaml new file mode 100644 index 00000000000..befdc3853b7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/irs_gross_income/military_retirement_pay.yaml @@ -0,0 +1,106 @@ +# IRC § 61(a)(10) includes pensions, including military retirement pay and +# military retirement survivor benefit payments, in gross income. +# See IRS Publication 525 (Taxable and Nontaxable Income) and +# IRS Publication 575 (Pension and Annuity Income). +# Military retirement pay is also market income, SNAP unearned income, +# and SSI unearned income. + +- name: Case 1, Military retirement pay flows into federal gross income, AGI, and taxable income. + period: 2024 + input: + people: + person1: + age: 55 + is_tax_unit_head: true + military_retirement_pay: 30_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: TX + output: + irs_gross_income: 30_000 + adjusted_gross_income: 30_000 + taxable_income: 30_000 - 14_600 + market_income: 30_000 + household_market_income: 30_000 + snap_unearned_income: 30_000 + ssi_unearned_income: 30_000 + household_net_income: 28_384 + +- name: Case 2, Military retirement pay survivors flows into federal gross income, AGI, and taxable income. + period: 2024 + input: + people: + person1: + age: 55 + is_tax_unit_head: true + military_retirement_pay_survivors: 24_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: TX + output: + irs_gross_income: 24_000 + adjusted_gross_income: 24_000 + taxable_income: 24_000 - 14_600 + market_income: 24_000 + household_market_income: 24_000 + snap_unearned_income: 24_000 + ssi_unearned_income: 24_000 + +- name: Case 3, Military retirement pay adds with employment income. + period: 2024 + input: + people: + person1: + age: 50 + is_tax_unit_head: true + employment_income: 40_000 + military_retirement_pay: 20_000 + military_retirement_pay_survivors: 10_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: TX + output: + irs_gross_income: 70_000 + adjusted_gross_income: 70_000 + taxable_income: 70_000 - 14_600 + market_income: 70_000 + household_market_income: 70_000 + household_net_income: 59_699 + +- name: Case 4, Dependent military retirement pay is excluded from the tax unit filer gross income. + period: 2024 + input: + people: + person1: + age: 45 + is_tax_unit_head: true + employment_income: 50_000 + person2: + age: 18 + is_tax_unit_dependent: true + military_retirement_pay_survivors: 15_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: TX + output: + irs_gross_income: [50_000, 0] + adjusted_gross_income: 50_000 + taxable_income: 50_000 - 21_900 + market_income: [50_000, 15_000] + household_market_income: 65_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/ca_military_retirement_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/ca_military_retirement_exclusion.yaml new file mode 100644 index 00000000000..344620e71d5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/ca_military_retirement_exclusion.yaml @@ -0,0 +1,100 @@ +- name: Military retirement pay and SBP exclusion under R&TC §§ 17132.9 and 17132.10 (2025) + period: 2025 + input: + military_retirement_pay: 50_000 + military_retirement_pay_survivors: 10_000 + state_code: CA + output: + ca_military_retirement_exclusion: 20_000 + 10_000 + +- name: CA AGI cliff at $125,000 (excludes when AGI does not exceed limit) + period: 2025 + input: + state_code: CA + employment_income: 105_000 + military_retirement_pay: 20_000 + output: + ca_military_retirement_exclusion: 20_000 + +- name: CA AGI cliff at $125,001 (cliff denies exclusion when AGI exceeds limit) + period: 2025 + input: + state_code: CA + employment_income: 105_001 + military_retirement_pay: 20_000 + output: + ca_military_retirement_exclusion: 0 + +- name: CA joint return at $250,000 AGI limit + period: 2025 + input: + people: + head: + is_tax_unit_head: true + employment_income: 100_000 + military_retirement_pay: 25_000 + spouse: + is_tax_unit_spouse: true + employment_income: 100_000 + military_retirement_pay: 25_000 + tax_units: + tax_unit: + members: [head, spouse] + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: CA + output: + ca_military_retirement_exclusion: 20_000 + +- name: CA dependent recipient does not generate exclusion on filer return + period: 2025 + input: + people: + head: + is_tax_unit_head: true + employment_income: 50_000 + dependent: + is_tax_unit_dependent: true + military_retirement_pay: 20_000 + tax_units: + tax_unit: + members: [head, dependent] + households: + household: + members: [head, dependent] + state_code: CA + output: + ca_military_retirement_exclusion: 0 + +- name: CA 2030 sunset of military retirement exclusion + period: 2030 + input: + state_code: CA + military_retirement_pay: 20_000 + output: + ca_military_retirement_exclusion: 0 + +- name: CA joint return with both spouses receiving military pay capped at $20,000 per return + period: 2025 + input: + people: + head: + age: 62 + is_tax_unit_head: true + military_retirement_pay: 60_000 + spouse: + age: 62 + is_tax_unit_spouse: true + military_retirement_pay: 60_000 + tax_units: + tax_unit: + members: [head, spouse] + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: CA + output: + ca_military_retirement_exclusion: 20_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/ca_taxable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/ca_taxable_income.yaml index 0b8fa6db0c6..6a0c1ce337a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/ca_taxable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/ca_taxable_income.yaml @@ -15,3 +15,25 @@ state_code: CA output: ca_taxable_income: 10_000 - 4_900 + +- name: Military retirement pay flows into CA taxable income via federal AGI (2024, pre-exclusion) + period: 2024 + input: + military_retirement_pay: 50_000 + ca_deductions: 5_540 + state_code: CA + output: + ca_agi: 50_000 + ca_taxable_income: 50_000 - 5_540 + +- name: Military retirement pay and SBP exclusion under R&TC §§ 17132.9 and 17132.10 (2025) + period: 2025 + input: + military_retirement_pay: 50_000 + military_retirement_pay_survivors: 10_000 + ca_deductions: 5_706 + state_code: CA + output: + ca_military_retirement_exclusion: 20_000 + 10_000 + ca_agi: 60_000 - 30_000 + ca_taxable_income: 30_000 - 5_706 diff --git a/policyengine_us/tests/policy/baseline/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.yaml b/policyengine_us/tests/policy/baseline/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.yaml index adfd98f3c1e..151e3579a41 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.yaml @@ -155,6 +155,16 @@ co_pension_subtraction_income: 15_000 co_pension_subtraction_indv: 15_000 +- name: Filer under 55 with military retirement survivor benefits subtracts up to $20,000 under Book 104 line 4 + period: 2025 + input: + state_code: CO + age: 45 + co_social_security_subtraction_indv: 0 + military_retirement_pay_survivors: 18_000 + co_pension_subtraction_indv_eligible: true + output: + co_pension_subtraction_indv: 18_000 - name: Only taxable disability benefits count toward the pension subtraction. period: 2024 diff --git a/policyengine_us/tests/policy/baseline/gov/states/dc/tax/income/subtractions/dc_survivor_benefits_subtraction.yaml b/policyengine_us/tests/policy/baseline/gov/states/dc/tax/income/subtractions/dc_survivor_benefits_subtraction.yaml new file mode 100644 index 00000000000..58228f08ab9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/dc/tax/income/subtractions/dc_survivor_benefits_subtraction.yaml @@ -0,0 +1,33 @@ +- name: Case 1, DC government survivor benefits subtraction eligible at age 62+. + period: 2024 + input: + people: + person1: + age: 65 + military_retirement_pay_survivors: 15_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: DC + output: + dc_survivor_benefits_subtraction: 15_000 + +- name: Case 2, DC government survivor benefits subtraction ineligible under age 62. + period: 2024 + input: + people: + person1: + age: 55 + military_retirement_pay_survivors: 15_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: DC + output: + dc_survivor_benefits_subtraction: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.yaml index 36f594749d8..935d7bd10f1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.yaml @@ -133,3 +133,23 @@ output: de_pension_exclusion: 10_000 +- name: DE under-60 survivor benefits treated as pension (capped at 2,000) + period: 2024 + input: + age: 50 + military_retirement_pay_survivors: 3_000 + is_tax_unit_head_or_spouse: true + state_code: DE + output: + de_pension_exclusion: 2_000 + +- name: DE 60+ filer with military retirement and survivor benefits in retirement basket + period: 2024 + input: + age: 65 + military_retirement_pay_survivors: 8_000 + military_retirement_pay: 8_000 + is_tax_unit_head_or_spouse: true + state_code: DE + output: + de_pension_exclusion: 12_500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.yaml index bb3b80f3fcd..79b111584db 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.yaml @@ -36,3 +36,24 @@ taxable_roth_conversions: 25_000 output: ga_retirement_income_exclusion_retirement_income: 25_000 + +- name: GA 2021 military retirement pay is fully included in retirement income (military exclusion starts in 2022) + period: 2021 + input: + state_code: GA + is_disabled: true + age: 50 + military_retirement_pay: 30_000 + output: + ga_retirement_income_exclusion_retirement_income: 30_000 + +- name: GA 2024 military retirement pay reduced by under-62 exclusion plus survivor pay + period: 2024 + input: + state_code: GA + is_disabled: true + age: 50 + military_retirement_pay: 40_000 + military_retirement_pay_survivors: 5_000 + output: + ga_retirement_income_exclusion_retirement_income: 27_500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/hi_subtractions.yaml b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/hi_subtractions.yaml index 124df1de700..326eeec2dda 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/hi_subtractions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/hi/tax/income/hi_subtractions.yaml @@ -119,3 +119,32 @@ # $40,000 - $16,000 joint standard deduction - 5 exemptions x $1,144 # (3 people plus 2 aged exemptions) = $18,280. hi_taxable_income: 18_280 + +- name: Hawaii subtracts military retirement pay and survivor benefits on line 13 + period: 2024 + input: + people: + head: + age: 60 + employment_income: 30_000 + military_retirement_pay: 20_000 + military_retirement_pay_survivors: 10_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [head] + filing_status: SINGLE + marital_units: + marital_unit: + members: [head] + spm_units: + spm_unit: + members: [head] + households: + household: + members: [head] + state_code: HI + output: + adjusted_gross_income: 60_000 + hi_subtractions: 30_000 + hi_agi: 30_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/consolidated/taxable_income/ia_subtractions_consolidated.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/consolidated/taxable_income/ia_subtractions_consolidated.yaml index 6b554452380..a857eb1a419 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/consolidated/taxable_income/ia_subtractions_consolidated.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/consolidated/taxable_income/ia_subtractions_consolidated.yaml @@ -163,3 +163,27 @@ output: ia_pension_exclusion: [0, 12_000, 0] ia_subtractions_consolidated: 12_000 + +- name: Filer military retirement pay and survivors subtracted in TY2023 under Iowa Code § 422.7(20)-(21) + period: 2023 + absolute_error_margin: 0.01 + input: + people: + head: + age: 50 + employment_income: 40_000 + military_retirement_pay: 30_000 + military_retirement_pay_survivors: 10_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [head] + marital_units: + head_marital_unit: + members: [head] + households: + household: + members: [head] + state_code: IA + output: + ia_subtractions_consolidated: 40_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.yaml index 40fd93a78ef..901804ef8e0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.yaml @@ -81,3 +81,23 @@ state_code: ID output: id_military_retirement_deduction: 30_000 + +- name: Military retirement survivor benefits for qualifying survivor aged 65 under Idaho Code § 63-3022A(1)(b) + period: 2025 + input: + people: + person1: + is_tax_unit_head_or_spouse: true + military_retirement_pay_survivors: 25_000 + age: 65 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: ID + output: + id_military_retirement_deduction: 25_000 + diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/tax/income/income/il_base_income_subtractions.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/tax/income/income/il_base_income_subtractions.yaml index abc24ec6242..5ea94fe1e66 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/tax/income/income/il_base_income_subtractions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/tax/income/income/il_base_income_subtractions.yaml @@ -142,3 +142,26 @@ adjusted_gross_income: 50_000 il_base_income_subtractions: 10_000 il_base_income: 40_000 + +- name: Filer military retirement pay and survivor benefits are subtracted from IL base income. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + head: + age: 60 + employment_income: 50_000 + military_retirement_pay: 20_000 + military_retirement_pay_survivors: 10_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [head] + households: + household: + members: [head] + state_code: IL + output: + adjusted_gross_income: 80_000 + il_base_income_subtractions: 30_000 + il_base_income: 50_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/in/tax/income/deductions/in_military_retirement_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/in/tax/income/deductions/in_military_retirement_deduction.yaml new file mode 100644 index 00000000000..5d7d2005361 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/in/tax/income/deductions/in_military_retirement_deduction.yaml @@ -0,0 +1,33 @@ +- name: Case 1, Indiana military retirement deduction under 2021 phase-in. + period: 2021 + input: + people: + person1: + military_retirement_pay: 10_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: IN + output: + in_military_retirement_deduction: 6_250 + 0.75 * (10_000 - 6_250) + +- name: Case 2, Indiana military retirement and survivor benefit deduction 100% exempt from 2022. + period: 2024 + input: + people: + person1: + military_retirement_pay: 30_000 + person2: + military_retirement_pay_survivors: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: IN + output: + in_military_retirement_deduction: 40_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_agi_subtractions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_agi_subtractions.yaml index f36e6e880ac..187d331cf36 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_agi_subtractions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_agi_subtractions.yaml @@ -149,3 +149,14 @@ ks_taxable_income: 29_170 # 23,001 * 5.2% + (29,170 - 23,001) * 5.58% = 1,196.05 + 344.23 ks_income_tax_before_credits: 1_540.28 + +- name: Filer military retirement pay and survivor benefits subtracted under K.S.A. § 79-32,117(c) + period: 2025 + input: + state_code: KS + employment_income: 50_000 + military_retirement_pay: 15_000 + military_retirement_pay_survivors: 10_000 + output: + ks_agi_subtractions: 25_000 + ks_agi: 50_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.yaml index 9b71e683b27..2b46d160a1b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.yaml @@ -73,3 +73,13 @@ state_code: KY output: ky_pension_income_exclusion: 20_000 + +- name: Military retirement pay and survivor benefits qualify for KY pension exclusion + period: 2024 + input: + state_code: KY + military_retirement_pay: 15_000 + military_retirement_pay_survivors: 10_000 + ky_pension_income_exclusion_exemption_eligible: false + output: + ky_pension_income_exclusion: 25_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/credits/senior_circuit_breaker/ma_scb_total_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/credits/senior_circuit_breaker/ma_scb_total_income.yaml index b336c7edd98..5f536473a77 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/credits/senior_circuit_breaker/ma_scb_total_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/credits/senior_circuit_breaker/ma_scb_total_income.yaml @@ -157,3 +157,32 @@ # The child's 10,000 public pension, 4,000 tax-exempt pension and 3,000 # Social Security are not the taxpayer's income and are not re-added. ma_scb_total_income: 52_600 + +- name: Military retirement pay is re-added to SCB total income under § 6(k)(1). + period: 2025 + absolute_error_margin: 0.1 + input: + people: + head: + age: 65 + military_retirement_pay: 30_000 + is_tax_unit_head: true + is_tax_unit_dependent: false + ssi: 0 + ma_state_supplement: 0 + tax_units: + tax_unit: + members: [head] + spm_units: + spm_unit: + tanf: 0 + members: [head] + households: + household: + members: [head] + state_code: MA + output: + # 30,000 pay is excluded from ma_gross_income (0), but re-added under § 6(k)(1); + # reduced by 700 aged exemption = 29,300. + ma_gross_income: 0 + ma_scb_total_income: 29_300 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/gross_income/ma_gross_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/gross_income/ma_gross_income.yaml index 00d8ca39995..2b3d6210c7d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/gross_income/ma_gross_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ma/tax/income/gross_income/ma_gross_income.yaml @@ -157,3 +157,16 @@ adjusted_gross_income: 50_000 ma_gross_income: 50_000 ma_agi: 50_000 + +- name: Filer military retirement pay and survivor benefits are excluded from MA gross income. + period: 2025 + absolute_error_margin: 0.1 + input: + state_code: MA + employment_income: 50_000 + military_retirement_pay: 20_000 + military_retirement_pay_survivors: 10_000 + output: + adjusted_gross_income: 80_000 + ma_gross_income: 50_000 + ma_agi: 50_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_pension_subtraction_amount.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_pension_subtraction_amount.yaml index 8a0e83c35fb..0f8234e781d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_pension_subtraction_amount.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_pension_subtraction_amount.yaml @@ -72,3 +72,32 @@ state_code: MD output: md_pension_subtraction_amount: 15_000 + +- name: Disabled filer aged 60 measures excess military pay against age-55 military cap under § 10-209(d)(1) + period: 2024 + input: + state_code: MD + is_tax_unit_dependent: false + age: 60 + is_disabled: true + military_retirement_pay: 40_000 + social_security: 0 + output: + # Military subtraction is $20,000; excess is $20,000 which feeds pension subtraction + md_military_retirement_subtraction_amount: 20_000 + md_pension_subtraction_amount: 20_000 + +- name: Filer aged 66 measures excess military pay against age-55 military cap under § 10-209(d)(1) + period: 2025 + input: + state_code: MD + is_tax_unit_dependent: false + age: 66 + is_disabled: false + military_retirement_pay: 40_000 + social_security: 0 + output: + # Military subtraction is $20,000; excess is $20,000 which feeds pension subtraction + md_military_retirement_subtraction_amount: 20_000 + md_pension_subtraction_amount: 20_000 + diff --git a/policyengine_us/tests/policy/baseline/gov/states/me/tax/income/taxable_income/me_pension_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/me/tax/income/taxable_income/me_pension_income_deduction.yaml index 55f750bd65b..5c21663f012 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/me/tax/income/taxable_income/me_pension_income_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/me/tax/income/taxable_income/me_pension_income_deduction.yaml @@ -367,3 +367,26 @@ me_pension_income_deduction: 0 me_agi: 60_000 +- name: Maine 2025 military retirement survivor benefits deducted in full (not phased out) + period: 2025 + input: + people: + person1: + is_tax_unit_head: true + age: 67 + social_security: 0 + military_retirement_pay_survivors: 35_000 + taxable_interest_income: 300_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: ME + spm_units: + spm_unit: + members: [person1] + output: + me_pension_income_deduction: 35_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.yaml index f2610ec056d..b58c60f5e55 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.yaml @@ -118,3 +118,27 @@ state_code: MI output: # 2025 MI-1040 booklet, Schedule 1 line 28: $14,688 single limit < 50,000 mi_interest_dividends_capital_gains_deduction: 14_688 + +- name: 2022 single filer with interest and dividends deduction reduced by military retirement and survivor pay + period: 2022 + input: + people: + person1: + taxable_pension_income: 10_000 + military_retirement_pay: 500 + military_retirement_pay_survivors: 500 + taxable_interest_income: 5_000 + dividend_income: 400 + capital_gains: 100 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + mi_interest_dividends_capital_gains_deduction_eligible: true + elderly_disabled_credit: 300 + members: [person1] + filing_status: SINGLE + household: + members: [person1] + state_code: MI + output: # 12697 - 10000 - (500 + 500) - 300 = 1397 < 5000 + 400 + 100 + mi_interest_dividends_capital_gains_deduction: 1_397 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.yaml index b7ff6a65dba..3839bf0b58a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.yaml @@ -199,4 +199,21 @@ mi_expanded_retirement_benefits_deduction: 20_000 mi_pension_benefit: 20_000 - +- name: 2023 single filer with expanded retirement deduction reduced by military survivor pay + period: 2023 + input: + people: + person1: + taxable_pension_income: 20_000 + military_retirement_pay_survivors: 1_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + mi_expanded_retirement_benefits_deduction_eligible: true + members: [person1] + filing_status: SINGLE + household: + members: [person1] + state_code: MI + output: # min(0.25 * (61518 - 1000), 20000) + mi_expanded_retirement_benefits_deduction: 15_129.5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.yaml index 3c9cdb576c0..c6e1780f293 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.yaml @@ -461,4 +461,24 @@ # 401(k) ($15,000) also qualifies -> total $35,000. mi_retirement_benefits_deduction_tier_one_amount: 35_000 - +- name: 2025 single filer with tier 1 cap reduced by military retirement and survivor pay + period: 2025 + input: + people: + person1: + taxable_public_pension_income: 0 + taxable_private_pension_income: 50_000 + military_retirement_pay: 10_000 + military_retirement_pay_survivors: 10_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + household: + members: [person1] + state_code: MI + output: + # Cap: $65,897 - ($10,000 + $10,000) = $45,897 + # min($45,897, $50,000) = $45,897 + mi_retirement_benefits_deduction_tier_one_amount: 45_897 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.yaml index e9667c90be4..040f0f15a38 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.yaml @@ -295,3 +295,25 @@ output: mi_retirement_benefits_deduction_tier_three_eligible: false mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired: 0 + +- name: 2022 single filer with tier 3 not retired deduction limited to tier 1 due to military survivor pay + period: 2022 + input: + people: + person1: + taxable_pension_income: 40_000 + military_retirement_pay_survivors: 1_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + mi_retirement_benefits_deduction_tier_three_eligible: true + mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired_eligible_people: 1 + mi_retirement_benefits_deduction_tier_one_amount: 10_000 + mi_expanded_retirement_benefits_deduction: 0 + members: [person1] + filing_status: SINGLE + household: + members: [person1] + state_code: MI + output: # min(min(15000, 10000), 40000) = 10000 + mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired: 10_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.yaml index fa8af99ffb7..a4dc58d4a61 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.yaml @@ -154,3 +154,24 @@ # The head's own military pay limits the cap: min(70,000, 60,000) = 60,000. # min(20,000 + 30,000, 60,000) = 50,000 mi_retirement_benefits_deduction_tier_three_ss_exempt_retired: 50_000 + +- name: 2022 single filer with tier 3 retired deduction limited to tier 1 due to military survivor pay + period: 2022 + input: + people: + person1: + taxable_pension_income: 40_000 + military_retirement_pay_survivors: 1_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + mi_retirement_benefits_deduction_tier_three_eligible: true + mi_retirement_benefits_deduction_tier_three_ss_exempt_retired_eligible_people: 1 + mi_retirement_benefits_deduction_tier_one_amount: 10_000 + members: [person1] + filing_status: SINGLE + household: + members: [person1] + state_code: MI + output: # min(35000 < 10000, 40000) = 10000 + mi_retirement_benefits_deduction_tier_three_ss_exempt_retired: 10_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.yaml index 5d3d636f0e6..cb513bc35af 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.yaml @@ -157,3 +157,26 @@ state_code: MI output: mi_standard_deduction_tier_three: 4_790 + +- name: 2022 single filer with tier 3 standard deduction reduced by military retirement and survivor pay + period: 2022 + input: + people: + person1: + military_retirement_pay: 1_000 + military_retirement_pay_survivors: 500 + military_service_income: 500 + taxable_social_security: 100 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + mi_standard_deduction_tier_three_eligible: true + mi_personal_exemptions: 2_000 + mi_expanded_retirement_benefits_deduction: 0 + members: [person1] + filing_status: SINGLE + household: + members: [person1] + state_code: MI + output: # 20000 - (1000 + 500) - (500 > 100) - 2000 = 16000 + mi_standard_deduction_tier_three: 16_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.yaml b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.yaml index 22b0a71930d..f62ff181535 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.yaml @@ -68,3 +68,24 @@ state_code: MI output: # 20000 - 9000 - 10000 < 20000 mi_standard_deduction_tier_two: 20_000 + +- name: 2022 single filer with tier 2 standard deduction reduced by military retirement and survivor pay + period: 2022 + input: + people: + person1: + military_retirement_pay: 3_000 + military_retirement_pay_survivors: 2_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + mi_standard_deduction_tier_two_eligible: true + mi_standard_deduction_tier_two_increase_eligible_people: 0 + mi_expanded_retirement_benefits_deduction: 0 + members: [person1] + filing_status: SINGLE + household: + members: [person1] + state_code: MI + output: # 20000 - 3000 - 2000 = 15000 + mi_standard_deduction_tier_two: 15_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mn/tax/income/mn_amt_taxable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/mn/tax/income/mn_amt_taxable_income.yaml index 4310e3a2c90..0b04373bb34 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mn/tax/income/mn_amt_taxable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mn/tax/income/mn_amt_taxable_income.yaml @@ -45,3 +45,13 @@ state_code: MN output: mn_amt_taxable_income: 200_000 + +- name: MN AMT taxable income subtracts military pension subtraction + period: 2024 + input: + state_code: MN + adjusted_gross_income: 200_000 + military_retirement_pay: 50_000 + output: + mn_military_pension_subtraction: 50_000 + mn_amt_taxable_income: 200_000 - 50_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction/mo_pension_and_ss_or_ssd_deduction_section_a.yaml b/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction/mo_pension_and_ss_or_ssd_deduction_section_a.yaml index ebd097bcf3d..eb2b1ca4499 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction/mo_pension_and_ss_or_ssd_deduction_section_a.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction/mo_pension_and_ss_or_ssd_deduction_section_a.yaml @@ -364,3 +364,16 @@ mo_pension_and_ss_or_ssd_deduction_section_a: [15_000, 0] # Section D: 15,000 (A) + 0 (B) + 5,000 (C). mo_pension_and_ss_or_ssd_deduction: 20_000 + +- name: Military retirement pay survivors is included in public pension amount in Section A + period: 2024 + absolute_error_margin: 0 + input: + mo_adjusted_gross_income: 30_000 + taxable_social_security: 0 + military_retirement_pay_survivors: 8_000 + filing_status: SINGLE + mo_pension_and_ss_or_ssd_deduction_section_c: 0 + state_code: MO + output: + mo_pension_and_ss_or_ssd_deduction_section_a: 8_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/subtractions/mo_agi_subtractions.yaml b/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/subtractions/mo_agi_subtractions.yaml index 3eee4f44290..fb6d128b363 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/subtractions/mo_agi_subtractions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/mo/tax/income/subtractions/mo_agi_subtractions.yaml @@ -174,3 +174,19 @@ mo_qualified_health_insurance_premiums: [6_000, 6_000] # Total subtractions per person: 6_000+6_000=12_000 and 4_000+6_000=10_000 mo_agi_subtractions: [12_000, 10_000] + +- name: Military retirement pay subtracted from MO AGI under MO-A line 10 + period: 2024 + input: + people: + person1: + military_retirement_pay: 30_000 + tax_units: + tax_unit1: + members: [person1] + households: + household1: + members: [person1] + state_code: MO + output: + mo_agi_subtractions: 30_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.yaml index 284887089b2..17e2f2ac373 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.yaml @@ -117,14 +117,11 @@ employment_income: 60_000 years_in_military: 20 military_retirement_pay: 20_000 - # Military pension descriptors do not add themselves to federal AGI. - taxable_public_pension_income: 20_000 person2: # A civilian spouse receiving Survivor Benefit Plan payments as the # beneficiary of a former spouse who retired after 20 years. age: 48 military_retirement_pay: 10_000 - taxable_public_pension_income: 10_000 nc_military_retirement_survivor_eligible: true tax_units: tax_unit: @@ -153,7 +150,6 @@ # The deceased member met the service test, but the recipient does not. military_retirement_pay_survivors: 10_000 nc_military_retirement_survivor_eligible: true - taxable_public_pension_income: 30_000 state_code: NC output: adjusted_gross_income: 30_000 @@ -165,7 +161,6 @@ age: 50 military_retirement_pay: 20_000 military_retirement_pay_survivors: 10_000 - taxable_public_pension_income: 30_000 # The caller supplies own-pay eligibility instead of service inputs. nc_military_retirement_deduction_eligible: true nc_military_retirement_survivor_eligible: false @@ -181,14 +176,12 @@ person1: age: 50 military_retirement_pay: 20_000 - taxable_public_pension_income: 20_000 nc_military_retirement_deduction_eligible: true person2: age: 48 years_in_military: 20 military_retirement_pay: 10_000 military_retirement_pay_survivors: 5_000 - taxable_public_pension_income: 15_000 # The head opens the unit's gate, but the spouse's explicit false # input must not be overridden by recomputing their service test. nc_military_retirement_deduction_eligible: false @@ -290,14 +283,12 @@ age: 50 years_in_military: 20 military_retirement_pay: 20_000 - taxable_public_pension_income: 20_000 # Supplying the spouse's eligibility makes this variable an input # for every member, so also supply the qualifying head's value. nc_military_retirement_deduction_eligible: true person2: age: 48 military_retirement_pay_survivors: 5_000 - taxable_public_pension_income: 5_000 # The head opens the unit's gate, but the spouse's explicit false # must also exclude separately recorded survivor benefits. nc_military_retirement_deduction_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/adjusted_gross_income/ne_military_retirement_subtraction.yaml b/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/adjusted_gross_income/ne_military_retirement_subtraction.yaml index 2c56b418ac8..9e500965817 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/adjusted_gross_income/ne_military_retirement_subtraction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ne/tax/income/adjusted_gross_income/ne_military_retirement_subtraction.yaml @@ -162,3 +162,39 @@ # The head is under 67, and the dependent relative is excluded despite # being 67 or older, so only the spouse's 10,000 counts: 40% * 10,000. ne_military_retirement_subtraction: 4_000 + +- name: NE 2021 military retirement survivor benefits are not eligible for subtraction (Form 1040N-MIL) + period: 2021 + input: + people: + person1: + age: 69 + military_retirement_pay_survivors: 20_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: NE + output: + ne_military_retirement_subtraction: 0 + +- name: NE 2022 military retirement survivor benefits are eligible for 100% subtraction (Info Guide 8-364) + period: 2022 + input: + people: + person1: + age: 60 + military_retirement_pay_survivors: 20_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: NE + output: + ne_military_retirement_subtraction: 20_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.yaml index 906d537ce4f..e3dabdad557 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.yaml @@ -39,3 +39,14 @@ employment_income: 100_000 output: nj_529_deduction: 0 + +- name: Case 5, filer with military retirement pay and wages under NJ gross income limit. + period: 2025 + absolute_error_margin: 0.1 + input: + state_code: NJ + employment_income: 185_000 + military_retirement_pay: 30_000 + investment_in_529_plan_indv: 10_000 + output: + nj_529_deduction: 10_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/ny_agi_subtractions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/ny_agi_subtractions.yaml index a61d2c71252..6fbcf257f9b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/ny_agi_subtractions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/ny_agi_subtractions.yaml @@ -67,3 +67,15 @@ output: # 1,000 (head's refund) + 500 (tax-unit U.S. government interest). ny_agi_subtractions: 1_500 + +- name: Military retirement pay and survivor benefits subtracted from NY AGI under § 612(c)(3) + period: 2024 + input: + state_code: NY + employment_income: 50_000 + military_retirement_pay: 20_000 + military_retirement_pay_survivors: 10_000 + output: + adjusted_gross_income: 80_000 + ny_agi_subtractions: 30_000 + ny_agi: 50_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/deductions/oh_uniformed_services_retirement_income_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/deductions/oh_uniformed_services_retirement_income_deduction.yaml new file mode 100644 index 00000000000..4e724fead7d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/oh/tax/income/deductions/oh_uniformed_services_retirement_income_deduction.yaml @@ -0,0 +1,36 @@ +- name: Case 1, Ohio uniformed services retirement deduction for retiree and survivor benefits. + period: 2024 + input: + people: + person1: + is_tax_unit_head: true + military_retirement_pay: 20_000 + military_retirement_pay_survivors: 10_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: OH + output: + oh_uniformed_services_retirement_income_deduction: 30_000 + +- name: Case 2, Dependent is ineligible for Ohio uniformed services retirement deduction. + period: 2024 + input: + people: + person1: + is_tax_unit_head: true + person2: + is_tax_unit_dependent: true + military_retirement_pay: 10_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: OH + output: + oh_uniformed_services_retirement_income_deduction: [0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/or/tax/income/credits/retirement_income/or_retirement_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/or/tax/income/credits/retirement_income/or_retirement_credit.yaml index 2529896a7a5..59d020855c0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/or/tax/income/credits/retirement_income/or_retirement_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/or/tax/income/credits/retirement_income/or_retirement_credit.yaml @@ -197,3 +197,25 @@ state_code: OR output: or_retirement_credit: 0 + +- name: Military retirement pay and survivor benefits count toward Line 1 retirement income under ORS 316.157 + period: 2022 + input: + people: + person1: + or_retirement_credit_eligible_person: true + military_retirement_pay: 5_000 + military_retirement_pay_survivors: 2_500 + social_security: 0 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + or_retirement_credit_household_income: 10_000 + or_federal_pension_subtraction: 0 + households: + household: + members: [person1] + state_code: OR + output: + or_retirement_credit: 675 diff --git a/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/forgiveness/pa_eligibility_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/forgiveness/pa_eligibility_income.yaml new file mode 100644 index 00000000000..e1ab38e4072 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/pa/tax/income/forgiveness/pa_eligibility_income.yaml @@ -0,0 +1,17 @@ +- name: Case 1, military pension benefits are excluded from PA tax forgiveness eligibility income per PA-40 SP. + period: 2025 + input: + state_code: PA + employment_income: 5_000 + military_retirement_pay: 30_000 + output: + pa_eligibility_income: 5_000 + +- name: Case 2, military retirement survivor benefits are included in PA tax forgiveness eligibility income per PA-40 SP. + period: 2025 + input: + state_code: PA + employment_income: 5_000 + military_retirement_pay_survivors: 10_000 + output: + pa_eligibility_income: 15_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/ri_retirement_income_subtraction.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/ri_retirement_income_subtraction.yaml index 30e11ab4738..cf0fb9772ce 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/ri_retirement_income_subtraction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/agi/subtractions/taxable_retirement_income/ri_retirement_income_subtraction.yaml @@ -138,3 +138,13 @@ taxable_ira_distributions: 20_000 output: ri_retirement_income_subtraction: 15_000 + +- name: 2022 - Eligible with military retirement pay and survivor pay + period: 2022 + input: + state_code: RI + ri_retirement_income_subtraction_eligible: true + military_retirement_pay: 10_000 + military_retirement_pay_survivors: 5_000 + output: + ri_retirement_income_subtraction: 15_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_military_retirement_pay_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_military_retirement_pay_exclusion.yaml index 21ce4ae0fa9..de17eece6d1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_military_retirement_pay_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/subtractions/vt_military_retirement_pay_exclusion.yaml @@ -193,3 +193,42 @@ # Federal AGI 50,000 is below the 125,000 full-exemption threshold, so the # head's 6,000 is fully exempt; the child's 10,000 is not counted. vt_military_retirement_pay_exclusion: 6_000 + +- name: VT 2024 military retirement survivor benefits are not eligible for exclusion under pre-2025 law + period: 2024 + input: + people: + person1: + age: 50 + military_retirement_pay_survivors: 10_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: VT + output: + vt_military_retirement_pay_exclusion: 0 + +- name: VT 2025 military retirement survivor benefits are eligible for exclusion under Act 71 (S.51) + period: 2025 + input: + people: + person1: + age: 50 + employment_income: 30_000 + military_retirement_pay_survivors: 10_000 + is_tax_unit_head: true + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: VT + output: + vt_military_retirement_pay_exclusion: 10_000 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 2f741281a38..9ed82a14d15 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 @@ -285,7 +285,7 @@ person: age: 66 military_retirement_pay: 30_000 - employment_income: 60_000 # military_retirement_pay is not itself wired into AGI + employment_income: 30_000 tax_units: tax_unit: members: [person] @@ -306,7 +306,7 @@ person: age: 66 military_retirement_pay: 30_000 - employment_income: 100_000 # military_retirement_pay is not itself wired into AGI + employment_income: 70_000 tax_units: tax_unit: members: [person] @@ -327,7 +327,7 @@ person: age: 66 military_retirement_pay: 30_000 - employment_income: 150_000 # military_retirement_pay is not itself wired into AGI + employment_income: 120_000 tax_units: tax_unit: members: [person] diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/subtractions/wi_income_subtractions.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/subtractions/wi_income_subtractions.yaml new file mode 100644 index 00000000000..4c9f4b6e557 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/subtractions/wi_income_subtractions.yaml @@ -0,0 +1,16 @@ +- name: Case 1, Wisconsin excludes military retirement pay and survivor benefits on Schedule SB. + period: 2024 + input: + people: + person1: + military_retirement_pay: 20_000 + military_retirement_pay_survivors: 10_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: WI + output: + wi_income_subtractions: 30_000 diff --git a/policyengine_us/variables/gov/states/ar/tax/income/exemptions/ar_military_retirement_income_person.py b/policyengine_us/variables/gov/states/ar/tax/income/exemptions/ar_military_retirement_income_person.py index 5eb6c9345f5..6c634462a9f 100644 --- a/policyengine_us/variables/gov/states/ar/tax/income/exemptions/ar_military_retirement_income_person.py +++ b/policyengine_us/variables/gov/states/ar/tax/income/exemptions/ar_military_retirement_income_person.py @@ -12,5 +12,5 @@ class ar_military_retirement_income_person(Variable): def formula(person, period, parameters): head_or_spouse = person("is_tax_unit_head_or_spouse", period) - military_retirement_pay = person("military_retirement_pay", period) - return military_retirement_pay * head_or_spouse + military_retirement = person("military_retirement_income", period) + return military_retirement * head_or_spouse diff --git a/policyengine_us/variables/gov/states/az/tax/income/subtractions/az_military_retirement_subtraction.py b/policyengine_us/variables/gov/states/az/tax/income/subtractions/az_military_retirement_subtraction.py index 78cfa7c7e54..c4f78c6d0ee 100644 --- a/policyengine_us/variables/gov/states/az/tax/income/subtractions/az_military_retirement_subtraction.py +++ b/policyengine_us/variables/gov/states/az/tax/income/subtractions/az_military_retirement_subtraction.py @@ -18,7 +18,7 @@ def formula(tax_unit, period, parameters): p = parameters(period).gov.states.az.tax.income.subtractions.military_retirement person = tax_unit.members head_or_spouse = person("is_tax_unit_head_or_spouse", period) - military_retirement_pay = person("military_retirement_pay", period) - eligible_military_pay = military_retirement_pay * head_or_spouse + military_retirement_income = person("military_retirement_income", period) + eligible_military_pay = military_retirement_income * head_or_spouse capped_military_pay = min_(eligible_military_pay, p.max_amount) return tax_unit.sum(capped_military_pay) diff --git a/policyengine_us/variables/gov/states/ca/tax/income/ca_military_retirement_exclusion.py b/policyengine_us/variables/gov/states/ca/tax/income/ca_military_retirement_exclusion.py new file mode 100644 index 00000000000..a3ed31902a7 --- /dev/null +++ b/policyengine_us/variables/gov/states/ca/tax/income/ca_military_retirement_exclusion.py @@ -0,0 +1,35 @@ +from policyengine_us.model_api import * + + +class ca_military_retirement_exclusion(Variable): + value_type = float + entity = TaxUnit + label = "California military retirement and survivor benefit exclusion" + unit = USD + definition_period = YEAR + reference = ( + "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?sectionNum=17132.9.&lawCode=RTC", + "https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?sectionNum=17132.10.&lawCode=RTC", + ) + defined_for = StateCode.CA + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.ca.tax.income.agi.military_retirement + agi = tax_unit("adjusted_gross_income", period) + filing_status = tax_unit("filing_status", period) + limit = p.agi_limit[filing_status] + eligible = agi <= limit + + # R&TC § 17132.9 excludes up to $20,000 of retired pay per return. + # R&TC § 17132.10 excludes up to $20,000 of SBP survivor benefits per return. + # The exclusion is capped at $20,000 for each payment category on a joint return, + # surviving spouse, or any other individual (Schedule CA (540) line 5a/5b). + retiree_pay = tax_unit_non_dep_add( + tax_unit, period, ["military_retirement_pay"] + ) + survivor_pay = tax_unit_non_dep_add( + tax_unit, period, ["military_retirement_pay_survivors"] + ) + capped_retiree = min_(p.cap, retiree_pay) + capped_survivors = min_(p.cap, survivor_pay) + return eligible * (capped_retiree + capped_survivors) diff --git a/policyengine_us/variables/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.py b/policyengine_us/variables/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.py index e6c4cf3f78e..1c63c5bd3f7 100644 --- a/policyengine_us/variables/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.py +++ b/policyengine_us/variables/gov/states/co/tax/income/subtractions/pension/co_pension_subtraction_indv.py @@ -18,7 +18,11 @@ class co_pension_subtraction_indv(Variable): def formula(person, period, parameters): p = parameters(period).gov.states.co.tax.income.subtractions.pension taxable_pension_income = person("co_pension_subtraction_income", period) - pension_survivors = person("pension_survivors", period) + pension_survivors = add( + person, + period, + ["pension_survivors", "military_retirement_pay_survivors"], + ) co_social_security_subtraction = person( "co_social_security_subtraction_indv", period ) diff --git a/policyengine_us/variables/gov/states/dc/tax/income/subtractions/dc_survivor_benefits_subtraction.py b/policyengine_us/variables/gov/states/dc/tax/income/subtractions/dc_survivor_benefits_subtraction.py new file mode 100644 index 00000000000..9f025eb1fd1 --- /dev/null +++ b/policyengine_us/variables/gov/states/dc/tax/income/subtractions/dc_survivor_benefits_subtraction.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * + + +class dc_survivor_benefits_subtraction(Variable): + value_type = float + entity = Person + label = "DC government survivor benefits subtraction" + unit = USD + definition_period = YEAR + reference = ( + "https://code.dccouncil.gov/us/dc/council/code/sections/47-1803.02#a_2_N_ii", + "https://otr.cfo.dc.gov/sites/default/files/dc/sites/otr/publication/attachments/2024_D40_Booklet_011525.pdf#page=34", + ) + defined_for = StateCode.DC + + def formula(person, period, parameters): + p = parameters(period).gov.states.dc.tax.income.subtractions.survivor_benefits + # Dependents' income is not in federal AGI; they report it on their + # own return. + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + age = person("age", period) + eligible = (age >= p.min_age) & head_or_spouse + # D.C. Code § 47-1803.02(a)(2)(N)(ii) allows exclusion of survivor benefits + # received from the District or federal government by persons 62 or older. + survivor_pay = person("military_retirement_pay_survivors", period) + return eligible * survivor_pay diff --git a/policyengine_us/variables/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.py b/policyengine_us/variables/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.py index ead5baabac0..a1d22553862 100644 --- a/policyengine_us/variables/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.py +++ b/policyengine_us/variables/gov/states/de/tax/income/subtractions/pension_exclusion/de_pension_exclusion.py @@ -25,8 +25,9 @@ def formula(person, period, parameters): eligible_for_pension_exclusion_income = p.age_threshold.calc(age) eligible_pension_income = ( - person("taxable_pension_income", period) * head_or_spouse - ) + person("taxable_pension_income", period) + + person("military_retirement_income", period) + ) * head_or_spouse eligible_retirement_income = ( person("de_pension_exclusion_income", period) * head_or_spouse diff --git a/policyengine_us/variables/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.py b/policyengine_us/variables/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.py index 7b81a1610bd..fdf8666eea5 100644 --- a/policyengine_us/variables/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.py +++ b/policyengine_us/variables/gov/states/ga/tax/income/subtractions/retirement/ga_retirement_income_exclusion_retirement_income.py @@ -22,6 +22,14 @@ def formula(person, period, parameters): countable_earned_income = max_( 0, person("ga_retirement_exclusion_countable_earned_income", period) ) - other_retirement_income = add(person, period, p.sources) + # Ga. Comp. R. & Regs. r. 560-7-4-.02(3): Only retirement income included + # in Georgia taxable income can be included. Subtract the military + # retirement exclusion already taken under O.C.G.A. § 48-7-27(a)(5)(E). + military_pay = person("military_retirement_pay", period) + military_exclusion = person("ga_military_retirement_exclusion_person", period) + remaining_military_pay = max_(0, military_pay - military_exclusion) + other_retirement_income = ( + add(person, period, p.sources) + remaining_military_pay + ) countable_other_retirement_income = max_(0, other_retirement_income) return countable_earned_income + countable_other_retirement_income diff --git a/policyengine_us/variables/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.py b/policyengine_us/variables/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.py index 340443b3009..8d1c74736b6 100644 --- a/policyengine_us/variables/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.py +++ b/policyengine_us/variables/gov/states/id/tax/income/subtractions/military_retirement/id_military_retirement_deduction.py @@ -17,8 +17,9 @@ def formula(tax_unit, period, parameters): p = parameters(period).gov.states.id.tax.income.subtractions.military_retirement person = tax_unit.members head_or_spouse = person("is_tax_unit_head_or_spouse", period) - military_retirement_pay = person("military_retirement_pay", period) - eligible_military_pay = military_retirement_pay * head_or_spouse + military_retirement_income = person("military_retirement_income", period) + eligible_military_pay = military_retirement_income * head_or_spouse + # Multiply by applies parameter (False when military retirement # is already handled in general retirement benefits deduction) return tax_unit.sum(eligible_military_pay) * p.applies diff --git a/policyengine_us/variables/gov/states/in/tax/income/deductions/in_military_retirement_deduction.py b/policyengine_us/variables/gov/states/in/tax/income/deductions/in_military_retirement_deduction.py new file mode 100644 index 00000000000..c2f10bb42c1 --- /dev/null +++ b/policyengine_us/variables/gov/states/in/tax/income/deductions/in_military_retirement_deduction.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * + + +class in_military_retirement_deduction(Variable): + value_type = float + entity = TaxUnit + label = "Indiana military retirement deduction" + unit = USD + definition_period = YEAR + reference = ( + "http://iga.in.gov/legislative/laws/2021/ic/titles/006#6-3-2-4", + "https://forms.in.gov/Download.aspx?id=16915#page=20", + ) + defined_for = StateCode.IN + + def formula(tax_unit, period, parameters): + person = tax_unit.members + p = ( + parameters(period) + .gov.states["in"] + .tax.income.deductions.military_retirement + ) + # Dependents' income is not in federal AGI; they report it on their + # own return. + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + military_retirement = person("military_retirement_income", period) + excess = max_(0, military_retirement - p.base) + person_deduction = min_(military_retirement, p.base) + p.excess_rate * excess + return tax_unit.sum(person_deduction * head_or_spouse) diff --git a/policyengine_us/variables/gov/states/in/tax/income/deductions/in_other_deductions.py b/policyengine_us/variables/gov/states/in/tax/income/deductions/in_other_deductions.py index df63c18ada9..722c7d91e0f 100644 --- a/policyengine_us/variables/gov/states/in/tax/income/deductions/in_other_deductions.py +++ b/policyengine_us/variables/gov/states/in/tax/income/deductions/in_other_deductions.py @@ -7,6 +7,6 @@ class in_other_deductions(Variable): label = "Indiana other deductions" unit = USD definition_period = YEAR - documentation = "Other deductions available in Indiana including those for civil service annuities, government or civic group capital contributions, human services for Medicaid recipients, infrastructure fund gifts, indiana lottery winings annuity, Indiana partnership long-term care policy premiums, military retirement income or survivor's benefits, National Guard and reserve component members, Olympic/Paralymic medal winners, qualified patents income eemption, railroad unemployment and sickness benefits, repayment of previously taxed income deductions, COVID-related employee retention credit dissalowed expenses, and Indiana-only tax-exempt bonds." + documentation = "Other deductions available in Indiana including those for government or civic group capital contributions, human services for Medicaid recipients, infrastructure fund gifts, indiana lottery winings annuity, Indiana partnership long-term care policy premiums, National Guard and reserve component members, Olympic/Paralymic medal winners, qualified patents income eemption, railroad unemployment and sickness benefits, repayment of previously taxed income deductions, COVID-related employee retention credit dissalowed expenses, and Indiana-only tax-exempt bonds." reference = "http://iga.in.gov/legislative/laws/2021/ic/titles/006#6-3-2" defined_for = StateCode.IN diff --git a/policyengine_us/variables/gov/states/ks/tax/income/ks_agi_subtractions.py b/policyengine_us/variables/gov/states/ks/tax/income/ks_agi_subtractions.py index d85b4251917..07a261b9c49 100644 --- a/policyengine_us/variables/gov/states/ks/tax/income/ks_agi_subtractions.py +++ b/policyengine_us/variables/gov/states/ks/tax/income/ks_agi_subtractions.py @@ -27,16 +27,22 @@ def formula(tax_unit, period, parameters): "salt_refund_income", tax_unit, period ) # K.S.A. § 79-32,117(c)(ii), (vii)–(ix) / Form K-40 Schedule S Line A13 - # Proxy note: Kansas exempts KPERS, Kansas police/firemen, Kansas judges, and federal - # civil service/military pensions; out-of-state public pensions are not exempt. - # PolicyEngine models this by subtracting taxable_public_pension_income as an in-state proxy. - taxable_public_pension_income = tax_unit_non_dep_sum( - "taxable_public_pension_income", tax_unit, period + # Kansas exempts KPERS, Kansas police/firemen, Kansas judges, federal civil service, + # military retirement pay, and military survivor benefits (10 U.S.C. 1450). + # Out-of-state public pensions are not exempt. PolicyEngine models this by subtracting + # taxable_public_pension_income as an in-state proxy, plus military retirement pay and survivors. + public_and_military_pension = tax_unit_non_dep_add( + tax_unit, + period, + [ + "taxable_public_pension_income", + "military_retirement_income", + ], ) return ( oasdi_subtraction + us_govt_interest + plan_529 + salt_refund_income - + taxable_public_pension_income + + public_and_military_pension ) diff --git a/policyengine_us/variables/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.py b/policyengine_us/variables/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.py index 29368948f28..225e9aa1469 100644 --- a/policyengine_us/variables/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.py +++ b/policyengine_us/variables/gov/states/ky/tax/income/exclusions/pension_income/ky_pension_income_exclusion.py @@ -13,7 +13,14 @@ def formula(person, period, parameters): p = parameters(period).gov.states.ky.tax.income.exclusions.pension_income # Get taxable pension and retirement income. - pension_income = person("taxable_pension_income", period) + pension_income = add( + person, + period, + [ + "taxable_pension_income", + "military_retirement_income", + ], + ) # Check if person is eligible for exemption. exemption_eligible = person( diff --git a/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_gross_income.py b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_gross_income.py index ca107287104..67f1f1b4b20 100644 --- a/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_gross_income.py +++ b/policyengine_us/variables/gov/states/ma/tax/income/gross_income/ma_gross_income.py @@ -29,12 +29,13 @@ def formula(tax_unit, period, parameters): foreign_earned_income = tax_unit( "ma_foreign_earned_income_exclusion_addback", period ) - # Exclude Social Security, state/local tax refunds, and contributory - # public pensions. - # Under M.G.L. c. 62 § 2(a)(2)(E), contributory pensions from the US, - # Massachusetts, or reciprocal states are excluded from MA gross income. - # Noncontributory or non-reciprocal public pensions are not exempt. - # PolicyEngine treats taxable_public_pension_income as exempt public pensions. + # Exclude Social Security, state/local tax refunds, contributory + # public pensions, and military retirement pay. + # Under M.G.L. c. 62 § 2(a)(2)(E) and TIR 08-16, pensions from the US + # (including military retirement pay), Massachusetts, or reciprocal states + # are excluded from MA gross income. + # PolicyEngine treats taxable_public_pension_income and military_retirement_income + # as exempt public pensions. # c.62 s.2(a)(2) deducts these items from the filer's federal gross # income. Dependents' income is not in it (irs_gross_income excludes # it; they report it on their own return), so deduct only the head's @@ -43,8 +44,13 @@ def formula(tax_unit, period, parameters): salt_refund_income = tax_unit_non_dep_sum( "salt_refund_income", tax_unit, period ) - public_pension = tax_unit_non_dep_sum( - "taxable_public_pension_income", tax_unit, period + public_pension = tax_unit_non_dep_add( + tax_unit, + period, + [ + "taxable_public_pension_income", + "military_retirement_income", + ], ) deductions = social_security_in_agi + salt_refund_income + public_pension return max_( diff --git a/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_military_retirement_subtraction.py b/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_military_retirement_subtraction.py index a7973d16495..a380c331cd3 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_military_retirement_subtraction.py +++ b/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_military_retirement_subtraction.py @@ -17,29 +17,4 @@ class md_military_retirement_subtraction(Variable): "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=12", ) - def formula(tax_unit, period, parameters): - # Md. Code Tax-General § 10-207(q)(1): "military retirement income" - # includes death benefits received as a result of military service, so - # Survivor Benefit Plan payments to surviving spouses qualify. - p = parameters( - period - ).gov.states.md.tax.income.agi.subtractions.military_retirement - person = tax_unit.members - age = person("age", period) - military_retirement_income = add( - person, - period, - ["military_retirement_pay", "military_retirement_pay_survivors"], - ) - at_or_above_threshold = age >= p.age_threshold - cap = where( - at_or_above_threshold, - p.max_amount.at_or_above_age_threshold, - p.max_amount.under_age_threshold, - ) - capped = min_(military_retirement_income, cap) - # § 10-207(a) subtracts amounts only to the extent included in federal - # AGI. Dependents' income is not in federal AGI; they report it on - # their own return (Form 502 filing status 6, dependent taxpayer). - head_or_spouse = person("is_tax_unit_head_or_spouse", period) - return tax_unit.sum(capped * head_or_spouse) + adds = ["md_military_retirement_subtraction_amount"] diff --git a/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_military_retirement_subtraction_amount.py b/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_military_retirement_subtraction_amount.py new file mode 100644 index 00000000000..fb2147bfc07 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_military_retirement_subtraction_amount.py @@ -0,0 +1,35 @@ +from policyengine_us.model_api import * + + +class md_military_retirement_subtraction_amount(Variable): + value_type = float + entity = Person + label = "Maryland military retirement income subtraction per person" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + reference = ( + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-207", + "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=17", + ) + + def formula(person, period, parameters): + # § 10-207(a) subtracts amounts only to the extent included in federal + # AGI. Dependents' income is not in federal AGI; they report it on + # their own return (Form 502 filing status 6, dependent taxpayer). + dependent = person("is_tax_unit_dependent", period) + # Md. Code Tax-General § 10-207(q)(1): "military retirement income" + # includes death benefits received as a result of military service, so + # Survivor Benefit Plan payments to surviving spouses qualify. + p = parameters( + period + ).gov.states.md.tax.income.agi.subtractions.military_retirement + age = person("age", period) + military_retirement_income = person("military_retirement_income", period) + at_or_above_threshold = age >= p.age_threshold + cap = where( + at_or_above_threshold, + p.max_amount.at_or_above_age_threshold, + p.max_amount.under_age_threshold, + ) + return ~dependent * min_(military_retirement_income, cap) diff --git a/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_pension_subtraction_amount.py b/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_pension_subtraction_amount.py index 6ce758fe58e..07795b5966a 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_pension_subtraction_amount.py +++ b/policyengine_us/variables/gov/states/md/tax/income/agi/subtractions/md_pension_subtraction_amount.py @@ -19,8 +19,18 @@ def formula(person, period, parameters): disabled = person("is_disabled", period) partner_is_disabled = person("has_disabled_spouse", period) eligible = ~dependent & (elderly | disabled | partner_is_disabled) + # Under Md. Code Tax-General § 10-209(d)(1) and Form 502 instructions + # (Worksheet 13A, line 1), military retirement income exceeding the + # § 10-207(q) military retirement subtraction qualifies for the + # general pension exclusion. + military_income = person("military_retirement_income", period) + military_subtraction = person( + "md_military_retirement_subtraction_amount", period + ) + excess_military = max_(0, military_income - military_subtraction) + # calculate pension subtraction amount for each person - peninc = add(person, period, p.pension.sources) + peninc = add(person, period, p.pension.sources) + excess_military socsec = person("social_security", period) amount = min_(peninc, max_(0, p.pension.max_amount - socsec)) # return pension subtraction amount for each eligible person diff --git a/policyengine_us/variables/gov/states/me/tax/income/adjusted_gross_income/me_pension_income_deduction.py b/policyengine_us/variables/gov/states/me/tax/income/adjusted_gross_income/me_pension_income_deduction.py index 74e668f9c3e..045b49f6391 100644 --- a/policyengine_us/variables/gov/states/me/tax/income/adjusted_gross_income/me_pension_income_deduction.py +++ b/policyengine_us/variables/gov/states/me/tax/income/adjusted_gross_income/me_pension_income_deduction.py @@ -37,7 +37,7 @@ def formula(tax_unit, period, parameters): ss_reduced_cap = max_(p.cap - gross_ss, 0) non_military_deduction = min_(pension_income, ss_reduced_cap) - military_retirement_pay = person("military_retirement_pay", period) + military_retirement = person("military_retirement_income", period) # Restrict to the head (and spouse if filing jointly) per Schedule 1S # line 4. @@ -52,9 +52,9 @@ def formula(tax_unit, period, parameters): total_non_military = where( is_joint, non_military_with_spouse, non_military_head_only ) - military_head_only = tax_unit.sum(where(is_head, military_retirement_pay, 0)) + military_head_only = tax_unit.sum(where(is_head, military_retirement, 0)) military_with_spouse = tax_unit.sum( - where(is_head | is_spouse, military_retirement_pay, 0) + where(is_head | is_spouse, military_retirement, 0) ) total_military = where(is_joint, military_with_spouse, military_head_only) diff --git a/policyengine_us/variables/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.py b/policyengine_us/variables/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.py index f8b7ea7cabc..298e32bf081 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/deductions/interest_dividends_capital_gains/mi_interest_dividends_capital_gains_deduction.py @@ -34,7 +34,10 @@ def formula(tax_unit, period, parameters): reductions_pay = add( person, period, - ["military_retirement_pay", "taxable_pension_income"], + [ + "military_retirement_income", + "taxable_pension_income", + ], ) elderly_disabled_credit = tax_unit("elderly_disabled_credit", period) diff --git a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.py b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.py index c6e48c01193..ad383d90463 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/expanded/mi_expanded_retirement_benefits_deduction.py @@ -54,7 +54,7 @@ def formula(tax_unit, period, parameters): # Line 1 tier_one_cap = p.tier_one.amount[filing_status] head_or_spouse_military_retirement_pay = ( - person("military_retirement_pay", period) * is_head_or_spouse + person("military_retirement_income", period) * is_head_or_spouse ) # Line 2 total_military_retirement_pay = tax_unit.sum( diff --git a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.py b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.py index 41afc7173ce..e38dd186796 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_one/mi_retirement_benefits_deduction_tier_one_amount.py @@ -32,7 +32,7 @@ def formula(tax_unit, period, parameters): # Line 10 is_head_or_spouse = person("is_tax_unit_head_or_spouse", period) military_retirement_pay = ( - person("military_retirement_pay", period) * is_head_or_spouse + person("military_retirement_income", period) * is_head_or_spouse ) total_military_retirement_pay = tax_unit.sum(military_retirement_pay) diff --git a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.py b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.py index 39aac5d1ec0..bdc3aa18b3a 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/not_retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_not_retired.py @@ -61,12 +61,10 @@ def formula(tax_unit, period, parameters): # If a filer is recieving military retirement pay, the calculation includes the smaller of # the tier one or tier three deduction amount - # Worksheet 3.2 counts only military retirement pay on the filer's Schedule 1, line 11, + # Worksheet 3.2 counts only military retirement income on the filer's Schedule 1, line 11, # which excludes a dependent's pay (not in the filer's AGI). - military_retirement_pay_received = ( - tax_unit.sum(person("military_retirement_pay", period) * is_head_or_spouse) - > 0 - ) + military_pay = person("military_retirement_income", period) * is_head_or_spouse + military_retirement_pay_received = tax_unit.sum(military_pay) > 0 # Line 8 tier_one_amount = tax_unit( "mi_retirement_benefits_deduction_tier_one_amount", diff --git a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.py b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.py index 8210b1e48cb..5a7ed0ced0f 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/deductions/retirement/tier_three/ss_exempt/retired/mi_retirement_benefits_deduction_tier_three_ss_exempt_retired.py @@ -76,12 +76,10 @@ def formula(tax_unit, period, parameters): # If a filer is recieving military retirement pay, the calculation includes the smaller of # the tier one or tier three deduction amount - # Worksheet 3.1 counts only military retirement pay on the filer's Schedule 1, line 11, + # Worksheet 3.1 counts only military retirement income on the filer's Schedule 1, line 11, # which excludes a dependent's pay (not in the filer's AGI). - military_retirement_pay_eligible = ( - tax_unit.sum(person("military_retirement_pay", period) * is_head_or_spouse) - > 0 - ) + military_pay = person("military_retirement_income", period) * is_head_or_spouse + military_retirement_pay_eligible = tax_unit.sum(military_pay) > 0 # Line 8 tier_one_amount = tax_unit( "mi_retirement_benefits_deduction_tier_one_amount", diff --git a/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.py b/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.py index 2798667deb7..059d5935ad1 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_three/mi_standard_deduction_tier_three.py @@ -30,8 +30,8 @@ def formula(tax_unit, period, parameters): person = tax_unit.members is_head_or_spouse = person("is_tax_unit_head_or_spouse", period) - # Line 2: enter military retirement pay - military_retirement_pay = person("military_retirement_pay", period) + # Line 2: enter military retirement pay and survivor benefits + military_retirement_income = person("military_retirement_income", period) # Line 3: enter military service income or taxable social security taxable_ss = person("taxable_social_security", period) military_service_income = person("military_service_income", period) @@ -43,7 +43,7 @@ def formula(tax_unit, period, parameters): mi_personal_exemptions = tax_unit("mi_personal_exemptions", period) # Line 5: add lines 2 through 4 total_person_reductions = tax_unit.sum( - is_head_or_spouse * (military_retirement_pay + larger_ss_or_military_pay) + is_head_or_spouse * (military_retirement_income + larger_ss_or_military_pay) ) total_reductions = total_person_reductions + mi_personal_exemptions # Line 6: subtract line 5 from line 1 diff --git a/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.py b/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.py index 6f87ca02091..d97feba92af 100644 --- a/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.py +++ b/policyengine_us/variables/gov/states/mi/tax/income/deductions/standard/tier_two/mi_standard_deduction_tier_two.py @@ -32,7 +32,10 @@ def formula(tax_unit, period, parameters): military_pay = add( person, period, - ["military_retirement_pay", "military_service_income"], + [ + "military_retirement_income", + "military_service_income", + ], ) is_head_or_spouse = person("is_tax_unit_head_or_spouse", period) head_or_spouse_military_pay = tax_unit.sum(military_pay * is_head_or_spouse) diff --git a/policyengine_us/variables/gov/states/mn/tax/income/amt/mn_amt_taxable_income.py b/policyengine_us/variables/gov/states/mn/tax/income/amt/mn_amt_taxable_income.py index 83736e79da5..eac3dca4bfc 100644 --- a/policyengine_us/variables/gov/states/mn/tax/income/amt/mn_amt_taxable_income.py +++ b/policyengine_us/variables/gov/states/mn/tax/income/amt/mn_amt_taxable_income.py @@ -30,6 +30,7 @@ def formula(tax_unit, period, parameters): "us_govt_interest", "mn_charity_subtraction", "mn_social_security_subtraction", + "mn_military_pension_subtraction", ] amt_subs = add(tax_unit, period, AMT_SUBTRACTIONS) return fagi - some_itm_deds - amt_subs diff --git a/policyengine_us/variables/gov/states/mn/tax/income/subtractions/mn_military_pension_subtraction.py b/policyengine_us/variables/gov/states/mn/tax/income/subtractions/mn_military_pension_subtraction.py index e02fa644808..6ef65353349 100644 --- a/policyengine_us/variables/gov/states/mn/tax/income/subtractions/mn_military_pension_subtraction.py +++ b/policyengine_us/variables/gov/states/mn/tax/income/subtractions/mn_military_pension_subtraction.py @@ -21,5 +21,5 @@ def formula(tax_unit, period, parameters): return tax_unit_non_dep_add( tax_unit, period, - ["military_retirement_pay", "military_retirement_pay_survivors"], + ["military_retirement_income"], ) diff --git a/policyengine_us/variables/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction_section_a.py b/policyengine_us/variables/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction_section_a.py index 70e8129ef39..3f9475edea3 100644 --- a/policyengine_us/variables/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction_section_a.py +++ b/policyengine_us/variables/gov/states/mo/tax/income/deductions/mo_pension_and_ss_or_ssd_deduction_section_a.py @@ -48,8 +48,9 @@ def formula(person, period, parameters): # AGI; they report it on their own return. head_or_spouse = person("is_tax_unit_head_or_spouse", period) public_pension_amount = ( - person("taxable_public_pension_income", period) * head_or_spouse - ) + person("taxable_public_pension_income", period) + + person("military_retirement_pay_survivors", period) + ) * head_or_spouse max_social_security_benefit = ( p.mo_max_social_security_benefit ) # Seen on Line 7, Section A diff --git a/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.py b/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.py index ad0d6c43f21..468857d1be1 100644 --- a/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.py +++ b/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_deduction.py @@ -37,10 +37,14 @@ def formula(tax_unit, period, parameters): # inputs. Otherwise the combined flag cannot establish own-pay # eligibility, which needs the recipient's service or medical record. own_pay_eligible = eligible & (~survivor | own_record_eligible) + # The fallback to `eligible` when `survivor_pay == 0` is retained for backward + # compatibility with legacy callers and tests where + # `nc_military_retirement_deduction_eligible` is set directly without populating + # the recipient's underlying service records (`years_in_military` or + # `is_permanently_disabled_veteran`). military_pay_eligible = where(survivor_pay > 0, own_pay_eligible, eligible) - # With no separate survivor amount, military_retirement_pay can instead - # contain only survivor benefits, as its documentation permits. Mixed - # own and survivor pay must be split between the two income inputs. + # Mixed own and survivor pay must be split between the two income inputs. + qualifying_pay = ( person("military_retirement_pay", period) * military_pay_eligible + survivor_pay * survivor * eligible diff --git a/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_survivor_eligible.py b/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_survivor_eligible.py index 792a626fd62..2ac2f671820 100644 --- a/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_survivor_eligible.py +++ b/policyengine_us/variables/gov/states/nc/tax/income/deductions/military_retirement/nc_military_retirement_survivor_eligible.py @@ -19,8 +19,6 @@ class nc_military_retirement_survivor_eligible(Variable): "is_permanently_disabled_veteran record: setting the combined " "nc_military_retirement_deduction_eligible input to true alone " "does not establish eligibility for their own pay. " - "If military_retirement_pay_survivors is zero, this flag also allows " - "military_retirement_pay to contain qualifying survivor benefits. " "Do not record the same survivor benefits in both income inputs." ) definition_period = YEAR diff --git a/policyengine_us/variables/gov/states/ne/tax/income/adjusted_gross_income/subtractions/ne_military_retirement_substraction.py b/policyengine_us/variables/gov/states/ne/tax/income/adjusted_gross_income/subtractions/ne_military_retirement_subtraction.py similarity index 84% rename from policyengine_us/variables/gov/states/ne/tax/income/adjusted_gross_income/subtractions/ne_military_retirement_substraction.py rename to policyengine_us/variables/gov/states/ne/tax/income/adjusted_gross_income/subtractions/ne_military_retirement_subtraction.py index 214de6b0576..803b453e703 100644 --- a/policyengine_us/variables/gov/states/ne/tax/income/adjusted_gross_income/subtractions/ne_military_retirement_substraction.py +++ b/policyengine_us/variables/gov/states/ne/tax/income/adjusted_gross_income/subtractions/ne_military_retirement_subtraction.py @@ -23,7 +23,11 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) age_eligible = age >= p.age_threshold - military_retirement_benefit = person("military_retirement_pay", period) + military_retirement_pay = person("military_retirement_pay", period) + survivor_pay = ( + person("military_retirement_pay_survivors", period) * p.survivors_eligible + ) + military_retirement_benefit = military_retirement_pay + survivor_pay # Dependents' income is not in federal AGI; they report it on their # own return. head_or_spouse = person("is_tax_unit_head_or_spouse", period) diff --git a/policyengine_us/variables/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.py b/policyengine_us/variables/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.py index d44aa2d8bf4..0b54ffc5ba3 100644 --- a/policyengine_us/variables/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.py +++ b/policyengine_us/variables/gov/states/nj/tax/income/deductions/plan_529_contributions/nj_529_deduction.py @@ -17,9 +17,10 @@ def formula(person, period, parameters): p = parameters( period ).gov.states.nj.tax.income.deductions.plan_529_contributions - # Check AGI income limit - agi = person.tax_unit("adjusted_gross_income", period) - income_eligible = agi <= p.income_limit + # Check NJ gross income limit (NJ-1040 line 29) + nj_agi = person.tax_unit("nj_agi", period) + income_eligible = nj_agi <= p.income_limit + # Get the TaxUnit-level deduction cap total_contributions = person.tax_unit("investment_in_529_plan", period) unit_deduction = min_(total_contributions, p.cap) diff --git a/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_armed_forces_retirement_pay_exemption_person.py b/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_armed_forces_retirement_pay_exemption_person.py index 6e4d9988ec0..96301c66b50 100644 --- a/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_armed_forces_retirement_pay_exemption_person.py +++ b/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_armed_forces_retirement_pay_exemption_person.py @@ -14,7 +14,8 @@ def formula(person, period, parameters): p = parameters( period ).gov.states.nm.tax.income.exemptions.armed_forces_retirement_pay - armed_forces_retirement_pay = person("military_retirement_pay", period) + armed_forces_retirement_pay = person("military_retirement_income", period) + capped_amount = min_(armed_forces_retirement_pay, p.cap) qualifies = person("is_tax_unit_head_or_spouse", period) return qualifies * capped_amount diff --git a/policyengine_us/variables/gov/states/oh/tax/income/deductions/oh_uniformed_services_retirement_income_deduction.py b/policyengine_us/variables/gov/states/oh/tax/income/deductions/oh_uniformed_services_retirement_income_deduction.py index 3f38596b82e..83d4899436f 100644 --- a/policyengine_us/variables/gov/states/oh/tax/income/deductions/oh_uniformed_services_retirement_income_deduction.py +++ b/policyengine_us/variables/gov/states/oh/tax/income/deductions/oh_uniformed_services_retirement_income_deduction.py @@ -4,8 +4,16 @@ class oh_uniformed_services_retirement_income_deduction(Variable): value_type = float entity = Person - label = "Ohio Uniformed services retirement income" + label = "Ohio uniformed services retirement income deduction" definition_period = YEAR unit = USD - reference = "https://tax.ohio.gov/static/forms/ohio_individual/individual/2022/it1040-bundle.pdf#page=4" + reference = ( + "https://codes.ohio.gov/ohio-revised-code/section-5747.01#A_23", + "https://tax.ohio.gov/static/forms/ohio_individual/individual/2022/it1040-bundle.pdf#page=4", + ) defined_for = StateCode.OH + + def formula(person, period, parameters): + is_head_or_spouse = person("is_tax_unit_head_or_spouse", period) + military_retirement = person("military_retirement_income", period) + return is_head_or_spouse * military_retirement diff --git a/policyengine_us/variables/gov/states/ok/tax/income/subtractions/ok_military_retirement_exclusion.py b/policyengine_us/variables/gov/states/ok/tax/income/subtractions/ok_military_retirement_exclusion.py index a686e17469f..180594bee87 100644 --- a/policyengine_us/variables/gov/states/ok/tax/income/subtractions/ok_military_retirement_exclusion.py +++ b/policyengine_us/variables/gov/states/ok/tax/income/subtractions/ok_military_retirement_exclusion.py @@ -24,7 +24,8 @@ def formula(tax_unit, period, parameters): period ).gov.states.ok.tax.income.agi.subtractions.military_retirement person = tax_unit.members - military_retirement_benefits = person("military_retirement_pay", period) + military_retirement_benefits = person("military_retirement_income", period) + adjust_military_retirement_amount = military_retirement_benefits * p.rate capped_exclusion_amount = max_(p.floor, adjust_military_retirement_amount) # Dependents' income is not in federal AGI; they report it on their diff --git a/policyengine_us/variables/gov/states/or/tax/income/credits/retirement_credit/or_retirement_credit.py b/policyengine_us/variables/gov/states/or/tax/income/credits/retirement_credit/or_retirement_credit.py index 37c6920071b..deac860a046 100644 --- a/policyengine_us/variables/gov/states/or/tax/income/credits/retirement_credit/or_retirement_credit.py +++ b/policyengine_us/variables/gov/states/or/tax/income/credits/retirement_credit/or_retirement_credit.py @@ -16,7 +16,10 @@ def formula(tax_unit, period, parameters): # Line 1, retirement income person = tax_unit.members eligible = person("or_retirement_credit_eligible_person", period) - retirement_income = eligible * person("taxable_pension_income", period) + pension = person("taxable_pension_income", period) + person( + "military_retirement_income", period + ) + retirement_income = eligible * pension total_retirement_income = tax_unit.sum(retirement_income) # Line 2, federal pension subtraction diff --git a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_eligibility_income.py b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_eligibility_income.py index 5e84425cb75..89f5a5f0578 100644 --- a/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_eligibility_income.py +++ b/policyengine_us/variables/gov/states/pa/tax/income/forgiveness/pa_eligibility_income.py @@ -12,4 +12,11 @@ class pa_eligibility_income(Variable): reference = "https://www.pa.gov/content/dam/copapwp-pagov/en/revenue/documents/formsandpublications/formsforindividuals/pit/documents/2021/2021_pa-40sp.pdf" defined_for = StateCode.PA - adds = "gov.states.pa.tax.income.forgiveness.eligibility_income_sources" + def formula(tax_unit, period, parameters): + sources = parameters( + period + ).gov.states.pa.tax.income.forgiveness.eligibility_income_sources + # The sources are amounts of the claimant and spouse; dependents file + # their own PA return and their income is not part of the filer's + # eligibility income. + return tax_unit_non_dep_add(tax_unit, period, sources) diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_eligible.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_eligible.py index cade8f049d3..71016fee68b 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_eligible.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_eligible.py @@ -12,9 +12,12 @@ class ut_military_retirement_credit_eligible(Variable): def formula(tax_unit, period, parameters): # Has military retirement pay included in federal AGI, which excludes # dependents' income; dependents report it on their own return. - military_retirement_pay = tax_unit_non_dep_sum( - "military_retirement_pay", tax_unit, period + military_retirement_pay = tax_unit_non_dep_add( + tax_unit, + period, + ["military_retirement_income"], ) + has_military_retirement_pay = military_retirement_pay > 0 # Cannot claim if claiming the retirement credit (code 18) claims_retirement_credit = tax_unit("ut_claims_retirement_credit", period) diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py index dfd712fefa9..011e94faa60 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/military_retirement_credit/ut_military_retirement_credit_potential.py @@ -14,8 +14,11 @@ def formula(tax_unit, period, parameters): # 59-10-1043(2)(b): only the pay included in adjusted gross income on # the claimant's federal return, which excludes dependents' income; # dependents report it on their own return. - military_retirement_pay = tax_unit_non_dep_sum( - "military_retirement_pay", tax_unit, period + military_retirement_pay = tax_unit_non_dep_add( + tax_unit, + period, + ["military_retirement_income"], ) + p = parameters(period).gov.states.ut.tax.income.credits.military_retirement return military_retirement_pay * p.rate diff --git a/policyengine_us/variables/gov/states/va/tax/income/subtractions/va_military_benefit_subtraction_person.py b/policyengine_us/variables/gov/states/va/tax/income/subtractions/va_military_benefit_subtraction_person.py index 7196e7e2112..e969fff99c7 100644 --- a/policyengine_us/variables/gov/states/va/tax/income/subtractions/va_military_benefit_subtraction_person.py +++ b/policyengine_us/variables/gov/states/va/tax/income/subtractions/va_military_benefit_subtraction_person.py @@ -12,7 +12,11 @@ class va_military_benefit_subtraction_person(Variable): def formula(person, period, parameters): p = parameters(period).gov.states.va.tax.income.subtractions.military_benefit - subtractable = min_(person("military_retirement_pay", period), p.amount) + subtractable = min_( + person("military_retirement_income", period), + p.amount, + ) + eligible = person("is_tax_unit_head_or_spouse", period) if p.availability: eligible = eligible & (person("age", period) >= p.age_threshold) diff --git a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_income_based_exemption.py b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_income_based_exemption.py index 387a12db3dc..fff4aba271d 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_income_based_exemption.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_income_based_exemption.py @@ -20,8 +20,10 @@ def formula(tax_unit, period, parameters): # Get retirement amount from military retirement system # Dependents' income is not in federal AGI; they report it on their # own return, so only the head's and spouse's pay counts. - tax_unit_military_retirement_pay = tax_unit_non_dep_sum( - "military_retirement_pay", tax_unit, period + tax_unit_military_retirement_pay = tax_unit_non_dep_add( + tax_unit, + period, + ["military_retirement_income"], ) agi = tax_unit("adjusted_gross_income", period) diff --git a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_pay_exclusion.py b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_pay_exclusion.py index 64e81b7660b..55d3a72cbfe 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_pay_exclusion.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/retirement_income_exemption/vt_military_retirement_pay_exclusion.py @@ -16,16 +16,8 @@ class vt_military_retirement_pay_exclusion(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.vt.tax.income.agi.retirement_income_exemption - # Get retirement amount from military retirement system - # Dependents' income is not in federal AGI; they report it on their - # own return, so only the head's and spouse's pay counts. - tax_unit_military_retirement_pay = tax_unit_non_dep_sum( - "military_retirement_pay", tax_unit, period - ) - # S.51 (2025): Income-based military pension exemption is_income_based_system = p.military_retirement.income_based_structure.in_effect - agi = tax_unit("adjusted_gross_income", period) # Calculate exemption based on system type income_based_exemption = tax_unit( 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 b5b64167c1a..a32b84737d9 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 @@ -25,14 +25,17 @@ def formula(tax_unit, period, parameters): # One of the retirement income should be greater than 0 # Dependents' income is not in federal AGI; they report it on their # own return, so only the head's and spouse's pay counts. + retirement_sources = [ + "tax_unit_taxable_social_security", + "military_retirement_pay", + "csrs_retirement_pay", + ] + if p.military_retirement.income_based_structure.in_effect: + retirement_sources.append("military_retirement_pay_survivors") retirement_income = tax_unit_non_dep_add( tax_unit, period, - [ - "tax_unit_taxable_social_security", - "military_retirement_pay", - "csrs_retirement_pay", - ], + retirement_sources, ) retirement_income_qualified = retirement_income > 0 # Determine which retirement system the filer uses, mirroring the diff --git a/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_income_subtractions.py b/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_income_subtractions.py index b11879fe327..77999458b0c 100644 --- a/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_income_subtractions.py +++ b/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_income_subtractions.py @@ -17,6 +17,6 @@ class wi_income_subtractions(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.wi.tax.income.subtractions - total_subtractions = add(tax_unit, period, p.sources) + total_subtractions = tax_unit_non_dep_add(tax_unit, period, p.sources) # Prevent negative subtractions from acting as additions return max_(0, total_subtractions) diff --git a/policyengine_us/variables/household/income/person/general/market_income.py b/policyengine_us/variables/household/income/person/general/market_income.py index a8dd2902b24..6447143a423 100644 --- a/policyengine_us/variables/household/income/person/general/market_income.py +++ b/policyengine_us/variables/household/income/person/general/market_income.py @@ -27,5 +27,6 @@ def formula(person, period, parameters): "alimony_income", "strike_benefits", "retirement_distributions", + "military_retirement_income", ] return add(person, period, COMPONENTS) diff --git a/policyengine_us/variables/household/income/person/retirement/military_retirement_income.py b/policyengine_us/variables/household/income/person/retirement/military_retirement_income.py new file mode 100644 index 00000000000..76e850d4ddb --- /dev/null +++ b/policyengine_us/variables/household/income/person/retirement/military_retirement_income.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class military_retirement_income(Variable): + value_type = float + entity = Person + label = "Military retirement income" + unit = USD + definition_period = YEAR + documentation = ( + "Total military retirement income, combining military retirement pay " + "and military retirement survivor benefit payments." + ) + reference = ( + "https://militarypay.defense.gov/Pay/Retirement/", + "https://www.irs.gov/pub/irs-prior/p525--2024.pdf#page=16", + ) + adds = ["military_retirement_pay", "military_retirement_pay_survivors"] diff --git a/policyengine_us/variables/household/income/person/retirement/military_retirement_pay.py b/policyengine_us/variables/household/income/person/retirement/military_retirement_pay.py index b0bac6477ad..8a9a5539c9e 100644 --- a/policyengine_us/variables/household/income/person/retirement/military_retirement_pay.py +++ b/policyengine_us/variables/household/income/person/retirement/military_retirement_pay.py @@ -7,6 +7,22 @@ class military_retirement_pay(Variable): label = "Military retirement pay" unit = USD definition_period = YEAR - documentation = "The benefits received under a United States military retirement plan, including survivor benefits." - reference = "https://militarypay.defense.gov/Pay/Retirement/" + documentation = ( + "Taxable retirement pay received by former members of the uniformed services " + "of the United States, meaning after the Survivor Benefit Plan (SBP) premium reduction, " + "and excluding Combat-Related Special Compensation (CRSC) and disability retirement pay " + "excludable under 26 U.S.C. § 104 (see IRS Pub 525 (2024), p. 16). Excludable amounts " + "such as CRSC and VA Dependency and Indemnity Compensation (DIC) should be reported " + "under veterans_benefits. Included in federal gross income under 26 U.S.C. § 61(a)(10).\n\n" + "Known limitations:\n" + "- Montana (MCA 15-30-2120(3)(n)): allows a deduction of up to 50% of military retired pay " + "(capped at Montana earned income) starting in 2024; this deduction is not yet modeled.\n" + "- North Carolina (N.C. Gen. Stat. § 105-153.5(b)(5a)): deduction requires either 20 years of military " + "service or medical retirement; entering military_retirement_pay alone without service record " + "variables (years_in_military or is_permanently_disabled_veteran) defaults to no deduction." + ) + reference = ( + "https://militarypay.defense.gov/Pay/Retirement/", + "https://www.irs.gov/pub/irs-prior/p525--2024.pdf#page=16", + ) uprating = "calibration.gov.irs.soi.taxable_pension_income" diff --git a/policyengine_us/variables/household/income/person/retirement/military_retirement_pay_survivors.py b/policyengine_us/variables/household/income/person/retirement/military_retirement_pay_survivors.py index df7f481d9bc..2cc783b8a4e 100644 --- a/policyengine_us/variables/household/income/person/retirement/military_retirement_pay_survivors.py +++ b/policyengine_us/variables/household/income/person/retirement/military_retirement_pay_survivors.py @@ -4,7 +4,26 @@ class military_retirement_pay_survivors(Variable): value_type = float entity = Person - label = "Military retirement income paid to surviving spouses" + label = "Military retirement survivor benefit payments" unit = USD definition_period = YEAR + documentation = ( + "Taxable survivor annuity payments received by surviving spouses, dependent children, " + "or other designated annuitants under a United States uniformed services retirement plan " + "(such as the Survivor Benefit Plan (SBP) or Retired Serviceman's Family Protection Plan). " + "Excludes tax-exempt payments such as VA Dependency and Indemnity Compensation (DIC), " + "which should be reported under veterans_benefits (see IRS Pub 525 (2024), p. 16). " + "Included in federal gross income under 26 U.S.C. § 61(a)(10) and § 72.\n\n" + "Known limitations:\n" + "- Montana (MCA 15-30-2120(3)(n)(ii)): allows exempting up to 50% of military survivor benefits " + "regardless of other income starting in 2024 (Form WMRE); this deduction is not yet modeled.\n" + "- North Carolina (N.C. Gen. Stat. § 105-153.5(b)(5a)): deduction requires either 20 years of military " + "service or medical retirement; entering military_retirement_pay_survivors alone without survivor " + "eligibility variables (nc_military_retirement_survivor_eligible) defaults to no deduction." + ) + reference = ( + "https://militarypay.defense.gov/Benefits/Survivor-Benefit-Program/", + "https://www.irs.gov/pub/irs-prior/p525--2024.pdf#page=16", + "https://www.irs.gov/publications/p575", + ) uprating = "calibration.gov.irs.soi.taxable_pension_income"