diff --git a/changelog.d/claimable-filer-ri-sc-ut-vt-wv-wi.fixed.md b/changelog.d/claimable-filer-ri-sc-ut-vt-wv-wi.fixed.md new file mode 100644 index 00000000000..d6e730396ae --- /dev/null +++ b/changelog.d/claimable-filer-ri-sc-ut-vt-wv-wi.fixed.md @@ -0,0 +1,11 @@ +Apply the Rhode Island, South Carolina, Utah, Vermont, West Virginia and Wisconsin rules for a filer who can be claimed as a dependent. On such a return, apply them to dependent exemptions, deductions and child credits, to the Wisconsin dependent standard deduction and to the West Virginia exemptions. Apply the Rhode Island and Vermont claimant tests for property tax relief and the renter credit, and Wisconsin's limits on care expenses. + +Count each claimable filer's West Virginia 11-21-16(d) exemption in the low-income family tax credit's family size, and let a return with no other exemption claim the credit. + +Count as Utah qualifying dependents only those for whom the federal child tax credit or credit for other dependents is allowed, in the exemption, the birth-year dependent and the contributed reform. + +Preserve claimable-filer counts and the dependent-claimant filing exception in the contributed Rhode Island, South Carolina, Utah, Vermont and West Virginia exemption reforms. Preserve the Rhode Island and Wisconsin filer counts under the state dependent exemption repeal. For West Virginia returns on which no dependent adds an exemption, preserve the statutory $500 allowance per claimable filer in the baseline and contributed reform. Apply it to every claimable filer under the repeal override. Keep the existing count when dependents add exemptions, pending a ruling. + +Measure Wisconsin dependent standard deduction earnings on both tax paths with the federal worksheet's earned income: wages after pretax payroll deductions, taxable disability wages, and business and farm income, less the self-employment tax deduction. + +Use HUD zero-bedroom rents for zero-exemption Vermont renters in every stored fair market rent year (2021–2025). diff --git a/policyengine_us/parameters/gov/states/vt/tax/income/credits/renter/fair_market_rent.yaml b/policyengine_us/parameters/gov/states/vt/tax/income/credits/renter/fair_market_rent.yaml index 6ddecf03a2c..0dfc6f7cc62 100644 --- a/policyengine_us/parameters/gov/states/vt/tax/income/credits/renter/fair_market_rent.yaml +++ b/policyengine_us/parameters/gov/states/vt/tax/income/credits/renter/fair_market_rent.yaml @@ -1,12 +1,12 @@ -description: Vermont sets these fair market rent amounts, based on the county and household size. +description: Vermont sets these fair market rent amounts, based on the county and the number of bedrooms allowed by personal exemptions. metadata: propagate_metadata_to_children: true unit: currency-USD period: month breakdown: - - list(range(1,9)) + - list(range(0,9)) breakdown_labels: - - Household size + - Bedrooms (personal exemptions) label: Vermont fair market rent amount reference: # The values are derived from the renter credit computation tables which represent 10% of the @@ -43,9 +43,19 @@ metadata: href: https://www.huduser.gov/portal/datasets/fmr/fmr2022/FY22_FMRs.xlsx - title: HUD FY2021 Fair Market Rents href: https://www.huduser.gov/portal/datasets/fmr/fmr2021/FY21_4050_FMRs_rev.xlsx + - title: "HUD FY2021 Final Fair Market Rent Schedule #page 48-49" + href: https://www.huduser.gov/portal/datasets/fmr/fmr2021/FY2021-ScheduleB.pdf#page=48 + - title: "HUD FY2022 Fair Market Rent Schedule #page 48-50" + href: https://www.huduser.gov/portal/datasets/fmr/fmr2022/FY2022_FMR_Schedule.pdf#page=48 + - title: "HUD FY2023 Fair Market Rent Schedule #page 49-50" + href: https://www.huduser.gov/portal/datasets/fmr/fmr2023/FY2023_FMR_Schedule.pdf#page=49 + - title: "HUD FY2024 Fair Market Rent Schedule #page 51-52" + href: https://www.huduser.gov/portal/datasets/fmr/fmr2024/FY2024_FMR_Schedule.pdf#page=51 + - title: "HUD FY2025 Fair Market Rent Schedule #page 51-52" + href: https://www.huduser.gov/portal/datasets/fmr/fmr2025/FY2025_FMR_Schedule.pdf#page=51 # Each county's value is HUD's fair market rent for the fiscal year that includes # June 30 of the taxable year (FY2025 for 2025), for the county's HUD area, with -# household size n using the min(n, 4)-bedroom rent. Chittenden's 2,083 is the +# exemption count n using the min(n, 4)-bedroom rent. Chittenden's 2,083 is the # rent at which 10% x 12 reaches the $2,500 maximum the department applies to # the credit amount (2,500 / 1.2 = 2,083.33). # @@ -64,6 +74,104 @@ metadata: # - 2023 reconstruction: the average with the Burlington four-bedroom rent # (2,170) held to 2,083.33 (all 12 unadjusted give 1,913, not the published 1,904). # - 2025: the unrounded average (1,057.75 x 1.2 = 1,269.3, published 1,269). +# Zero-bedroom rents below are the published HUD 0 BR amounts. Franklin and +# Grand Isle use the unrounded arithmetic mean of all 12 Vermont HUD FMR areas, +# following the state-average rule in 6061(7)(C). This is the averaging convention +# that reproduces the department's unrounded 2025 rents. These zero-bedroom +# values are calculated from HUD schedules rather than department credit tables. +# The unrounded 12-area method is used in every year. It differs from the +# existing 1-4 bedroom reconstructions in 2021 and 2024 (whole-dollar rounding) +# and 2022 (Addison excluded). Applying those alternatives to zero bedrooms +# gives full-year credits of $883 either way in 2021, $919 versus $918 in 2022, +# and $1,172 versus $1,171 in 2024 (this method first); 2023 and 2025 agree. +# A 14-county average instead weights the Burlington area three times and +# gives a 2025 zero-bedroom credit of $1,273 versus this method's $1,209. +# Section 6061(7)(C) does not specify averaging weights or intermediate rounding. +0: + ADDISON_COUNTY_VT: + 2021-01-01: 751 + 2022-01-01: 779 + 2023-01-01: 842 + 2024-01-01: 1_017 + 2025-01-01: 1_096 + BENNINGTON_COUNTY_VT: + 2021-01-01: 710 + 2022-01-01: 763 + 2023-01-01: 849 + 2024-01-01: 936 + 2025-01-01: 936 + CALEDONIA_COUNTY_VT: + 2021-01-01: 708 + 2022-01-01: 741 + 2023-01-01: 810 + 2024-01-01: 899 + 2025-01-01: 905 + CHITTENDEN_COUNTY_VT: + 2021-01-01: 1_091 + 2022-01-01: 1_033 + 2023-01-01: 1_139 + 2024-01-01: 1_341 + 2025-01-01: 1_380 + ESSEX_COUNTY_VT: + 2021-01-01: 560 + 2022-01-01: 585 + 2023-01-01: 730 + 2024-01-01: 812 + 2025-01-01: 823 + FRANKLIN_COUNTY_VT: + 2021-01-01: 736.0833333333334 + 2022-01-01: 766 + 2023-01-01: 849.0833333333334 + 2024-01-01: 976.3333333333334 + 2025-01-01: 1_007.6666666666666 + GRAND_ISLE_COUNTY_VT: + 2021-01-01: 736.0833333333334 + 2022-01-01: 766 + 2023-01-01: 849.0833333333334 + 2024-01-01: 976.3333333333334 + 2025-01-01: 1_007.6666666666666 + LAMOILLE_COUNTY_VT: + 2021-01-01: 788 + 2022-01-01: 801 + 2023-01-01: 874 + 2024-01-01: 913 + 2025-01-01: 883 + ORANGE_COUNTY_VT: + 2021-01-01: 740 + 2022-01-01: 787 + 2023-01-01: 852 + 2024-01-01: 976 + 2025-01-01: 1_013 + ORLEANS_COUNTY_VT: + 2021-01-01: 592 + 2022-01-01: 638 + 2023-01-01: 706 + 2024-01-01: 831 + 2025-01-01: 845 + RUTLAND_COUNTY_VT: + 2021-01-01: 764 + 2022-01-01: 814 + 2023-01-01: 904 + 2024-01-01: 991 + 2025-01-01: 992 + WASHINGTON_COUNTY_VT: + 2021-01-01: 717 + 2022-01-01: 760 + 2023-01-01: 839 + 2024-01-01: 985 + 2025-01-01: 1_075 + WINDHAM_COUNTY_VT: + 2021-01-01: 697 + 2022-01-01: 734 + 2023-01-01: 803 + 2024-01-01: 976 + 2025-01-01: 1_020 + WINDSOR_COUNTY_VT: + 2021-01-01: 715 + 2022-01-01: 757 + 2023-01-01: 841 + 2024-01-01: 1_039 + 2025-01-01: 1_124 1: ADDISON_COUNTY_VT: 2021-01-01: 846 diff --git a/policyengine_us/parameters/gov/states/wv/tax/income/exemptions/base_personal.yaml b/policyengine_us/parameters/gov/states/wv/tax/income/exemptions/base_personal.yaml index ac4a5c8f5a7..3d5916fca1d 100644 --- a/policyengine_us/parameters/gov/states/wv/tax/income/exemptions/base_personal.yaml +++ b/policyengine_us/parameters/gov/states/wv/tax/income/exemptions/base_personal.yaml @@ -1,12 +1,14 @@ -description: West Virginia provides an income tax exemption of this value for tax units with no exemptions claimed. +description: West Virginia provides this personal income tax exemption for each individual who is claimable as a dependent on another return. values: 1987-01-01: 500 metadata: period: year unit: currency-USD - label: West Virginia personal exemption + label: West Virginia claimable filer personal exemption reference: + - title: "1988 West Virginia H.B. 4472, enacted personal exemptions #page 9-10" + href: https://code.wvlegislature.gov/signed_bills/1988/1988-RS-HB4472-SUB%20ENR_signed.pdf#page=9 - title: West Virginia Personal Income Tax Forms And Instructions 2025 href: https://tax.wv.gov/Documents/PIT/2025/it140.PersonalIncomeTaxFormsAndInstructions.2025.pdf#page=26 - title: West Virginia Personal Income Tax Forms And Instructions 2024 diff --git a/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py b/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py index 862d1e6c8c7..eabb1c43696 100644 --- a/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py +++ b/policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py @@ -167,7 +167,10 @@ class ri_exemptions(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.ri.tax.income.exemption - exemptions_count = tax_unit("head_spouse_count", period) + # Repeal removes dependents, preserving the baseline filer count. + exemptions_count = tax_unit( + "head_spouse_count_not_dependent_elsewhere", period + ) exemption_amount = exemptions_count * p.amount @@ -235,10 +238,25 @@ class wv_personal_exemption(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.wv.tax.income.exemptions - tax_unit_size = tax_unit("head_spouse_count", period) - return where( - tax_unit_size == 0, p.base_personal, p.personal * tax_unit_size + own_exemptions = tax_unit( + "head_spouse_count_not_dependent_elsewhere", period ) + # Repeal preserves each claimable filer's statutory $500. The + # ordinary amount counts only own exemptions, so dependents add + # nothing here and the per-filer amount applies whenever a filer + # can be claimed. + person = tax_unit.members + claimable_filers = tax_unit.sum( + person("is_tax_unit_head_or_spouse", period) + & person("claimable_as_dependent_on_another_return", period) + ) + filer_allowances = ( + p.personal * own_exemptions + p.base_personal * claimable_filers + ) + ordinary_amount = where( + own_exemptions == 0, p.base_personal, p.personal * own_exemptions + ) + return where(claimable_filers > 0, filer_allowances, ordinary_amount) class ca_exemptions(Variable): value_type = float @@ -392,7 +410,6 @@ def formula(tax_unit, period, parameters): ) return exempt_status.base[filing_status] + personal_exemptions_added - # Using head and spouse count instead of exemptions count class wi_base_exemption(Variable): value_type = float entity = TaxUnit @@ -411,7 +428,11 @@ class wi_base_exemption(Variable): def formula(tax_unit, period, parameters): # compute base exemption amount p = parameters(period).gov.states.wi.tax.income - return tax_unit("head_spouse_count", period) * p.exemption.base + # Repeal removes dependents, preserving the baseline filer count. + own_exemptions = tax_unit( + "head_spouse_count_not_dependent_elsewhere", period + ) + return own_exemptions * p.exemption.base class de_personal_credit(Variable): value_type = float diff --git a/policyengine_us/reforms/states/ri/exemption/ri_exemption_reform.py b/policyengine_us/reforms/states/ri/exemption/ri_exemption_reform.py index edd25e32b79..ecf00256286 100644 --- a/policyengine_us/reforms/states/ri/exemption/ri_exemption_reform.py +++ b/policyengine_us/reforms/states/ri/exemption/ri_exemption_reform.py @@ -16,7 +16,10 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) - is_dependent = person("is_tax_unit_dependent", period) + # Retain the baseline dependent taxpayer test and filing exception. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # Apply age limit if in effect if p.age_limit.in_effect: @@ -83,7 +86,10 @@ class ri_older_dependents_count(Variable): def formula(tax_unit, period, parameters): person = tax_unit.members - is_dependent = person("is_tax_unit_dependent", period) + # Retain the baseline dependent taxpayer test and filing exception. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) total_dependents = tax_unit.sum(is_dependent) eligible_dependent_exemptions = tax_unit( "ri_eligible_dependents_count", period @@ -101,17 +107,13 @@ class ri_exemptions(Variable): def formula(tax_unit, period, parameters): p_base = parameters(period).gov.states.ri.tax.income.exemption - # Calculate personal exemptions base amount - filing_status = tax_unit("filing_status", period) - older_dependents = tax_unit("ri_older_dependents_count", period) - personal_exemptions = ( - where( - filing_status == filing_status.possible_values.JOINT, - 2, - 1, - ) - + older_dependents + # Preserve the baseline exclusion of claimable filers, even when + # the filing exception permits them to claim their dependents. + own_exemptions = tax_unit( + "head_spouse_count_not_dependent_elsewhere", period ) + older_dependents = tax_unit("ri_older_dependents_count", period) + personal_exemptions = own_exemptions + older_dependents personal_exemption_base = personal_exemptions * p_base.amount # Apply baseline phase-out to personal exemptions diff --git a/policyengine_us/reforms/states/sc/dependent_exemption/sc_dependent_exemption_reform.py b/policyengine_us/reforms/states/sc/dependent_exemption/sc_dependent_exemption_reform.py index ccb3db4039e..f227705ede8 100644 --- a/policyengine_us/reforms/states/sc/dependent_exemption/sc_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/sc/dependent_exemption/sc_dependent_exemption_reform.py @@ -21,7 +21,11 @@ def formula(tax_unit, period, parameters): period ).gov.states.sc.tax.income.deductions.dependent_exemption.amount person = tax_unit.members - is_dependent = person("is_tax_unit_dependent", period) + # Apply the dependent taxpayer test before either age path, + # preserving the claimant filing exception (IRC 152(b)(1)). + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # Age gate: when in effect, only dependents under the chosen age # are re-priced to the reform amount; older dependents keep the # baseline exemption. Otherwise every dependent is re-priced, diff --git a/policyengine_us/reforms/states/ut/dependent_exemption/ut_dependent_exemption_reform.py b/policyengine_us/reforms/states/ut/dependent_exemption/ut_dependent_exemption_reform.py index 5e4ebc0dccc..84f0200ba99 100644 --- a/policyengine_us/reforms/states/ut/dependent_exemption/ut_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/ut/dependent_exemption/ut_dependent_exemption_reform.py @@ -33,7 +33,11 @@ def formula(tax_unit, period, parameters): return p.personal_exemption * total_dependents person = tax_unit.members age = person("age", period) - dependent = person("is_tax_unit_dependent", period) + # Count the baseline's qualifying dependents (59-10-1018(1)(c)): + # those for whom the claimant is allowed an IRC 24 credit, which + # a return on which a filer can be claimed as a dependent has none + # of (IRC 152(b)(1)) outside the claimant filing exception. + dependent = person("ut_qualifying_dependent", period) # Dependents under the age threshold (all dependents when the # age limit is off) take the contrib amount; older dependents # keep the baseline (uprated) personal-exemption amount. diff --git a/policyengine_us/reforms/states/vt/dependent_exemption/vt_dependent_exemption_reform.py b/policyengine_us/reforms/states/vt/dependent_exemption/vt_dependent_exemption_reform.py index 35ba6e2a210..69440c7d77b 100644 --- a/policyengine_us/reforms/states/vt/dependent_exemption/vt_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/vt/dependent_exemption/vt_dependent_exemption_reform.py @@ -15,7 +15,10 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) - is_dependent = person("is_tax_unit_dependent", period) + # Retain the baseline dependent taxpayer test and filing exception. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # Apply age limit if in effect if p.age_limit.in_effect: @@ -49,7 +52,11 @@ class vt_older_dependents_count(Variable): def formula(tax_unit, period, parameters): person = tax_unit.members - is_dependent = person("is_tax_unit_dependent", period) + # Mask the fallback too, so disallowed children cannot reappear + # as older dependents after the eligible count is reduced. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) total_dependents = tax_unit.sum(is_dependent) eligible_dependent_exemptions = tax_unit( "vt_eligible_dependents_count", period diff --git a/policyengine_us/reforms/states/wv/dependent_exemption/wv_dependent_exemption_reform.py b/policyengine_us/reforms/states/wv/dependent_exemption/wv_dependent_exemption_reform.py index 933e8deed81..4af8b64ba2a 100644 --- a/policyengine_us/reforms/states/wv/dependent_exemption/wv_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/wv/dependent_exemption/wv_dependent_exemption_reform.py @@ -15,7 +15,10 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) - is_dependent = person("is_tax_unit_dependent", period) + # Retain the baseline dependent taxpayer test and filing exception. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # Apply age limit if in effect if p.age_limit.in_effect: @@ -49,7 +52,10 @@ class wv_older_dependents_count(Variable): def formula(tax_unit, period, parameters): person = tax_unit.members - is_dependent = person("is_tax_unit_dependent", period) + # Apply the same gate to the older-dependent fallback. + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) total_dependents = tax_unit.sum(is_dependent) eligible_dependent_exemptions = tax_unit( "wv_eligible_dependents_count", period @@ -67,22 +73,32 @@ class wv_personal_exemption(Variable): def formula(tax_unit, period, parameters): p_base = parameters(period).gov.states.wv.tax.income.exemptions - # Personal exemptions exclude the dependent portion (head + spouse + - # any over-age dependents that fall back to the personal count). - tax_unit_size = tax_unit("tax_unit_size", period) - dependents = tax_unit("tax_unit_dependents", period) - older_dependents = tax_unit("wv_older_dependents_count", period) - personal_count = tax_unit_size - dependents + older_dependents - personal_amount = where( - tax_unit_size == 0, - p_base.base_personal, - p_base.personal * personal_count, + # Count ordinary own exemptions separately from dependent eligibility. + own_exemptions = tax_unit( + "head_spouse_count_not_dependent_elsewhere", period ) + older_dependents = tax_unit("wv_older_dependents_count", period) + personal_count = own_exemptions + older_dependents + personal_amount = p_base.personal * personal_count # Add separated dependent exemption. dependent_exemption_amount = tax_unit("wv_dependent_exemption", period) - return personal_amount + dependent_exemption_amount + # Add the baseline's 11-21-16(d) $500 for each filer who can be + # claimed as a dependent, on a return whose dependents add no + # exemption. + claimable_filer_exemptions = tax_unit( + "wv_claimable_filer_exemptions_count", period + ) + amount = ( + personal_amount + + dependent_exemption_amount + + p_base.base_personal * claimable_filer_exemptions + ) + # As in the baseline, a return with no exemption at all gets $500. + exemptions = tax_unit("exemptions_count", period) + no_exemption = (exemptions + claimable_filer_exemptions) == 0 + return where(no_exemption, p_base.base_personal, amount) class reform(Reform): def apply(self): diff --git a/policyengine_us/tests/core/test_claimable_filer_ri_sc_ut_vt_wv_wi_invariants.py b/policyengine_us/tests/core/test_claimable_filer_ri_sc_ut_vt_wv_wi_invariants.py new file mode 100644 index 00000000000..6fb2ca5f3ae --- /dev/null +++ b/policyengine_us/tests/core/test_claimable_filer_ri_sc_ut_vt_wv_wi_invariants.py @@ -0,0 +1,171 @@ +"""Rhode Island, South Carolina, Utah, Vermont, West Virginia and Wisconsin +rules for a filer who can be claimed as a dependent. + +A return on which the filer (or, if joint, either spouse) can be claimed has +no dependents (IRC 152(b)(1)) unless the would-be claimant meets the filing +exception, so the dependent-based amounts below are zero on it. Claimant +rules that turn on an actual claim (RI property tax relief, VT renter credit) +and per-filer exemptions (WV, WI $250) test each spouse separately. + +For couples drawn by Hypothesis (claimable, actually claimed and filing +exception drawn per spouse) and a seeded population in these states: + +1. Swap invariance: each output is the same under either head/spouse + labelling. +2. Monotonicity: marking another filer as claimed never raises the amounts + in MONOTONE. Wisconsin homestead income and the West Virginia family + credit are left out by design: they rise when a dependent deduction or + exemption goes away. +3. Identities: the dependent-based amounts are zero on a return where the + Dependent Taxpayer Test applies; a return whose every filer is actually + claimed gets no RI relief or VT renter credit; and a West Virginia + return with no lawful dependent exemptions (childless, or whose children + add none) gets $500 per claimable filer and $2,000 per other filer. + West Virginia allocation when dependents add exemptions retains the + existing behavior. +""" + +import numpy as np +import pytest +from hypothesis import HealthCheck, given, settings +from hypothesis import strategies as st + +from policyengine_us.tests.core.test_claimable_filer_federal_invariants import ( + check_monotone, + check_swap, +) +from policyengine_us.tests.core.test_dependent_elsewhere_head_spouse_swap_invariance import ( + CLAIM_PATTERNS, + _calc, + _crafted_cases, + _seeded_couples, + adults, + dependents, + money, +) + +STATES = ["RI", "SC", "UT", "VT", "WV", "WI"] +YEARS = [2021, 2023, 2025, 2026] +# Zero on a return where either filer can be claimed (IRC 152(b)(1)). +DEPENDENT_BASED = [ + "ri_child_tax_rebate", + "sc_dependent_exemption", + "sc_young_child_deduction", + "ut_total_dependents", + "ut_personal_exemption", + "ut_at_home_parent_credit_potential", + "vt_ctc", +] +MONOTONE = DEPENDENT_BASED + [ + "ri_property_tax_credit", + "vt_personal_exemptions", + "vt_renter_credit", + "wv_personal_exemption", + "wv_low_income_family_tax_credit_eligible", + "wv_low_income_family_tax_credit_fpg", + "wi_standard_deduction", + "wi_additional_exemption", + "wi_homestead_credit", + "wi_childcare_expense_subtraction", + "wi_childcare_expense_credit_potential", +] +OUTPUTS = MONOTONE + [ + "wv_low_income_family_tax_credit", + "wi_homestead_income", + "wi_retirement_income_exclusion_tax", + "state_income_tax", +] + + +@st.composite +def adults_with_retirement_income(draw): + # Exercise the positive Wisconsin retirement-exclusion path as well as + # earnings-only returns, without changing the other states' generators. + return { + **draw(adults()), + "taxable_pension_income": draw(money(40_000)), + "taxable_ira_distributions": draw(money(20_000)), + } + + +@st.composite +def couples(draw): + claimable = draw(st.sampled_from(CLAIM_PATTERNS)) + claimed = tuple(can and draw(st.booleans()) for can in claimable) + return { + "state": draw(st.sampled_from(STATES)), + "adults": [ + draw(adults_with_retirement_income()), + draw(adults_with_retirement_income()), + ], + "dependents": draw(st.lists(dependents(), max_size=2)), + "claimed": claimed, + "claimable": claimable, + "exception": tuple(not c and draw(st.booleans()) for c in claimed), + } + + +def _identities(sim, year): + no_dependents = ( + _calc( + sim, "head_or_spouse_is_dependent_elsewhere_without_filing_exception", year + ) + > 0 + ) + for name in DEPENDENT_BASED: + values = _calc(sim, name, year) + assert not values[no_dependents].any(), ( + f"{name} in {year} is positive on a return where the Dependent " + "Taxpayer Test applies" + ) + person_claimed = np.asarray( + sim.calculate("claimed_as_dependent_on_another_return", year, map_to="tax_unit") + ) + filers = np.asarray( + sim.calculate("is_tax_unit_head_or_spouse", year, map_to="tax_unit") + ) + every_filer_claimed = (person_claimed >= filers) & (filers > 0) + for name in ["ri_property_tax_credit", "vt_renter_credit"]: + assert not _calc(sim, name, year)[every_filer_claimed].any(), ( + f"{name} in {year} is positive when every filer is claimed" + ) + state = np.asarray(sim.populations["tax_unit"].household("state_code_str", year)) + own = _calc(sim, "head_spouse_count_not_dependent_elsewhere", year) + # Children who add no exemption (IRC 152(b)(1)) leave the per-filer + # amounts alone, so this covers childless returns and returns whose + # dependents add none. + wv_no_lawful_dependents = (state == "WV") & ( + _calc(sim, "exemptions_count", year) == own + ) + np.testing.assert_array_equal( + _calc(sim, "wv_personal_exemption", year)[wv_no_lawful_dependents], + (2_000 * own + 500 * (filers - own))[wv_no_lawful_dependents], + ) + + +@settings( + max_examples=2, + deadline=None, + derandomize=True, + suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], +) +@given(st.sampled_from(YEARS), st.lists(couples(), min_size=6, max_size=12)) +def test_ri_sc_ut_vt_wv_wi_claimable_filer_rules_are_label_free(year, units): + check_swap(units, year, OUTPUTS, _identities) + + +@pytest.mark.parametrize("year", YEARS) +def test_ri_sc_ut_vt_wv_wi_claimable_filer_rules_seeded_population(year): + units = _seeded_couples(STATES, per_state=2) + _crafted_cases(STATES) + rng = np.random.default_rng(20261019) + for unit in units: + unit["adults"] = [ + { + **adult, + "taxable_pension_income": float(rng.choice([0, 8_000, 30_000])), + "taxable_ira_distributions": float(rng.choice([0, 4_000, 12_000])), + } + for adult in unit["adults"] + ] + check_swap(units, year, OUTPUTS, _identities) + check_monotone(units, year, MONOTONE, _identities) diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit.yaml index b9a19ddc96c..073f9801cb1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit.yaml @@ -88,6 +88,9 @@ tax_unit_size: 1 real_estate_taxes: 2_000 rent: 0 - greater_age_head_spouse: 70 + # The claimant's own age now sets eligibility (R.I. Gen. Laws 44-33-3), + # so the income cutoff alone makes this filer ineligible. + age: 70 output: + ri_property_tax_credit_eligible: false ri_property_tax_credit: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.yaml index 4e50ae67af2..37cfcc20745 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.yaml @@ -1,59 +1,408 @@ - name: Head above minimum age, and disabled period: 2022 input: - state_code: RI - greater_age_head_spouse: 65 - head_is_disabled: true - spouse_is_disabled: false + people: + head: + age: 65 + is_disabled: true + tax_units: + tax_unit: + members: [head] + households: + household: + members: [head] + state_code: RI output: ri_property_tax_credit_eligible: true -- name: Head above minimum age, not diabled +- name: Head above minimum age, not disabled period: 2022 input: - state_code: RI - greater_age_head_spouse: 65 - head_is_disabled: false - spouse_is_disabled: false + people: + head: + age: 65 + tax_units: + tax_unit: + members: [head] + households: + household: + members: [head] + state_code: RI output: ri_property_tax_credit_eligible: true - name: Head disabled, not above minimum age period: 2022 input: - state_code: RI - greater_age_head_spouse: 64 - head_is_disabled: true - spouse_is_disabled: false + people: + head: + age: 64 + is_disabled: true + tax_units: + tax_unit: + members: [head] + households: + household: + members: [head] + state_code: RI output: ri_property_tax_credit_eligible: true - + - name: Spouse above minimum age, not disabled period: 2021 input: - state_code: RI - greater_age_head_spouse: 65 - head_is_disabled: false - spouse_is_disabled: false + people: + head: + age: 64 + spouse: + age: 65 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: RI output: ri_property_tax_credit_eligible: true - name: Not above minimum age, not disabled period: 2021 input: - state_code: RI - greater_age_head_spouse: 64 - head_is_disabled: false - spouse_is_disabled: false + people: + head: + age: 64 + spouse: + age: 64 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: RI output: ri_property_tax_credit_eligible: false - name: Spouse disabled period: 2021 input: - state_code: RI - greater_age_head_spouse: 64 - head_is_disabled: false - spouse_is_disabled: true + people: + head: + age: 64 + spouse: + age: 64 + is_disabled: true + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: RI + output: + ri_property_tax_credit_eligible: true + +- name: "2025 single filer who can be claimed as a dependent: property tax relief needs a claimant aged 65 or older or disabled who is not claimed as a dependent" + period: 2025 + input: + people: + filer: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: RI + output: + # R.I. Gen. Laws 44-33-3: the claimant does not include any person + # claimed as a dependent by any taxpayer. + ri_property_tax_credit_eligible: false + ri_property_tax_credit: 0 + +- name: "2025 joint return with one claimable spouse: property tax relief needs a claimant aged 65 or older or disabled who is not claimed as a dependent (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 65 + real_estate_taxes: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: RI output: + # The unclaimed spouse, aged 65, may be the claimant (household + # members choose who claims). Household income $0, so the + # threshold is $0; property tax $1,000 is capped at the 2025 + # maximum of $700. ri_property_tax_credit_eligible: true + ri_property_tax_credit: 700 + +- name: "2025 joint return with one claimable spouse: property tax relief needs a claimant aged 65 or older or disabled who is not claimed as a dependent (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 65 + real_estate_taxes: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: RI + output: + ri_property_tax_credit_eligible: true + ri_property_tax_credit: 700 + +- name: "2025 joint return with both spouses claimable: property tax relief needs a claimant aged 65 or older or disabled who is not claimed as a dependent" + period: 2025 + input: + people: + person_a: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: RI + output: + ri_property_tax_credit_eligible: false + ri_property_tax_credit: 0 + +- name: "2025 joint return with neither spouse claimable: property tax relief needs a claimant aged 65 or older or disabled who is not claimed as a dependent" + period: 2025 + input: + people: + person_a: + age: 65 + real_estate_taxes: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 65 + real_estate_taxes: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: RI + output: + # Same as above: min($1,000 - 0 x 3%, $700) = $700. + ri_property_tax_credit_eligible: true + ri_property_tax_credit: 700 + +- name: "2025 joint return where only the claimable spouse is 65 or older: property tax relief has no eligible claimant (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 40 + real_estate_taxes: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: RI + output: + # The age test and the dependency test apply to the same claimant, + # so the claimed spouse's age does not qualify the other spouse. + ri_property_tax_credit_eligible: false + ri_property_tax_credit: 0 + +- name: "2025 joint return where only the claimable spouse is 65 or older: property tax relief has no eligible claimant (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 40 + real_estate_taxes: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: RI + output: + ri_property_tax_credit_eligible: false + ri_property_tax_credit: 0 + +- name: "2025 joint return where the unclaimed spouse is disabled: property tax relief stays available (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 40 + is_disabled: true + real_estate_taxes: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: RI + output: + # The disabled, unclaimed spouse is the claimant. + ri_property_tax_credit_eligible: true + ri_property_tax_credit: 700 + +- name: "2025 joint return where the unclaimed spouse is disabled: property tax relief stays available (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 40 + is_disabled: true + real_estate_taxes: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 65 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: RI + output: + ri_property_tax_credit_eligible: true + ri_property_tax_credit: 700 + +- name: 2025 single filer aged 65 who can be claimed but is not claimed is a Rhode Island property tax relief claimant + period: 2025 + input: + people: + filer: + age: 65 + real_estate_taxes: 1000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: RI + output: + # 44-33-3 excludes a person "claimed as a dependent by any taxpayer": + # an actual claim. min($1,000 - $0, $700) = $700. + ri_property_tax_credit_eligible: true + ri_property_tax_credit: 700 + +- name: 2025 single filer aged 40 whose 70-year-old parent is a dependent of the return has no Rhode Island property tax relief claimant + period: 2025 + input: + people: + filer: + age: 40 + real_estate_taxes: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + parent: + age: 70 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [filer, parent] + households: + household: + members: [filer, parent] + state_code: RI + output: + # 44-33-3(1): the claimant is aged 65 or older or disabled and is not + # "any person claimed as a dependent by any taxpayer". The parent is 70 + # but is claimed as a dependent on this return, and the filer is 40 and + # not disabled, so the household has no claimant. + ri_property_tax_credit_eligible: false + ri_property_tax_credit: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.yaml index a69c04874f5..95f0cd279d6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.yaml @@ -200,3 +200,168 @@ ri_refundable_credits: 250 # 1,000 before refundable credits - 250 refundable credits = 750. ri_income_tax: 750 + +- name: "2021 single filer who can be claimed as a dependent: the 2021 child tax rebate needs a child validly claimed as a dependent" + period: 2021 + input: + people: + filer: + age: 20 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + child: + age: 4 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: RI + output: + # R.I. Gen. Laws 44-30-103: $250 for each child the taxpayer validly + # claimed as a dependent; under IRC 152(b)(1) a filer who can be + # claimed has no dependents. + ri_child_tax_rebate: 0 + +- name: "2021 joint return with one claimable spouse: the 2021 child tax rebate needs a child validly claimed as a dependent (the claimable spouse is the head)" + period: 2021 + input: + people: + person_a: + age: 20 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: RI + output: + # On a joint return either spouse being claimable leaves no + # dependents (Publication 501, Dependent Taxpayer Test). + ri_child_tax_rebate: 0 + +- name: "2021 joint return with one claimable spouse: the 2021 child tax rebate needs a child validly claimed as a dependent (the claimable spouse is the spouse)" + period: 2021 + input: + people: + person_b: + age: 20 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 20 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: RI + output: + ri_child_tax_rebate: 0 + +- name: "2021 joint return with both spouses claimable: the 2021 child tax rebate needs a child validly claimed as a dependent" + period: 2021 + input: + people: + person_a: + age: 20 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: RI + output: + ri_child_tax_rebate: 0 + +- name: "2021 joint return with neither spouse claimable: the 2021 child tax rebate needs a child validly claimed as a dependent" + period: 2021 + input: + people: + person_a: + age: 20 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: RI + output: + # One child aged 4: min(1, 3) x $250. + ri_child_tax_rebate: 250 + +# Publication 501 claimant filing exception restores the valid dependent. + +- name: 2021 claimable but unclaimed filer whose claimant meets the filing exception keeps the Rhode Island + child rebate + period: 2021 + input: + people: + filer: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: RI + output: + ri_child_tax_rebate: 250 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/sc_young_child_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/sc_young_child_deduction.yaml index c7acead018f..09ba8177f9d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/sc_young_child_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/sc_young_child_deduction.yaml @@ -72,3 +72,138 @@ # Young child deduction requires child to be under age 6 (ineligible_age = 6) # Child age 6 does NOT qualify - must be younger than 6 sc_young_child_deduction: 0 + +- name: "2025 single filer who can be claimed as a dependent: no South Carolina young child deduction" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + child: + age: 4 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: SC + output: + # S.C. Code 12-6-1160 requires a dependent eligible for the South + # Carolina dependent exemption, which a claimable filer has none of. + sc_young_child_deduction: 0 + +- name: "2025 joint return with one claimable spouse: no South Carolina young child deduction (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: SC + output: + sc_young_child_deduction: 0 + +- name: "2025 joint return with one claimable spouse: no South Carolina young child deduction (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: SC + output: + sc_young_child_deduction: 0 + +- name: "2025 joint return with both spouses claimable: no South Carolina young child deduction" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: SC + output: + sc_young_child_deduction: 0 + +- name: "2025 joint return with neither spouse claimable (control): South Carolina young child deduction" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: SC + output: + # One dependent under 6 x $4,930 (2025). + sc_young_child_deduction: 4930 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.yaml index 23771760581..5c8be843c2e 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.yaml @@ -63,3 +63,166 @@ output: # 2025 dependent exemption amount is $4,930; 3 * $4,930 = $14,790. sc_dependent_exemption: 14_790 + +- name: "2025 single filer who can be claimed as a dependent: no South Carolina dependent exemption" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + child: + age: 4 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: SC + output: + # S.C. Code 12-6-1140(13) allows the exemption for dependents claimed + # under IRC 151 and 152; IRC 152(b)(1) leaves a claimable filer none. + sc_dependent_exemption: 0 + +- name: "2025 joint return with one claimable spouse: no South Carolina dependent exemption (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: SC + output: + # Either spouse being claimable leaves the joint return no + # dependents (Publication 501, Dependent Taxpayer Test). + sc_dependent_exemption: 0 + +- name: "2025 joint return with one claimable spouse: no South Carolina dependent exemption (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: SC + output: + sc_dependent_exemption: 0 + +- name: "2025 joint return with both spouses claimable: no South Carolina dependent exemption" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: SC + output: + sc_dependent_exemption: 0 + +- name: "2025 joint return with neither spouse claimable (control): South Carolina dependent exemption" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: SC + output: + # One dependent x $4,930 (2025). + sc_dependent_exemption: 4930 + +- name: 2025 single filer who can be claimed but whose would-be claimant meets the filing exception keeps the South Carolina dependent exemption + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 4 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: SC + output: + # Publication 501, Dependent Taxpayer Test: the bar does not apply when + # the would-be claimant is not required to file and files only for a + # refund. One child aged 4: $4,930 each. + sc_dependent_exemption: 4930 + sc_young_child_deduction: 4930 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_at_home_parent_credit_potential.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_at_home_parent_credit_potential.yaml new file mode 100644 index 00000000000..1ca288b7054 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_at_home_parent_credit_potential.yaml @@ -0,0 +1,219 @@ +- name: "2025 single filer who can be claimed as a dependent: no Utah at-home parent credit" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 2000 + claimed_as_dependent_on_another_return: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [filer, newborn] + households: + household: + members: [filer, newborn] + state_code: UT + output: + # Utah Code 59-10-1005: the parent must claim the qualifying child as a + # dependent; under IRC 152(b)(1) a claimable filer has no dependents. + ut_at_home_parent_credit_potential: 0 + +- name: "2025 joint return with one claimable spouse: no Utah at-home parent credit (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 2000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 24 + employment_income: 4000 + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + # Either spouse being claimable leaves the joint return no dependents. + ut_at_home_parent_credit_potential: 0 + +- name: "2025 joint return with one claimable spouse: no Utah at-home parent credit (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 24 + employment_income: 4000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 2000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_b, person_a, newborn] + filing_status: JOINT + households: + household: + members: [person_b, person_a, newborn] + state_code: UT + output: + ut_at_home_parent_credit_potential: 0 + +- name: "2025 joint return with both spouses claimable: no Utah at-home parent credit" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 2000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 24 + employment_income: 4000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + ut_at_home_parent_credit_potential: 0 + +- name: "2025 joint return with neither spouse claimable (control): Utah at-home parent credit" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 2000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 24 + employment_income: 4000 + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + # One child under 1 x $100 x one parent earning $3,000 or less + # (the other parent earns $4,000); AGI $6,000 is under $50,000. + ut_at_home_parent_credit_potential: 100 + +- name: '2025 joint return with both spouses claimable: no Utah at-home parent credit (head and spouse + labels swapped)' + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 2000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + person_b: + age: 24 + employment_income: 4000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + ut_at_home_parent_credit_potential: 0 + +- name: '2025 joint return with neither spouse claimable (control): Utah at-home parent credit (head and + spouse labels swapped)' + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 2000 + is_tax_unit_head: false + is_tax_unit_spouse: true + person_b: + age: 24 + employment_income: 4000 + is_tax_unit_head: true + is_tax_unit_spouse: false + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + ut_at_home_parent_credit_potential: 100 + +- name: 2025 claimable but unclaimed filer whose claimant meets the filing exception keeps the Utah at-home + parent credit + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 2000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 0 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: UT + output: + ut_at_home_parent_credit_potential: 100 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption.yaml index 3e278e3e5a2..c9f16e5b851 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption.yaml @@ -33,3 +33,143 @@ state_code: UT output: ut_personal_exemption: 5_406 # 1802 * 3 + +- name: "2025 single filer who can be claimed as a dependent: no Utah additional dependent for a child born this year" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [filer, newborn] + households: + household: + members: [filer, newborn] + state_code: UT + output: + # The birth-year dependent (59-10-1018(1)(g)) must also be a dependent + # of the return; IRC 152(b)(1) leaves a claimable filer none. + ut_personal_exemption_additional_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with one claimable spouse: no Utah additional dependent for a child born this year (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + ut_personal_exemption_additional_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with one claimable spouse: no Utah additional dependent for a child born this year (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_b, person_a, newborn] + filing_status: JOINT + households: + household: + members: [person_b, person_a, newborn] + state_code: UT + output: + ut_personal_exemption_additional_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with both spouses claimable: no Utah additional dependent for a child born this year" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + ut_personal_exemption_additional_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with neither spouse claimable (control): Utah additional dependent for a child born this year" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + newborn: + age: 0 + tax_units: + tax_unit: + members: [person_a, person_b, newborn] + filing_status: JOINT + households: + household: + members: [person_a, person_b, newborn] + state_code: UT + output: + # (1 dependent + 1 additional dependent) x $2,111 = $4,222. + ut_personal_exemption_additional_dependents: 1 + ut_personal_exemption: 4222 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption_additional_dependent_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption_additional_dependent_eligible.yaml index 7ac1f305543..a27db94c3d7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption_additional_dependent_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_personal_exemption_additional_dependent_eligible.yaml @@ -24,3 +24,56 @@ state_code: UT output: ut_personal_exemption_additional_dependent_eligible: false + +- name: 2025 newborn of a filer whose would-be claimant meets the filing exception is an additional Utah dependent + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8_000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + newborn: + age: 0 + birth_year: 2025 + tax_units: + tax_unit: + members: [filer, newborn] + households: + household: + members: [filer, newborn] + state_code: UT + output: + # The filing exception keeps IRC 152(b)(1) from applying, so the newborn + # is a qualifying dependent and adds one more in the birth year + # (59-10-1018(1)(g)): (1 + 1) x $2,111 = $4,222. + ut_personal_exemption_additional_dependent_eligible: [false, true] + ut_personal_exemption: 4_222 + +- name: 2025 newborn with no SSN and no taxpayer identification number is not an additional Utah dependent + period: 2025 + input: + people: + filer: + age: 30 + employment_income: 30_000 + newborn: + age: 0 + birth_year: 2025 + is_tax_unit_dependent: true + ssn_card_type: NONE + has_tin: false + tax_units: + tax_unit: + members: [filer, newborn] + households: + household: + members: [filer, newborn] + state_code: UT + output: + # No IRC 24 credit is allowed for the newborn, so it is not a qualifying + # dependent, and it adds neither the ordinary nor the birth-year one. + ut_personal_exemption_additional_dependent_eligible: [false, false] + ut_personal_exemption: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_total_dependents.yaml b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_total_dependents.yaml new file mode 100644 index 00000000000..7b0f8f74dc5 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ut/tax/income/credits/ut_total_dependents.yaml @@ -0,0 +1,220 @@ +- name: "2025 single filer who can be claimed as a dependent: no Utah dependents for the taxpayer credit" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + child: + age: 2 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: UT + output: + # Utah Code 59-10-1018 counts dependents for whom the claimant is + # entitled to an IRC 24 credit; under IRC 152(b)(1) a claimable filer + # has no dependents. + ut_total_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with one claimable spouse: no Utah dependents for the taxpayer credit (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: UT + output: + # Either spouse being claimable leaves the joint return no dependents. + ut_total_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with one claimable spouse: no Utah dependents for the taxpayer credit (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: UT + output: + ut_total_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with both spouses claimable: no Utah dependents for the taxpayer credit" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: UT + output: + ut_total_dependents: 0 + ut_personal_exemption: 0 + +- name: "2025 joint return with neither spouse claimable (control): Utah dependents for the taxpayer credit" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: UT + output: + # One dependent x $2,111 (2025). + ut_total_dependents: 1 + ut_personal_exemption: 2111 + +- name: 2025 single filer whose would-be claimant meets the filing exception keeps Utah dependents + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 2 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: UT + output: + # The federal credit for the child is allowed (Dependent Taxpayer Test + # exception), so the child is a qualifying dependent: 1 x $2,111. + ut_total_dependents: 1 + ut_personal_exemption: 2111 + +- name: 2025 single filer whose child has no SSN and no taxpayer identification number has no Utah qualifying dependent + period: 2025 + input: + people: + filer: + age: 30 + employment_income: 30_000 + child: + age: 5 + is_tax_unit_dependent: true + ssn_card_type: NONE + has_tin: false + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: UT + output: + # 59-10-1018(1)(c): the claimant is allowed no IRC 24 credit for the + # child, since the child tax credit needs the child's SSN and the credit + # for other dependents needs a TIN. So the child is not a qualifying + # dependent. + ctc_individual_maximum: [0, 0] + ut_total_dependents: 0 + ut_personal_exemption: 0 + +- name: 2025 single filer whose child has an ITIN but no SSN keeps a Utah qualifying dependent through the credit for other dependents + period: 2025 + input: + people: + filer: + age: 30 + employment_income: 30_000 + child: + age: 5 + is_tax_unit_dependent: true + ssn_card_type: NONE + has_tin: true + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: UT + output: + # The $500 credit for other dependents (IRC 24(h)(4)) needs only a TIN, + # so the child is a qualifying dependent: 1 x $2,111. + ctc_individual_maximum: [0, 500] + ut_total_dependents: 1 + ut_personal_exemption: 2_111 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/rent/vt_renter_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/rent/vt_renter_credit.yaml index 652efa72b92..0e10e5fb8c7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/rent/vt_renter_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/rent/vt_renter_credit.yaml @@ -146,6 +146,173 @@ output: vt_renter_credit: 1_692 +- name: "2025 single filer who can be claimed as a dependent: Vermont renter credit needs a claimant who is not claimed as a dependent and sizes rent by personal exemptions" + period: 2025 + input: + people: + filer: + age: 30 + employment_income: 1000 + rent: 12000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: VT + county: CHITTENDEN_COUNTY_VT + output: + # 32 V.S.A. 6066(c)(2): the claimant may not be a person claimed as a + # dependent by any taxpayer. + vt_renter_credit: 0 + +- name: "2025 joint return with one claimable spouse: Vermont renter credit needs a claimant who is not claimed as a dependent and sizes rent by personal exemptions (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 500 + rent: 6000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 500 + rent: 6000 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: VT + county: CHITTENDEN_COUNTY_VT + output: + # The unclaimed spouse is the claimant. 6066(b)(2) sizes fair market + # rent by the number of personal exemptions: one. Income $1,000 is + # below the full-credit limit: round($1,476 x 12 x 10%) = $1,771. + vt_renter_credit: 1771 + +- name: "2025 joint return with one claimable spouse: Vermont renter credit needs a claimant who is not claimed as a dependent and sizes rent by personal exemptions (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 500 + rent: 6000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 500 + rent: 6000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: VT + county: CHITTENDEN_COUNTY_VT + output: + vt_renter_credit: 1771 + +- name: "2025 joint return with both spouses claimable: Vermont renter credit needs a claimant who is not claimed as a dependent and sizes rent by personal exemptions" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 500 + rent: 6000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 500 + rent: 6000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: VT + county: CHITTENDEN_COUNTY_VT + output: + vt_renter_credit: 0 + +- name: "2025 joint return with neither spouse claimable: Vermont renter credit needs a claimant who is not claimed as a dependent and sizes rent by personal exemptions" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 500 + rent: 6000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 500 + rent: 6000 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: VT + county: CHITTENDEN_COUNTY_VT + output: + # Two exemptions: round($1,936 x 12 x 10%) = $2,323. + vt_renter_credit: 2323 + +- name: 2025 single renter who can be claimed but is not claimed keeps the Vermont renter credit + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 1000 + rent: 12000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: VT + county: CHITTENDEN_COUNTY_VT + output: + # 6066(c)(2) bars a claimant "claimed as a dependent", an actual claim. + # A filer who can be claimed has no personal exemption; the fair market + # rent uses the zero-bedroom HUD schedule under 6066(b)(2): + # round($1,380 x 12 x 10%) = $1,656. + vt_renter_credit: 1656 + # Franklin and Grand Isle use the state-average fair market rent (32 V.S.A. # 6061(7)(C)). Expected values are the department's Renter Credit Website # Calculators (2022, 2023, 2025), recalculated in LibreOffice for each household: @@ -496,3 +663,327 @@ # Full limit 31,050 = HUD FY2021 extremely low-income limit (PE had 31,040). # Full credit: ROUND(2,083 x 12 x 0.1, 0) = ROUND(2,499.6, 0) = 2,500. vt_renter_credit: 2_500 + +- name: 2021 zero-exemption renter uses HUD zero-bedroom rents in all Vermont counties + period: 2021 + input: + state_code: + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + county: + - ADDISON_COUNTY_VT + - BENNINGTON_COUNTY_VT + - CALEDONIA_COUNTY_VT + - CHITTENDEN_COUNTY_VT + - ESSEX_COUNTY_VT + - FRANKLIN_COUNTY_VT + - GRAND_ISLE_COUNTY_VT + - LAMOILLE_COUNTY_VT + - ORANGE_COUNTY_VT + - ORLEANS_COUNTY_VT + - RUTLAND_COUNTY_VT + - WASHINGTON_COUNTY_VT + - WINDHAM_COUNTY_VT + - WINDSOR_COUNTY_VT + tax_unit_size: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + exemptions_count: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + vt_renter_credit_income: [5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000] + rent_is_shared_with_another_tax_unit: [false, false, false, false, false, false, false, false, false, false, false, false, false, false] + housing_assistance: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + rent: [12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000] + output: + # Each HUD monthly 0BR amount x 12 x 10%, rounded half up. + # Franklin and Grand Isle use the average of Vermont's 12 HUD areas. + vt_renter_credit: + - 901 # ADDISON_COUNTY_VT + - 852 # BENNINGTON_COUNTY_VT + - 850 # CALEDONIA_COUNTY_VT + - 1309 # CHITTENDEN_COUNTY_VT + - 672 # ESSEX_COUNTY_VT + - 883 # FRANKLIN_COUNTY_VT + - 883 # GRAND_ISLE_COUNTY_VT + - 946 # LAMOILLE_COUNTY_VT + - 888 # ORANGE_COUNTY_VT + - 710 # ORLEANS_COUNTY_VT + - 917 # RUTLAND_COUNTY_VT + - 860 # WASHINGTON_COUNTY_VT + - 836 # WINDHAM_COUNTY_VT + - 858 # WINDSOR_COUNTY_VT + +- name: 2022 zero-exemption renter uses HUD zero-bedroom rents in all Vermont counties + period: 2022 + input: + state_code: + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + county: + - ADDISON_COUNTY_VT + - BENNINGTON_COUNTY_VT + - CALEDONIA_COUNTY_VT + - CHITTENDEN_COUNTY_VT + - ESSEX_COUNTY_VT + - FRANKLIN_COUNTY_VT + - GRAND_ISLE_COUNTY_VT + - LAMOILLE_COUNTY_VT + - ORANGE_COUNTY_VT + - ORLEANS_COUNTY_VT + - RUTLAND_COUNTY_VT + - WASHINGTON_COUNTY_VT + - WINDHAM_COUNTY_VT + - WINDSOR_COUNTY_VT + tax_unit_size: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + exemptions_count: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + vt_renter_credit_income: [5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000] + rent_is_shared_with_another_tax_unit: [false, false, false, false, false, false, false, false, false, false, false, false, false, false] + housing_assistance: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + rent: [12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000] + output: + # Each HUD monthly 0BR amount x 12 x 10%, rounded half up. + # Franklin and Grand Isle use the average of Vermont's 12 HUD areas. + vt_renter_credit: + - 935 # ADDISON_COUNTY_VT + - 916 # BENNINGTON_COUNTY_VT + - 889 # CALEDONIA_COUNTY_VT + - 1240 # CHITTENDEN_COUNTY_VT + - 702 # ESSEX_COUNTY_VT + - 919 # FRANKLIN_COUNTY_VT + - 919 # GRAND_ISLE_COUNTY_VT + - 961 # LAMOILLE_COUNTY_VT + - 944 # ORANGE_COUNTY_VT + - 766 # ORLEANS_COUNTY_VT + - 977 # RUTLAND_COUNTY_VT + - 912 # WASHINGTON_COUNTY_VT + - 881 # WINDHAM_COUNTY_VT + - 908 # WINDSOR_COUNTY_VT + +- name: 2023 zero-exemption renter uses HUD zero-bedroom rents in all Vermont counties + period: 2023 + input: + state_code: + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + county: + - ADDISON_COUNTY_VT + - BENNINGTON_COUNTY_VT + - CALEDONIA_COUNTY_VT + - CHITTENDEN_COUNTY_VT + - ESSEX_COUNTY_VT + - FRANKLIN_COUNTY_VT + - GRAND_ISLE_COUNTY_VT + - LAMOILLE_COUNTY_VT + - ORANGE_COUNTY_VT + - ORLEANS_COUNTY_VT + - RUTLAND_COUNTY_VT + - WASHINGTON_COUNTY_VT + - WINDHAM_COUNTY_VT + - WINDSOR_COUNTY_VT + tax_unit_size: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + exemptions_count: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + vt_renter_credit_income: [5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000] + rent_is_shared_with_another_tax_unit: [false, false, false, false, false, false, false, false, false, false, false, false, false, false] + housing_assistance: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + rent: [12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000] + output: + # Each HUD monthly 0BR amount x 12 x 10%, rounded half up. + # Franklin and Grand Isle use the average of Vermont's 12 HUD areas. + vt_renter_credit: + - 1010 # ADDISON_COUNTY_VT + - 1019 # BENNINGTON_COUNTY_VT + - 972 # CALEDONIA_COUNTY_VT + - 1367 # CHITTENDEN_COUNTY_VT + - 876 # ESSEX_COUNTY_VT + - 1019 # FRANKLIN_COUNTY_VT + - 1019 # GRAND_ISLE_COUNTY_VT + - 1049 # LAMOILLE_COUNTY_VT + - 1022 # ORANGE_COUNTY_VT + - 847 # ORLEANS_COUNTY_VT + - 1085 # RUTLAND_COUNTY_VT + - 1007 # WASHINGTON_COUNTY_VT + - 964 # WINDHAM_COUNTY_VT + - 1009 # WINDSOR_COUNTY_VT + +- name: 2024 zero-exemption renter uses HUD zero-bedroom rents in all Vermont counties + period: 2024 + input: + state_code: + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + county: + - ADDISON_COUNTY_VT + - BENNINGTON_COUNTY_VT + - CALEDONIA_COUNTY_VT + - CHITTENDEN_COUNTY_VT + - ESSEX_COUNTY_VT + - FRANKLIN_COUNTY_VT + - GRAND_ISLE_COUNTY_VT + - LAMOILLE_COUNTY_VT + - ORANGE_COUNTY_VT + - ORLEANS_COUNTY_VT + - RUTLAND_COUNTY_VT + - WASHINGTON_COUNTY_VT + - WINDHAM_COUNTY_VT + - WINDSOR_COUNTY_VT + tax_unit_size: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + exemptions_count: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + vt_renter_credit_income: [5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000] + rent_is_shared_with_another_tax_unit: [false, false, false, false, false, false, false, false, false, false, false, false, false, false] + housing_assistance: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + rent: [12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000] + output: + # Each HUD monthly 0BR amount x 12 x 10%, rounded half up. + # Franklin and Grand Isle use the average of Vermont's 12 HUD areas. + vt_renter_credit: + - 1220 # ADDISON_COUNTY_VT + - 1123 # BENNINGTON_COUNTY_VT + - 1079 # CALEDONIA_COUNTY_VT + - 1609 # CHITTENDEN_COUNTY_VT + - 974 # ESSEX_COUNTY_VT + - 1172 # FRANKLIN_COUNTY_VT + - 1172 # GRAND_ISLE_COUNTY_VT + - 1096 # LAMOILLE_COUNTY_VT + - 1171 # ORANGE_COUNTY_VT + - 997 # ORLEANS_COUNTY_VT + - 1189 # RUTLAND_COUNTY_VT + - 1182 # WASHINGTON_COUNTY_VT + - 1171 # WINDHAM_COUNTY_VT + - 1247 # WINDSOR_COUNTY_VT + +- name: 2025 zero-exemption renter uses HUD zero-bedroom rents in all Vermont counties + period: 2025 + input: + state_code: + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + - VT + county: + - ADDISON_COUNTY_VT + - BENNINGTON_COUNTY_VT + - CALEDONIA_COUNTY_VT + - CHITTENDEN_COUNTY_VT + - ESSEX_COUNTY_VT + - FRANKLIN_COUNTY_VT + - GRAND_ISLE_COUNTY_VT + - LAMOILLE_COUNTY_VT + - ORANGE_COUNTY_VT + - ORLEANS_COUNTY_VT + - RUTLAND_COUNTY_VT + - WASHINGTON_COUNTY_VT + - WINDHAM_COUNTY_VT + - WINDSOR_COUNTY_VT + tax_unit_size: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + exemptions_count: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + vt_renter_credit_income: [5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000, 5_000] + rent_is_shared_with_another_tax_unit: [false, false, false, false, false, false, false, false, false, false, false, false, false, false] + housing_assistance: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + rent: [12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000, 12_000] + output: + # Each HUD monthly 0BR amount x 12 x 10%, rounded half up. + # Franklin and Grand Isle use the average of Vermont's 12 HUD areas. + vt_renter_credit: + - 1315 # ADDISON_COUNTY_VT + - 1123 # BENNINGTON_COUNTY_VT + - 1086 # CALEDONIA_COUNTY_VT + - 1656 # CHITTENDEN_COUNTY_VT + - 988 # ESSEX_COUNTY_VT + - 1209 # FRANKLIN_COUNTY_VT + - 1209 # GRAND_ISLE_COUNTY_VT + - 1060 # LAMOILLE_COUNTY_VT + - 1216 # ORANGE_COUNTY_VT + - 1014 # ORLEANS_COUNTY_VT + - 1190 # RUTLAND_COUNTY_VT + - 1290 # WASHINGTON_COUNTY_VT + - 1224 # WINDHAM_COUNTY_VT + - 1349 # WINDSOR_COUNTY_VT + +- name: 2025 Vermont renter income limits count both resident spouses when one spouse is claimed + period: 2025 + input: + people: + unclaimed_spouse: + age: 30 + rent: 6_000 + is_tax_unit_head: true + is_tax_unit_spouse: false + claimed_spouse: + age: 30 + rent: 6_000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [unclaimed_spouse, claimed_spouse] + filing_status: JOINT + vt_renter_credit_income: 62_000 + households: + household: + members: [unclaimed_spouse, claimed_spouse] + state_code: VT + county: CHITTENDEN_COUNTY_VT + output: + exemptions_count: 1 + tax_unit_size: 2 + # Resident-family income limits use two people; the fair market rent + # uses one personal exemption. The alternative of one-person income + # limits would deny the credit at this income. + vt_renter_credit: 270 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/vt_ctc.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/vt_ctc.yaml index 661d94eee9a..cf2c36ba0d2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/vt_ctc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/vt_ctc.yaml @@ -312,27 +312,57 @@ - name: Fully phases out at $175,000. 1000-20*(175000-125000)/1000 = 0 period: 2023 input: - state_code: VT - age: 5 - adjusted_gross_income: 175_000 + people: + parent: + age: 35 + child1: + age: 5 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 175_000 + households: + household: + members: [parent, child1] + state_code: VT output: vt_ctc: 0 - name: Check we're not creating a negative value. period: 2023 input: - state_code: VT - age: 5 - adjusted_gross_income: 200_000 + people: + parent: + age: 35 + child1: + age: 5 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 200_000 + households: + household: + members: [parent, child1] + state_code: VT output: vt_ctc: 0 - name: Halfway phased out at $150,000. 1000-20*(150000-125000)/1000 = 500 period: 2023 input: - state_code: VT - age: 5 - adjusted_gross_income: 150_000 + people: + parent: + age: 35 + child1: + age: 5 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 150_000 + households: + household: + members: [parent, child1] + state_code: VT output: vt_ctc: 500 @@ -340,35 +370,261 @@ - name: S.51 - CTC includes 6-year-olds starting 2025 period: 2025 input: - state_code: VT - age: 6 - adjusted_gross_income: 50_000 + people: + parent: + age: 35 + child1: + age: 6 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 50_000 + households: + household: + members: [parent, child1] + state_code: VT output: vt_ctc: 1_000 - name: S.51 - CTC still applies to 5-year-olds in 2025 period: 2025 input: - state_code: VT - age: 5 - adjusted_gross_income: 50_000 + people: + parent: + age: 35 + child1: + age: 5 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 50_000 + households: + household: + members: [parent, child1] + state_code: VT output: vt_ctc: 1_000 - name: S.51 - CTC does not apply to 7-year-olds in 2025 period: 2025 input: - state_code: VT - age: 7 - adjusted_gross_income: 50_000 + people: + parent: + age: 35 + child1: + age: 7 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 50_000 + households: + household: + members: [parent, child1] + state_code: VT output: vt_ctc: 0 - name: S.51 - CTC did not include 6-year-olds before 2025 period: 2024 input: - state_code: VT - age: 6 - adjusted_gross_income: 50_000 + people: + parent: + age: 35 + child1: + age: 6 + tax_units: + tax_unit: + members: [parent, child1] + adjusted_gross_income: 50_000 + households: + household: + members: [parent, child1] + state_code: VT output: vt_ctc: 0 + +- name: "2025 single filer who can be claimed as a dependent: no Vermont child tax credit" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 2000 + claimed_as_dependent_on_another_return: true + child: + age: 2 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: VT + output: + # 32 V.S.A. 5830f requires entitlement to the federal child tax credit + # (waiving only the identification-number rules); IRC 152(b)(1) leaves + # a claimable filer no dependents and so no federal credit. + vt_ctc: 0 + +- name: "2025 joint return with one claimable spouse: no Vermont child tax credit (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: VT + output: + # Either spouse being claimable leaves the joint return no dependents. + vt_ctc: 0 + +- name: "2025 joint return with one claimable spouse: no Vermont child tax credit (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: VT + output: + vt_ctc: 0 + +- name: "2025 joint return with both spouses claimable: no Vermont child tax credit" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: VT + output: + vt_ctc: 0 + +- name: "2025 joint return with neither spouse claimable (control): Vermont child tax credit" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 2 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: VT + output: + # One qualifying child aged 6 or under x $1,000; AGI $2,000 is below + # the $125,000 phase-out start. + vt_ctc: 1000 + +- name: 2025 a young household member who is not a dependent does not count for the Vermont child tax credit + period: 2025 + input: + people: + parent: + age: 30 + employment_income: 2000 + sibling: + age: 5 + is_tax_unit_dependent: false + tax_units: + tax_unit: + members: [parent, sibling] + households: + household: + members: [parent, sibling] + state_code: VT + output: + # 5830f counts qualifying children under IRC 152(c), who are dependents. + vt_ctc: 0 + +# IRC 152(b)(1) does not bar dependents under the claimant filing exception. + +- name: 2025 claimable but unclaimed filer whose claimant meets the filing exception keeps the Vermont + child tax credit + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 2000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 2 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: VT + output: + vt_ctc: 1000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.yaml index 584f51e0e02..7cffbef37a2 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.yaml @@ -4,6 +4,7 @@ filing_status: JOINT head_is_dependent_elsewhere: true spouse_is_dependent_elsewhere: true + head_or_spouse_is_dependent_elsewhere_without_filing_exception: true tax_unit_count_dependents: 0 state_code: VT output: @@ -15,10 +16,12 @@ filing_status: JOINT head_is_dependent_elsewhere: true spouse_is_dependent_elsewhere: true + head_or_spouse_is_dependent_elsewhere_without_filing_exception: true tax_unit_count_dependents: 2 state_code: VT output: - vt_personal_exemptions: 9_000 # 2*4500 + # IRC 152(b)(1): a return with a claimable filer has no dependents. + vt_personal_exemptions: 0 - name: "Joint household, one claimable elsewhere, with no dependents" period: 2022 @@ -26,6 +29,7 @@ filing_status: JOINT head_is_dependent_elsewhere: true spouse_is_dependent_elsewhere: false + head_or_spouse_is_dependent_elsewhere_without_filing_exception: true tax_unit_count_dependents: 0 state_code: VT output: @@ -37,10 +41,12 @@ filing_status: JOINT head_is_dependent_elsewhere: true spouse_is_dependent_elsewhere: false + head_or_spouse_is_dependent_elsewhere_without_filing_exception: true tax_unit_count_dependents: 2 state_code: VT output: - vt_personal_exemptions: 13_500 # 3*4500 + # The unclaimed spouse only; IRC 152(b)(1) leaves the return no dependents. + vt_personal_exemptions: 4_500 # 1*4500 - name: "Joint household, neither claimable elsewhere, with no dependents" period: 2022 @@ -69,6 +75,7 @@ input: filing_status: SINGLE head_is_dependent_elsewhere: true + head_or_spouse_is_dependent_elsewhere_without_filing_exception: true tax_unit_count_dependents: 0 state_code: VT output: @@ -79,10 +86,12 @@ input: filing_status: SINGLE head_is_dependent_elsewhere: true + head_or_spouse_is_dependent_elsewhere_without_filing_exception: true tax_unit_count_dependents: 2 state_code: VT output: - vt_personal_exemptions: 9_000 # 2*4500 + # IRC 152(b)(1): a filer who can be claimed has no dependents. + vt_personal_exemptions: 0 - name: "Single household, not claimable elsewhere, with no dependents" period: 2022 @@ -143,3 +152,163 @@ state_code: VT output: vt_personal_exemptions: 13_050 # 3*4350 + +- name: "2025 single filer who can be claimed as a dependent: Vermont personal exemptions count only filers who cannot be claimed and, when none can be, the dependents" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + child: + age: 4 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: VT + output: + # 32 V.S.A. 5811(21)(C): no exemption for a dependent individual, and + # IRC 152(b)(1) leaves a claimable filer no dependents. + vt_personal_exemptions: 0 + +- name: "2025 joint return with one claimable spouse: Vermont personal exemptions count only filers who cannot be claimed and, when none can be, the dependents (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: VT + output: + # The unclaimed spouse's exemption only: 1 x $5,300. + vt_personal_exemptions: 5300 + +- name: "2025 joint return with one claimable spouse: Vermont personal exemptions count only filers who cannot be claimed and, when none can be, the dependents (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: VT + output: + vt_personal_exemptions: 5300 + +- name: "2025 joint return with both spouses claimable: Vermont personal exemptions count only filers who cannot be claimed and, when none can be, the dependents" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: VT + output: + vt_personal_exemptions: 0 + +- name: "2025 joint return with neither spouse claimable: Vermont personal exemptions count only filers who cannot be claimed and, when none can be, the dependents" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: VT + output: + # 3 exemptions x $5,300 (2025). + vt_personal_exemptions: 15900 + +- name: 2025 single filer who can be claimed but whose would-be claimant meets the filing exception gets Vermont dependent exemptions only + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 8000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 4 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: VT + output: + # No own exemption (the filer can be claimed); the child counts because + # the Dependent Taxpayer Test does not apply: 1 x $5,300. + vt_personal_exemptions: 5300 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_additional_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_additional_exemption.yaml index c97d3f5d799..852e5868214 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_additional_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_additional_exemption.yaml @@ -1,25 +1,291 @@ - name: Aged head period: 2022 input: - age_head: 65 - state_code: WI + people: + head: + age: 65 + tax_units: + tax_unit: + members: [head] + households: + household: + members: [head] + state_code: WI output: wi_additional_exemption: 250 - name: Aged head and aged spouse period: 2022 input: - age_head: 65 - age_spouse: 65 - state_code: WI + people: + head: + age: 65 + spouse: + age: 65 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: WI output: wi_additional_exemption: 500 - name: No aged head or aged spouse period: 2022 input: - age_head: 64 - age_spouse: 64 - state_code: WI + people: + head: + age: 64 + spouse: + age: 64 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [head, spouse] + filing_status: JOINT + households: + household: + members: [head, spouse] + state_code: WI output: wi_additional_exemption: 0 + +- name: 2025 single filer aged 65 who is claimed as a dependent keeps the Wisconsin $250 exemption + period: 2025 + input: + people: + filer: + age: 65 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WI + output: + # Wis. Stat. 71.05(23)(b)3 tests only age: 1 filer aged 65 x $250. + wi_additional_exemption: 250 + +- name: 2025 joint return with one claimed spouse, both aged 65, gets the Wisconsin $250 exemption for each spouse (the claimed spouse is the head) + period: 2025 + input: + people: + person_a: + age: 65 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 65 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + # 71.05(23)(b)3: 2 spouses aged 65 x $250, whether or not one is claimed. + wi_additional_exemption: 500 + +- name: 2025 joint return with one claimed spouse, both aged 65, gets the Wisconsin $250 exemption for each spouse (the claimed spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 65 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 65 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: WI + output: + wi_additional_exemption: 500 + +- name: 2025 joint return with both spouses claimed and aged 65 gets the Wisconsin $250 exemption for each spouse + period: 2025 + input: + people: + person_a: + age: 65 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 65 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + # 2 spouses aged 65 x $250. + wi_additional_exemption: 500 + +- name: "2025 joint return with neither spouse claimable: control for the Wisconsin $250 exemption cases with a claimed spouse" + period: 2025 + input: + people: + person_a: + age: 65 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 65 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + # Two filers aged 65 or older x $250. + wi_additional_exemption: 500 + +- name: 2025 joint return where only the claimed spouse is 65 or older gets one Wisconsin $250 exemption (the claimed spouse is the head) + period: 2025 + input: + people: + person_a: + age: 65 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 40 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + # Only the claimed spouse is 65: 1 x $250. + wi_additional_exemption: 250 + +- name: 2025 joint return where only the claimed spouse is 65 or older gets one Wisconsin $250 exemption (the claimed spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 40 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 65 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: WI + output: + wi_additional_exemption: 250 + +- name: 2025 single filer aged 65 who can be claimed but is not claimed keeps the Wisconsin $250 exemption + period: 2025 + input: + people: + filer: + age: 65 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WI + output: + # Wis. Stat. 71.05(23)(b)3 tests only age: 1 filer aged 65 x $250. + wi_additional_exemption: 250 + +- name: 2025 joint return where one spouse aged 65 can be claimed but is not gets the Wisconsin $250 exemption for each spouse (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 65 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 65 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + # 2 spouses aged 65 x $250. + wi_additional_exemption: 500 + +- name: 2025 joint return where one spouse aged 65 can be claimed but is not gets the Wisconsin $250 exemption for each spouse (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 65 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 65 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: WI + output: + wi_additional_exemption: 500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_childcare_expense_credit_potential.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_childcare_expense_credit_potential.yaml new file mode 100644 index 00000000000..1b301608797 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_childcare_expense_credit_potential.yaml @@ -0,0 +1,102 @@ +# Disabled-adult care remains eligible when the filer can be claimed. +# The $2,000 childcare is excluded unless the filing exception applies +# or the child is incapable of self-care (IRC 21(b)(1)(B)). + +- name: 2025 claimable filer keeps adult care and only qualifying childcare + period: 2025 + absolute_error_margin: 0.01 + input: + people: + filer: + age: 22 + employment_income: 60000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + child: + age: 4 + is_tax_unit_dependent: true + is_incapable_of_self_care: false + adult: + age: 30 + is_tax_unit_spouse: false + is_tax_unit_dependent: true + is_incapable_of_self_care: true + care_expenses: 1000 + tax_units: + tax_unit: + members: [filer, child, adult] + tax_unit_childcare_expenses: 2000 + households: + household: + members: [filer, child, adult] + state_code: WI + output: + wi_childcare_expense_credit_potential: 200.0 + +- name: 2025 filing exception filer keeps adult care and only qualifying childcare + period: 2025 + absolute_error_margin: 0.01 + input: + people: + filer: + age: 22 + employment_income: 60000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 4 + is_tax_unit_dependent: true + is_incapable_of_self_care: false + adult: + age: 30 + is_tax_unit_spouse: false + is_tax_unit_dependent: true + is_incapable_of_self_care: true + care_expenses: 1000 + tax_units: + tax_unit: + members: [filer, child, adult] + tax_unit_childcare_expenses: 2000 + households: + household: + members: [filer, child, adult] + state_code: WI + output: + wi_childcare_expense_credit_potential: 600.0 + +- name: 2025 incapable child filer keeps adult care and only qualifying childcare + period: 2025 + absolute_error_margin: 0.01 + input: + people: + filer: + age: 22 + employment_income: 60000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + child: + age: 4 + is_tax_unit_dependent: true + is_incapable_of_self_care: true + adult: + age: 30 + is_tax_unit_spouse: false + is_tax_unit_dependent: true + is_incapable_of_self_care: true + care_expenses: 1000 + tax_units: + tax_unit: + members: [filer, child, adult] + tax_unit_childcare_expenses: 2000 + households: + household: + members: [filer, child, adult] + state_code: WI + output: + wi_childcare_expense_credit_potential: 600.0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_childcare_expense_subtraction.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_childcare_expense_subtraction.yaml index fc6bfbf91c6..3feb4d685d5 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_childcare_expense_subtraction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_childcare_expense_subtraction.yaml @@ -79,3 +79,106 @@ state_code: WI output: wi_childcare_expense_subtraction: 2_000 + +# Disabled-adult care remains eligible when the filer can be claimed. +# The $2,000 childcare is excluded unless the filing exception applies +# or the child is incapable of self-care (IRC 21(b)(1)(B)). + +- name: 2021 claimable filer keeps adult care and only qualifying childcare + period: 2021 + absolute_error_margin: 0.01 + input: + people: + filer: + age: 22 + employment_income: 60000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + child: + age: 4 + is_tax_unit_dependent: true + is_incapable_of_self_care: false + adult: + age: 30 + is_tax_unit_spouse: false + is_tax_unit_dependent: true + is_incapable_of_self_care: true + care_expenses: 1000 + tax_units: + tax_unit: + members: [filer, child, adult] + tax_unit_childcare_expenses: 2000 + households: + household: + members: [filer, child, adult] + state_code: WI + output: + wi_childcare_expense_subtraction: 1000 + +- name: 2021 filing exception filer keeps adult care and only qualifying childcare + period: 2021 + absolute_error_margin: 0.01 + input: + people: + filer: + age: 22 + employment_income: 60000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 4 + is_tax_unit_dependent: true + is_incapable_of_self_care: false + adult: + age: 30 + is_tax_unit_spouse: false + is_tax_unit_dependent: true + is_incapable_of_self_care: true + care_expenses: 1000 + tax_units: + tax_unit: + members: [filer, child, adult] + tax_unit_childcare_expenses: 2000 + households: + household: + members: [filer, child, adult] + state_code: WI + output: + wi_childcare_expense_subtraction: 3000 + +- name: 2021 incapable child filer keeps adult care and only qualifying childcare + period: 2021 + absolute_error_margin: 0.01 + input: + people: + filer: + age: 22 + employment_income: 60000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: false + child: + age: 4 + is_tax_unit_dependent: true + is_incapable_of_self_care: true + adult: + age: 30 + is_tax_unit_spouse: false + is_tax_unit_dependent: true + is_incapable_of_self_care: true + care_expenses: 1000 + tax_units: + tax_unit: + members: [filer, child, adult] + tax_unit_childcare_expenses: 2000 + households: + household: + members: [filer, child, adult] + state_code: WI + output: + wi_childcare_expense_subtraction: 3000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_exemption.yaml index 96a1ec8eddb..17307b8dd1c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_exemption.yaml @@ -1,16 +1,32 @@ - name: WI exemption unit test 1 period: 2021 input: - exemptions_count: 5 - state_code: WI + people: + head: {} + tax_units: + tax_unit: + members: [head] + exemptions_count: 5 + households: + household: + members: [head] + state_code: WI output: wi_exemption: 5 * 700 - name: WI exemption unit test 2 period: 2022 input: - exemptions_count: 5 - age_head: 65 - state_code: WI + people: + head: + age: 65 + tax_units: + tax_unit: + members: [head] + exemptions_count: 5 + households: + household: + members: [head] + state_code: WI output: wi_exemption: 5 * 700 + 250 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_homestead_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_homestead_income.yaml index 8a453c0b9bd..0733c2e02d7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_homestead_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_homestead_income.yaml @@ -100,6 +100,208 @@ # add-back is the 5,000 non-SSTB loss. wi_homestead_income: 5_000 +# Hold TANF at zero to isolate the $500 dependent deduction on wage income. + +- name: "2025 single filer who can be claimed as a dependent: no Wisconsin homestead $500 dependent deduction" + period: 2025 + input: + people: + filer: + age: 62 + employment_income: 10000 + real_estate_taxes: 1000 + claimed_as_dependent_on_another_return: true + child: + age: 4 + spm_units: + spm_unit: + members: [filer, child] + tanf: 0 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: WI + output: + # The $500 deduction is for a dependent under IRC 152, and a claimant + # who can be claimed has none (IRC 152(b)(1)). The claimant, 62 or + # older, stays eligible: ($1,000 - ($10,000 - $8,060) x 8.785%) x 80%. + wi_homestead_income: 10000 + wi_homestead_credit: 663.6568 + +- name: "2025 joint return with one claimable spouse: no Wisconsin homestead $500 dependent deduction (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + spm_units: + spm_unit: + members: [person_a, person_b, child] + tanf: 0 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: WI + output: + # Either spouse being claimable leaves the joint return no dependents. + wi_homestead_income: 10000 + wi_homestead_credit: 663.6568 + +- name: "2025 joint return with one claimable spouse: no Wisconsin homestead $500 dependent deduction (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + spm_units: + spm_unit: + members: [person_b, person_a, child] + tanf: 0 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: WI + output: + wi_homestead_income: 10000 + wi_homestead_credit: 663.6568 + +- name: "2025 joint return with both spouses claimable: no Wisconsin homestead $500 dependent deduction" + period: 2025 + input: + people: + person_a: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + spm_units: + spm_unit: + members: [person_a, person_b, child] + tanf: 0 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: WI + output: + wi_homestead_income: 10000 + wi_homestead_credit: 663.6568 + +- name: "2025 joint return with neither spouse claimable (control): Wisconsin homestead $500 dependent deduction" + period: 2025 + input: + people: + person_a: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 62 + employment_income: 5000 + real_estate_taxes: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + spm_units: + spm_unit: + members: [person_a, person_b, child] + tanf: 0 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: WI + output: + # $10,000 - $500 = $9,500; ($1,000 - $1,440 x 8.785%) x 80% = $698.7968. + wi_homestead_income: 9500 + wi_homestead_credit: 698.7968 + +# $10,000 income less the restored $500 dependent deduction. + +- name: 2025 claimant filing exception preserves the Wisconsin homestead dependent deduction + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 10000 + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: WI + spm_units: + spm_unit: + members: [filer, child] + tanf: 0 + output: + wi_homestead_income: 9500 # A household is the claimant and the claimant's spouse (Wis. Stat. 71.52(4); # 2024 Schedule H instructions, page 8), and the instructions say to leave out # children's social security and SSI (page 13), so a dependent's income is not diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.yaml index 2ec7fa9cf4d..a79101d3d55 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.yaml @@ -219,3 +219,28 @@ # tax = 6,000 * 0.035 = 210. wi_retirement_income_exclusion_amount: 24_000 wi_retirement_income_exclusion_tax: 210 + +# $34,000 WI income - $24,000 exclusion - $4,450 dependent deduction +# - $250 exemption = $5,300, taxed at 3.5% = $185.50. Pension and IRA both +# qualify. The exemption is the age-65 $250 under Wis. Stat. 71.05(23)(b)3, +# which tests only age; the $700 personal exemption stays at $0 as built. + +- name: 2025 claimable but unclaimed retiree uses the dependent deduction on the positive retirement exclusion + path + period: 2025 + absolute_error_margin: 0.01 + input: + age: 70 + employment_income: 4000 + taxable_pension_income: 20000 + taxable_ira_distributions: 10000 + is_tax_unit_head: true + filing_status: SINGLE + state_code: WI + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + output: + wi_retirement_income_exclusion_amount: 24000 + wi_standard_deduction: 4450 + wi_exemption: 250 + wi_retirement_income_exclusion_tax: 185.50 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_standard_deduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_standard_deduction.yaml index 24ec29f0189..e5165514367 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_standard_deduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wi/tax/income/wi_standard_deduction.yaml @@ -97,3 +97,371 @@ # same amount through the 22.515% and 12% segments that meet at $58,827, # within $0.05 of the schedule. wi_standard_deduction: 13_960 - 0.12 * (70_000 - 20_120) + +- name: "2025 single filer who can be claimed as a dependent: Wisconsin standard deduction limited for a filer who can be claimed" + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WI + output: + # Wis. Stat. 71.05(22)(f): the lesser of the ordinary deduction and + # max($1,350, earned income + $450) = max($1,350, $1,000 + $450). + wi_standard_deduction: 1450 + +- name: "2025 joint return with one claimable spouse: Wisconsin standard deduction limited for a filer who can be claimed (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + # Form 1 worksheet: applies if you or your spouse can be claimed; the + # couple's earned income is $1,000, so $1,450. + wi_standard_deduction: 1450 + +- name: "2025 joint return with one claimable spouse: Wisconsin standard deduction limited for a filer who can be claimed (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 22 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 22 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: WI + output: + wi_standard_deduction: 1450 + +- name: "2025 joint return with both spouses claimable: Wisconsin standard deduction limited for a filer who can be claimed" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + wi_standard_deduction: 1450 + +- name: "2025 joint return with neither spouse claimable: Wisconsin standard deduction limited for a filer who can be claimed" + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 22 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WI + output: + # Joint maximum at WI income $1,000: $25,110 (2025). + wi_standard_deduction: 25110 + +- name: 2025 single filer who cannot be claimed gets the full Wisconsin standard deduction + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 1000 + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WI + output: + wi_standard_deduction: 13560 + +- name: 2025 single filer who can be claimed and has no earned income gets the Wisconsin dependent floor + period: 2025 + input: + people: + filer: + age: 20 + taxable_interest_income: 2000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WI + output: + # max($1,350, $0 + $450) = $1,350. + wi_standard_deduction: 1350 + +- name: "2021 single filer who can be claimed: Wisconsin dependent standard deduction" + period: 2021 + input: + people: + filer: + age: 20 + employment_income: 600 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WI + output: + # 2021 Form 1 worksheet: max($1,100, $600 + $350) = $1,100. + wi_standard_deduction: 1100 + +- name: "2023 single filer who can be claimed: Wisconsin dependent standard deduction" + period: 2023 + input: + people: + filer: + age: 20 + employment_income: 3000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WI + output: + # 2023 Form 1 worksheet: max($1,250, $3,000 + $400) = $3,400. + wi_standard_deduction: 3400 + + +- name: Wisconsin dependent deduction uses wages included in Wisconsin income after pretax retirement contributions + period: 2025 + input: + people: + filer: + age: 22 + is_full_time_student: true + employment_income: 10_000 + traditional_401k_contributions: 5_000 + taxable_interest_income: 10_000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + spm_units: + spm_unit: + members: [filer] + tanf: 0 + households: + household: + members: [filer] + state_code: WI + output: + # 2025 Form 1 dependent worksheet: WI-included earnings $5,000 + $450. + irs_employment_income: 5_000 + wi_agi: 15_000 + wi_standard_deduction: 5_450 + wi_taxable_income: 9_550 + +- name: Wisconsin caps an unclaimed but claimable filer's standard deduction + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 1_000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: [filer] + spm_units: + spm_unit: + members: [filer] + tanf: 0 + households: + household: + members: [filer] + state_code: WI + output: + # Claimability, regardless of whether anyone actually claims the filer. + wi_standard_deduction: 1_450 + +- name: Wisconsin counts a claimable filer's taxable disability wages as earned income + period: 2025 + input: + people: + filer: + age: 22 + disability_benefits: 10_000 + disability_benefits_before_minimum_retirement_age: 10_000 + taxable_interest_income: 20_000 + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + spm_units: + spm_unit: + members: [filer] + tanf: 0 + households: + household: + members: [filer] + state_code: WI + output: + adjusted_gross_income: 30_000 + wi_agi: 30_000 + earned_disability_benefits: 10_000 + basic_standard_deduction: 10_450 + # Ordinary: 13,560 - 0.12 * (30,000 - 19,550) = 12,306. + # Dependent limit: max(1,350, 10,000 + 450) = 10,450. + wi_standard_deduction: 10_450 + +- name: Without disability wages, the same claimable filer's interest earns only the minimum + period: 2025 + input: + people: + filer: + age: 22 + taxable_interest_income: 20_000 + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + spm_units: + spm_unit: + members: [filer] + tanf: 0 + households: + household: + members: [filer] + state_code: WI + output: + wi_agi: 20_000 + # Ordinary: 13,560 - 0.12 * (20,000 - 19,550) = 13,506. + # Dependent limit: max(1,350, 0 + 450) = 1,350. + wi_standard_deduction: 1_350 + +- name: Wisconsin counts a claimable filer's farm income less the self-employment tax deduction as earned income + period: 2025 + absolute_error_margin: 0.01 + input: + people: + filer: + age: 22 + farm_operations_income: 10_000 + taxable_interest_income: 20_000 + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + spm_units: + spm_unit: + members: [filer] + tanf: 0 + households: + household: + members: [filer] + state_code: WI + output: + # SE tax deduction: 10,000 * 0.9235 * 0.153 / 2 = 706.48. + self_employment_tax_ald: 706.48 + # AGI: 10,000 + 20,000 - 706.48 = 29,293.52. + wi_agi: 29_293.52 + # Earned income: 10,000 - 706.48 = 9,293.52. + standard_deduction_worksheet_earned_income: 9_293.52 + basic_standard_deduction: 9_743.52 + # Ordinary: 13,560 - 0.12 * (29,293.52 - 19,550) = 12,390.78. + # Dependent limit: max(1,350, 9,293.52 + 450) = 9,743.52. + wi_standard_deduction: 9_743.52 + +- name: Wisconsin leaves a dependent's own wages out of a claimable filer's earned income + period: 2025 + input: + people: + filer: + age: 22 + taxable_interest_income: 20_000 + claimable_as_dependent_on_another_return: true + child: + age: 16 + employment_income: 5_000 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: WI + output: + standard_deduction_worksheet_earned_income: 0 + # The child's wages belong on the child's own return. + # Dependent limit: max(1,350, 0 + 450) = 1,350. + wi_standard_deduction: 1_350 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.yaml index 73a49c95403..5c7ff75e947 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.yaml @@ -13,3 +13,192 @@ alternative_minimum_tax: 0 output: wv_low_income_family_tax_credit_eligible: true + +- name: 2025 single filer who is claimed as a dependent counts the 11-21-16(d) exemption in West Virginia family size + period: 2025 + input: + people: + filer: + age: 30 + employment_income: 16000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WV + output: + # W. Va. Code 11-21-22A(b): family size counts the filer's single + # 11-21-16(d) exemption, so family size 1: 2025 FPG $15,650. Taxable + # income $16,000 - $500 = $15,500; tax $222 + $5,500 x 2.96% = $384.80. + # Income exceeds the FPG by $350, so the single credit is 80%: $307.84. + wv_low_income_family_tax_credit_eligible: true + wv_low_income_family_tax_credit_fpg: 15650 + wv_personal_exemption: 500 + wv_taxable_income: 15500 + wv_income_tax_before_non_refundable_credits: 384.8 + wv_low_income_family_tax_credit_potential: 307.84 + +- name: 2025 joint return with one claimed spouse counts that spouse's 11-21-16(d) exemption in West Virginia family size (the claimed spouse is the head) + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WV + output: + # Family size 2 (one $2,000 exemption and one 11-21-16(d) exemption): + # 2025 FPG $15,650 + $5,500 = $21,150. Taxable income $16,000 - $2,500 = + # $13,500; tax $10,000 x 2.22% + $3,500 x 2.96% = $325.60. Income is + # below the FPG, so the credit is 100%: $325.60. + wv_low_income_family_tax_credit_eligible: true + wv_low_income_family_tax_credit_fpg: 21150 + wv_personal_exemption: 2500 + wv_taxable_income: 13500 + wv_income_tax_before_non_refundable_credits: 325.6 + wv_low_income_family_tax_credit_potential: 325.6 + +- name: 2025 joint return with one claimed spouse counts that spouse's 11-21-16(d) exemption in West Virginia family size (the claimed spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: WV + output: + wv_low_income_family_tax_credit_eligible: true + wv_low_income_family_tax_credit_fpg: 21150 + wv_personal_exemption: 2500 + wv_taxable_income: 13500 + wv_income_tax_before_non_refundable_credits: 325.6 + wv_low_income_family_tax_credit_potential: 325.6 + +- name: 2025 joint return with both spouses claimed counts both 11-21-16(d) exemptions in West Virginia family size + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WV + output: + # Family size 2: FPG $21,150. Taxable income $16,000 - 2 x $500 = + # $15,000; tax $222 + $5,000 x 2.96% = $370. Income is below the FPG, + # so the credit is 100%: $370. + wv_low_income_family_tax_credit_eligible: true + wv_low_income_family_tax_credit_fpg: 21150 + wv_personal_exemption: 1000 + wv_taxable_income: 15000 + wv_income_tax_before_non_refundable_credits: 370 + wv_low_income_family_tax_credit_potential: 370 + +- name: "2025 joint return with neither spouse claimable: control for the West Virginia family size cases with a claimed spouse" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WV + output: + # Family size 2: $15,650 + $5,500 = $21,150. Taxable income $12,000; + # tax $222 + $2,000 x 2.96% = $281.20; income below the FPG: 100%. + wv_low_income_family_tax_credit_eligible: true + wv_low_income_family_tax_credit_fpg: 21150 + wv_income_tax_before_non_refundable_credits: 281.2 + wv_low_income_family_tax_credit_potential: 281.2 + +- name: 2025 single filer who can be claimed, with a child the filing exception lets the filer claim, keeps the IT-140 count in West Virginia family size + period: 2025 + input: + people: + parent: + age: 22 + employment_income: 16_000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + households: + household: + members: [parent, child] + state_code: WV + output: + # The child adds an exemption, so the return keeps the ordinary count: + # family size 1 and a $2,000 exemption, with no 11-21-16(d) exemption. + # FPG $15,650. Taxable income $14,000; tax $222 + $4,000 x 2.96% = + # $340.40. Income exceeds the FPG by $350, so the credit is 80%: $272.32. + wv_low_income_family_tax_credit_fpg: 15650 + wv_personal_exemption: 2000 + wv_income_tax_before_non_refundable_credits: 340.4 + wv_low_income_family_tax_credit_potential: 272.32 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/exemptions/wv_personal_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/exemptions/wv_personal_exemption.yaml index a41435eb495..95d7ae6bbe5 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/exemptions/wv_personal_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wv/tax/income/exemptions/wv_personal_exemption.yaml @@ -28,3 +28,389 @@ tax_unit_size: 2 output: wv_personal_exemption: 4_000 + +- name: "2025 single filer who can be claimed as a dependent: West Virginia personal exemption counts only exemptions that may be claimed" + period: 2025 + input: + people: + filer: + age: 30 + employment_income: 16000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [filer] + households: + household: + members: [filer] + state_code: WV + output: + # W. Va. Code 11-21-16 and IRC 151(d)(2): no exemption for a filer who + # can be claimed; section 11-21-16(d) grants that individual $500. + wv_personal_exemption: 500 + +- name: "2025 joint return with one claimable spouse: West Virginia personal exemption counts only exemptions that may be claimed (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WV + output: + # $2,000 for the nonclaimable spouse plus the claimable filer's $500. + wv_personal_exemption: 2500 + +- name: "2025 joint return with one claimable spouse: West Virginia personal exemption counts only exemptions that may be claimed (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_b, person_a] + filing_status: JOINT + households: + household: + members: [person_b, person_a] + state_code: WV + output: + wv_personal_exemption: 2500 + +- name: "2025 joint return with both spouses claimable: West Virginia personal exemption counts only exemptions that may be claimed" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WV + output: + # Section 11-21-16(d) grants each claimable spouse a $500 allowance. + wv_personal_exemption: 1000 + +- name: "2025 joint return with neither spouse claimable: West Virginia personal exemption counts only exemptions that may be claimed" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: WV + output: + # Two exemptions x $2,000. + wv_personal_exemption: 4000 + +- name: "2025 joint return with one claimable spouse and a child: West Virginia personal exemption has no dependent exemption (the claimable spouse is the head)" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: WV + output: + # IRC 152(b)(1): either spouse being claimable leaves the return no + # dependents, so the child adds no exemption. One exemption x $2,000 + # plus $500 for the claimable spouse (Section 11-21-16(d)); the control + # below gets $6,000. + wv_personal_exemption: 2500 + +- name: "2025 joint return with one claimable spouse and a child: West Virginia personal exemption has no dependent exemption (the claimable spouse is the spouse)" + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 8000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: WV + output: + # The child adds no exemption: $2,000 + $500 for the claimable spouse. + wv_personal_exemption: 2500 + +- name: "2025 joint return with neither spouse claimable and a child: West Virginia personal exemption" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: WV + output: + wv_personal_exemption: 6000 + +- name: "2025 joint return with both spouses claimable and two children: West Virginia personal exemption gives each claimable spouse $500" + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 8000 + claimable_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 8000 + claimable_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child1: + age: 4 + child2: + age: 7 + tax_units: + tax_unit: + members: [person_a, person_b, child1, child2] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child1, child2] + state_code: WV + output: + # IRC 151(d)(2) and 152(b)(1): no own or dependent exemptions, so the + # children add nothing. Section 11-21-16(d): $500 for each claimable + # spouse, $1,000 in all. + exemptions_count: 0 + wv_personal_exemption: 1000 + +- name: 2025 single filer who can be claimed but whose would-be claimant meets the filing exception gets a West Virginia dependent exemption + period: 2025 + input: + people: + filer: + age: 22 + employment_income: 16000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: + age: 4 + tax_units: + tax_unit: + members: [filer, child] + households: + household: + members: [filer, child] + state_code: WV + output: + # No own exemption; one dependent exemption x $2,000, so no $500. + wv_personal_exemption: 2000 + +- name: WV statutory individual allowance - single claimable filer + period: 2025 + input: + people: + filer: + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - filer + filing_status: SINGLE + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - filer + state_code: WV + output: + wv_personal_exemption: 500 + wv_taxable_income: 29500 + +- name: WV statutory individual allowance - claimable head and nonclaimable spouse + period: 2025 + input: + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: true + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 2500 + wv_taxable_income: 27500 + +- name: WV statutory individual allowance - two claimable spouses + period: 2025 + input: + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: true + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 1000 + wv_taxable_income: 29000 + +- name: WV statutory individual allowance - nonclaimable head and claimable spouse + period: 2025 + input: + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: false + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 2500 + wv_taxable_income: 27500 diff --git a/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml b/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml index d6009003126..62692cab825 100644 --- a/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml +++ b/policyengine_us/tests/policy/contrib/state_dependent_exemptions/repeal_state_dependent_exemptions.yaml @@ -495,6 +495,353 @@ # Baseline keeps the dependent add: 7,600 + 1 x 1,000 + 6,800 = 15,400. ma_income_tax_exemption_threshold: 15_400 +- name: WV dependent exemption repeal - claimed filer with a child keeps the zero-exemption amount + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: WV}} + output: {wv_personal_exemption: 500} + +- name: WV dependent exemption repeal - joint return with one claimable spouse and two children keeps the per-filer amount + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + parent1: {age: 40, employment_income: 60_000} + parent2: + age: 38 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child1: {age: 10, is_tax_unit_dependent: true} + child2: {age: 12, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent1, parent2, child1, child2], filing_status: JOINT}} + households: {household: {members: [parent1, parent2, child1, child2], state_name: WV}} + output: + # Repeal counts only own exemptions: $2,000 for parent1 plus $500 for + # the claimable spouse; the children add nothing. + wv_personal_exemption: 2_500 + +- name: WV dependent exemption repeal - claimed childless filer keeps the zero-exemption amount + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: {tax_unit: {members: [parent], filing_status: SINGLE}} + households: {household: {members: [parent], state_name: WV}} + output: {wv_personal_exemption: 500} + +- name: WV dependent exemption repeal - unclaimed but claimable childless filer keeps the zero-exemption amount + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: {tax_unit: {members: [parent], filing_status: SINGLE}} + households: {household: {members: [parent], state_name: WV}} + output: {wv_personal_exemption: 500} + +- name: WI repeal - single filer claimed - baseline + period: 2025 + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: WI}} + output: + exemptions_count: 0 + wi_base_exemption: 0 + +- name: WI repeal - single filer claimed - reform + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: WI}} + output: + exemptions_count: 0 + wi_base_exemption: 0 + +- name: WI repeal - both joint filers claimed - baseline + period: 2025 + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + spouse: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: {tax_unit: {members: [head, spouse], filing_status: JOINT}} + households: {household: {members: [head, spouse], state_name: WI}} + output: + exemptions_count: 0 + wi_base_exemption: 0 + +- name: WI repeal - both joint filers claimed - reform + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + spouse: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: {tax_unit: {members: [head, spouse], filing_status: JOINT}} + households: {household: {members: [head, spouse], state_name: WI}} + output: + exemptions_count: 0 + wi_base_exemption: 0 + +- name: RI repeal - single filer claimed - baseline + period: 2025 + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI repeal - single filer claimed - reform + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: WI repeal - single filer unclaimed but claimable - baseline + period: 2025 + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: WI}} + output: + exemptions_count: 0 + wi_base_exemption: 0 + +- name: WI repeal - single filer unclaimed but claimable - reform + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: WI}} + output: + exemptions_count: 0 + wi_base_exemption: 0 + +- name: RI repeal - single filer unclaimed but claimable - baseline + period: 2025 + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI repeal - single filer unclaimed but claimable - reform + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + tax_units: {tax_unit: {members: [head], filing_status: SINGLE}} + households: {household: {members: [head], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: WV statutory individual allowance - single claimable filer + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + filer: + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - filer + filing_status: SINGLE + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - filer + state_code: WV + output: + wv_personal_exemption: 500 + wv_taxable_income: 29500 + +- name: WV statutory individual allowance - claimable head and nonclaimable spouse + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: true + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 2500 + wv_taxable_income: 27500 + +- name: WV statutory individual allowance - two claimable spouses + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: true + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 1000 + wv_taxable_income: 29000 + +- name: WV statutory individual allowance - nonclaimable head and claimable spouse + period: 2025 + reforms: policyengine_us.reforms.state_dependent_exemptions.repeal_state_dependent_exemptions.repeal_state_dependent_exemptions + input: + gov.contrib.repeal_state_dependent_exemptions.in_effect: true + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: false + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 2500 + wv_taxable_income: 27500 + # California keeps its personal credits under the repeal, with the baseline's # rule that a filer who can be claimed as a dependent gets none (RTC 17054; # Form 540 line 7). 2025: $153 per credit. diff --git a/policyengine_us/tests/policy/contrib/states/ri/exemption_reform_claimable_filer_test.yaml b/policyengine_us/tests/policy/contrib/states/ri/exemption_reform_claimable_filer_test.yaml new file mode 100644 index 00000000000..eaea41e6aed --- /dev/null +++ b/policyengine_us/tests/policy/contrib/states/ri/exemption_reform_claimable_filer_test.yaml @@ -0,0 +1,291 @@ +- name: RI exemption reform - young dependent of claimed filer - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI exemption reform - young dependent of claimed filer - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + ri_eligible_dependents_count: 0 + ri_older_dependents_count: 0 + +- name: RI exemption reform - young dependent of unclaimed but claimable filer - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI exemption reform - young dependent of unclaimed but claimable filer - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + ri_eligible_dependents_count: 0 + ri_older_dependents_count: 0 + +- name: RI exemption reform - older dependent of claimed filer - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + gov.contrib.states.ri.dependent_exemption.age_limit.in_effect: true + gov.contrib.states.ri.dependent_exemption.age_limit.threshold: 18 + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 20, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI exemption reform - older dependent of claimed filer - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + gov.contrib.states.ri.dependent_exemption.age_limit.in_effect: true + gov.contrib.states.ri.dependent_exemption.age_limit.threshold: 18 + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 20, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + ri_eligible_dependents_count: 0 + ri_older_dependents_count: 0 + +- name: RI exemption reform - older dependent of unclaimed but claimable filer - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + gov.contrib.states.ri.dependent_exemption.age_limit.in_effect: true + gov.contrib.states.ri.dependent_exemption.age_limit.threshold: 18 + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child: {age: 20, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI exemption reform - older dependent of unclaimed but claimable filer - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + gov.contrib.states.ri.dependent_exemption.age_limit.in_effect: true + gov.contrib.states.ri.dependent_exemption.age_limit.threshold: 18 + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child: {age: 20, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + ri_eligible_dependents_count: 0 + ri_older_dependents_count: 0 + +- name: RI exemption reform - joint return with only head claimable - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + spouse: + age: 22 + claimable_as_dependent_on_another_return: false + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [head, spouse, child], filing_status: JOINT}} + households: {household: {members: [head, spouse, child], state_name: RI}} + output: + exemptions_count: 1 + ri_exemptions: 5_100 + +- name: RI exemption reform - joint return with only head claimable - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + spouse: + age: 22 + claimable_as_dependent_on_another_return: false + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [head, spouse, child], filing_status: JOINT}} + households: {household: {members: [head, spouse, child], state_name: RI}} + output: + exemptions_count: 1 + ri_exemptions: 5_100 + +- name: RI exemption reform - joint return with only spouse claimable - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: false + spouse: + age: 22 + claimable_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [head, spouse, child], filing_status: JOINT}} + households: {household: {members: [head, spouse, child], state_name: RI}} + output: + exemptions_count: 1 + ri_exemptions: 5_100 + +- name: RI exemption reform - joint return with only spouse claimable - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: false + spouse: + age: 22 + claimable_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [head, spouse, child], filing_status: JOINT}} + households: {household: {members: [head, spouse, child], state_name: RI}} + output: + exemptions_count: 1 + ri_exemptions: 5_100 + +- name: RI exemption reform - joint return with both filers claimable - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + spouse: + age: 22 + claimable_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [head, spouse, child], filing_status: JOINT}} + households: {household: {members: [head, spouse, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI exemption reform - joint return with both filers claimable - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + people: + head: + age: 22 + claimable_as_dependent_on_another_return: true + spouse: + age: 22 + claimable_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [head, spouse, child], filing_status: JOINT}} + households: {household: {members: [head, spouse, child], state_name: RI}} + output: + exemptions_count: 0 + ri_exemptions: 0 + +- name: RI exemption reform - dependent claimant filing exception preserves child exemption - baseline + period: 2025 + input: + gov.contrib.states.ri.dependent_exemption.in_effect: false + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 1 + ri_exemptions: 5_100 + +- name: RI exemption reform - dependent claimant filing exception preserves child exemption - reform + period: 2025 + reforms: policyengine_us.reforms.states.ri.exemption.ri_exemption_reform.ri_exemption_reform + input: + gov.contrib.states.ri.dependent_exemption.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: RI}} + output: + exemptions_count: 1 + ri_exemptions: 5_100 diff --git a/policyengine_us/tests/policy/contrib/states/sc/dependent_exemption_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/sc/dependent_exemption_reform_test.yaml index b9dd61a79e2..ef737773dc1 100644 --- a/policyengine_us/tests/policy/contrib/states/sc/dependent_exemption_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/sc/dependent_exemption_reform_test.yaml @@ -89,3 +89,67 @@ households: {household: {members: [parent, child1], state_name: SC}} # Dependent one year under the limit (12 < 13) is re-priced to the reform amount (0). output: {sc_dependent_exemption: 0} + +# IRC 152(b)(1) applies inside the reform as well as in the baseline. +- name: SC dependent exemption reform - claimed filer cannot claim a child at default parameters + period: 2025 + reforms: policyengine_us.reforms.states.sc.dependent_exemption.sc_dependent_exemption_reform.sc_dependent_exemption_reform + input: + gov.contrib.states.sc.dependent_exemption.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: SC}} + output: {sc_dependent_exemption: 0} + +- name: SC dependent exemption reform - unclaimed but claimable filer cannot claim a child + period: 2025 + reforms: policyengine_us.reforms.states.sc.dependent_exemption.sc_dependent_exemption_reform.sc_dependent_exemption_reform + input: + gov.contrib.states.sc.dependent_exemption.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: SC}} + output: {sc_dependent_exemption: 0} + +- name: SC dependent exemption reform - claimable filer cannot recover an older dependent exemption + period: 2025 + reforms: policyengine_us.reforms.states.sc.dependent_exemption.sc_dependent_exemption_reform.sc_dependent_exemption_reform + input: + gov.contrib.states.sc.dependent_exemption.in_effect: true + gov.contrib.states.sc.dependent_exemption.age_limit.in_effect: true + gov.contrib.states.sc.dependent_exemption.age_limit.threshold: 13 + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 15, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: SC}} + output: {sc_dependent_exemption: 0} + +- name: SC dependent exemption reform - filing exception permits the child exemption + period: 2025 + reforms: policyengine_us.reforms.states.sc.dependent_exemption.sc_dependent_exemption_reform.sc_dependent_exemption_reform + input: + gov.contrib.states.sc.dependent_exemption.in_effect: true + people: + parent: + age: 22 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: SC}} + output: {sc_dependent_exemption: 4_930} diff --git a/policyengine_us/tests/policy/contrib/states/ut/dependent_exemption/ut_dependent_exemption.yaml b/policyengine_us/tests/policy/contrib/states/ut/dependent_exemption/ut_dependent_exemption.yaml index 49278857c1e..885bdc606a0 100644 --- a/policyengine_us/tests/policy/contrib/states/ut/dependent_exemption/ut_dependent_exemption.yaml +++ b/policyengine_us/tests/policy/contrib/states/ut/dependent_exemption/ut_dependent_exemption.yaml @@ -148,3 +148,195 @@ # in_effect is false, so the $0 amount does not apply: two dependents # at the uprated baseline amount. ut_personal_exemption: 4_318 + +- name: Reform in effect counts no dependents on a claimable filer's return (single filer) + period: 2026 + reforms: policyengine_us.reforms.states.ut.dependent_exemption.ut_dependent_exemption_reform + input: + gov.contrib.states.ut.dependent_exemption.in_effect: true + gov.contrib.states.ut.dependent_exemption.amount: 3_000 + people: + filer: + age: 20 + claimed_as_dependent_on_another_return: true + child1: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [filer, child1] + households: + household: + members: [filer, child1] + state_code: UT + output: + # IRC 152(b)(1): a filer who can be claimed has no dependents, as in the + # baseline ut_total_dependents. + ut_personal_exemption: 0 + +- name: Reform in effect counts no dependents when one joint spouse can be claimed (the claimable spouse is the spouse) + period: 2026 + reforms: policyengine_us.reforms.states.ut.dependent_exemption.ut_dependent_exemption_reform + input: + gov.contrib.states.ut.dependent_exemption.in_effect: true + gov.contrib.states.ut.dependent_exemption.amount: 3_000 + people: + person_b: + age: 22 + is_tax_unit_head: true + person_a: + age: 20 + is_tax_unit_spouse: true + claimed_as_dependent_on_another_return: true + child1: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child1] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child1] + state_code: UT + output: + ut_personal_exemption: 0 + +- name: Reform in effect counts no dependents when one joint spouse can be claimed (the claimable spouse is the head) + period: 2026 + reforms: policyengine_us.reforms.states.ut.dependent_exemption.ut_dependent_exemption_reform + input: + gov.contrib.states.ut.dependent_exemption.in_effect: true + gov.contrib.states.ut.dependent_exemption.amount: 3_000 + people: + person_a: + age: 20 + is_tax_unit_head: true + claimed_as_dependent_on_another_return: true + person_b: + age: 22 + is_tax_unit_spouse: true + child1: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child1] + state_code: UT + output: + ut_personal_exemption: 0 + +- name: Reform in effect, neither spouse claimable (control) + period: 2026 + reforms: policyengine_us.reforms.states.ut.dependent_exemption.ut_dependent_exemption_reform + input: + gov.contrib.states.ut.dependent_exemption.in_effect: true + gov.contrib.states.ut.dependent_exemption.amount: 3_000 + people: + person_a: + age: 20 + is_tax_unit_head: true + person_b: + age: 22 + is_tax_unit_spouse: true + child1: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child1] + state_code: UT + output: + # One dependent at the reform amount (no age limit): $3,000. + ut_personal_exemption: 3_000 + +- name: Reform in effect, neither spouse claimable (control) (head and spouse labels swapped) + period: 2026 + reforms: policyengine_us.reforms.states.ut.dependent_exemption.ut_dependent_exemption_reform + input: + gov.contrib.states.ut.dependent_exemption.in_effect: true + gov.contrib.states.ut.dependent_exemption.amount: 3000 + people: + person_a: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + person_b: + age: 22 + is_tax_unit_spouse: false + is_tax_unit_head: true + child1: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child1] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child1] + state_code: UT + output: + ut_personal_exemption: 3000 + +- name: Reform in effect counts the dependent of a claimable filer whose would-be claimant meets the filing exception + period: 2026 + reforms: policyengine_us.reforms.states.ut.dependent_exemption.ut_dependent_exemption_reform + input: + gov.contrib.states.ut.dependent_exemption.in_effect: true + gov.contrib.states.ut.dependent_exemption.amount: 3_000 + people: + filer: + age: 20 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child1: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [filer, child1] + households: + household: + members: [filer, child1] + state_code: UT + output: + # The filing exception keeps the child a qualifying dependent, as in the + # baseline: one dependent at the reform amount, $3,000. + ut_personal_exemption: 3_000 + +- name: Reform in effect counts only qualifying dependents (a child with no SSN and no taxpayer identification number) + period: 2026 + reforms: policyengine_us.reforms.states.ut.dependent_exemption.ut_dependent_exemption_reform + input: + gov.contrib.states.ut.dependent_exemption.in_effect: true + gov.contrib.states.ut.dependent_exemption.amount: 3_000 + people: + filer: + age: 30 + employment_income: 30_000 + child1: + age: 5 + is_tax_unit_dependent: true + ssn_card_type: NONE + has_tin: false + tax_units: + tax_unit: + members: [filer, child1] + households: + household: + members: [filer, child1] + state_code: UT + output: + # No IRC 24 credit is allowed for the child, so the reform, like the + # baseline, counts no qualifying dependent (59-10-1018(1)(c)). + ut_personal_exemption: 0 diff --git a/policyengine_us/tests/policy/contrib/states/vt/dependent_exemption_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/vt/dependent_exemption_reform_test.yaml index e87d6f00982..36c9d083418 100644 --- a/policyengine_us/tests/policy/contrib/states/vt/dependent_exemption_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/vt/dependent_exemption_reform_test.yaml @@ -252,3 +252,80 @@ # VT income tax from 1,221.08 to 1,576.18 (about +355.10). output: vt_income_tax: 1576.18 + +# The dependent taxpayer test masks both reform and older-dependent paths. + +- name: VT dependent exemption reform - claimed filer cannot claim a child at default parameters + period: 2025 + reforms: policyengine_us.reforms.states.vt.dependent_exemption.vt_dependent_exemption_reform.vt_dependent_exemption_reform + input: + gov.contrib.states.vt.dependent_exemption.in_effect: true + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: VT}} + output: + vt_eligible_dependents_count: 0 + vt_older_dependents_count: 0 + vt_personal_exemptions: 0 + +- name: VT dependent exemption reform - unclaimed but claimable filer cannot claim a child + period: 2025 + reforms: policyengine_us.reforms.states.vt.dependent_exemption.vt_dependent_exemption_reform.vt_dependent_exemption_reform + input: + gov.contrib.states.vt.dependent_exemption.in_effect: true + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: VT}} + output: + vt_eligible_dependents_count: 0 + vt_older_dependents_count: 0 + vt_personal_exemptions: 0 + +- name: VT dependent exemption reform - claimable filer cannot recover an older dependent exemption + period: 2025 + reforms: policyengine_us.reforms.states.vt.dependent_exemption.vt_dependent_exemption_reform.vt_dependent_exemption_reform + input: + gov.contrib.states.vt.dependent_exemption.in_effect: true + gov.contrib.states.vt.dependent_exemption.age_limit.in_effect: true + gov.contrib.states.vt.dependent_exemption.age_limit.threshold: 18 + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 20, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: VT}} + output: + vt_eligible_dependents_count: 0 + vt_older_dependents_count: 0 + vt_personal_exemptions: 0 + +- name: VT dependent exemption reform - filing exception permits the child exemption without an own exemption + period: 2025 + reforms: policyengine_us.reforms.states.vt.dependent_exemption.vt_dependent_exemption_reform.vt_dependent_exemption_reform + input: + gov.contrib.states.vt.dependent_exemption.in_effect: true + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: VT}} + output: + vt_eligible_dependents_count: 1 + vt_older_dependents_count: 0 + vt_personal_exemptions: 5_300 diff --git a/policyengine_us/tests/policy/contrib/states/wv/dependent_exemption_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/wv/dependent_exemption_reform_test.yaml index 69a598e05a0..509836b58c5 100644 --- a/policyengine_us/tests/policy/contrib/states/wv/dependent_exemption_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/wv/dependent_exemption_reform_test.yaml @@ -136,3 +136,293 @@ # exemption from $6,000 to $2,000 ($4,000 of taxable income added), raising WV # income tax from 1,787.10 to 1,964.70 (about +177.60). output: {wv_income_tax: 1964.70} + +# The dependent taxpayer test masks both reform and older-dependent paths. + +- name: WV dependent exemption reform - claimed filer cannot claim a child at default parameters + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: WV}} + output: + wv_personal_exemption: 500 + wv_eligible_dependents_count: 0 + wv_older_dependents_count: 0 + +- name: WV dependent exemption reform - unclaimed but claimable filer cannot claim a child + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: WV}} + output: + wv_personal_exemption: 500 + wv_eligible_dependents_count: 0 + wv_older_dependents_count: 0 + +- name: WV dependent exemption reform - claimable filer cannot recover an older dependent exemption + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + gov.contrib.states.wv.dependent_exemption.age_limit.in_effect: true + gov.contrib.states.wv.dependent_exemption.age_limit.threshold: 18 + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: true + child: {age: 20, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: WV}} + output: + wv_personal_exemption: 500 + wv_eligible_dependents_count: 0 + wv_older_dependents_count: 0 + +- name: WV dependent exemption reform - filing exception permits the child exemption without an own exemption + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + people: + parent: + age: 40 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + dependent_claimant_filing_exception: true + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent, child], filing_status: SINGLE}} + households: {household: {members: [parent, child], state_name: WV}} + output: + wv_personal_exemption: 2_000 + wv_eligible_dependents_count: 1 + wv_older_dependents_count: 0 + +- name: WV baseline - joint return with one claimable spouse and two children + period: 2025 + input: + people: + parent1: {age: 40, employment_income: 60_000} + parent2: + age: 38 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child1: {age: 10, is_tax_unit_dependent: true} + child2: {age: 12, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent1, parent2, child1, child2], filing_status: JOINT}} + households: {household: {members: [parent1, parent2, child1, child2], state_name: WV}} + output: + exemptions_count: 1 + # The children add no exemption: $2,000 + $500 for the claimable spouse. + wv_personal_exemption: 2_500 + +- name: WV dependent exemption reform - joint return with one claimable spouse and two children + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + people: + parent1: {age: 40, employment_income: 60_000} + parent2: + age: 38 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child1: {age: 10, is_tax_unit_dependent: true} + child2: {age: 12, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent1, parent2, child1, child2], filing_status: JOINT}} + households: {household: {members: [parent1, parent2, child1, child2], state_name: WV}} + output: + exemptions_count: 1 + # The children add no exemption: $2,000 + $500 for the claimable spouse. + wv_personal_exemption: 2_500 + wv_eligible_dependents_count: 0 + wv_older_dependents_count: 0 + +- name: WV baseline - joint return with both spouses claimable and two children + period: 2025 + input: + people: + parent1: + age: 40 + employment_income: 60_000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + parent2: + age: 38 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child1: {age: 10, is_tax_unit_dependent: true} + child2: {age: 12, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent1, parent2, child1, child2], filing_status: JOINT}} + households: {household: {members: [parent1, parent2, child1, child2], state_name: WV}} + output: + exemptions_count: 0 + # The children add no exemption: $500 for each claimable spouse. + wv_personal_exemption: 1_000 + +- name: WV dependent exemption reform - joint return with both spouses claimable and two children + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + people: + parent1: + age: 40 + employment_income: 60_000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + parent2: + age: 38 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + child1: {age: 10, is_tax_unit_dependent: true} + child2: {age: 12, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [parent1, parent2, child1, child2], filing_status: JOINT}} + households: {household: {members: [parent1, parent2, child1, child2], state_name: WV}} + output: + exemptions_count: 0 + # The children add no exemption: $500 for each claimable spouse. + wv_personal_exemption: 1_000 + wv_eligible_dependents_count: 0 + wv_older_dependents_count: 0 + +- name: WV statutory individual allowance - single claimable filer + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + gov.contrib.states.wv.dependent_exemption.amount: 0 + people: + filer: + is_tax_unit_head: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - filer + filing_status: SINGLE + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - filer + state_code: WV + output: + wv_personal_exemption: 500 + wv_taxable_income: 29500 + +- name: WV statutory individual allowance - claimable head and nonclaimable spouse + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + gov.contrib.states.wv.dependent_exemption.amount: 0 + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: true + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: false + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 2500 + wv_taxable_income: 27500 + +- name: WV statutory individual allowance - two claimable spouses + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + gov.contrib.states.wv.dependent_exemption.amount: 0 + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: true + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 1000 + wv_taxable_income: 29000 + +- name: WV statutory individual allowance - nonclaimable head and claimable spouse + period: 2025 + reforms: policyengine_us.reforms.states.wv.dependent_exemption.wv_dependent_exemption_reform.wv_dependent_exemption_reform + input: + gov.contrib.states.wv.dependent_exemption.in_effect: true + gov.contrib.states.wv.dependent_exemption.amount: 0 + people: + head: + is_tax_unit_head: true + is_tax_unit_spouse: false + claimable_as_dependent_on_another_return: false + spouse: + is_tax_unit_head: false + is_tax_unit_spouse: true + claimable_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: + - head + - spouse + filing_status: JOINT + wv_agi: 30000 + wv_low_income_earned_income_exclusion: 0 + households: + household: + members: + - head + - spouse + state_code: WV + output: + wv_personal_exemption: 2500 + wv_taxable_income: 27500 diff --git a/policyengine_us/variables/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.py b/policyengine_us/variables/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.py index a69dffa25c4..3294148b8a8 100644 --- a/policyengine_us/variables/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.py +++ b/policyengine_us/variables/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.py @@ -14,15 +14,19 @@ class ri_property_tax_credit_eligible(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.ri.tax.income.credits.property_tax - # minimum age eligibility - greater_head_or_spouse_age = tax_unit("greater_age_head_spouse", period) - age_eligible = greater_head_or_spouse_age >= p.age_threshold - # disability eligibility - head_is_disabled = tax_unit("head_is_disabled", period) - spouse_is_disabled = tax_unit("spouse_is_disabled", period) - head_or_spouse_disabled = head_is_disabled | spouse_is_disabled + person = tax_unit.members + # R.I. Gen. Laws 44-33-3: the claimant is a homeowner or renter aged + # 65 or older or disabled, and "shall not mean or include any person + # claimed as a dependent by any taxpayer". Members of a household choose who + # claims, so either spouse may be the claimant, but the age or + # disability and the dependency test belong to the same person. + filer = person("is_tax_unit_head_or_spouse", period) + age_eligible = person("age", period) >= p.age_threshold + disabled = person("is_disabled", period) + claimed = person("claimed_as_dependent_on_another_return", period) + eligible_claimant = filer & (age_eligible | disabled) & ~claimed household_income = tax_unit("ri_property_tax_household_income", period) income_threshold = p.rate.one_person.thresholds[-1] # The tax form RI-1040H specifies the income of a household as a eligibility requirement household_income_eligible = household_income <= income_threshold - return (age_eligible | head_or_spouse_disabled) & household_income_eligible + return tax_unit.any(eligible_claimant) & household_income_eligible diff --git a/policyengine_us/variables/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.py b/policyengine_us/variables/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.py index 763afdcd31c..bda0a7ac857 100644 --- a/policyengine_us/variables/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.py +++ b/policyengine_us/variables/gov/states/ri/tax/income/credits/rebates/ri_child_tax_rebate.py @@ -24,7 +24,15 @@ def formula(tax_unit, period, parameters): dependent = person("is_tax_unit_dependent", period) p = parameters(period).gov.states.ri.tax.income.credits.child_tax_rebate age_eligibility = age <= p.limit.age - eligible_child = age_eligibility & dependent + # R.I. Gen. Laws 44-30-103(b)(1) pays the rebate for each child "whom + # the eligible taxpayer validly claims as a dependent" on the 2021 + # return. Under IRC 152(b)(1) a return on which the filer (or, if + # joint, either spouse) can be claimed as a dependent has none, unless + # the would-be claimant meets the filing exception (Publication 501). + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + eligible_child = age_eligibility & dependent & ~filer_is_dependent child_count = tax_unit.sum(eligible_child) capped_children = min_(child_count, p.limit.child) return capped_children * p.amount diff --git a/policyengine_us/variables/gov/states/sc/tax/income/deductions/sc_young_child_deduction.py b/policyengine_us/variables/gov/states/sc/tax/income/deductions/sc_young_child_deduction.py index 2e827e9eeea..c1dff53f03b 100644 --- a/policyengine_us/variables/gov/states/sc/tax/income/deductions/sc_young_child_deduction.py +++ b/policyengine_us/variables/gov/states/sc/tax/income/deductions/sc_young_child_deduction.py @@ -20,7 +20,19 @@ def formula(tax_unit, period, parameters): # Determine eligibility for each person in the tax unit. person = tax_unit.members meets_age_limit = person("age", period) < p.ineligible_age - eligible_dependent = meets_age_limit & person("is_tax_unit_dependent", period) + # Section 12-6-1160 requires a "dependent eligible for the South + # Carolina dependent exemption", which a return on which the filer (or, + # if joint, either spouse) can be claimed as a dependent has none of + # (IRC 152(b)(1), incorporated by Section 12-6-1140(13)), unless the + # would-be claimant meets the filing exception (Publication 501). + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + eligible_dependent = ( + meets_age_limit + & person("is_tax_unit_dependent", period) + & ~filer_is_dependent + ) # Count number of eligible people in the tax unit. total_eligible_dependents = tax_unit.sum(eligible_dependent) # Multiply by the amount per eligible dependent. diff --git a/policyengine_us/variables/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.py b/policyengine_us/variables/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.py index 77c51754adb..1a4a75cab4e 100644 --- a/policyengine_us/variables/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.py +++ b/policyengine_us/variables/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.py @@ -17,7 +17,16 @@ class sc_dependent_exemption(Variable): def formula(tax_unit, period, parameters): # Section 12-6-1140(13): a dependent exemption for every dependent. p = parameters(period).gov.states.sc.tax.income.deductions.dependent_exemption - # every dependent is eligible - dependents = tax_unit("tax_unit_dependents", period) + # Section 12-6-1140(13): "each dependent must meet the eligibility + # requirements of Section 151 and 152", and under IRC 152(b)(1) a + # return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents, unless the would-be + # claimant meets the filing exception (Publication 501). + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependents = where( + filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) + ) # Multiply by the amount per exemption. return dependents * p.amount diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_personal_exemption_additional_dependent_eligible.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_personal_exemption_additional_dependent_eligible.py index bf3e43f098f..e16391397fb 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_personal_exemption_additional_dependent_eligible.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_personal_exemption_additional_dependent_eligible.py @@ -10,7 +10,12 @@ class ut_personal_exemption_additional_dependent_eligible(Variable): reference = "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1018.html" # 59-10-1018 (1)(g) def formula(person, period, parameters): - is_dependent = person("is_tax_unit_dependent", period) + # 59-10-1018(1)(g) adds "an additional qualifying dependent in the + # year of a qualifying dependent's birth", so the newborn must be a + # qualifying dependent: one for whom the claimant is allowed an IRC 24 + # credit, which a return on which a filer can be claimed as a + # dependent has none of (IRC 152(b)(1)) outside the filing exception. + qualifying_dependent = person("ut_qualifying_dependent", period) birth_year = person("birth_year", period) born_this_year = birth_year == period.start.year - return is_dependent & born_this_year + return qualifying_dependent & born_this_year diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_qualifying_dependent.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_qualifying_dependent.py new file mode 100644 index 00000000000..27708a00a7d --- /dev/null +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_qualifying_dependent.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ut_qualifying_dependent(Variable): + value_type = bool + entity = Person + label = "Utah qualifying dependent" + documentation = ( + "A dependent with respect to whom the claimant is allowed a federal " + "child tax credit or credit for other dependents under IRC 24." + ) + definition_period = YEAR + defined_for = StateCode.UT + reference = "https://le.utah.gov/xcode/Title59/Chapter10/C59-10-S1018_2026050620260506.pdf#page=1" # (1)(c) + + def formula(person, period, parameters): + # Utah Code 59-10-1018(1)(c): a qualifying dependent is "an individual + # with respect to whom the claimant is allowed to claim a tax credit + # under Section 24". ctc_individual_maximum is that IRC 24 amount + # before the phase-out. It is zero for a dependent with no child or + # other-dependent credit, such as one with no taxpayer identification + # number. It is also zero on a return where a filer can be claimed as + # a dependent (IRC 152(b)(1)), unless the filing exception applies. + return person("ctc_individual_maximum", period) > 0 diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_total_dependents.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_total_dependents.py index f9be89959c4..84aed24aa5f 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_total_dependents.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/taxpayer_credit/ut_total_dependents.py @@ -9,4 +9,11 @@ class ut_total_dependents(Variable): documentation = "Form TC-40, line 2c" definition_period = YEAR defined_for = StateCode.UT - adds = ["tax_unit_count_dependents"] + reference = "https://le.utah.gov/xcode/Title59/Chapter10/59-10-S1018.html" + + def formula(tax_unit, period, parameters): + # Utah Code 59-10-1018(1)(g) multiplies the exemption by "the number + # of the claimant's qualifying dependents", those for whom the + # claimant is allowed an IRC 24 credit (ut_qualifying_dependent). + person = tax_unit.members + return tax_unit.sum(person("ut_qualifying_dependent", period)) diff --git a/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_at_home_parent_credit_potential.py b/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_at_home_parent_credit_potential.py index 0a9f3d1d51d..fe9f259defc 100644 --- a/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_at_home_parent_credit_potential.py +++ b/policyengine_us/variables/gov/states/ut/tax/income/credits/ut_at_home_parent_credit_potential.py @@ -22,7 +22,15 @@ def formula(tax_unit, period, parameters): age = person("age", period) is_dependent = person("is_tax_unit_dependent", period) p = parameters(period).gov.states.ut.tax.income.credits.at_home_parent - qualifying_child = (age < p.max_child_age) & is_dependent + # Utah Code 59-10-1005 requires that the parent claim the qualifying + # child as a dependent. Under IRC 152(b)(1) a return on which the filer + # (or, if joint, either spouse) can be claimed as a dependent has no + # dependents, unless the would-be claimant meets the filing exception + # (Publication 501). + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + qualifying_child = (age < p.max_child_age) & is_dependent & ~filer_is_dependent count_qualifying_children = tax_unit.sum(qualifying_child) # 59-10-1005(2): $100 "for each qualifying child if ... the claimant or diff --git a/policyengine_us/variables/gov/states/vt/tax/income/credits/ctc/vt_ctc.py b/policyengine_us/variables/gov/states/vt/tax/income/credits/ctc/vt_ctc.py index d5941eac418..20bd13b9baf 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/credits/ctc/vt_ctc.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/credits/ctc/vt_ctc.py @@ -11,11 +11,22 @@ class vt_ctc(Variable): defined_for = StateCode.VT def formula(tax_unit, period, parameters): - # Get age status of all people in the tax unit. + # 32 V.S.A. 5830f: a taxpayer entitled to a child tax credit under the + # laws of the United States (or who would be but for the taxpayer + # identification number requirements of IRC 24(e) and (h)(7)) gets the + # credit for each qualifying child under IRC 152(c) at or under the + # age limit. The identification waiver does not reach IRC 152(b)(1): + # a return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents and no federal credit, + # unless the would-be claimant meets the filing exception. person = tax_unit.members age = person("age", period) p = parameters(period).gov.states.vt.tax.income.credits.ctc - eligible = age <= p.age_limit + dependent = person("is_tax_unit_dependent", period) + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + eligible = (age <= p.age_limit) & dependent & ~filer_is_dependent count_eligible = tax_unit.sum(eligible) # Get adjusted gross income. agi = tax_unit("adjusted_gross_income", period) diff --git a/policyengine_us/variables/gov/states/vt/tax/income/credits/renter/vt_renter_credit.py b/policyengine_us/variables/gov/states/vt/tax/income/credits/renter/vt_renter_credit.py index c5866c1da44..77a94e5376f 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/credits/renter/vt_renter_credit.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/credits/renter/vt_renter_credit.py @@ -9,6 +9,7 @@ class vt_renter_credit(Variable): unit = USD definition_period = YEAR reference = ( + "https://legislature.vermont.gov/statutes/fullchapter/32/154", # 6066(b)(2), (c)(2) "https://law.justia.com/codes/vermont/2022/title-32/chapter-154/section-6066/", # b "https://tax.vermont.gov/sites/tax/files/documents/Income%20Booklet-2022.pdf#page=35", # the formula used in this file is based on the excel sheet provided on the official Vermont government website @@ -35,12 +36,17 @@ def formula(tax_unit, period, parameters): county, "ADDISON_COUNTY_VT", ) + # 32 V.S.A. 6066(b)(2): the fair market rent is for "a number of + # bedrooms equal to the number of personal exemptions" under + # 5811(21)(C), which allows none for a filer who can be claimed as a + # dependent and no dependents on a return where either filer can be. + exemptions = clip(tax_unit("exemptions_count", period), 0, 8) # locate the values by family size and county full_credit_income_limit = p.income_limit_ami.thirty_percent[size][safe_county] partial_credit_income_limit = p.income_limit_ami.fifty_percent[size][ safe_county ] - fmr = p.fair_market_rent[size][safe_county] + fmr = p.fair_market_rent[exemptions][safe_county] # The department rounds the credit amount to whole dollars, half up, # before applying the income phase-out: its 2021 calculator computes # ROUND(FMR * 12 * 10%, 0), and its published tables are whole dollars. @@ -92,7 +98,15 @@ def formula(tax_unit, period, parameters): # 6066(b)(1)); 2026 Vt. Act 169 raises this for claim year 2027 only. capped_credit = min_(credit_value, p.max_credit) unrounded = capped_credit * (1 - shared_residence_reduction) + # 6066(c)(2): the claimant "may not be a person claimed as a dependent + # by any taxpayer", an actual claim. On a joint return either spouse + # may be the claimant, so only a return on which every filer is + # claimed loses it. + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + claimed = person("claimed_as_dependent_on_another_return", period) + claimant_eligible = tax_unit.any(filer & ~claimed) # The department calculators use ROUND(..., 0): Calculator!G16 in # 2021-2022 and Calculator!G17 in 2023-2025. Credits are nonnegative, # so floor(x + 0.5) matches their half-up rounding at exact ties. - return np.floor(unrounded + 0.5) + return claimant_eligible * np.floor(unrounded + 0.5) diff --git a/policyengine_us/variables/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.py b/policyengine_us/variables/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.py index c93c3526bca..484a862d1a5 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/exemptions/vt_personal_exemptions.py @@ -18,7 +18,17 @@ def formula(tax_unit, period, parameters): eligible_head = (~elsewhere_head).astype(int) eligible_spouse = (~elsewhere_spouse).astype(int) eligible_count = eligible_head + (eligible_spouse * is_joint) - # add number of other dependents claimed on federal Form 1040 (line 5c) - dependents = tax_unit("tax_unit_count_dependents", period) + # add number of other dependents claimed on federal Form 1040 (line 5c). + # 32 V.S.A. 5811(21)(C): "no exemption may be claimed" for a dependent + # individual, and under IRC 152(b)(1) a return on which the filer (or, + # if joint, either spouse) can be claimed as a dependent has no + # dependents, unless the would-be claimant meets the filing exception + # (Publication 501). + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependents = where( + filer_is_dependent, 0, tax_unit("tax_unit_count_dependents", period) + ) total_exemption_count = eligible_count + dependents return total_exemption_count * p.personal diff --git a/policyengine_us/variables/gov/states/wi/tax/income/credits/childcare_expense/wi_childcare_expense_credit_potential.py b/policyengine_us/variables/gov/states/wi/tax/income/credits/childcare_expense/wi_childcare_expense_credit_potential.py index 3df0c6e0477..a296d445201 100644 --- a/policyengine_us/variables/gov/states/wi/tax/income/credits/childcare_expense/wi_childcare_expense_credit_potential.py +++ b/policyengine_us/variables/gov/states/wi/tax/income/credits/childcare_expense/wi_childcare_expense_credit_potential.py @@ -31,7 +31,11 @@ def formula(tax_unit, period, parameters): # limits, so the §21 employment-related expense definition # applies: childcare plus care for a disabled adult qualifying # individual (care_expenses). - childcare = tax_unit("tax_unit_childcare_expenses", period) + # Only childcare for a qualifying individual counts (IRC + # 21(b)(2)(A)(ii)): outside the claimant filing exception, a + # return whose filer can be claimed has no qualifying child + # under 13 (152(b)(1)), unless incapable of self-care. + childcare = tax_unit("cdcc_qualifying_childcare_expenses", period) adult_care = add(tax_unit, period, ["care_expenses"]) raw_expenses = childcare + adult_care # Cap to WI limit, then also cap to min head/spouse earned (§21(d)) diff --git a/policyengine_us/variables/gov/states/wi/tax/income/credits/homestead/wi_homestead_income.py b/policyengine_us/variables/gov/states/wi/tax/income/credits/homestead/wi_homestead_income.py index e30f967a6c6..f20a39cdc53 100644 --- a/policyengine_us/variables/gov/states/wi/tax/income/credits/homestead/wi_homestead_income.py +++ b/policyengine_us/variables/gov/states/wi/tax/income/credits/homestead/wi_homestead_income.py @@ -38,5 +38,14 @@ def formula(tax_unit, period, parameters): ) income += min_(net_social_security, 0) disqualified_losses = tax_unit("wi_homestead_disqualified_losses", period) - dependents = tax_unit("tax_unit_dependents", period) + # The $500 deduction is for each dependent under IRC 152; a return on + # which the claimant (or, if joint, either spouse) can be claimed as a + # dependent has none (IRC 152(b)(1)), unless the would-be claimant + # meets the filing exception (Publication 501). + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependents = where( + filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) + ) return income + disqualified_losses - dependents * p.homestead.income.exemption diff --git a/policyengine_us/variables/gov/states/wi/tax/income/exemptions/wi_additional_exemption.py b/policyengine_us/variables/gov/states/wi/tax/income/exemptions/wi_additional_exemption.py index c270c849cba..a95bc911f82 100644 --- a/policyengine_us/variables/gov/states/wi/tax/income/exemptions/wi_additional_exemption.py +++ b/policyengine_us/variables/gov/states/wi/tax/income/exemptions/wi_additional_exemption.py @@ -8,19 +8,26 @@ class wi_additional_exemption(Variable): unit = USD definition_period = YEAR reference = ( + "https://docs.legis.wisconsin.gov/statutes/statutes/71/i/05/23", # (b)3 "https://www.revenue.wi.gov/TaxForms2021/2021-Form1f.pdf", "https://www.revenue.wi.gov/TaxForms2021/2021-Form1-Inst.pdf", "https://www.revenue.wi.gov/TaxForms2022/2022-Form1f.pdf", "https://www.revenue.wi.gov/TaxForms2022/2022-Form1-Inst.pdf", "https://docs.legis.wisconsin.gov/misc/lfb/informational_papers/january_2023/0002_individual_income_tax_informational_paper_2.pdf", + # Lines 10a and 10b + # PDF pages 15-16 + "https://www.revenue.wi.gov/TaxForms2025/2025-Form1-Inst.pdf#page=15", ) defined_for = StateCode.WI def formula(tax_unit, period, parameters): # compute extra exemption amount p = parameters(period).gov.states.wi.tax.income - elderly_head = (tax_unit("age_head", period) >= p.exemption.old_age).astype(int) - elderly_spouse = (tax_unit("age_spouse", period) >= p.exemption.old_age).astype( - int - ) - return (elderly_head + elderly_spouse) * p.exemption.extra + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + elderly = person("age", period) >= p.exemption.old_age + # Wis. Stat. 71.05(23)(b)3 allows $250 for a taxpayer who "has + # reached the age of 65" by the end of the year, and $250 for the + # spouse who has. Age is its only condition, so a filer who can be + # claimed as a dependent still gets it. Each spouse counts separately. + return tax_unit.sum(filer & elderly) * p.exemption.extra diff --git a/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_childcare_expense_subtraction.py b/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_childcare_expense_subtraction.py index 739f18d564c..47feef772ce 100644 --- a/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_childcare_expense_subtraction.py +++ b/policyengine_us/variables/gov/states/wi/tax/income/subtractions/wi_childcare_expense_subtraction.py @@ -19,7 +19,11 @@ def formula(tax_unit, period, parameters): # §71.05(6)(b)43. adopts the IRC §21 employment-related expense # definition, which covers childcare plus care for a disabled adult # qualifying individual (care_expenses). - childcare = tax_unit("tax_unit_childcare_expenses", period) + # Only childcare for a qualifying individual counts (IRC + # 21(b)(2)(A)(ii)): outside the claimant filing exception, a return + # whose filer can be claimed has no qualifying child under 13 + # (152(b)(1)), unless the child is incapable of self-care. + childcare = tax_unit("cdcc_qualifying_childcare_expenses", period) adult_care = add(tax_unit, period, ["care_expenses"]) uncapped_expenses = childcare + adult_care eligible_dependents = tax_unit("count_cdcc_eligible", period) diff --git a/policyengine_us/variables/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.py b/policyengine_us/variables/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.py index 031448a3262..6e2f61491cd 100644 --- a/policyengine_us/variables/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.py +++ b/policyengine_us/variables/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.py @@ -1,5 +1,6 @@ from policyengine_us.model_api import * from policyengine_us.variables.gov.states.wi.tax.income.wi_standard_deduction import ( + wi_dependent_standard_deduction_limit, wi_standard_deduction_for_income, ) @@ -37,8 +38,13 @@ def formula(tax_unit, period, parameters): fstatus = tax_unit("filing_status", period) wi_agi = tax_unit("wi_agi", period) standard_deduction_full = tax_unit("wi_standard_deduction", period) - standard_deduction_reduced = wi_standard_deduction_for_income( - max_(0, wi_agi - line16 + line17_offset), fstatus, parameters, period + # The dependent limit (71.05(22)(f)) caps the deduction on this path + # too; it depends on earned income, which line 16 does not change. + standard_deduction_reduced = min_( + wi_standard_deduction_for_income( + max_(0, wi_agi - line16 + line17_offset), fstatus, parameters, period + ), + wi_dependent_standard_deduction_limit(tax_unit, period, parameters), ) extra_standard_deduction = standard_deduction_reduced - standard_deduction_full exclusion_taxinc = max_( diff --git a/policyengine_us/variables/gov/states/wi/tax/income/wi_standard_deduction.py b/policyengine_us/variables/gov/states/wi/tax/income/wi_standard_deduction.py index 362bdf7f14b..f12ccdd45de 100644 --- a/policyengine_us/variables/gov/states/wi/tax/income/wi_standard_deduction.py +++ b/policyengine_us/variables/gov/states/wi/tax/income/wi_standard_deduction.py @@ -29,6 +29,30 @@ def wi_standard_deduction_for_income(income, filing_status, parameters, period): return max_(0, max_amount - phase_out_amount) +def wi_dependent_standard_deduction_limit(tax_unit, period, parameters): + # Wis. Stat. 71.05(22)(f): for a taxpayer whom another person can claim + # as a dependent, the standard deduction is the lesser of the ordinary + # deduction and the greater of $500 or earned income (IRC 911(d)(2)) plus + # $250, both indexed "in the manner prescribed by sections 1 (f) (3) to + # (6) and 63 (c) (4)" of the IRC, so they equal the federal amounts (Form + # 1 instructions: $1,100 + $350 in 2021 through $1,350 + $450 in 2025). + # The Form 1 worksheet applies when "you (or your spouse if filing a + # joint return) can be claimed", using the return's earned income. + # Returns infinity when no filer can be claimed. + p = parameters(period).gov.irs.deductions.standard.dependent + # Worksheet line 1 reuses the federal Standard Deduction Worksheet for + # Dependents' earned income: the head's and spouse's wages after pretax + # payroll deductions, taxable disability benefits received before the + # plan's minimum retirement age (wages for federal purposes, IRS + # Publication 907), and business and farm income, minus the deductible + # part of self-employment tax, summed on a joint return and floored at + # zero. Non-W-2 scholarship/grant income is not among these sources. + earned_income = tax_unit("standard_deduction_worksheet_earned_income", period) + limit = max_(p.amount, earned_income + p.additional_earned_income) + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + return where(filer_is_dependent, limit, np.inf) + + class wi_standard_deduction(Variable): value_type = float entity = TaxUnit @@ -41,13 +65,21 @@ class wi_standard_deduction(Variable): "https://www.revenue.wi.gov/TaxForms2022/2022-Form1f.pdf", "https://www.revenue.wi.gov/TaxForms2022/2022-Form1-Inst.pdf", "https://docs.legis.wisconsin.gov/misc/lfb/informational_papers/january_2023/0002_individual_income_tax_informational_paper_2.pdf", - # Standard Deduction Table (keyed to WI income, line 7) and the statute, corroborating the phaseout: - "https://www.revenue.wi.gov/TaxForms2025/2025-Form1-inst.pdf#page=35", "https://docs.legis.wisconsin.gov/statutes/statutes/71/i/05/22", + # Dependent worksheet and standard deduction table, PDF pages 15, 35-37 + "https://www.revenue.wi.gov/TaxForms2025/2025-Form1-Inst.pdf#page=15", + # Disability pensions before minimum retirement age are wages. + "https://www.irs.gov/pub/irs-prior/p907--2025.pdf#page=3", ) defined_for = StateCode.WI def formula(tax_unit, period, parameters): fstatus = tax_unit("filing_status", period) agi = tax_unit("wi_agi", period) - return wi_standard_deduction_for_income(agi, fstatus, parameters, period) + standard_deduction = wi_standard_deduction_for_income( + agi, fstatus, parameters, period + ) + return min_( + standard_deduction, + wi_dependent_standard_deduction_limit(tax_unit, period, parameters), + ) diff --git a/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.py b/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.py index 28551572e43..5dc2f624cc6 100644 --- a/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.py +++ b/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.py @@ -6,10 +6,18 @@ class wv_low_income_family_tax_credit_eligible(Variable): entity = TaxUnit label = "Eligible for the West Virginia low-income family tax credit" unit = USD - reference = "https://code.wvlegislature.gov/11-21-22/" + reference = ( + "https://code.wvlegislature.gov/11-21-22/", + "https://code.wvlegislature.gov/11-21-22A/", + "https://tax.wv.gov/Documents/PIT/2025/it140.PersonalIncomeTaxFormsAndInstructions.2025.pdf#page=13", + ) definition_period = YEAR defined_for = StateCode.WV def formula(tax_unit, period, parameters): + # W. Va. Code 11-21-22A(e) sets no minimum number of exemptions, and + # family size counts the 11-21-16(d) exemption of a filer who can be + # claimed as a dependent, so every return has a family size of one or + # more. alternative_minimum_tax = tax_unit("alternative_minimum_tax", period) return alternative_minimum_tax == 0 diff --git a/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_fpg.py b/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_fpg.py index d61d8af8840..0e44a747996 100644 --- a/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_fpg.py +++ b/policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_fpg.py @@ -9,6 +9,10 @@ class wv_low_income_family_tax_credit_fpg(Variable): ) unit = USD definition_period = YEAR + reference = ( + "https://code.wvlegislature.gov/11-21-22A/", # (b) + "https://code.wvlegislature.gov/11-21-16/", # (c), (d) + ) defined_for = "wv_low_income_family_tax_credit_eligible" def formula(tax_unit, period, parameters): @@ -16,8 +20,14 @@ def formula(tax_unit, period, parameters): period ).gov.states.wv.tax.income.credits.liftc # low_income_family_tax_credit - # max family size limit - n = tax_unit("tax_unit_size", period) + # W. Va. Code 11-21-22A(b): family size is "the total number of + # exemptions that may be legally claimed" on the return, leaving out + # only the 11-21-16(c) surviving spouse exemption. That count includes + # the single 11-21-16(d) exemption of each filer who can be claimed + # as a dependent. + n = tax_unit("exemptions_count", period) + tax_unit( + "wv_claimable_filer_exemptions_count", period + ) state_group = tax_unit.household("state_group_str", period) p_fpg = parameters(period).gov.hhs.fpg diff --git a/policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_claimable_filer_exemptions_count.py b/policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_claimable_filer_exemptions_count.py new file mode 100644 index 00000000000..5d7d849cb9a --- /dev/null +++ b/policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_claimable_filer_exemptions_count.py @@ -0,0 +1,38 @@ +from policyengine_us.model_api import * + + +class wv_claimable_filer_exemptions_count(Variable): + value_type = int + entity = TaxUnit + label = "West Virginia exemptions for filers who can be claimed as dependents" + documentation = ( + "Number of $500 West Virginia exemptions under W. Va. Code " + "11-21-16(d): one for each head or spouse who can be claimed as a " + "dependent on another return, on a return whose dependents add no " + "exemption." + ) + definition_period = YEAR + reference = ( + "https://code.wvlegislature.gov/11-21-16/", # (d) + "https://code.wvlegislature.gov/11-21-22A/", # (b) + ) + defined_for = StateCode.WV + + def formula(tax_unit, period, parameters): + # 11-21-16(d): "a resident individual whose exemption amount for + # federal tax purposes is zero by virtue of section 151(d)(2)", one + # who can be claimed as a dependent, "shall be allowed a single West + # Virginia exemption in the amount of $500". Each such filer gets one. + person = tax_unit.members + claimable_filers = tax_unit.sum( + person("is_tax_unit_head_or_spouse", period) + & person("claimable_as_dependent_on_another_return", period) + ) + # Limit this to returns whose dependents add no exemption: a child who + # adds none (IRC 152(b)(1)) leaves the per-filer exemption alone. When + # dependents add exemptions, applying the single-exemption limit needs + # an attribution rule, so those returns keep the ordinary count. + own_exemptions = tax_unit("head_spouse_count_not_dependent_elsewhere", period) + exemptions = tax_unit("exemptions_count", period) + no_dependent_exemptions = exemptions == own_exemptions + return where(no_dependent_exemptions, claimable_filers, 0) diff --git a/policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_personal_exemption.py b/policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_personal_exemption.py index 4e685595093..29a6cfb9832 100644 --- a/policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_personal_exemption.py +++ b/policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_personal_exemption.py @@ -8,9 +8,24 @@ class wv_personal_exemption(Variable): defined_for = StateCode.WV unit = USD definition_period = YEAR - reference = "https://code.wvlegislature.gov/11-21/" + reference = ( + "https://code.wvlegislature.gov/11-21-16/", + # Form IT-140 exemptions box (e) and line 6 instructions + # PDF pages 3, 26 + "https://tax.wv.gov/Documents/PIT/2025/it140.PersonalIncomeTaxFormsAndInstructions.2025.pdf#page=3", + ) def formula(tax_unit, period, parameters): p = parameters(period).gov.states.wv.tax.income.exemptions - tax_unit_size = tax_unit("tax_unit_size", period) - return where(tax_unit_size == 0, p.base_personal, p.personal * tax_unit_size) + # $2,000 for each exemption on the return, plus the 11-21-16(d) $500 + # for each filer who can be claimed as a dependent, on a return whose + # dependents add no exemption. Other returns keep the ordinary count. + exemptions = tax_unit("exemptions_count", period) + claimable_filer_exemptions = tax_unit( + "wv_claimable_filer_exemptions_count", period + ) + amount = p.personal * exemptions + p.base_personal * claimable_filer_exemptions + # IT-140 line 6 gives $500 to a return with no exemption at all, which + # an input of zero for tax_unit_size can produce. + no_exemption = (exemptions + claimable_filer_exemptions) == 0 + return where(no_exemption, p.base_personal, amount) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index c442426b6b3..8079c1275c7 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -9644,6 +9644,37 @@ candidates: state: ruled note: The code already uses a strict comparison and the eligibility tests pin AGI equal to the threshold as ineligible. Verify the statute's and the worksheet's wording before registering. +- id: us-ri:property-tax-relief-claimant-same-person + program: property-tax-relief + years: + from: 2025 + type: tax + question: Must one household member be both aged 65 or older (or disabled) and not claimed as a dependent, or may + the age test and the dependency test fall on different spouses, as the RI-1040H question allows? + sources: + - kind: statute + citation: R.I. Gen. Laws § 44-33-3(1) + url: https://webserver.rilegislature.gov/Statutes/TITLE44/44-33/44-33-3.htm + - kind: form + citation: 2025 Form RI-1040H, page 1, question D + url: https://tax.ri.gov/sites/g/files/xkgbur541/files/2025-10/2025%201040H_VENDOR.pdf#page=1 + readings: + statute: 'The claimant is a homeowner or renter "sixty-five (65) years of age or older, and/or disabled", and the + claimant "shall not mean or include any person claimed as a dependent by any taxpayer".' + other: 'Question D asks "Were you or your spouse 65 years of age or older and/or disabled", which a joint return + passes when only the claimed spouse is 65.' + example: '2025 joint return where only the claimed spouse is 65 and the other spouse is 40 and not disabled: $0 under + the statute versus $700 if question D governs.' + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_credit_eligible.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10044 + state: open + note: 'PE-US requires a filer who is both aged 65 or older or disabled and not claimed (ri_property_tax_credit_eligible.py). + Household members may choose the claimant between themselves, so either spouse may claim. Only the 2025 form was + read; earlier editions are not checked.' - id: us-ri:ssp-category-d-without-federal-ssi program: ssi-state-supplement years: @@ -11610,10 +11641,41 @@ candidates: state: unreviewed note: 'Verify whether HUD extensions or the calculator''s caps properly fill the statutory silence. Code not yet on main: vt_renter_credit, gov.states.vt.tax.income.credits.renter.max_household_size.' +- id: us-vt:renter-credit-income-limit-household-size + program: renter-credit + years: + from: 2021 + to: 2025 + type: tax + question: Are the renter credit's HUD income limits looked up by the number of resident family members, as the + department does, or by the number of personal exemptions that sizes the fair market rent? + sources: + - kind: statute + citation: 32 V.S.A. § 6061(19)-(20); § 6066(b) + url: https://legislature.vermont.gov/statutes/section/32/154/06061 + - kind: guidance + citation: Vermont Department of Taxes, Renter Credit page + url: https://tax.vermont.gov/renter-credit + readings: + statute: The limits are HUD's extremely low-income and very low-income limits, which HUD sets by family size. The + statute does not say whose family size counts. + other: 'The department sizes the limits by "the number of family members who live with you". Another reading uses + the exemption count that sizes the fair market rent under 6066(b)(2).' + example: '2025 Chittenden joint return with one claimed spouse and $62,000 of income: $270 with resident-member limits + versus $0 with exemption-sized limits.' + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/states/vt/tax/income/credits/renter/vt_renter_credit.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10044 + state: open + note: 'PE-US looks up the income limits by tax_unit_size, capped at the tables'' eight people, and the fair market + rent by exemptions_count (vt_renter_credit.py). Axiom issue 1678 in rulespec-us pursues exemption-sized limits.' - id: us-vt:renter-credit-statewide-average-fmr program: renter-credit years: - from: 2022 + from: 2021 to: 2025 type: tax question: Should the statewide fair-market-rent average use a plain HUD-area mean or the department tables' inferred @@ -11628,7 +11690,9 @@ candidates: readings: statute: The statute calls for a statewide average without specifying weights or rounding. other: The published tables require inferred reconstructions rather than a plain mean of HUD areas. - example: '2022 sizes 4-8: PE $1,774 versus published $1,773; 2025 size 3: $2,026 versus $2,025.' + example: '2022 sizes 4-8: PE $1,774 versus published $1,773; 2025 size 3: $2,026 versus $2,025. Zero bedrooms: $883 + either way in 2021, $919 versus $918 in 2022 and $1,172 versus $1,171 in 2024; a 14-county mean gives $1,273 + versus $1,209 in 2025.' pe_us: follows: gap-fill code: @@ -11636,11 +11700,14 @@ candidates: - policyengine_us/variables/gov/states/vt/tax/income/credits/renter/vt_renter_credit.py prs: - https://github.com/PolicyEngine/policyengine-us/pull/10130 + - https://github.com/PolicyEngine/policyengine-us/pull/10044 state: unreviewed note: 'PE-US fills the gap with the published tables: Franklin and Grand Isle use a reconstruction of the statewide average for each year that reproduces the department''s credit amounts, and the file''s comment says these are not department rules (fair_market_rent.yaml, read by vt_renter_credit.py). Document the inferred reconstruction - and distinguish averaging assumptions from official table values.' + and distinguish averaging assumptions from official table values. The zero-bedroom rows (2021-2025) follow + another convention: the unrounded mean of the 12 HUD rent areas in every year, 2021 included. No department + table exists for zero bedrooms, so nothing reproduces them; the parameter comment lists the alternatives.' - id: us-vt:renter-credit-zero-exemption-rent program: renter-credit years: @@ -11665,12 +11732,15 @@ candidates: example: 'Claimable but unclaimed single Burlington renter, 2025: $1,656 versus $1,771.' pe_us: follows: statute - code: [] + code: + - policyengine_us/variables/gov/states/vt/tax/income/credits/renter/vt_renter_credit.py + - policyengine_us/parameters/gov/states/vt/tax/income/credits/renter/fair_market_rent.yaml prs: - https://github.com/PolicyEngine/policyengine-us/pull/10044 state: ruled note: 'Ruled in October 2026 to follow the statute; verify the calculator editions and zero-exemption example. - Code not yet on main: vt_renter_credit.' + vt_renter_credit.py indexes the fair market rent by exemptions_count, and fair_market_rent.yaml carries the + zero-bedroom (efficiency) rows for 2021-2025.' - id: us-vt:snap-child-support-deduction program: snap years: @@ -11885,6 +11955,36 @@ candidates: so wa_pte_wholly_service_connected_disability defaults to is_disabled (or is_fully_disabled_service_connected_veteran) as an overridable proxy, read together with is_veteran in wa_pte_categorical_eligible; it over-includes a veteran whose disability is not service-connected. +- id: us-wi:age-65-exemption-claimable-filer + program: income-tax + years: + from: 2021 + type: tax + question: Does a filer aged 65 or older who can be claimed as a dependent get Wisconsin's $250 additional exemption? + sources: + - kind: statute + citation: Wis. Stat. § 71.05(23)(b)3 + url: https://docs.legis.wisconsin.gov/statutes/statutes/71/i/05/23 + - kind: instructions + citation: 2025 Wisconsin Form 1 instructions, lines 10a and 10b, PDF pp. 15-16 + url: https://www.revenue.wi.gov/TaxForms2025/2025-Form1-Inst.pdf#page=15 + readings: + statute: 'Subdivision 3 allows $250 "if the taxpayer has reached the age of 65" and $250 for a spouse who has. Age + is its only condition.' + other: 'Line 10b allows the $250 only to filers who "are allowed the $700 exemption on line 10a", and line 10a gives + no exemption to a filer who can be claimed as a dependent.' + example: '2025 single filer aged 70 who can be claimed, with $34,000 of income and a $24,000 retirement exclusion: tax + of $185.50 with the $250 versus $194.25 without it.' + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/wi/tax/income/exemptions/wi_additional_exemption.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10044 + state: open + note: 'PE-US allows $250 for each filer aged 65 or older, as main did before this PR (wi_additional_exemption.py). + Only the 2025 instructions were read. The official statute site was unavailable, so the statute text came from a + LawServer copy. The $700 exemption is a separate item (us-wi:personal-exemption-claimable-filer).' - id: us-wi:claim-of-right-itemized-deduction-credit program: income-tax years: @@ -11914,6 +12014,45 @@ candidates: note: An October 2026 ruling followed the worksheet; under the later statute-first rule the code includes the federal claim of right deduction in the credit base with the Schedule 1 components. The separate Wisconsin repayment credit that would trigger the 71.07(5)(a)6 exclusion is not modeled. +- id: us-wi:dependent-standard-deduction-earned-income + program: income-tax + years: + from: 2021 + type: tax + question: Does Wisconsin's dependent standard deduction limit count earned income as IRC 911(d)(2) defines it, or as + the federal Standard Deduction Worksheet for Dependents measures it? + sources: + - kind: statute + citation: Wis. Stat. § 71.05(22)(f)3m; 26 U.S.C. § 911(d)(2) + url: https://www.law.cornell.edu/uscode/text/26/911 + - kind: instructions + citation: 2025 Wisconsin Form 1 instructions, Standard Deduction Worksheet for Dependents footnote, PDF p. 15 + url: https://www.revenue.wi.gov/TaxForms2025/2025-Form1-Inst.pdf#page=15 + - kind: instructions + citation: 2025 Form 1040 instructions, Standard Deduction Worksheet for Dependents footnote + url: https://www.irs.gov/pub/irs-prior/i1040gi--2025.pdf#page=23 + readings: + statute: 'Subdivision 3m uses "earned income, as defined in section 911 (d) (2)". That counts at most 30 percent of + net profits from a business in which capital is material, and subtracts no self-employment tax.' + other: 'The Wisconsin footnote lists "wages, salaries, tips, professional fees, and any other compensation received + for services you performed". The federal worksheet adds business and farm income, less the self-employment tax + deduction.' + example: '2025 claimable single filer with $10,000 of farm income: a $9,743.52 deduction under the federal worksheet + measure versus at most $3,450 if capital is material to the farm.' + pe_us: + follows: conflicting-source + code: + - policyengine_us/variables/gov/states/wi/tax/income/wi_standard_deduction.py + - policyengine_us/variables/gov/states/wi/tax/income/wi_retirement_income_exclusion_tax.py + - policyengine_us/variables/gov/irs/income/taxable_income/deductions/standard_deduction/standard_deduction_worksheet_earned_income.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10044 + state: open + note: 'Both Wisconsin deduction paths read the federal standard_deduction_worksheet_earned_income: wages after pretax + deductions, taxable disability wages, and business and farm income less the self-employment tax deduction. + Section 911(d)(2) also needs a reasonable allowance for the filer''s services, which the model has no input for. + The federal item us:dependent-deduction-worksheet-earned-income rests on section 63(c)(5) leaving earned income + undefined, which Wisconsin''s statute does not.' - id: us-wi:homestead-age-disability-earned-income-routes program: homestead-credit years: @@ -12116,6 +12255,35 @@ candidates: note: 'PE-US follows the statute and state plan: Wisconsin elects the option, and the formula requires is_full_time_student, a proxy the comments say is broader than the federal option because it also captures full-time college students (student_option.yaml, is_parent_for_medicaid_nfc.py). Verify whether its wording reflects practice.' +- id: us-wi:personal-exemption-claimable-filer + program: income-tax + years: + from: 2021 + type: tax + question: Does Wisconsin's $700 personal exemption turn on the filing requirement, as the statute says, or on whether + the filer can be claimed as a dependent, as line 10a says? + sources: + - kind: statute + citation: Wis. Stat. § 71.05(23)(b)1 + url: https://docs.legis.wisconsin.gov/statutes/statutes/71/i/05/23 + - kind: instructions + citation: 2025 Wisconsin Form 1 instructions, line 10a, PDF p. 15 + url: https://www.revenue.wi.gov/TaxForms2025/2025-Form1-Inst.pdf#page=15 + readings: + statute: 'Subdivision 1 allows $700 "if the taxpayer is required to file a return under s. 71.03 (2) (a) 1. or 2.", + with no condition on whether anyone can claim the taxpayer.' + other: 'Line 10a gives no exemption to a single filer who "can be claimed as a dependent on someone else''s return".' + example: 'A claimable single filer who must file under s. 71.03(2)(a)1.: a $700 exemption under the statute versus $0 + under line 10a, which PE-US follows.' + pe_us: + follows: conflicting-source + code: + - policyengine_us/variables/gov/states/wi/tax/income/exemptions/wi_base_exemption.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10044 + state: open + note: 'PE-US prices the $700 at the federal exemptions_count, which gives a filer who can be claimed none + (wi_base_exemption.py). PR 10044 records this but does not change it. The statute text came from a LawServer copy.' - id: us-wi:shares-home-value-and-vehicle-asset-tests program: child-care-assistance years: @@ -12180,6 +12348,72 @@ candidates: state: ruled note: Ruled in November 2026 as a gap-fill, because the statute does not address repayments and the instructions provide the modification. Statutory authority remains unidentified, and the study's citation remains unresolved. +- id: us-wv:claimable-filer-exemption-with-dependents + program: income-tax + years: + from: 1987 + type: tax + question: When a filer who can be claimed has dependents who add exemptions under the filing exception, does the + filer's 11-21-16(d) exemption replace the return's count, add $500 to it, or give way to the IT-140 count? + sources: + - kind: statute + citation: W. Va. Code §11-21-16(d) + url: https://code.wvlegislature.gov/11-21-16/ + - kind: form + citation: 'IT-140 (2025), exemption boxes and line 6 instructions #page 3,26' + url: https://tax.wv.gov/Documents/PIT/2025/it140.PersonalIncomeTaxFormsAndInstructions.2025.pdf#page=3 + readings: + statute: '"Notwithstanding any provisions in this section", the individual "shall be allowed a single West Virginia + exemption in the amount of $500". Read literally, that is the whole allowance; read per person, it adds to the + dependents'' exemptions.' + other: 'IT-140 counts box (c) dependents at $2,000 each and adds $500 only "If box e is zero".' + example: '2025 filing-exception single filer with one child: $2,000 on IT-140 (PE-US), $500 on the literal reading, + $2,500 per person. Joint return, one claimable spouse, two children: $6,000 (PE-US) versus $6,500 per person.' + pe_us: + follows: conflicting-source + code: + - policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_claimable_filer_exemptions_count.py + - policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_personal_exemption.py + - policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_fpg.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10044 + state: open + note: 'PE-US keeps the IT-140 count on these returns: wv_claimable_filer_exemptions_count is zero when dependents add + exemptions, so the exemption amount and the family tax credit''s family size count no 11-21-16(d) exemption. The + pinned cases are in wv_personal_exemption.yaml and wv_low_income_family_tax_credit_eligible.yaml.' +- id: us-wv:family-tax-credit-claimable-filer-family-size + program: income-tax + years: + from: 2007 + type: tax + question: Does the low-income family tax credit's family size count each claimable filer's 11-21-16(d) exemption, + and may a return the form treats as having zero exemptions claim the credit? + sources: + - kind: statute + citation: W. Va. Code §11-21-22a(b); §11-21-16(d) + url: https://code.wvlegislature.gov/11-21-22A/ + - kind: instructions + citation: IT-140 (2025), Family Tax Credit schedule, PDF p. 13 + url: https://tax.wv.gov/Documents/PIT/2025/it140.PersonalIncomeTaxFormsAndInstructions.2025.pdf#page=13 + readings: + statute: 'Family size is "the total number of exemptions that may be legally claimed" on the return, leaving out + only the 16(c) surviving spouse exemption, and 16(d) calls the $500 "a single West Virginia exemption".' + other: 'The schedule says "Individuals who file their income tax return with zero exemptions cannot claim the + credit", and line 5 takes family size from boxes a, b and c, which leave out the $500 allowance.' + example: '2025, $16,000 of wages: single claimable filer $307.84 versus $0; joint with one claimable spouse $325.60 + versus $260.48; joint with both claimable $370 versus $0.' + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_fpg.py + - policyengine_us/variables/gov/states/wv/tax/income/credits/liftc/wv_low_income_family_tax_credit_eligible.py + - policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_claimable_filer_exemptions_count.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10044 + state: open + note: 'PE-US counts exemptions_count plus wv_claimable_filer_exemptions_count, capped at eight, and sets no + zero-exemption bar. Main used tax_unit_size, which gave the same family size for these childless returns. Only the + 2025 IT-140 was read; earlier editions are assumed to match.' - id: us-wv:liheap-income-limit-above-federal-ceiling program: liheap years: @@ -12407,8 +12641,7 @@ candidates: - id: us-wv:zero-exemption-return-500-allowance program: income-tax years: - from: 2025 - to: 2025 + from: 1987 type: tax question: Is the $500 allowance for claimable filers applied per person under the statute or once per return under IT-140? @@ -12420,17 +12653,27 @@ candidates: citation: IT-140 (2025), PDF p. 3 url: https://tax.wv.gov/Documents/PIT/2025/it140.PersonalIncomeTaxFormsAndInstructions.2025.pdf#page=3 readings: - statute: The individual wording supports a per-person allowance. + statute: '16(d) says "a resident individual" whose federal exemption amount is zero under IRC 151(d)(2) "shall be + allowed a single West Virginia exemption in the amount of $500", so each such individual gets one.' other: The form directs a single $500 allowance when the return's exemption count is zero. example: 'Joint return with one claimable spouse: $2,500 versus $2,000; both claimable: $1,000 versus $500.' pe_us: - follows: conflicting-source - code: [] + follows: statute + code: + - policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_claimable_filer_exemptions_count.py + - policyengine_us/variables/gov/states/wv/tax/income/exemptions/wv_personal_exemption.py + - policyengine_us/parameters/gov/states/wv/tax/income/exemptions/base_personal.yaml + - policyengine_us/reforms/states/wv/dependent_exemption/wv_dependent_exemption_reform.py + - policyengine_us/reforms/state_dependent_exemptions/repeal_state_dependent_exemptions.py prs: - https://github.com/PolicyEngine/policyengine-us/pull/10044 state: ruled - note: 'The October 2026 statute-first ruling requires changing the form-based allowance if the per-person reading - is confirmed; obtain the exact statutory text. Code not yet on main: wv_personal_exemption.' + note: 'The October 2026 statute-first ruling applies, and the statutory text now read supports the per-person reading. + PE-US gives $500 to each claimable filer on a return whose dependents add no exemption, in the baseline and the + contributed reform (wv_claimable_filer_exemptions_count.py, wv_personal_exemption.py, base_personal.yaml, + wv_dependent_exemption_reform.py). The repeal reform gives it to every claimable filer, since it repeals the + dependent exemptions (repeal_state_dependent_exemptions.py). 16(d) applies to taxable years beginning after December + 31, 1986. Returns whose dependents add exemptions are a separate item (us-wv:claimable-filer-exemption-with-dependents).' - id: us-wy:ccap-continuing-eligibility-employment-condition program: child-care-assistance years: