From f3467ae9cff0876b62eecb26f75e3b2cd7e8e34a Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 10 Oct 2026 06:19:46 -0400 Subject: [PATCH 1/4] Apply IA, KS, LA and MD 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 as a dependent has no dependents (IRC 152(b)(1)), and these states never applied that or their own rules for such a filer. Now: - Iowa: no $40 dependent credits (the personal credits stay, "even if you are claimed"); a claimed single filer is exempt from tax only with income below $5,000, a joint return with a claimed spouse is not exempt, and the single tax reduction worksheet excludes a claimed filer. - Kansas: a claimed filer has no exemptions in 2021-2023 ("enter '0' in the Total Kansas exemptions box"); from 2024 the filing-status allowance stays and dependents are zero; the food sales tax credit counts exemptions the same way and has no child route. - Louisiana: no dependent exemption (2021-2024). - Maryland: no own exemption for a filer who can be claimed (filing status 6) and no dependent or aged-dependent exemptions; no child tax credit; no childless EITC on the pro forma federal credit without the minimum age; the poverty line credit is barred for a claimable filer and, on a joint return, kept for the other spouse on that spouse's earnings with the poverty level for the exemptions that spouse may claim (10-709(a)(2)). The Iowa, Kansas and Maryland dependent-exemption contrib reforms and the state dependent exemption repeal keep these rules. Kentucky needs no change: its care and tuition credits read the federal credits the base branch already corrects; YAML cases pin that. Co-Authored-By: Claude Opus 5.5 --- .../claimable-filer-ia-ks-ky-la-md.fixed.md | 1 + .../tax_exempt/dependent/income_limit.yaml | 21 + .../tax_exempt/dependent/income_sources.yaml | 24 + .../repeal_state_dependent_exemptions.py | 14 +- .../ia_dependent_credit_reform.py | 6 +- .../ks_dependent_exemption_reform.py | 6 +- .../md_dependent_exemption_reform.py | 23 +- ...aimable_filer_ia_ks_ky_la_md_invariants.py | 143 ++++++ .../gov/states/ia/tax/income/ia_cdcc.yaml | 174 +++++++ .../gov/states/ia/tax/income/ia_eitc.yaml | 150 ++++++ .../ia/tax/income/ia_exemption_credit.yaml | 136 ++++++ ..._income_tax_before_refundable_credits.yaml | 164 +++++++ .../ia/tax/income/ia_is_tax_exempt.yaml | 243 ++++++++++ .../exemptions/ks_count_exemptions.yaml | 141 ++++++ .../tax/income/exemptions/ks_exemptions.yaml | 137 ++++++ .../gov/states/ks/tax/income/ks_cdcc.yaml | 180 +++++++ .../gov/states/ks/tax/income/ks_fstc.yaml | 447 ++++++++++++++++++ .../states/ks/tax/income/ks_total_eitc.yaml | 150 ++++++ .../ky_cdcc_potential.yaml | 180 +++++++ .../credits/cdcc/la_refundable_cdcc.yaml | 174 +++++++ .../states/la/tax/income/credits/la_eitc.yaml | 150 ++++++ .../personal/la_dependents_exemption.yaml | 159 +++++++ .../agi/md_dependent_care_subtraction.yaml | 174 +++++++ .../md/tax/income/credits/ctc/md_ctc.yaml | 175 +++++++ .../federal_eitc_without_age_minimum.yaml | 159 +++++++ .../md_poverty_line_credit_earned_income.yaml | 210 ++++++++ .../md_aged_dependent_exemption.yaml | 135 ++++++ .../md_total_personal_exemptions.yaml | 170 +++++++ .../repeal_state_dependent_exemptions.yaml | 56 +++ .../ia/dependent_credit_reform_test.yaml | 30 ++ .../ks/dependent_exemption_reform_test.yaml | 28 ++ .../md/dependent_exemption_reform_test.yaml | 29 ++ .../tax/income/credits/ia_exemption_credit.py | 14 +- .../states/ia/tax/income/ia_is_tax_exempt.py | 19 +- .../states/ia/tax/income/ia_reduced_tax.py | 8 +- .../states/ks/tax/income/credits/ks_fstc.py | 32 +- .../income/exemptions/ks_count_exemptions.py | 11 +- .../ks/tax/income/exemptions/ks_exemptions.py | 19 +- .../personal/la_dependents_exemption.py | 11 +- .../md/tax/income/credits/ctc/md_ctc.py | 8 +- .../tax/income/credits/ctc/md_ctc_eligible.py | 8 +- .../eitc/federal_eitc_without_age_minimum.py | 20 +- .../is_eligible_md_poverty_line_credit.py | 26 +- .../md_poverty_line_credit_earned_income.py | 51 ++ .../md_poverty_line_credit_income_level.py | 30 ++ .../md_poverty_line_credit_potential.py | 4 +- .../exemptions/md_aged_dependent_exemption.py | 8 +- .../md_total_personal_exemptions.py | 20 +- .../credits/md_local_poverty_line_credit.py | 4 +- 49 files changed, 4239 insertions(+), 43 deletions(-) create mode 100644 changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md create mode 100644 policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml create mode 100644 policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_sources.yaml create mode 100644 policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/credits/dependent_care_service/ky_cdcc_potential.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_dependent_care_subtraction.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.yaml create mode 100644 policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py create mode 100644 policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py diff --git a/changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md b/changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md new file mode 100644 index 00000000000..e8492608950 --- /dev/null +++ b/changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md @@ -0,0 +1 @@ +Apply Iowa, Kansas, Louisiana and Maryland rules for a filer who can be claimed as a dependent: no dependent exemptions or credits on a return with a claimable filer (Iowa dependent credit, Kansas dependent exemption and food sales tax credit child, Louisiana dependent exemption, Maryland dependent and aged-dependent exemptions and child tax credit); no Iowa low-income exemption for a claimed filer except a single filer with income below $5,000, and no Iowa tax reduction; no Kansas exemptions for a claimed filer in 2021-2023; no Maryland personal exemption, poverty line credit or childless EITC for a filer who can be claimed, with the poverty line credit kept for a spouse who cannot be claimed. diff --git a/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml b/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml new file mode 100644 index 00000000000..9ffc3a42678 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml @@ -0,0 +1,21 @@ +description: Iowa exempts a single filer who can be claimed as a dependent on another return from income tax when that filer's income is below this amount. +values: + 2021-01-01: 5_000 + +metadata: + label: Iowa tax exemption income limit for single filers claimed as dependents + period: year + unit: currency-USD + reference: + - title: Iowa Code 422.13(1)(a) + href: https://www.legis.iowa.gov/docs/code/2026/422.pdf#page=46 + - title: 2021 IA1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/2650/download?inline#page=38 + - title: 2022 IA1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/2721/download?inline#page=37 + - title: 2023 IA 1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/2811/download?inline#page=12 + - title: 2024 IA 1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/4152/download?inline#page=10 + - title: 2025 IA 1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/4435/download?inline#page=11 diff --git a/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_sources.yaml b/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_sources.yaml new file mode 100644 index 00000000000..e77b33d81d6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_sources.yaml @@ -0,0 +1,24 @@ +description: Iowa compares this income of a single filer who can be claimed as a dependent on another return with the dependent tax exemption limit. +values: + # Net income from all sources, IA 1040 line 26. + 2021-01-01: + - ia_net_income + # Iowa taxable income, IA 1040 line 4, without adding back deductions. + 2023-01-01: + - ia_taxable_income_consolidated + +metadata: + unit: list + period: year + label: Iowa tax exemption income sources for single filers claimed as dependents + reference: + - title: 2021 IA1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/2650/download?inline#page=38 + - title: 2022 IA1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/2721/download?inline#page=37 + - title: 2023 IA 1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/2811/download?inline#page=12 + - title: 2024 IA 1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/4152/download?inline#page=10 + - title: 2025 IA 1040 Income Tax Return instructions + href: https://revenue.iowa.gov/media/4435/download?inline#page=11 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 55765f89e4b..c83d396cfa1 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 @@ -34,10 +34,13 @@ class md_total_personal_exemptions(Variable): defined_for = StateCode.MD def formula(tax_unit, period, parameters): - # Get md_personal_exemption from tax_unit multiplied by tax_unit_size + # Only the filers' own exemptions remain; a filer who can be + # claimed as a dependent has none (filing status 6). md_personal_exemption = tax_unit("md_personal_exemption", period) - tax_unit_size = tax_unit("head_spouse_count", period) - return md_personal_exemption * tax_unit_size + own_exemptions = tax_unit( + "head_spouse_count_not_dependent_elsewhere", period + ) + return md_personal_exemption * own_exemptions class mi_personal_exemptions(Variable): value_type = float @@ -351,6 +354,11 @@ def formula(tax_unit, period, parameters): joint = filing_status == statuses.JOINT hoh = filing_status == statuses.HEAD_OF_HOUSEHOLD adults = where(joint | hoh, 2, 1) + # A filer who can be claimed as a dependent enters "0" exemptions. + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) + adults = where(filer_is_dependent, 0, adults) return adults * p.consolidated.amount + veterans_exemption_amount class ma_income_tax_exemption_threshold(Variable): diff --git a/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py b/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py index 446ae2e4c34..8362a3ef88e 100644 --- a/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py +++ b/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py @@ -38,7 +38,11 @@ def formula(tax_unit, period, parameters): # dependent is age-eligible, matching the baseline count. person = tax_unit.members age = person("age", period) - is_dependent = person("is_tax_unit_dependent", period) + # A return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents (IRC 152(b)(1)). + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) if c.age_limit.in_effect: eligible = is_dependent & (age < c.age_limit.threshold) else: diff --git a/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py b/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py index d3c89f7c568..6c05ccefed2 100644 --- a/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py @@ -15,7 +15,11 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) - is_dependent = person("is_tax_unit_dependent", period) + # A return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents (IRC 152(b)(1)). + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) # Apply age limit if in effect. if p.age_limit.in_effect: diff --git a/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py b/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py index 21357d4bff6..039fa78efcd 100644 --- a/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py @@ -14,7 +14,11 @@ def formula(tax_unit, period, parameters): p = parameters(period).gov.contrib.states.md.dependent_exemption person = tax_unit.members age = person("age", period) - is_dependent = person("is_tax_unit_dependent", period) + # A return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents (IRC 152(b)(1)). + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) if p.age_limit.in_effect: eligible = is_dependent & (age < p.age_limit.threshold) else: @@ -97,7 +101,11 @@ class md_older_dependents_count(Variable): def formula(tax_unit, period, parameters): person = tax_unit.members - is_dependent = person("is_tax_unit_dependent", period) + # A return on which the filer (or, if joint, either spouse) can be + # claimed as a dependent has no dependents (IRC 152(b)(1)). + is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) total_dependents = tax_unit.sum(is_dependent) eligible = tax_unit("md_eligible_dependents_count", period) return max_(0, total_dependents - eligible) @@ -112,12 +120,15 @@ class md_total_personal_exemptions(Variable): def formula(tax_unit, period, parameters): # Personal portion keeps the baseline per-person (AGI-stepped) - # amount; dependents are separated out. + # amount; dependents are separated out. These are the filers' own + # exemptions (none for a filer who can be claimed as a dependent) + # plus over-age dependents. per_person = tax_unit("md_personal_exemption", period) - tax_unit_size = tax_unit("tax_unit_size", period) - dependents = tax_unit("tax_unit_dependents", period) + own_exemptions = tax_unit( + "head_spouse_count_not_dependent_elsewhere", period + ) older_dependents = tax_unit("md_older_dependents_count", period) - personal_count = tax_unit_size - dependents + older_dependents + personal_count = own_exemptions + older_dependents personal_amount = personal_count * per_person dependent_exemption_amount = tax_unit("md_dependent_exemption", period) diff --git a/policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py b/policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py new file mode 100644 index 00000000000..fb2aa551c3e --- /dev/null +++ b/policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py @@ -0,0 +1,143 @@ +"""Iowa, Kansas, Kentucky, Louisiana and Maryland 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)), so these states' dependent exemptions and credits, +Kansas's food sales tax credit child route and Maryland's child tax credit +count none. A claimed filer keeps Iowa's personal credit and, from 2024, +Kansas's filing-status allowance, but gets no Kansas exemptions in 2021-2023, +no Iowa low-income exemption above $5,000 or tax reduction, and no Maryland +personal exemption, poverty line credit or childless EITC; on a joint return +Maryland's poverty line credit stays for the spouse who cannot be claimed. + +For couples drawn by Hypothesis and a seeded population in these states, with +either, both or neither spouse claimed: + +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. This holds for the drawn inputs, which have no self-employment + losses: on separate Maryland returns a claimable spouse's loss no longer + offsets the other spouse's earnings, which is intended. +3. Identities: with a claimable filer there is no Louisiana dependent + exemption, Maryland aged dependent exemption or child tax credit, and no + pro forma federal EITC without a child; with no claimable filer the + poverty line credit's earned income and poverty level are the unchanged + EITC earned income and tax unit poverty guideline. +4. Differential: wherever the federal EITC's eligibility holds, Maryland's + pro forma federal EITC without the minimum age equals the federal credit + before take-up, so the two eligibility paths agree, including on the + claimable-filer bar. +""" + +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, + TOLERANCE, + _calc, + _crafted_cases, + _seeded_couples, + adults, + dependents, +) + +STATES = ["IA", "KS", "KY", "LA", "MD"] +# 2022: Iowa's net-income path, Kansas's exemption count and Louisiana's +# exemptions; 2024: Iowa's consolidated path and Kansas's filing-status +# allowance; 2026: Louisiana's flat tax and Maryland's child tax credit +# phase-out. +YEARS = [2022, 2024, 2026] +MONOTONE = [ + "ia_exemption_credit", + "ks_exemptions", + "ks_fstc", + "la_dependents_exemption", + "md_total_personal_exemptions", + "md_aged_dependent_exemption", + "federal_eitc_without_age_minimum", + "md_ctc", + "md_poverty_line_credit_earned_income", +] +OUTPUTS = MONOTONE + [ + "ia_is_tax_exempt", + "ia_income_tax", + "ks_income_tax", + "ky_income_tax", + "la_income_tax", + "is_eligible_md_poverty_line_credit", + "md_poverty_line_credit", + "md_local_poverty_line_credit", + "md_income_tax", + "state_income_tax", +] + + +@st.composite +def couples(draw): + return { + "state": draw(st.sampled_from(STATES)), + "adults": [draw(adults()), draw(adults())], + "dependents": draw(st.lists(dependents(), max_size=2)), + "claimed": draw(st.sampled_from(CLAIM_PATTERNS)), + } + + +def _identities(sim, year): + claimed = _calc(sim, "head_or_spouse_is_dependent_elsewhere", year) > 0 + every = _calc(sim, "every_filer_is_dependent_elsewhere", year) > 0 + childless = _calc(sim, "eitc_child_count", year) == 0 + for name in ["la_dependents_exemption", "md_aged_dependent_exemption", "md_ctc"]: + assert not _calc(sim, name, year)[claimed].any(), name + pro_forma = _calc(sim, "federal_eitc_without_age_minimum", year) + assert not pro_forma[claimed & childless].any() + assert not _calc(sim, "is_eligible_md_poverty_line_credit", year)[every].any() + # Each tax unit has its own household, in the same order. + md = np.asarray(sim.calculate("state_code_str", year)) == "MD" + nobody = md & ~claimed + np.testing.assert_allclose( + _calc(sim, "md_poverty_line_credit_earned_income", year)[nobody], + _calc(sim, "eitc_earned_income", year)[nobody], + atol=TOLERANCE, + ) + np.testing.assert_allclose( + _calc(sim, "md_poverty_line_credit_income_level", year)[nobody], + _calc(sim, "tax_unit_fpg", year)[nobody], + atol=TOLERANCE, + ) + # 4. Differential: the federal credit before take-up and filing. + federal_eligible = md & (_calc(sim, "eitc_eligible", year) > 0) + federal = np.minimum( + _calc(sim, "eitc_phased_in", year), + np.maximum( + 0, _calc(sim, "eitc_maximum", year) - _calc(sim, "eitc_reduction", year) + ), + ) + np.testing.assert_allclose( + pro_forma[federal_eligible], federal[federal_eligible], atol=TOLERANCE + ) + + +@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_ia_ks_ky_la_md_claimable_filer_rules_are_label_free(year, units): + check_swap(units, year, OUTPUTS, _identities) + + +@pytest.mark.parametrize("year", YEARS) +def test_ia_ks_ky_la_md_claimable_filer_rules_seeded_population(year): + units = _seeded_couples(STATES, per_state=3) + _crafted_cases(STATES) + check_swap(units, year, OUTPUTS, _identities) + check_monotone(units, year, MONOTONE, _identities) diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_cdcc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_cdcc.yaml index 513aa8e048b..9267a71f5ce 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_cdcc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_cdcc.yaml @@ -165,3 +165,177 @@ ia_taxable_income: 13_166 cdcc_potential: 690 ia_cdcc: 517.5 + + +- name: 2024 single filer who can be claimed as a dependent gets no Iowa child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: IA + output: + # IRC 21(b)(1)(A) needs a dependent; IRC 152(b)(1) leaves none. + ia_cdcc: 0 + +- name: 2024 single filer who cannot be claimed gets the Iowa child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: IA + output: + # $1,000 x .35 = $350; Iowa taxable income $0 < $10,000: x .75 = $262.50. + ia_cdcc: 262.5 + +- name: 2024 joint return with one claimable spouse gets no Iowa child care credit (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: IA + output: + # Either spouse being claimable leaves the return no dependents. + ia_cdcc: 0 + +- name: 2024 joint return with one claimable spouse gets no Iowa child care credit (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: IA + output: + ia_cdcc: 0 + +- name: 2024 joint return with both spouses claimable gets no Iowa child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: IA + output: + ia_cdcc: 0 + +- name: 2024 joint return with no claimable spouse gets the Iowa child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: IA + output: + # $1,000 x .35 = $350 federal; x .75 = $262.50. + ia_cdcc: 262.5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_eitc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_eitc.yaml index 80b3282ee42..4fa50d7fe1f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_eitc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_eitc.yaml @@ -5,3 +5,153 @@ state_code: IA output: ia_eitc: 150 + + +- name: 2024 single filer who can be claimed as a dependent gets no Iowa EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: IA + output: + # IRC 32(c)(1)(A)(ii)(III): no childless federal EITC to match. + ia_eitc: 0 + +- name: 2024 single filer who cannot be claimed gets the Iowa EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: IA + output: + # $76.50 x .15 = $11.475. + ia_eitc: 11.475 + +- name: 2024 joint return with one claimable spouse gets no Iowa EITC (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: IA + output: + # Pub. 596: "Someone can claim your spouse as a dependent" bars it. + ia_eitc: 0 + +- name: 2024 joint return with one claimable spouse gets no Iowa EITC (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + 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: IA + output: + ia_eitc: 0 + +- name: 2024 joint return with both spouses claimable gets no Iowa EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: IA + output: + ia_eitc: 0 + +- name: 2024 joint return with no claimable spouse gets the Iowa EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: IA + output: + # $1,000 x .0765 = $76.50; x .15 = $11.475. + ia_eitc: 11.475 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml index 8bd9dfdc642..10b114c96eb 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml @@ -47,3 +47,139 @@ state_code: IA output: ia_exemption_credit: 180 # = 40*2 + 20*3 + 40*1 + + +- name: 2024 single filer who can be claimed as a dependent keeps the personal credit but gets no dependent credit + period: 2024 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: IA + output: + # Iowa Code 422.12(2)(a): $40 personal credit, kept "even if you are + # claimed"; IRC 152(b)(1) leaves the return no dependents. + ia_exemption_credit: 40 + +- name: 2024 joint return with one claimable spouse keeps both personal credits but gets no dependent credit (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: IA + output: + # $80 for a joint return; no $40 dependent credit (IRC 152(b)(1)). + ia_exemption_credit: 80 + +- name: 2024 joint return with one claimable spouse keeps both personal credits but gets no dependent credit (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: IA + output: + ia_exemption_credit: 80 + +- name: 2024 joint return with both spouses claimable keeps both personal credits but gets no dependent credit + period: 2024 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: IA + output: + ia_exemption_credit: 80 + +- name: 2024 joint return with no claimable spouse gets the dependent credit + period: 2024 + input: + people: + person_a: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: IA + output: + # $80 + $40 for the child = $120. + ia_exemption_credit: 120 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml index 9418543b4e0..1034f2e50d7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml @@ -41,3 +41,167 @@ state_code: IA output: ia_income_tax_before_refundable_credits: 40 + + +- name: 2022 single filer who can be claimed as a dependent gets no tax reduction + period: 2022 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + ia_income_tax_before_credits: 700 + ia_non_refundable_credits: 0 + ia_is_tax_exempt: false + ia_modified_income: 9500 + households: + household: + members: [person_a] + state_code: IA + output: + # The Tax Reduction Worksheet is for single filers "not claimed as a + # dependent on another person's Iowa return" (2022 instructions, p.60). + ia_income_tax_before_refundable_credits: 700 + +- name: 2022 single filer who cannot be claimed has tax reduced to income above $9,000 + period: 2022 + input: + people: + person_a: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + ia_income_tax_before_credits: 700 + ia_non_refundable_credits: 0 + ia_is_tax_exempt: false + ia_modified_income: 9500 + households: + household: + members: [person_a] + state_code: IA + output: + # min($700, $9,500 - $9,000) = $500. + ia_income_tax_before_refundable_credits: 500 + +- name: 2022 joint return with one claimable spouse gets no tax reduction (the claimable spouse is the head) + period: 2022 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + ia_income_tax_before_credits: 700 + ia_non_refundable_credits: 0 + ia_is_tax_exempt: false + ia_modified_income: 9500 + households: + household: + members: [person_a, person_b] + state_code: IA + output: + # The worksheet is for single filers only. + ia_income_tax_before_refundable_credits: 700 + +- name: 2022 joint return with one claimable spouse gets no tax reduction (the claimable spouse is the spouse) + period: 2022 + input: + people: + person_b: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + 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 + ia_income_tax_before_credits: 700 + ia_non_refundable_credits: 0 + ia_is_tax_exempt: false + ia_modified_income: 9500 + households: + household: + members: [person_b, person_a] + state_code: IA + output: + ia_income_tax_before_refundable_credits: 700 + +- name: 2022 joint return with both spouses claimable gets no tax reduction + period: 2022 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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 + ia_income_tax_before_credits: 700 + ia_non_refundable_credits: 0 + ia_is_tax_exempt: false + ia_modified_income: 9500 + households: + household: + members: [person_a, person_b] + state_code: IA + output: + ia_income_tax_before_refundable_credits: 700 + +- name: 2022 joint return with no claimable spouse gets no tax reduction + period: 2022 + input: + people: + person_a: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + ia_income_tax_before_credits: 700 + ia_non_refundable_credits: 0 + ia_is_tax_exempt: false + ia_modified_income: 9500 + households: + household: + members: [person_a, person_b] + state_code: IA + output: + ia_income_tax_before_refundable_credits: 700 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml index 0e8eacbec18..9d00a475797 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml @@ -45,3 +45,246 @@ state_code: IA output: ia_is_tax_exempt: true + + +- name: 2022 single filer who can be claimed as a dependent with $4,999 of net income is exempt + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 4999 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: IA + output: + # "less than $5,000 and you are claimed as a dependent" (2022 IA 1040 + # instructions, p.37). + ia_is_tax_exempt: true + +- name: 2022 single filer who can be claimed as a dependent with $5,000 of net income is not exempt + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: IA + output: + # "less than $5,000 and you are claimed as a dependent" (2022 IA 1040 + # instructions, p.37). + ia_is_tax_exempt: false + +- name: 2022 single filer who can be claimed as a dependent with $6,000 of net income is not exempt + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 6000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: IA + output: + # $6,000 is not less than $5,000. + ia_is_tax_exempt: false + +- name: 2022 single filer who cannot be claimed with $6,000 of net income is exempt + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 6000 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: IA + output: + # $6,000 <= $9,000 single limit. + ia_is_tax_exempt: true + +- name: 2022 joint return with one claimable spouse is not exempt (the claimable spouse is the head) + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 3000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + ia_net_income: 3000 + 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: IA + output: + # Joint returns are exempt only if "You are not claimed as a + # dependent on another person's Iowa return"; either spouse bars it. + ia_is_tax_exempt: false + +- name: 2022 joint return with one claimable spouse is not exempt (the claimable spouse is the spouse) + period: 2022 + input: + people: + person_b: + age: 30 + ia_net_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + ia_net_income: 3000 + 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: IA + output: + ia_is_tax_exempt: false + +- name: 2022 joint return with both spouses claimable is not exempt + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 3000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + ia_net_income: 3000 + 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: IA + output: + ia_is_tax_exempt: false + +- name: 2022 joint return with no claimable spouse with $6,000 of net income is exempt + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + ia_net_income: 3000 + 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: IA + output: + # $3,000 + $3,000 = $6,000 <= $13,500 joint limit. + ia_is_tax_exempt: true + +- name: 2025 single filer who can be claimed as a dependent is exempt on Iowa taxable income below $5,000 + period: 2025 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + ia_taxable_income_consolidated: 4000 + ia_modified_income: 19750 + households: + household: + members: [person_a] + state_code: IA + output: + # IA 1040 line 4 is $4,000 < $5,000; "none of the income listed + # above is required to be added back" (2025 instructions, p.11). + ia_is_tax_exempt: true + +- name: 2025 single filer who cannot be claimed is not exempt once deductions are added back + period: 2025 + input: + people: + person_a: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + ia_taxable_income_consolidated: 4000 + ia_modified_income: 19750 + households: + household: + members: [person_a] + state_code: IA + output: + # $4,000 + $15,750 standard deduction added back = $19,750 > $9,000. + ia_is_tax_exempt: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml new file mode 100644 index 00000000000..be183a06f9c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml @@ -0,0 +1,141 @@ + + +- name: 2022 single filer who can be claimed as a dependent has no Kansas exemptions + period: 2022 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: KS + output: + # 2022 K-40 instructions, p.6: "If you are claimed as a dependent by + # another taxpayer, enter '0' in the Total Kansas exemptions box." + ks_count_exemptions: 0 + ks_exemptions: 0 + +- name: 2022 joint return with one claimable spouse has no Kansas exemptions (the claimable spouse is the head) + period: 2022 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # Either spouse being claimable zeroes the joint return's exemptions. + ks_count_exemptions: 0 + ks_exemptions: 0 + +- name: 2022 joint return with one claimable spouse has no Kansas exemptions (the claimable spouse is the spouse) + period: 2022 + input: + people: + person_b: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: KS + output: + ks_count_exemptions: 0 + ks_exemptions: 0 + +- name: 2022 joint return with both spouses claimable has no Kansas exemptions + period: 2022 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + ks_count_exemptions: 0 + ks_exemptions: 0 + +- name: 2022 joint return with no claimable spouse has three Kansas exemptions + period: 2022 + input: + people: + person_a: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # 2 + 1 child = 3 exemptions x $2,250 = $6,750. + ks_count_exemptions: 3 + ks_exemptions: 6750 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml index 7dc4e135fd5..1b8fddc1dd6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml @@ -51,3 +51,140 @@ state_code: KS output: ks_exemptions: 9_000 + + +- name: 2024 single filer who can be claimed as a dependent keeps the personal exemption allowance but no dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: KS + output: + # K.S.A. 79-32,121b: $9,160; a claimable taxpayer "will qualify for the + # personal exemption allowance of $9,160" (KDOR FAQ). No $2,320 dependent + # exemption: "enter '0' in the number of dependents box". + ks_exemptions: 9160 + +- name: 2024 joint return with one claimable spouse keeps the joint allowance but no dependent exemption (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # $18,320 joint allowance; no dependents under IRC 152(b)(1). + ks_exemptions: 18320 + +- name: 2024 joint return with one claimable spouse keeps the joint allowance but no dependent exemption (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: KS + output: + ks_exemptions: 18320 + +- name: 2024 joint return with both spouses claimable keeps the joint allowance but no dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + ks_exemptions: 18320 + +- name: 2024 joint return with no claimable spouse gets the dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # $18,320 + $2,320 = $20,640. + ks_exemptions: 20640 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_cdcc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_cdcc.yaml index e2ff3ef47d6..5a9ed44d5bc 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_cdcc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_cdcc.yaml @@ -34,3 +34,183 @@ output: cdcc: 600 # federal credit, fed by the adult-care expense ks_cdcc: 300 # Kansas share of the federal credit + + +- name: 2024 single filer who can be claimed as a dependent gets no Kansas child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, child] + state_code: KS + output: + # IRC 21(b)(1)(A) needs a dependent; IRC 152(b)(1) leaves none. + ks_cdcc: 0 + +- name: 2024 single filer who cannot be claimed gets the Kansas child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, child] + state_code: KS + output: + # $1,000 x .35 = $350 federal credit allowed; x .50 = $175. + ks_cdcc: 175 + +- name: 2024 joint return with one claimable spouse gets no Kansas child care credit (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # Either spouse being claimable leaves the return no dependents. + ks_cdcc: 0 + +- name: 2024 joint return with one claimable spouse gets no Kansas child care credit (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_b, person_a, child] + state_code: KS + output: + ks_cdcc: 0 + +- name: 2024 joint return with both spouses claimable gets no Kansas child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + ks_cdcc: 0 + +- name: 2024 joint return with no claimable spouse gets the Kansas child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # $350 x .50 = $175. + ks_cdcc: 175 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_fstc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_fstc.yaml index a76454b38c9..7e85a89332c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_fstc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_fstc.yaml @@ -41,3 +41,450 @@ state_code: KS output: ks_fstc: 0 # income ineligible + + +- name: 2022 single filer who can be claimed as a dependent gets no food sales tax credit + period: 2022 + input: + people: + person_a: + age: 60 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: KS + output: + # Line E is the total Kansas exemptions, which is "0" for a claimed filer + # (2022 K-40 instructions, p.6). + ks_fstc: 0 + +- name: 2022 single filer who cannot be claimed gets the food sales tax credit + period: 2022 + input: + people: + person_a: + age: 60 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: KS + output: + # Age 60 qualifies; AGI $1,000 <= $30,615; 1 x $125. + ks_fstc: 125 + +- name: 2022 joint return with one claimable spouse gets no food sales tax credit (the claimable spouse is the head) + period: 2022 + input: + people: + person_a: + age: 60 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + # The joint return's total exemptions are 0 when either spouse is claimable. + ks_fstc: 0 + +- name: 2022 joint return with one claimable spouse gets no food sales tax credit (the claimable spouse is the spouse) + period: 2022 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 60 + 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: KS + output: + ks_fstc: 0 + +- name: 2022 joint return with both spouses claimable gets no food sales tax credit + period: 2022 + input: + people: + person_a: + age: 60 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + ks_fstc: 0 + +- name: 2022 joint return with no claimable spouse gets the food sales tax credit for both spouses + period: 2022 + input: + people: + person_a: + age: 60 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + # 2 x $125 = $250. + ks_fstc: 250 + +- name: 2024 single filer who can be claimed as a dependent keeps the food sales tax credit for the filer + period: 2024 + input: + people: + person_a: + age: 60 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: KS + output: + # From 2024 the filing-status exemption stays; only the dependents box is + # "0" (2024 K-40 instructions, p.6). 1 x $125. + ks_fstc: 125 + +- name: 2024 joint return with one claimable spouse keeps the food sales tax credit for both spouses (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 60 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + # 2 filing-status exemptions x $125 = $250. + ks_fstc: 250 + +- name: 2024 joint return with one claimable spouse keeps the food sales tax credit for both spouses (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 60 + 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: KS + output: + ks_fstc: 250 + +- name: 2024 joint return with both spouses claimable keeps the food sales tax credit for both spouses + period: 2024 + input: + people: + person_a: + age: 60 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + ks_fstc: 250 + +- name: 2024 joint return with no claimable spouse gets the food sales tax credit for both spouses + period: 2024 + input: + people: + person_a: + age: 60 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + ks_fstc: 250 + +- name: 2024 single filer who can be claimed as a dependent with a child gets no food sales tax credit + period: 2024 + input: + people: + person_a: + age: 25 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: KS + output: + # No child is claimed "as a personal exemption" (IRC 152(b)(1)) and no + # filer is 55 or older, so no route to the credit. + ks_fstc: 0 + +- name: 2024 single filer who cannot be claimed with a child gets the food sales tax credit + period: 2024 + input: + people: + person_a: + age: 25 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: KS + output: + # Child under 18 qualifies; 2 exemptions x $125 = $250. + ks_fstc: 250 + +- name: 2024 joint return with one claimable spouse and a child gets no food sales tax credit (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 25 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 25 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # No dependent child and nobody 55 or older. + ks_fstc: 0 + +- name: 2024 joint return with one claimable spouse and a child gets no food sales tax credit (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 25 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 25 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: KS + output: + ks_fstc: 0 + +- name: 2024 joint return with both spouses claimable and a child gets no food sales tax credit + period: 2024 + input: + people: + person_a: + age: 25 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 25 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + ks_fstc: 0 + +- name: 2024 joint return with no claimable spouse and a child gets the food sales tax credit + period: 2024 + input: + people: + person_a: + age: 25 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 25 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # 3 exemptions x $125 = $375. + ks_fstc: 375 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_total_eitc.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_total_eitc.yaml index 4c183dd7387..118273f9c57 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_total_eitc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/ks_total_eitc.yaml @@ -5,3 +5,153 @@ state_code: KS output: ks_total_eitc: 0.17 * 1_000 + + +- name: 2024 single filer who can be claimed as a dependent gets no Kansas EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: KS + output: + # No childless federal EITC to match (IRC 32(c)(1)(A)(ii)(III)). + ks_total_eitc: 0 + +- name: 2024 single filer who cannot be claimed gets the Kansas EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: KS + output: + # $76.50 x .17 = $13.005. + ks_total_eitc: 13.005 + +- name: 2024 joint return with one claimable spouse gets no Kansas EITC (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + # Either spouse being claimable bars the childless federal EITC. + ks_total_eitc: 0 + +- name: 2024 joint return with one claimable spouse gets no Kansas EITC (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + 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: KS + output: + ks_total_eitc: 0 + +- name: 2024 joint return with both spouses claimable gets no Kansas EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + ks_total_eitc: 0 + +- name: 2024 joint return with no claimable spouse gets the Kansas EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: KS + output: + # $1,000 x .0765 = $76.50; x .17 = $13.005. + ks_total_eitc: 13.005 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/credits/dependent_care_service/ky_cdcc_potential.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/credits/dependent_care_service/ky_cdcc_potential.yaml new file mode 100644 index 00000000000..a04a25ce952 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/income/credits/dependent_care_service/ky_cdcc_potential.yaml @@ -0,0 +1,180 @@ + + +- name: 2024 single filer who can be claimed as a dependent gets no Kentucky child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, child] + state_code: KY + output: + # IRC 21(b)(1)(A) needs a dependent; IRC 152(b)(1) leaves none. + ky_cdcc_potential: 0 + +- name: 2024 single filer who cannot be claimed gets the Kentucky child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, child] + state_code: KY + output: + # KRS 141.067: 20% x $350 federal credit = $70. + ky_cdcc_potential: 70 + +- name: 2024 joint return with one claimable spouse gets no Kentucky child care credit (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, person_b, child] + state_code: KY + output: + # Either spouse being claimable leaves the return no dependents. + ky_cdcc_potential: 0 + +- name: 2024 joint return with one claimable spouse gets no Kentucky child care credit (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_b, person_a, child] + state_code: KY + output: + ky_cdcc_potential: 0 + +- name: 2024 joint return with both spouses claimable gets no Kentucky child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, person_b, child] + state_code: KY + output: + ky_cdcc_potential: 0 + +- name: 2024 joint return with no claimable spouse gets the Kentucky child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + cdcc_credit_limit: 1000 + households: + household: + members: [person_a, person_b, child] + state_code: KY + output: + # $350 x .20 = $70. + ky_cdcc_potential: 70 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/cdcc/la_refundable_cdcc.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/cdcc/la_refundable_cdcc.yaml index 66f63494203..a5d7be724f1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/cdcc/la_refundable_cdcc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/cdcc/la_refundable_cdcc.yaml @@ -24,3 +24,177 @@ state_code: LA output: la_refundable_cdcc: 250 + + +- name: 2024 single filer who can be claimed as a dependent gets no refundable child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: LA + output: + # IRC 21(b)(1)(A) needs a dependent; IRC 152(b)(1) leaves none. + la_refundable_cdcc: 0 + +- name: 2024 single filer who cannot be claimed gets the refundable child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: LA + output: + # $1,000 x .35 = $350; AGI $10,000 <= $25,000: x .50 = $175. + la_refundable_cdcc: 175 + +- name: 2024 joint return with one claimable spouse gets no refundable child care credit (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: LA + output: + # Either spouse being claimable leaves the return no dependents. + la_refundable_cdcc: 0 + +- name: 2024 joint return with one claimable spouse gets no refundable child care credit (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: LA + output: + la_refundable_cdcc: 0 + +- name: 2024 joint return with both spouses claimable gets no refundable child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: LA + output: + la_refundable_cdcc: 0 + +- name: 2024 joint return with no claimable spouse gets the refundable child care credit + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: LA + output: + # $350 x .50 = $175. + la_refundable_cdcc: 175 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/la_eitc.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/la_eitc.yaml index cd194b78196..49cdeaae78a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/la_eitc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/la_eitc.yaml @@ -13,3 +13,153 @@ state_code: LA output: la_eitc: 0 + + +- name: 2024 single filer who can be claimed as a dependent gets no Louisiana EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: LA + output: + # No childless federal EITC to match (IRC 32(c)(1)(A)(ii)(III)). + la_eitc: 0 + +- name: 2024 single filer who cannot be claimed gets the Louisiana EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: LA + output: + # $76.50 x .05 = $3.825. + la_eitc: 3.825 + +- name: 2024 joint return with one claimable spouse gets no Louisiana EITC (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: LA + output: + # Either spouse being claimable bars the childless federal EITC. + la_eitc: 0 + +- name: 2024 joint return with one claimable spouse gets no Louisiana EITC (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + 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: LA + output: + la_eitc: 0 + +- name: 2024 joint return with both spouses claimable gets no Louisiana EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: LA + output: + la_eitc: 0 + +- name: 2024 joint return with no claimable spouse gets the Louisiana EITC + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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: LA + output: + # $1,000 x .0765 = $76.50; x .05 = $3.825. + la_eitc: 3.825 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml index ee9c6d9bb5c..4edcc03dd03 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml @@ -21,3 +21,162 @@ tax_unit_dependents: 0 output: la_dependents_exemption: 0 + + +- name: 2024 single filer who can be claimed as a dependent gets no dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: LA + output: + # Line 6C counts "the dependents claimed on your federal return" (2024 + # IT-540 instructions, p.3); IRC 152(b)(1) leaves none. + la_dependents_exemption: 0 + +- name: 2024 single filer who cannot be claimed gets the dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: LA + output: + # 1 dependent x $1,000. + la_dependents_exemption: 1000 + +- name: 2024 joint return with one claimable spouse gets no dependent exemption (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: LA + output: + # Either spouse being claimable leaves the federal return no dependents. + la_dependents_exemption: 0 + +- name: 2024 joint return with one claimable spouse gets no dependent exemption (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: LA + output: + la_dependents_exemption: 0 + +- name: 2024 joint return with both spouses claimable gets no dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: LA + output: + la_dependents_exemption: 0 + +- name: 2024 joint return with no claimable spouse gets the dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: LA + output: + # 1 dependent x $1,000. + la_dependents_exemption: 1000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_dependent_care_subtraction.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_dependent_care_subtraction.yaml new file mode 100644 index 00000000000..fccdb96b1ad --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/agi/md_dependent_care_subtraction.yaml @@ -0,0 +1,174 @@ + + +- name: 2024 single filer who can be claimed as a dependent gets no dependent care subtraction + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # Section 10-208(e) uses section 21's qualifying individuals; none here. + md_dependent_care_subtraction: 0 + +- name: 2024 single filer who cannot be claimed gets the dependent care subtraction + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 10000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # min($3,000 x 1 qualifying child, $1,000 expenses) = $1,000. + md_dependent_care_subtraction: 1000 + +- name: 2024 joint return with one claimable spouse gets no dependent care subtraction (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # Either spouse being claimable leaves the return no dependents. + md_dependent_care_subtraction: 0 + +- name: 2024 joint return with one claimable spouse gets no dependent care subtraction (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: MD + output: + md_dependent_care_subtraction: 0 + +- name: 2024 joint return with both spouses claimable gets no dependent care subtraction + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + md_dependent_care_subtraction: 0 + +- name: 2024 joint return with no claimable spouse gets the dependent care subtraction + period: 2024 + input: + people: + person_a: + age: 30 + employment_income: 5000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + employment_income: 5000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 5 + pre_subsidy_childcare_expenses: 1000 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # min($3,000, $1,000) = $1,000. + md_dependent_care_subtraction: 1000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml index 3052884bccc..479bdff52c7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml @@ -550,3 +550,178 @@ md_ctc: 900 md_refundable_credits: 900 md_income_tax: -800 + + +- name: 2025 single filer who can be claimed as a dependent gets no child tax credit + period: 2025 + input: + people: + person_a: + age: 20 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # Section 10-751(a)(2)(i): a qualified child is "a dependent for purposes + # of section 152"; IRC 152(b)(1) leaves the return none. + md_ctc_eligible: false + md_ctc: 0 + +- name: 2025 single filer who cannot be claimed gets the child tax credit + period: 2025 + input: + people: + person_a: + age: 20 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # One child under 6, AGI $1,000 <= $15,000: $500. + md_ctc_eligible: true + md_ctc: 500 + +- name: 2025 joint return with one claimable spouse gets no child tax credit (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 20 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # Either spouse being claimable leaves the return no dependents. + md_ctc_eligible: false + md_ctc: 0 + +- name: 2025 joint return with one claimable spouse gets no child tax credit (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 20 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 20 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: MD + output: + md_ctc_eligible: false + md_ctc: 0 + +- name: 2025 joint return with both spouses claimable gets no child tax credit + period: 2025 + input: + people: + person_a: + age: 20 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + md_ctc_eligible: false + md_ctc: 0 + +- name: 2025 joint return with no claimable spouse gets the child tax credit + period: 2025 + input: + people: + person_a: + age: 20 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 20 + employment_income: 500 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # One child under 6, AGI $1,000 <= $15,000: $500. + md_ctc_eligible: true + md_ctc: 500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml index 625f3439f17..52987e5fa59 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml @@ -109,3 +109,162 @@ # phase-out start (Rev. Proc. 2024-40). eitc: 649 federal_eitc_without_age_minimum: 649 + + +- name: 2025 single filer who can be claimed as a dependent gets no pro forma federal EITC + period: 2025 + input: + people: + person_a: + age: 21 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: MD + output: + # Section 10-704 waives only "the minimum age requirement"; the filer must + # be "otherwise eligible" (2025 Resident Booklet, p.22), and IRC + # 32(c)(1)(A)(ii)(III) bars a childless filer who can be claimed. + federal_eitc_without_age_minimum: 0 + md_unmarried_childless_refundable_eitc: 0 + +- name: 2025 single filer who cannot be claimed gets the pro forma federal EITC despite the minimum age + period: 2025 + input: + people: + person_a: + age: 21 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: MD + output: + # Age 21 fails the federal minimum age, which Maryland waives: + # $1,000 x .0765 = $76.50; unmarried childless match 100%, no tax. + federal_eitc_without_age_minimum: 76.5 + md_unmarried_childless_refundable_eitc: 76.5 + +- name: 2025 joint return with one claimable spouse gets no pro forma federal EITC (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 21 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 21 + 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: MD + output: + # Either spouse being claimable bars the childless federal EITC. + federal_eitc_without_age_minimum: 0 + md_married_or_has_child_refundable_eitc: 0 + +- name: 2025 joint return with one claimable spouse gets no pro forma federal EITC (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 21 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 21 + 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: MD + output: + federal_eitc_without_age_minimum: 0 + md_married_or_has_child_refundable_eitc: 0 + +- name: 2025 joint return with both spouses claimable gets no pro forma federal EITC + period: 2025 + input: + people: + person_a: + age: 21 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 21 + 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: MD + output: + federal_eitc_without_age_minimum: 0 + md_married_or_has_child_refundable_eitc: 0 + +- name: 2025 joint return with no claimable spouse gets the pro forma federal EITC despite the minimum age + period: 2025 + input: + people: + person_a: + age: 21 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 21 + 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: MD + output: + # $76.50; married refundable match .45 x $76.50 - $0 tax = $34.425. + federal_eitc_without_age_minimum: 76.5 + md_married_or_has_child_refundable_eitc: 34.425 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml index 0bc6f5cda6e..f91325b0b1d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml @@ -324,3 +324,213 @@ # TAXSIM: low-income credit 0.00. is_eligible_md_poverty_line_credit: false md_poverty_line_credit: 0 + + +# Rules for a filer who can be claimed as a dependent on another return. +# Expected values are hand-computed from Md. Code, Tax-General 10-709 +# and 10-211, the 2025 Resident Booklet and the repository parameters. + +- name: 2025 single filer who can be claimed as a dependent gets no poverty line credit + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + md_income_tax_before_credits: 200 + md_married_or_has_child_non_refundable_eitc: 0 + md_local_income_tax_before_credits: 100 + md_local_eitc: 0 + households: + household: + members: [person_a] + state_code: MD + county_str: BALTIMORE_CITY_MD + output: + # "You are not eligible for this credit if you checked filing status 6 + # (dependent taxpayer)" (2025 Resident Booklet, p.23). + md_poverty_line_credit_earned_income: 0 + is_eligible_md_poverty_line_credit: false + md_poverty_line_credit_potential: 0 + md_local_poverty_line_credit: 0 + +- name: 2025 single filer who cannot be claimed gets the poverty line credit + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + md_income_tax_before_credits: 200 + md_married_or_has_child_non_refundable_eitc: 0 + md_local_income_tax_before_credits: 100 + md_local_eitc: 0 + households: + household: + members: [person_a] + state_code: MD + county_str: BALTIMORE_CITY_MD + output: + # Poverty level for 1 exemption $15,650; 5% x $1,000 = $50 <= $200 tax; + # Baltimore City .032 x $1,000 = $32 <= $100 local tax. + md_poverty_line_credit_earned_income: 1000 + is_eligible_md_poverty_line_credit: true + md_poverty_line_credit_potential: 50 + md_local_poverty_line_credit: 32 + md_poverty_line_credit_income_level: 15650 + +- name: 2025 joint return with one claimable spouse gets the poverty line credit on the other spouse's earnings (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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 + md_income_tax_before_credits: 200 + md_married_or_has_child_non_refundable_eitc: 0 + md_local_income_tax_before_credits: 100 + md_local_eitc: 0 + households: + household: + members: [person_a, person_b] + state_code: MD + county_str: BALTIMORE_CITY_MD + output: + # The claimable spouse files a separate status 6 return; the other spouse's + # separate return has 1 exemption (poverty level $15,650) and $500 earned: + # 5% x $500 = $25; .032 x $500 = $16. + md_poverty_line_credit_earned_income: 500 + is_eligible_md_poverty_line_credit: true + md_poverty_line_credit_potential: 25 + md_local_poverty_line_credit: 16 + md_poverty_line_credit_income_level: 15650 + +- name: 2025 joint return with one claimable spouse gets the poverty line credit on the other spouse's earnings (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + 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 + md_income_tax_before_credits: 200 + md_married_or_has_child_non_refundable_eitc: 0 + md_local_income_tax_before_credits: 100 + md_local_eitc: 0 + households: + household: + members: [person_b, person_a] + state_code: MD + county_str: BALTIMORE_CITY_MD + output: + md_poverty_line_credit_earned_income: 500 + is_eligible_md_poverty_line_credit: true + md_poverty_line_credit_potential: 25 + md_local_poverty_line_credit: 16 + md_poverty_line_credit_income_level: 15650 + +- name: 2025 joint return with both spouses claimable gets no poverty line credit + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 500 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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 + md_income_tax_before_credits: 200 + md_married_or_has_child_non_refundable_eitc: 0 + md_local_income_tax_before_credits: 100 + md_local_eitc: 0 + households: + household: + members: [person_a, person_b] + state_code: MD + county_str: BALTIMORE_CITY_MD + output: + md_poverty_line_credit_earned_income: 0 + is_eligible_md_poverty_line_credit: false + md_poverty_line_credit_potential: 0 + md_local_poverty_line_credit: 0 + +- name: 2025 joint return with no claimable spouse gets the poverty line credit on both spouses' earnings + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 500 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + 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 + md_income_tax_before_credits: 200 + md_married_or_has_child_non_refundable_eitc: 0 + md_local_income_tax_before_credits: 100 + md_local_eitc: 0 + households: + household: + members: [person_a, person_b] + state_code: MD + county_str: BALTIMORE_CITY_MD + output: + # 2 exemptions: $15,650 + $5,500 = $21,150; 5% x $1,000 = $50; .032 x $1,000 = $32. + md_poverty_line_credit_earned_income: 1000 + is_eligible_md_poverty_line_credit: true + md_poverty_line_credit_potential: 50 + md_local_poverty_line_credit: 32 + md_poverty_line_credit_income_level: 21150 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml index 1b9cbedfa42..5d406d7d336 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml @@ -20,3 +20,138 @@ state_code: MD output: md_aged_dependent_exemption: 3_200 + + +- name: 2025 single filer who can be claimed as a dependent gets no aged dependent exemption + period: 2025 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + parent: + age: 66 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, parent] + filing_status: SINGLE + households: + household: + members: [person_a, parent] + state_code: MD + output: + # Section 10-211(b)(2) needs an IRC 152 dependent; IRC 152(b)(1) leaves none. + md_aged_dependent_exemption: 0 + +- name: 2025 joint return with one claimable spouse gets no aged dependent exemption (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: true + parent: + age: 66 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, parent] + filing_status: JOINT + households: + household: + members: [person_a, person_b, parent] + state_code: MD + output: + # Either spouse being claimable leaves the return no dependents. + md_aged_dependent_exemption: 0 + +- name: 2025 joint return with one claimable spouse gets no aged dependent exemption (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + parent: + age: 66 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, parent] + filing_status: JOINT + households: + household: + members: [person_b, person_a, parent] + state_code: MD + output: + md_aged_dependent_exemption: 0 + +- name: 2025 joint return with both spouses claimable gets no aged dependent exemption + period: 2025 + input: + people: + person_a: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + parent: + age: 66 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, parent] + filing_status: JOINT + households: + household: + members: [person_a, person_b, parent] + state_code: MD + output: + md_aged_dependent_exemption: 0 + +- name: 2025 joint return with no claimable spouse gets the aged dependent exemption + period: 2025 + input: + people: + person_a: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: true + parent: + age: 66 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, parent] + filing_status: JOINT + households: + household: + members: [person_a, person_b, parent] + state_code: MD + output: + # One dependent aged 65 or older: $3,200. + md_aged_dependent_exemption: 3200 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.yaml new file mode 100644 index 00000000000..b9e1714659d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.yaml @@ -0,0 +1,170 @@ + + +- name: 2025 single filer who can be claimed as a dependent gets no personal exemptions + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # Filing status 6: "You do not get an exemption for yourself" (2025 + # Resident Booklet, p.12); IRC 152(b)(1) leaves no dependents. + md_total_personal_exemptions: 0 + +- name: 2025 single filer who cannot be claimed gets personal exemptions for the filer and the child + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # 2 exemptions x $3,200 (AGI under $100,000). + md_total_personal_exemptions: 6400 + +- name: 2025 joint return with one claimable spouse gets only the other spouse's exemption (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # Separate Maryland returns: "Each spouse must claim their own personal + # exemption" and the spouses split the federal return's dependents (none). + md_total_personal_exemptions: 3200 + +- name: 2025 joint return with one claimable spouse gets only the other spouse's exemption (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: MD + output: + md_total_personal_exemptions: 3200 + +- name: 2025 joint return with both spouses claimable gets no personal exemptions + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + md_total_personal_exemptions: 0 + +- name: 2025 joint return with no claimable spouse gets exemptions for both spouses and the child + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # 3 exemptions x $3,200 = $9,600. + md_total_personal_exemptions: 9600 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 2c9f3842667..f2c115c4b0e 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 @@ -151,3 +151,59 @@ output: # Baseline keeps the dependent add: 7,600 + 1 x 1,000 + 6,800 = 15,400. ma_income_tax_exemption_threshold: 15_400 + + +- name: Joint filers with a claimable spouse in Maryland keep only the other spouse's exemption (the claimable spouse is the head) + period: 2024 + 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: + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_b: {age: 30, employment_income: 500, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_a, person_b, child], filing_status: JOINT}} + households: {household: {members: [person_a, person_b, child], state_name: MD}} + # Filing status 6: no exemption for the claimable spouse; 1 x 3,200. + output: {md_total_personal_exemptions: 3_200} + +- name: Joint filers with a claimable spouse in Maryland keep only the other spouse's exemption (the claimable spouse is the spouse) + period: 2024 + 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: + person_b: {age: 30, employment_income: 500, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_b, person_a, child], filing_status: JOINT}} + households: {household: {members: [person_b, person_a, child], state_name: MD}} + output: {md_total_personal_exemptions: 3_200} + + +- name: Joint filers with a claimable spouse in Kansas have no exemptions in 2022 (the claimable spouse is the head) + period: 2022 + 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: + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_b: {age: 30, employment_income: 500, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_a, person_b, child], filing_status: JOINT}} + households: {household: {members: [person_a, person_b, child], state_name: KS}} + # 2022 K-40: a claimed filer enters 0 in the Total Kansas exemptions box. + output: {ks_exemptions: 0} + +- name: Joint filers with a claimable spouse in Kansas have no exemptions in 2022 (the claimable spouse is the spouse) + period: 2022 + 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: + person_b: {age: 30, employment_income: 500, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_b, person_a, child], filing_status: JOINT}} + households: {household: {members: [person_b, person_a, child], state_name: KS}} + output: {ks_exemptions: 0} diff --git a/policyengine_us/tests/policy/contrib/states/ia/dependent_credit_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/ia/dependent_credit_reform_test.yaml index 11d65c9d7af..fbdbe90f50c 100644 --- a/policyengine_us/tests/policy/contrib/states/ia/dependent_credit_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/ia/dependent_credit_reform_test.yaml @@ -86,3 +86,33 @@ households: {household: {members: [parent, child1], state_name: IA}} # Dependent one year under the limit (12 < 13) is re-priced to the reform amount. output: {ia_exemption_credit: 140} # 40 personal + 100 young + + +- name: IA dependent credit reform - joint return with a claimable spouse has no dependent credit (the claimable spouse is the head) + period: 2025 + reforms: policyengine_us.reforms.states.ia.dependent_credit.ia_dependent_credit_reform.ia_dependent_credit_reform + input: + gov.contrib.states.ia.dependent_credit.in_effect: true + gov.contrib.states.ia.dependent_credit.amount: 100 + people: + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_b: {age: 30, employment_income: 500, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_a, person_b, child], filing_status: JOINT}} + households: {household: {members: [person_a, person_b, child], state_name: IA}} + # IRC 152(b)(1): no dependents when either spouse can be claimed; 80 personal. + output: {ia_exemption_credit: 80} + +- name: IA dependent credit reform - joint return with a claimable spouse has no dependent credit (the claimable spouse is the spouse) + period: 2025 + reforms: policyengine_us.reforms.states.ia.dependent_credit.ia_dependent_credit_reform.ia_dependent_credit_reform + input: + gov.contrib.states.ia.dependent_credit.in_effect: true + gov.contrib.states.ia.dependent_credit.amount: 100 + people: + person_b: {age: 30, employment_income: 500, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_b, person_a, child], filing_status: JOINT}} + households: {household: {members: [person_b, person_a, child], state_name: IA}} + output: {ia_exemption_credit: 80} diff --git a/policyengine_us/tests/policy/contrib/states/ks/dependent_exemption_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/ks/dependent_exemption_reform_test.yaml index b4c9df30af0..2e2c196594f 100644 --- a/policyengine_us/tests/policy/contrib/states/ks/dependent_exemption_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/ks/dependent_exemption_reform_test.yaml @@ -105,3 +105,31 @@ # Dependent one year under the limit (17 < 18) gets the exemption. # 9,160 personal + 1 eligible dependent * 2,320 = 11,480. output: {ks_exemptions: 11_480} + + +- name: KS dependent exemption reform - joint return with a claimable spouse has no dependent exemption (the claimable spouse is the head) + period: 2025 + reforms: policyengine_us.reforms.states.ks.dependent_exemption.ks_dependent_exemption_reform.ks_dependent_exemption_reform + input: + gov.contrib.states.ks.dependent_exemption.in_effect: true + people: + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_b: {age: 30, employment_income: 500, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_a, person_b, child], filing_status: JOINT}} + households: {household: {members: [person_a, person_b, child], state_name: KS}} + # Joint base 18,320; IRC 152(b)(1): no dependents when either spouse can be claimed. + output: {ks_exemptions: 18_320} + +- name: KS dependent exemption reform - joint return with a claimable spouse has no dependent exemption (the claimable spouse is the spouse) + period: 2025 + reforms: policyengine_us.reforms.states.ks.dependent_exemption.ks_dependent_exemption_reform.ks_dependent_exemption_reform + input: + gov.contrib.states.ks.dependent_exemption.in_effect: true + people: + person_b: {age: 30, employment_income: 500, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_b, person_a, child], filing_status: JOINT}} + households: {household: {members: [person_b, person_a, child], state_name: KS}} + output: {ks_exemptions: 18_320} diff --git a/policyengine_us/tests/policy/contrib/states/md/dependent_exemption_reform_test.yaml b/policyengine_us/tests/policy/contrib/states/md/dependent_exemption_reform_test.yaml index d7dd6d790a9..a97f3271c64 100644 --- a/policyengine_us/tests/policy/contrib/states/md/dependent_exemption_reform_test.yaml +++ b/policyengine_us/tests/policy/contrib/states/md/dependent_exemption_reform_test.yaml @@ -156,3 +156,32 @@ # step-down is driven through the contrib schedule, not just a flat amount. output: {md_total_personal_exemptions: 2_400} + + +- name: MD dependent exemption reform - joint return with a claimable spouse keeps only the other spouse's exemption (the claimable spouse is the head) + period: 2025 + reforms: policyengine_us.reforms.states.md.dependent_exemption.md_dependent_exemption_reform.md_dependent_exemption_reform + input: + gov.contrib.states.md.dependent_exemption.in_effect: true + people: + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_b: {age: 30, employment_income: 500, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_a, person_b, child], filing_status: JOINT}} + households: {household: {members: [person_a, person_b, child], state_name: MD}} + # Filing status 6: no exemption for the claimable spouse; no dependents (IRC 152(b)(1)); + # 1 x 3,200. + output: {md_total_personal_exemptions: 3_200} + +- name: MD dependent exemption reform - joint return with a claimable spouse keeps only the other spouse's exemption (the claimable spouse is the spouse) + period: 2025 + reforms: policyengine_us.reforms.states.md.dependent_exemption.md_dependent_exemption_reform.md_dependent_exemption_reform + input: + gov.contrib.states.md.dependent_exemption.in_effect: true + people: + person_b: {age: 30, employment_income: 500, is_tax_unit_head: true, is_tax_unit_spouse: false} + person_a: {age: 30, employment_income: 500, claimed_as_dependent_on_another_return: true, is_tax_unit_head: false, is_tax_unit_spouse: true} + child: {age: 5, is_tax_unit_dependent: true} + tax_units: {tax_unit: {members: [person_b, person_a, child], filing_status: JOINT}} + households: {household: {members: [person_b, person_a, child], state_name: MD}} + output: {md_total_personal_exemptions: 3_200} diff --git a/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py b/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py index b6dec677c45..4c21bca132e 100644 --- a/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py +++ b/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py @@ -10,6 +10,9 @@ class ia_exemption_credit(Variable): reference = ( "https://revenue.iowa.gov/sites/default/files/2021-12/IA6251%2841131%29.pdf", "https://revenue.iowa.gov/sites/default/files/2023-01/IA6251%2841131%29.pdf", + "https://www.legis.iowa.gov/docs/code/2026/422.pdf#page=39", + # 2025 IA 1040 instructions, Personal and dependent credits. + "https://revenue.iowa.gov/media/4435/download?inline#page=8", ) defined_for = StateCode.IA @@ -19,7 +22,16 @@ def formula(tax_unit, period, parameters): filing_status = tax_unit("filing_status", period) hoh_status = filing_status.possible_values.HEAD_OF_HOUSEHOLD hoh_bonus = filing_status == hoh_status - dependent_count = tax_unit("tax_unit_dependents", period) + # Iowa Code 422.12(1)(a) gives "dependent" its Internal Revenue Code + # meaning, and the instructions count the dependents "you are + # claiming for federal income tax purposes". Under IRC 152(b)(1) a + # return on which the filer (or, if joint, either spouse) can be + # claimed has none. Each filer keeps the personal credit, which + # Iowa allows "even if you are claimed as a dependent". + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + dependent_count = where( + filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) + ) # count extra adult exemptions based on being elderly and/or blind p = parameters(period).gov.states.ia.tax.income exemption = p.credits.exemption diff --git a/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py b/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py index c6537563957..20137994c2a 100644 --- a/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py +++ b/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py @@ -11,6 +11,11 @@ class ia_is_tax_exempt(Variable): "https://revenue.iowa.gov/media/2650/download?inline#page=37", "https://revenue.iowa.gov/sites/default/files/2023-01/2022IA1040%2841001%29.pdf", "https://revenue.iowa.gov/media/2721/download?inline#page=37", + "https://revenue.iowa.gov/media/2811/download?inline#page=12", + "https://revenue.iowa.gov/media/4152/download?inline#page=10", + "https://revenue.iowa.gov/media/4435/download?inline#page=11", + # PDF pages 7-8: Iowa Code 422.5(2)(a) and (3)(a). + "https://www.legis.iowa.gov/docs/code/2026/422.pdf#page=7", ) defined_for = StateCode.IA @@ -27,4 +32,16 @@ def formula(tax_unit, period, parameters): where(is_elderly, pil.single_elderly, pil.single_nonelderly), where(is_elderly, pil.other_elderly, pil.other_nonelderly), ) - return tax_unit("ia_modified_income", period) <= modified_income_limit + exempt = tax_unit("ia_modified_income", period) <= modified_income_limit + # The instructions limit the ordinary exemption to filers who are "not + # claimed as a dependent on another person's Iowa return". A single + # filer who is claimed is instead exempt when income, without adding + # back deductions, is "less than $5,000"; a joint, head of household + # or surviving spouse return is not exempt if either spouse is + # claimed. Iowa Code 422.5(2)-(3) denies the exemption only when the + # claimer's own net income exceeds the limit; the model has no input + # for the claimer's income, so it follows the instructions. + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + dependent_income = add(tax_unit, period, p.dependent.income_sources) + dependent_exempt = is_single & (dependent_income < p.dependent.income_limit) + return where(filer_is_dependent, dependent_exempt, exempt) diff --git a/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py b/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py index 299b93cac67..18dad5be134 100644 --- a/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py +++ b/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py @@ -12,6 +12,8 @@ class ia_reduced_tax(Variable): "https://revenue.iowa.gov/media/2650/download?inline#page=60", "https://revenue.iowa.gov/sites/default/files/2023-01/2022IA1040%2841001%29.pdf", "https://revenue.iowa.gov/media/2721/download?inline#page=60", + "https://revenue.iowa.gov/media/4152/download?inline#page=18", + "https://revenue.iowa.gov/media/4435/download?inline#page=18", ) defined_for = StateCode.IA @@ -24,8 +26,10 @@ def formula(tax_unit, period, parameters): is_elderly, p.threshold.elderly, p.threshold.nonelderly ) amount = max_(0, modified_income - modified_income_threshold) # Line 3 - # reduced tax available only to single tax units + # reduced tax available only to single tax units "not claimed as a + # dependent on another person's Iowa return" (Tax Reduction Worksheet) filing_status = tax_unit("filing_status", period) is_single = filing_status == filing_status.possible_values.SINGLE - return where(is_single, amount, np.inf) + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + return where(is_single & ~filer_is_dependent, amount, np.inf) # see ia_income_tax_before_refundable_credits formula for variable use diff --git a/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py b/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py index 6e09ebf3fa8..77743670687 100644 --- a/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py +++ b/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py @@ -8,21 +8,31 @@ class ks_fstc(Variable): unit = USD definition_period = YEAR reference = ( - "https://www.ksrevenue.gov/pdf/ip21.pdf", - "https://www.ksrevenue.gov/pdf/ip22.pdf", + "https://www.ksrevenue.gov/pdf/ip21.pdf#page=6", + "https://www.ksrevenue.gov/pdf/ip22.pdf#page=6", + "https://www.ksrevenue.gov/pdf/ip23.pdf#page=6", + "https://www.ksrevenue.gov/pdf/ip24.pdf#page=6", ) defined_for = StateCode.KS def formula(tax_unit, period, parameters): p = parameters(period).gov.states.ks.tax.income.credits + # A return on which the filer (or, if joint, either spouse) can be + # claimed has no dependents (IRC 152(b)(1)): the K-40 dependent count is + # "0" and no child is claimed "as a personal exemption". + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) # determine if tax unit is eligible for credit person = tax_unit.members # ... any child dependents? - count_all_dependents = tax_unit("tax_unit_dependents", period) + count_all_dependents = where( + filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) + ) child_age = p.food_sales_tax.child_age is_child = person("age", period) < child_age is_child_dependent = person("is_tax_unit_dependent", period) & is_child - count_child_dependents = tax_unit.sum(is_child_dependent) + count_child_dependents = where( + filer_is_dependent, 0, tax_unit.sum(is_child_dependent) + ) has_eligible_child = count_child_dependents > 0 # ... any elderly adults? min_adult_age = p.food_sales_tax.min_adult_age @@ -43,7 +53,19 @@ def formula(tax_unit, period, parameters): eligible_income = fagi <= p.food_sales_tax.agi_limit # compute credit amount eligible = eligible_unit & eligible_income - exemptions = tax_unit("tax_unit_size", period) + # Line E is the "total number of exemptions" from the front of the + # K-40. Through 2023 a claimed filer enters "0" there; from 2024 the + # filing-status exemptions remain and only the dependent count is "0". + exemption_regime = parameters(period).gov.states.ks.tax.income.exemptions + filers = tax_unit("head_spouse_count", period) + claimed_filer_exemptions = where( + exemption_regime.by_filing_status.in_effect, filers, 0 + ) + exemptions = where( + filer_is_dependent, + claimed_filer_exemptions, + tax_unit("tax_unit_size", period), + ) old_dependents = count_all_dependents - count_child_dependents fstc_exemptions = max_(0, exemptions - old_dependents) return eligible * fstc_exemptions * p.food_sales_tax.amount diff --git a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py index d69c01f2d84..5e32dd581fe 100644 --- a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py +++ b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py @@ -8,8 +8,9 @@ class ks_count_exemptions(Variable): unit = USD definition_period = YEAR reference = ( - "https://www.ksrevenue.gov/pdf/ip21.pdf", - "https://www.ksrevenue.gov/pdf/ip22.pdf", + "https://www.ksrevenue.gov/pdf/ip21.pdf#page=6", + "https://www.ksrevenue.gov/pdf/ip22.pdf#page=6", + "https://www.ksrevenue.gov/pdf/ip23.pdf#page=6", ) defined_for = StateCode.KS @@ -20,4 +21,8 @@ def formula(tax_unit, period, parameters): hoh = filing_status == statuses.HEAD_OF_HOUSEHOLD adults = where(joint | hoh, 2, 1) dependents = tax_unit("tax_unit_dependents", period) - return adults + dependents + # K-40 instructions: "If you are claimed as a dependent by another + # taxpayer, enter '0' in the Total Kansas exemptions box." Applied when + # either spouse on a joint return can be claimed. + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + return where(filer_is_dependent, 0, adults + dependents) diff --git a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py index 3b43e3598f0..94f32f180ea 100644 --- a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py +++ b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py @@ -8,7 +8,10 @@ class ks_exemptions(Variable): unit = USD definition_period = YEAR reference = ( - "https://law.justia.com/codes/kansas/chapter-79/article-32/section-79-32-121/" + "https://law.justia.com/codes/kansas/chapter-79/article-32/section-79-32-121/", + "https://ksrevisor.gov/statutes/chapters/ch79/079_032_0121b.html", + "https://www.ksrevenue.gov/pdf/ip24.pdf#page=6", + "https://www.ksrevenue.gov/faqs-taxii.html", ) defined_for = StateCode.KS @@ -24,7 +27,19 @@ def formula(tax_unit, period, parameters): if p.by_filing_status.in_effect: filing_status = tax_unit("filing_status", period) base_amount = p.by_filing_status.amount[filing_status] - dependents = tax_unit("tax_unit_dependents", period) + # K.S.A. 79-32,121b allows the dependent amount for each dependent + # "for which such taxpayer is entitled to a deduction" federally; + # under IRC 152(b)(1) a return on which the filer (or, if joint, + # either spouse) can be claimed has none ("enter '0' in the number + # of dependents box"). The filing-status amount stays: a claimable + # taxpayer "will qualify for the personal exemption allowance" + # (Kansas Department of Revenue FAQ). + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) + dependents = where( + filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) + ) dependent_amount = p.by_filing_status.dependent * dependents head_of_household = ( filing_status == filing_status.possible_values.HEAD_OF_HOUSEHOLD diff --git a/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py b/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py index 49489ff2ad9..0820545b58e 100644 --- a/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py +++ b/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py @@ -8,6 +8,8 @@ class la_dependents_exemption(Variable): reference = [ "https://dam.ldr.la.gov/taxforms/6935(11_02)F.pdf#page=1", "https://dam.ldr.la.gov/taxforms/IT540iWEB(2022)D1.pdf#page=2", + "https://dam.ldr.la.gov/taxforms/IT540i(2021)%20Instructions.pdf#page=3", + "https://dam.ldr.la.gov/taxforms/IT540i%20WEB%20(2024)D18%20INSTRUCTIONS.pdf#page=3", ] # Even though the tax computation worksheet refers "dependent exemption" as credits, the instructions for # preparing tax form line 6a-6b specifies it as exemption. @@ -16,6 +18,13 @@ class la_dependents_exemption(Variable): defined_for = StateCode.LA def formula(tax_unit, period, parameters): - dependents = tax_unit("tax_unit_dependents", period) + # Line 6C counts "the dependents claimed on your federal return". Under + # IRC 152(b)(1) a federal return on which the filer (or, if joint, + # either spouse) can be claimed has none. The filer's own exemption + # (Line 6A) stays "even if someone else claimed you". + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + dependents = where( + filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) + ) p = parameters(period).gov.states.la.tax.income.exemptions return dependents * p.dependent diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py index 4fa63d7ab46..16ad2ca8007 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py @@ -18,7 +18,13 @@ class md_ctc(Variable): def formula_2020(tax_unit, period, parameters): p = parameters(period).gov.states.md.tax.income.credits.ctc person = tax_unit.members - dependent = person("is_tax_unit_dependent", period) + # § 10-751(a)(2)(i): a qualified child is "a dependent for purposes of + # § 152 of the Internal Revenue Code"; under IRC 152(b)(1) a return on + # which the filer (or, if joint, either spouse) can be claimed has none. + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) + dependent = person("is_tax_unit_dependent", period) & ~filer_is_dependent disabled = person("is_disabled", period) age_limit = where(disabled, p.age_threshold.disabled, p.age_threshold.main) meets_age_limit = person("age", period) < age_limit diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py index ed911d52e95..f45fa99c784 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py @@ -18,7 +18,13 @@ def formula(tax_unit, period, parameters): # Check for qualifying children (used in both paths) person = tax_unit.members - dependent = person("is_tax_unit_dependent", period) + # § 10-751(a)(2)(i): a qualified child is "a dependent for purposes of + # § 152 of the Internal Revenue Code"; under IRC 152(b)(1) a return on + # which the filer (or, if joint, either spouse) can be claimed has none. + filer_is_dependent = person.tax_unit( + "head_or_spouse_is_dependent_elsewhere", period + ) + dependent = person("is_tax_unit_dependent", period) & ~filer_is_dependent disabled = person("is_disabled", period) age_limit = where(disabled, p.age_threshold.disabled, p.age_threshold.main) meets_age_limit = person("age", period) < age_limit diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py b/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py index 3661cbc88dc..78a7aaf2aa6 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py @@ -6,9 +6,13 @@ class federal_eitc_without_age_minimum(Variable): entity = TaxUnit label = "Federal EITC without age minimum" unit = USD - documentation = "The federal EITC with the minimum age condition ignored; the maximum age condition still applies." + documentation = "The federal EITC with the minimum age condition ignored; the maximum age condition and the bar on a childless filer who can be claimed as a dependent still apply." definition_period = YEAR - reference = "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-704&enactments=false" + reference = ( + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-704&enactments=false", + "https://www.law.cornell.edu/uscode/text/26/32#c_1_A_ii", + "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=22", + ) defined_for = StateCode.MD def formula(tax_unit, period, parameters): @@ -24,7 +28,15 @@ def formula(tax_unit, period, parameters): max_age = parameters.gov.irs.credits.eitc.eligibility.age.max(period) is_filer_or_spouse = ~person("is_tax_unit_dependent", period) below_max_age = person("age", period) <= max_age - meets_max_age = has_child | tax_unit.any(below_max_age & is_filer_or_spouse) + # § 10-704 waives only the minimum age: a childless filer must still be + # "otherwise eligible for the federal credit", and § 32(c)(1)(A)(ii)(III) + # bars a childless return on which the filer (or, if joint, either + # spouse) can be claimed as a dependent. + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + childless_eligible = ( + tax_unit.any(below_max_age & is_filer_or_spouse) & ~filer_is_dependent + ) + demographic_eligible = has_child | childless_eligible phased_in = tax_unit("eitc_phased_in", period) maximum = tax_unit("eitc_maximum", period) reduction = tax_unit("eitc_reduction", period) @@ -34,5 +46,5 @@ def formula(tax_unit, period, parameters): min_(phased_in, max_(0, maximum - reduction)) * investment_eligible * filer_has_ssn - * meets_max_age + * demographic_eligible ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/is_eligible_md_poverty_line_credit.py b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/is_eligible_md_poverty_line_credit.py index 1cadf64ba83..7c0ef5fe903 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/is_eligible_md_poverty_line_credit.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/is_eligible_md_poverty_line_credit.py @@ -12,6 +12,8 @@ class is_eligible_md_poverty_line_credit(Variable): "https://www.law.cornell.edu/uscode/text/26/32#c_2", "https://www.law.cornell.edu/cfr/text/26/1.32-2", "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-107&enactments=false", + # PDF pages 12, 23: filing status 6 and the poverty level credit. + "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=12", ) defined_for = StateCode.MD @@ -27,7 +29,7 @@ def formula(tax_unit, period, parameters): "md_total_additions", ] agi_plus_md_additions = add(tax_unit, period, AGI_COMPONENTS) - fpg = tax_unit("tax_unit_fpg", period) + fpg = tax_unit("md_poverty_line_credit_income_level", period) agi_below_fpg = agi_plus_md_additions <= fpg # (ii) whose earned income as defined under § 32(c)(2) of the # Internal Revenue Code does not exceed the applicable poverty @@ -35,12 +37,21 @@ def formula(tax_unit, period, parameters): # eitc_earned_income is PolicyEngine's § 32(c)(2) measure, the one the # federal EITC uses: wages plus net earnings from self-employment # (including farm and partnership earnings) after the § 164(f) - # deduction, netted across the filers and floored at zero. - earnings = tax_unit("eitc_earned_income", period) + # deduction, netted across the filers and floored at zero. When a + # filer can be claimed, only the other filer's earnings count (see + # md_poverty_line_credit_earned_income). + earnings = tax_unit("md_poverty_line_credit_earned_income", period) earnings_below_fpg = earnings <= fpg # (iii) who is not claimed as an exemption on another individual’s # tax return under § 10–211 of this title; - # SKIP - assumed throughout PolicyEngine-us. + # The instructions bar filing status 6, "Any person who can be claimed + # as a dependent". A married person who can be claimed files a + # separate Maryland return, so a joint federal return keeps the credit + # only for a spouse who cannot be claimed, on that spouse's earnings. + # The AGI test and the tax limit still use the joint return. + every_filer_is_dependent = tax_unit( + "every_filer_is_dependent_elsewhere", period + ) # (iv) for whom the credit allowed under § 10–704(a)(1) of this # subtitle is less than the State income tax. # This appears to refer to the MD total EITC per @@ -50,4 +61,9 @@ def formula(tax_unit, period, parameters): md_eitc = tax_unit("md_married_or_has_child_non_refundable_eitc", period) md_income_tax_before_credits = tax_unit("md_income_tax_before_credits", period) eitc_less_than_income_tax = md_eitc < md_income_tax_before_credits - return agi_below_fpg & earnings_below_fpg & eitc_less_than_income_tax + return ( + agi_below_fpg + & earnings_below_fpg + & ~every_filer_is_dependent + & eitc_less_than_income_tax + ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py new file mode 100644 index 00000000000..328745c6157 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py @@ -0,0 +1,51 @@ +from policyengine_us.model_api import * + + +class md_poverty_line_credit_earned_income(Variable): + value_type = float + entity = TaxUnit + label = "Maryland poverty line credit earned income" + documentation = ( + "Earned income under IRC section 32(c)(2) of the filers who can take " + "the Maryland poverty line credit: every filer, unless a filer can be " + "claimed as a dependent on another return, in which case only the " + "filers who cannot be claimed." + ) + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + reference = ( + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-709&enactments=false", + "https://www.law.cornell.edu/uscode/text/26/32#c_2", + # PDF pages 12-13, 23: filing status 6, Instruction 8 and the poverty + # level credit. + "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=12", + ) + + def formula(tax_unit, period, parameters): + # § 10-709(a)(3)(iii) excludes a taxpayer "claimed as an exemption on + # another individual's tax return", and the instructions bar filing + # status 6 (a person who can be claimed as a dependent). A married + # person who can be claimed files a separate Maryland return, so on a + # federal joint return only the spouse who cannot be claimed can take + # the credit, on that spouse's own earned income. + person = tax_unit.members + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + sources = [ + "employment_income", + "self_employment_income", + "sstb_self_employment_income", + "farm_operations_income", + "partnership_self_employment_net_earnings", + ] + gross = add(person, period, sources) + self_employment_tax_ald = person("self_employment_tax_ald_person", period) + own_earned_income = max_(0, gross - self_employment_tax_ald) + can_claim = person("is_tax_unit_head_or_spouse", period) & ~person( + "claimed_as_dependent_on_another_return", period + ) + return where( + filer_is_dependent, + tax_unit.sum(own_earned_income * can_claim), + tax_unit("eitc_earned_income", period), + ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py new file mode 100644 index 00000000000..324434d1dda --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py @@ -0,0 +1,30 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class md_poverty_line_credit_income_level(Variable): + value_type = float + entity = TaxUnit + label = "Maryland poverty line credit applicable poverty income level" + unit = USD + definition_period = YEAR + defined_for = StateCode.MD + reference = ( + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-709&enactments=false", + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-211&enactments=false", + ) + + def formula(tax_unit, period, parameters): + # § 10-709(a)(2): the poverty income standard "that corresponds to the + # number of exemptions which the individual is allowed and claims + # under § 10-211(b)(1)". That is the tax unit's size unless a filer + # can be claimed as a dependent, in which case only the filers who + # cannot be claimed count and there are no dependents (IRC 152(b)(1)). + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + exemptions = tax_unit("exemptions_count", period) + state_group = tax_unit.household("state_group_str", period) + return where( + filer_is_dependent, + fpg(exemptions, state_group, period, parameters), + tax_unit("tax_unit_fpg", period), + ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_potential.py b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_potential.py index beb5fdc63dd..a3721a325c3 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_potential.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_potential.py @@ -43,7 +43,9 @@ def formula(tax_unit, period, parameters): # § 32(c)(2) reference, which § 10-107 reads with federal # interpretations. p = parameters(period).gov.states.md.tax.income.credits.poverty_line - earnings = tax_unit("eitc_earned_income", period) + # A filer who can be claimed takes no credit (see + # md_poverty_line_credit_earned_income). + earnings = tax_unit("md_poverty_line_credit_earned_income", period) earnings_portion = earnings * p.earned_income_share amount_if_eligible = min_(tax_after_non_refundable_eitc, earnings_portion) return amount_if_eligible * eligible diff --git a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py index 84fa556f5f6..a23bef19fa9 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py +++ b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py @@ -17,5 +17,11 @@ def formula(tax_unit, period, parameters): dependent = person("is_tax_unit_dependent", period) age = person("age", period) elderly = age >= p.age - aged_dependents = tax_unit.sum(dependent & elderly) + # § 10-211(b)(2) counts dependents "as defined in § 152 of the Internal + # Revenue Code"; under IRC 152(b)(1) a return on which the filer (or, + # if joint, either spouse) can be claimed has none. + filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + aged_dependents = where( + filer_is_dependent, 0, tax_unit.sum(dependent & elderly) + ) return aged_dependents * p.aged_dependent diff --git a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py index 8b3df55927b..cbe0d478cd0 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py +++ b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py @@ -8,9 +8,23 @@ class md_total_personal_exemptions(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD + reference = ( + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-211&enactments=false", + # PDF pages 12-13: filing status 6 and Instruction 8. + "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=12", + ) def formula(tax_unit, period, parameters): - # Get md_personal_exemption from tax_unit multiplied by tax_unit_size + # § 10-211(a) and (b)(1) allow an exemption for each filer and for each + # dependent "as defined in § 152 of the Internal Revenue Code". A + # person who can be claimed on another return is a dependent taxpayer + # (filing status 6): "You do not get an exemption for yourself". Under + # IRC 152(b)(1) a return on which the filer (or, if joint, either + # spouse) can be claimed has no dependents; Maryland requires such a + # couple to file separate returns, where each spouse claims their own + # exemption and they split "the overall number of dependents" of the + # federal return. The federal exemption count applies exactly these + # rules. md_personal_exemption = tax_unit("md_personal_exemption", period) - tax_unit_size = tax_unit("tax_unit_size", period) - return md_personal_exemption * tax_unit_size + exemptions = tax_unit("exemptions_count", period) + return md_personal_exemption * exemptions diff --git a/policyengine_us/variables/gov/states/md/tax/income/local/credits/md_local_poverty_line_credit.py b/policyengine_us/variables/gov/states/md/tax/income/local/credits/md_local_poverty_line_credit.py index 22caada540b..3d511b4347b 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/local/credits/md_local_poverty_line_credit.py +++ b/policyengine_us/variables/gov/states/md/tax/income/local/credits/md_local_poverty_line_credit.py @@ -23,7 +23,9 @@ def formula(tax_unit, period, parameters): # eligible low income taxpayer's earned income, as defined under # § 32(c)(2) (floored at zero, as for the State credit). eligible = tax_unit("is_eligible_md_poverty_line_credit", period) - earnings = tax_unit("eitc_earned_income", period) + # A filer who can be claimed takes no credit (see + # md_poverty_line_credit_earned_income). + earnings = tax_unit("md_poverty_line_credit_earned_income", period) rate = tax_unit("md_applicable_local_tax_rate", period) earnings_portion = earnings * rate local_tax = tax_unit("md_local_income_tax_before_credits", period) From 704a604a296ed6d502d18fb1c5a5ea2e0d1ef62a Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 10 Oct 2026 06:23:43 -0400 Subject: [PATCH 2/4] Limit Maryland's aged dependent exemption by federal AGI Tax-General 10-211(c) limits "the amount allowed for each exemption under subsection (b)(1) or (2)" once federal AGI exceeds $100,000 ($150,000 joint, head of household or surviving spouse), and the Resident Booklet's chart says "This reduction applies to the additional dependency exemptions as well". The aged dependent exemption ((b)(2)) was a flat $3,200 at any income; it now takes the same per-exemption amount as the personal exemption. Co-Authored-By: Claude Opus 5.5 --- .../md_aged_dependent_exemption.yaml | 105 ++++++++++++++++++ .../exemptions/md_aged_dependent_exemption.py | 14 ++- 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml index 5d406d7d336..8e8637ff131 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.yaml @@ -155,3 +155,108 @@ output: # One dependent aged 65 or older: $3,200. md_aged_dependent_exemption: 3200 + + +- name: 2025 aged dependent exemption is limited like the personal exemption at $110,000 of single AGI + period: 2025 + input: + people: + person_a: + age: 50 + employment_income: 110000 + is_tax_unit_head: true + is_tax_unit_spouse: false + parent: + age: 70 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, parent] + filing_status: SINGLE + households: + household: + members: [person_a, parent] + state_code: MD + output: + # Single AGI over $100,000 but not over $125,000: each exemption is $1,600 (10-211(c)(1)(i)). + # The chart's "reduction applies to the additional dependency exemptions as well". + md_aged_dependent_exemption: 1600 + +- name: 2025 aged dependent exemption is limited like the personal exemption at $130,000 of single AGI + period: 2025 + input: + people: + person_a: + age: 50 + employment_income: 130000 + is_tax_unit_head: true + is_tax_unit_spouse: false + parent: + age: 70 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, parent] + filing_status: SINGLE + households: + household: + members: [person_a, parent] + state_code: MD + output: + # Single AGI over $125,000 but not over $150,000: each exemption is $800 (10-211(c)(1)(ii)). + # The chart's "reduction applies to the additional dependency exemptions as well". + md_aged_dependent_exemption: 800 + +- name: 2025 aged dependent exemption is limited like the personal exemption at $160,000 of single AGI + period: 2025 + input: + people: + person_a: + age: 50 + employment_income: 160000 + is_tax_unit_head: true + is_tax_unit_spouse: false + parent: + age: 70 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, parent] + filing_status: SINGLE + households: + household: + members: [person_a, parent] + state_code: MD + output: + # Single AGI over $150,000: each exemption is $0 (10-211(c)(1)(iii)). + # The chart's "reduction applies to the additional dependency exemptions as well". + md_aged_dependent_exemption: 0 + +- name: 2025 aged dependent exemption is limited at $160,000 of joint AGI + period: 2025 + input: + people: + person_a: + age: 50 + employment_income: 80000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 50 + employment_income: 80000 + is_tax_unit_head: false + is_tax_unit_spouse: true + parent: + age: 70 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, parent] + filing_status: JOINT + households: + household: + members: [person_a, person_b, parent] + state_code: MD + output: + # Joint AGI over $150,000 but not over $175,000: $1,600 (10-211(c)(2)(i)). + md_aged_dependent_exemption: 1600 diff --git a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py index a23bef19fa9..1f1d3c0611b 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py +++ b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py @@ -7,7 +7,12 @@ class md_aged_dependent_exemption(Variable): label = "MD aged dependent exemption" unit = USD definition_period = YEAR - reference = "https://govt.westlaw.com/mdc/Document/NF59A76006EA511E8ABBEE50DE853DFF4?viewType=FullText&originationContext=documenttoc&transitionType=CategoryPageItem&contextData=(sc.Default)" + reference = ( + "https://govt.westlaw.com/mdc/Document/NF59A76006EA511E8ABBEE50DE853DFF4?viewType=FullText&originationContext=documenttoc&transitionType=CategoryPageItem&contextData=(sc.Default)", + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-211&enactments=false", + # Exemption amount chart (10A). + "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=12", + ) defined_for = StateCode.MD def formula(tax_unit, period, parameters): @@ -24,4 +29,9 @@ def formula(tax_unit, period, parameters): aged_dependents = where( filer_is_dependent, 0, tax_unit.sum(dependent & elderly) ) - return aged_dependents * p.aged_dependent + # § 10-211(c) limits "the amount allowed for each exemption under + # subsection (b)(1) or (2)" by federal AGI, the same limit as the + # personal exemption; the chart's "reduction applies to the additional + # dependency exemptions as well". + per_exemption = tax_unit("md_personal_exemption", period) + return aged_dependents * min_(p.aged_dependent, per_exemption) From 61275e99d212db0d527a89799d29ad9ccb238a09 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 12:17:05 -0400 Subject: [PATCH 3/4] Read the split dependency inputs in the IA, KS, LA and MD rules #10024 now separates claimability (`claimable_as_dependent_on_another_return`) from an actual claim (`claimed_as_dependent_on_another_return`) and adds the claimant filing exception. Each rule now reads the fact its law names: - IRC 152(b)(1) "no dependents" rules (Iowa dependent credit, Kansas dependents and food sales tax credit child, Louisiana dependent exemption, Maryland dependents, aged dependents and CTC, and the childless pro forma EITC) read `head_or_spouse_is_dependent_elsewhere_without_filing_exception`, as the federal formulas do. - Rules whose text says "claimed" read the claim: Iowa's low-income exemption and tax reduction ("not claimed as a dependent on another person's Iowa return") and Kansas's 2021-2023 zero exemptions ("If you are claimed as a dependent"). - Maryland's filing status 6 ("Any person who can be claimed") keeps reading claimability for the own exemption and the poverty line credit. Maryland now counts its own exemptions in `md_personal_exemptions_count` instead of reading federal `exemptions_count`, so a federal-only reform of that count no longer changes Maryland's exemptions (review r1 finding 1). The changelog names the aged dependent AGI limit (r1 finding 2). Co-Authored-By: Claude Opus 5.5 --- .../claimable-filer-ia-ks-ky-la-md.fixed.md | 2 +- .../repeal_state_dependent_exemptions.py | 10 ++--- .../ia_dependent_credit_reform.py | 5 ++- .../ks_dependent_exemption_reform.py | 5 ++- .../md_dependent_exemption_reform.py | 10 +++-- .../tax/income/credits/ia_exemption_credit.py | 10 +++-- .../states/ia/tax/income/ia_is_tax_exempt.py | 8 +++- .../states/ia/tax/income/ia_reduced_tax.py | 8 +++- .../states/ks/tax/income/credits/ks_fstc.py | 30 ++++++++----- .../income/exemptions/ks_count_exemptions.py | 18 ++++++-- .../ks/tax/income/exemptions/ks_exemptions.py | 10 +++-- .../personal/la_dependents_exemption.py | 10 +++-- .../md/tax/income/credits/ctc/md_ctc.py | 6 ++- .../tax/income/credits/ctc/md_ctc_eligible.py | 6 ++- .../eitc/federal_eitc_without_age_minimum.py | 8 +++- .../md_poverty_line_credit_earned_income.py | 3 +- .../md_poverty_line_credit_income_level.py | 5 ++- .../exemptions/md_aged_dependent_exemption.py | 7 +++- .../md_personal_exemptions_count.py | 42 +++++++++++++++++++ .../md_total_personal_exemptions.py | 20 ++------- 20 files changed, 154 insertions(+), 69 deletions(-) create mode 100644 policyengine_us/variables/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.py diff --git a/changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md b/changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md index e8492608950..49bed9d9de0 100644 --- a/changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md +++ b/changelog.d/claimable-filer-ia-ks-ky-la-md.fixed.md @@ -1 +1 @@ -Apply Iowa, Kansas, Louisiana and Maryland rules for a filer who can be claimed as a dependent: no dependent exemptions or credits on a return with a claimable filer (Iowa dependent credit, Kansas dependent exemption and food sales tax credit child, Louisiana dependent exemption, Maryland dependent and aged-dependent exemptions and child tax credit); no Iowa low-income exemption for a claimed filer except a single filer with income below $5,000, and no Iowa tax reduction; no Kansas exemptions for a claimed filer in 2021-2023; no Maryland personal exemption, poverty line credit or childless EITC for a filer who can be claimed, with the poverty line credit kept for a spouse who cannot be claimed. +Apply Iowa, Kansas, Louisiana and Maryland rules for a filer who can be claimed as a dependent: no dependent exemptions or credits on a return with a claimable filer outside the claimant filing exception (Iowa dependent credit, Kansas dependent exemption and food sales tax credit child, Louisiana dependent exemption, Maryland dependent and aged-dependent exemptions and child tax credit); a claimed Iowa filer gets the low-income exemption only as a single filer with income below $5,000, and no tax reduction; a claimed Kansas filer has no exemptions in 2021-2023; a Maryland filer who can be claimed gets no personal exemption, poverty line credit or childless EITC, and the poverty line credit stays for a spouse who cannot be claimed. Also limit Maryland's aged dependent exemption by federal AGI under Tax-General 10-211(c), as for the personal exemption. 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 2619661346e..1a7939c32df 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 @@ -354,11 +354,11 @@ def formula(tax_unit, period, parameters): joint = filing_status == statuses.JOINT hoh = filing_status == statuses.HEAD_OF_HOUSEHOLD adults = where(joint | hoh, 2, 1) - # A filer who can be claimed as a dependent enters "0" exemptions. - filer_is_dependent = tax_unit( - "head_or_spouse_is_dependent_elsewhere", period - ) - adults = where(filer_is_dependent, 0, adults) + # A filer who is claimed as a dependent enters "0" exemptions. + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + claimed = person("claimed_as_dependent_on_another_return", period) + adults = where(tax_unit.any(filer & claimed), 0, adults) return adults * p.consolidated.amount + veterans_exemption_amount class ma_income_tax_exemption_threshold(Variable): diff --git a/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py b/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py index 8362a3ef88e..c3484976a33 100644 --- a/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py +++ b/policyengine_us/reforms/states/ia/dependent_credit/ia_dependent_credit_reform.py @@ -39,9 +39,10 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) # A return on which the filer (or, if joint, either spouse) can be - # claimed as a dependent has no dependents (IRC 152(b)(1)). + # claimed as a dependent has no dependents (IRC 152(b)(1)), unless + # the would-be claimant meets the filing exception (Publication 501). is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( - "head_or_spouse_is_dependent_elsewhere", period + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period ) if c.age_limit.in_effect: eligible = is_dependent & (age < c.age_limit.threshold) diff --git a/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py b/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py index 6c05ccefed2..bcddb285a66 100644 --- a/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/ks/dependent_exemption/ks_dependent_exemption_reform.py @@ -16,9 +16,10 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) # A return on which the filer (or, if joint, either spouse) can be - # claimed as a dependent has no dependents (IRC 152(b)(1)). + # claimed as a dependent has no dependents (IRC 152(b)(1)), unless + # the would-be claimant meets the filing exception (Publication 501). is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( - "head_or_spouse_is_dependent_elsewhere", period + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period ) # Apply age limit if in effect. diff --git a/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py b/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py index 039fa78efcd..f0905385e50 100644 --- a/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py +++ b/policyengine_us/reforms/states/md/dependent_exemption/md_dependent_exemption_reform.py @@ -15,9 +15,10 @@ def formula(tax_unit, period, parameters): person = tax_unit.members age = person("age", period) # A return on which the filer (or, if joint, either spouse) can be - # claimed as a dependent has no dependents (IRC 152(b)(1)). + # claimed as a dependent has no dependents (IRC 152(b)(1)), unless + # the would-be claimant meets the filing exception (Publication 501). is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( - "head_or_spouse_is_dependent_elsewhere", period + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period ) if p.age_limit.in_effect: eligible = is_dependent & (age < p.age_limit.threshold) @@ -102,9 +103,10 @@ class md_older_dependents_count(Variable): def formula(tax_unit, period, parameters): person = tax_unit.members # A return on which the filer (or, if joint, either spouse) can be - # claimed as a dependent has no dependents (IRC 152(b)(1)). + # claimed as a dependent has no dependents (IRC 152(b)(1)), unless + # the would-be claimant meets the filing exception (Publication 501). is_dependent = person("is_tax_unit_dependent", period) & ~person.tax_unit( - "head_or_spouse_is_dependent_elsewhere", period + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period ) total_dependents = tax_unit.sum(is_dependent) eligible = tax_unit("md_eligible_dependents_count", period) diff --git a/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py b/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py index 4c21bca132e..4a61f6be932 100644 --- a/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py +++ b/policyengine_us/variables/gov/states/ia/tax/income/credits/ia_exemption_credit.py @@ -26,9 +26,13 @@ def formula(tax_unit, period, parameters): # meaning, and the instructions count the dependents "you are # claiming for federal income tax purposes". Under IRC 152(b)(1) a # return on which the filer (or, if joint, either spouse) can be - # claimed has none. Each filer keeps the personal credit, which - # Iowa allows "even if you are claimed as a dependent". - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + # claimed has none, unless the would-be claimant meets the filing + # exception (Publication 501, Dependent Taxpayer Test). Each filer + # keeps the personal credit, which Iowa allows "even if you are + # claimed as a dependent". + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) dependent_count = where( filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) ) diff --git a/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py b/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py index 20137994c2a..d089f5d6997 100644 --- a/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py +++ b/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py @@ -40,8 +40,12 @@ def formula(tax_unit, period, parameters): # or surviving spouse return is not exempt if either spouse is # claimed. Iowa Code 422.5(2)-(3) denies the exemption only when the # claimer's own net income exceeds the limit; the model has no input - # for the claimer's income, so it follows the instructions. - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + # for the claimer's income, so it follows the instructions. Both turn + # on being claimed, not on being claimable, so this reads the claim. + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + claimed = person("claimed_as_dependent_on_another_return", period) + filer_is_dependent = tax_unit.any(filer & claimed) dependent_income = add(tax_unit, period, p.dependent.income_sources) dependent_exempt = is_single & (dependent_income < p.dependent.income_limit) return where(filer_is_dependent, dependent_exempt, exempt) diff --git a/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py b/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py index 18dad5be134..5a6cb809fff 100644 --- a/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py +++ b/policyengine_us/variables/gov/states/ia/tax/income/ia_reduced_tax.py @@ -30,6 +30,10 @@ def formula(tax_unit, period, parameters): # dependent on another person's Iowa return" (Tax Reduction Worksheet) filing_status = tax_unit("filing_status", period) is_single = filing_status == filing_status.possible_values.SINGLE - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) - return where(is_single & ~filer_is_dependent, amount, np.inf) + # The worksheet turns on being claimed, not on being claimable. + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + claimed = person("claimed_as_dependent_on_another_return", period) + filer_claimed = tax_unit.any(filer & claimed) + return where(is_single & ~filer_claimed, amount, np.inf) # see ia_income_tax_before_refundable_credits formula for variable use diff --git a/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py b/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py index 77743670687..444920c097f 100644 --- a/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py +++ b/policyengine_us/variables/gov/states/ks/tax/income/credits/ks_fstc.py @@ -18,9 +18,13 @@ class ks_fstc(Variable): def formula(tax_unit, period, parameters): p = parameters(period).gov.states.ks.tax.income.credits # A return on which the filer (or, if joint, either spouse) can be - # claimed has no dependents (IRC 152(b)(1)): the K-40 dependent count is - # "0" and no child is claimed "as a personal exemption". - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + # claimed has no dependents (IRC 152(b)(1)), unless the would-be + # claimant meets the filing exception (Publication 501, Dependent + # Taxpayer Test): the K-40 dependent count is "0" and no child is + # claimed "as a personal exemption". + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) # determine if tax unit is eligible for credit person = tax_unit.members # ... any child dependents? @@ -54,18 +58,24 @@ def formula(tax_unit, period, parameters): # compute credit amount eligible = eligible_unit & eligible_income # Line E is the "total number of exemptions" from the front of the - # K-40. Through 2023 a claimed filer enters "0" there; from 2024 the - # filing-status exemptions remain and only the dependent count is "0". + # K-40: the filers and the dependents counted above. Through 2023 a + # filer who is claimed enters "0" there; from 2024 the filing-status + # exemptions remain. exemption_regime = parameters(period).gov.states.ks.tax.income.exemptions - filers = tax_unit("head_spouse_count", period) - claimed_filer_exemptions = where( - exemption_regime.by_filing_status.in_effect, filers, 0 - ) + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + claimed = person("claimed_as_dependent_on_another_return", period) + filer_claimed = tax_unit.any(filer & claimed) exemptions = where( filer_is_dependent, - claimed_filer_exemptions, + tax_unit("head_spouse_count", period), tax_unit("tax_unit_size", period), ) + exemptions = where( + filer_claimed & ~exemption_regime.by_filing_status.in_effect, + 0, + exemptions, + ) old_dependents = count_all_dependents - count_child_dependents fstc_exemptions = max_(0, exemptions - old_dependents) return eligible * fstc_exemptions * p.food_sales_tax.amount diff --git a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py index 5e32dd581fe..aac20cb79ec 100644 --- a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py +++ b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_count_exemptions.py @@ -20,9 +20,19 @@ def formula(tax_unit, period, parameters): joint = filing_status == statuses.JOINT hoh = filing_status == statuses.HEAD_OF_HOUSEHOLD adults = where(joint | hoh, 2, 1) - dependents = tax_unit("tax_unit_dependents", period) + # Dependents are those "you claim as a dependent" federally; under IRC + # 152(b)(1) a return on which the filer (or, if joint, either spouse) + # can be claimed has none, unless the would-be claimant meets the + # filing exception (Publication 501, Dependent Taxpayer Test). + no_dependents = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependents = where(no_dependents, 0, tax_unit("tax_unit_dependents", period)) # K-40 instructions: "If you are claimed as a dependent by another # taxpayer, enter '0' in the Total Kansas exemptions box." Applied when - # either spouse on a joint return can be claimed. - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) - return where(filer_is_dependent, 0, adults + dependents) + # either spouse on a joint return is claimed. + person = tax_unit.members + filer = person("is_tax_unit_head_or_spouse", period) + claimed = person("claimed_as_dependent_on_another_return", period) + filer_claimed = tax_unit.any(filer & claimed) + return where(filer_claimed, 0, adults + dependents) diff --git a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py index 94f32f180ea..5b6fd4a9665 100644 --- a/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py +++ b/policyengine_us/variables/gov/states/ks/tax/income/exemptions/ks_exemptions.py @@ -31,11 +31,13 @@ def formula(tax_unit, period, parameters): # "for which such taxpayer is entitled to a deduction" federally; # under IRC 152(b)(1) a return on which the filer (or, if joint, # either spouse) can be claimed has none ("enter '0' in the number - # of dependents box"). The filing-status amount stays: a claimable - # taxpayer "will qualify for the personal exemption allowance" - # (Kansas Department of Revenue FAQ). + # of dependents box"), unless the would-be claimant meets the + # filing exception (Publication 501, Dependent Taxpayer Test). The + # filing-status amount stays: a claimable taxpayer "will qualify + # for the personal exemption allowance" (Kansas Department of + # Revenue FAQ). filer_is_dependent = tax_unit( - "head_or_spouse_is_dependent_elsewhere", period + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period ) dependents = where( filer_is_dependent, 0, tax_unit("tax_unit_dependents", period) diff --git a/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py b/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py index 0820545b58e..19d6b430d18 100644 --- a/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py +++ b/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py @@ -20,9 +20,13 @@ class la_dependents_exemption(Variable): def formula(tax_unit, period, parameters): # Line 6C counts "the dependents claimed on your federal return". Under # IRC 152(b)(1) a federal return on which the filer (or, if joint, - # either spouse) can be claimed has none. The filer's own exemption - # (Line 6A) stays "even if someone else claimed you". - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + # either spouse) can be claimed has none, unless the would-be claimant + # meets the filing exception (Publication 501, Dependent Taxpayer + # Test). The filer's own exemption (Line 6A) stays "even if someone + # else claimed you". + 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) ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py index 16ad2ca8007..56591152927 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc.py @@ -20,9 +20,11 @@ def formula_2020(tax_unit, period, parameters): person = tax_unit.members # § 10-751(a)(2)(i): a qualified child is "a dependent for purposes of # § 152 of the Internal Revenue Code"; under IRC 152(b)(1) a return on - # which the filer (or, if joint, either spouse) can be claimed has none. + # which the filer (or, if joint, either spouse) can be claimed has + # none, unless the would-be claimant meets the filing exception + # (Publication 501, Dependent Taxpayer Test). filer_is_dependent = person.tax_unit( - "head_or_spouse_is_dependent_elsewhere", period + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period ) dependent = person("is_tax_unit_dependent", period) & ~filer_is_dependent disabled = person("is_disabled", period) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py index f45fa99c784..61309a347d8 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/ctc/md_ctc_eligible.py @@ -20,9 +20,11 @@ def formula(tax_unit, period, parameters): person = tax_unit.members # § 10-751(a)(2)(i): a qualified child is "a dependent for purposes of # § 152 of the Internal Revenue Code"; under IRC 152(b)(1) a return on - # which the filer (or, if joint, either spouse) can be claimed has none. + # which the filer (or, if joint, either spouse) can be claimed has + # none, unless the would-be claimant meets the filing exception + # (Publication 501, Dependent Taxpayer Test). filer_is_dependent = person.tax_unit( - "head_or_spouse_is_dependent_elsewhere", period + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period ) dependent = person("is_tax_unit_dependent", period) & ~filer_is_dependent disabled = person("is_disabled", period) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py b/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py index 78a7aaf2aa6..cdf22733bdc 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.py @@ -31,8 +31,12 @@ def formula(tax_unit, period, parameters): # § 10-704 waives only the minimum age: a childless filer must still be # "otherwise eligible for the federal credit", and § 32(c)(1)(A)(ii)(III) # bars a childless return on which the filer (or, if joint, either - # spouse) can be claimed as a dependent. - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + # spouse) can be claimed as a dependent, unless the would-be claimant + # meets the filing exception (Publication 596), as in + # eitc_demographic_eligible. + filer_is_dependent = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) childless_eligible = ( tax_unit.any(below_max_age & is_filer_or_spouse) & ~filer_is_dependent ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py index 328745c6157..417907eee8a 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.py @@ -31,6 +31,7 @@ def formula(tax_unit, period, parameters): # the credit, on that spouse's own earned income. person = tax_unit.members filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + # The same sources as eitc_earned_income, per person. sources = [ "employment_income", "self_employment_income", @@ -42,7 +43,7 @@ def formula(tax_unit, period, parameters): self_employment_tax_ald = person("self_employment_tax_ald_person", period) own_earned_income = max_(0, gross - self_employment_tax_ald) can_claim = person("is_tax_unit_head_or_spouse", period) & ~person( - "claimed_as_dependent_on_another_return", period + "claimable_as_dependent_on_another_return", period ) return where( filer_is_dependent, diff --git a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py index 324434d1dda..96f4e4c60ab 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py +++ b/policyengine_us/variables/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_income_level.py @@ -19,9 +19,10 @@ def formula(tax_unit, period, parameters): # number of exemptions which the individual is allowed and claims # under § 10-211(b)(1)". That is the tax unit's size unless a filer # can be claimed as a dependent, in which case only the filers who - # cannot be claimed count and there are no dependents (IRC 152(b)(1)). + # cannot be claimed count, with dependents only under the claimant + # filing exception (IRC 152(b)(1)). filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) - exemptions = tax_unit("exemptions_count", period) + exemptions = tax_unit("md_personal_exemptions_count", period) state_group = tax_unit.household("state_group_str", period) return where( filer_is_dependent, diff --git a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py index 1f1d3c0611b..1141cc60539 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py +++ b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_aged_dependent_exemption.py @@ -24,8 +24,11 @@ def formula(tax_unit, period, parameters): elderly = age >= p.age # § 10-211(b)(2) counts dependents "as defined in § 152 of the Internal # Revenue Code"; under IRC 152(b)(1) a return on which the filer (or, - # if joint, either spouse) can be claimed has none. - filer_is_dependent = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + # if joint, either spouse) can be claimed has none, 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 + ) aged_dependents = where( filer_is_dependent, 0, tax_unit.sum(dependent & elderly) ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.py b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.py new file mode 100644 index 00000000000..c8d6b76cd73 --- /dev/null +++ b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.py @@ -0,0 +1,42 @@ +from policyengine_us.model_api import * + + +class md_personal_exemptions_count(Variable): + value_type = int + entity = TaxUnit + label = "Maryland personal exemptions count" + documentation = ( + "Number of exemptions under Md. Code, Tax-General 10-211(a) and " + "(b)(1): one for each filer who cannot be claimed as a dependent on " + "another return, plus one for each dependent unless a filer can be " + "claimed (outside the claimant filing exception)." + ) + definition_period = YEAR + defined_for = StateCode.MD + reference = ( + "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-211&enactments=false", + # PDF pages 12-13: filing status 6 and Instruction 8. + "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=12", + "https://www.irs.gov/pub/irs-prior/p501--2025.pdf#page=11", + ) + + def formula(tax_unit, period, parameters): + # § 10-211(a) allows an exemption for each filer and for each + # dependent "as defined in § 152 of the Internal Revenue Code". A + # person who can be claimed on another return is a dependent taxpayer + # (filing status 6): "You do not get an exemption for yourself". + # Maryland requires a married filer who can be claimed to file a + # separate return, where each spouse claims their own exemption and + # the spouses split "the overall number of dependents" of the federal + # return. Under IRC 152(b)(1) that return has none when either spouse + # can be claimed, unless the would-be claimant meets the filing + # exception (Publication 501, Dependent Taxpayer Test). + claimable_filer = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + own = tax_unit("head_spouse_count_not_dependent_elsewhere", period) + no_dependents = tax_unit( + "head_or_spouse_is_dependent_elsewhere_without_filing_exception", period + ) + dependents = where(no_dependents, 0, tax_unit("tax_unit_dependents", period)) + return where( + claimable_filer, own + dependents, tax_unit("tax_unit_size", period) + ) diff --git a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py index cbe0d478cd0..e2cbb8214f7 100644 --- a/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py +++ b/policyengine_us/variables/gov/states/md/tax/income/exemptions/md_total_personal_exemptions.py @@ -8,23 +8,11 @@ class md_total_personal_exemptions(Variable): unit = USD definition_period = YEAR defined_for = StateCode.MD - reference = ( - "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-211&enactments=false", - # PDF pages 12-13: filing status 6 and Instruction 8. - "https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/instructions/2025/resident-booklet.pdf#page=12", - ) + reference = "https://mgaleg.maryland.gov/mgawebsite/Laws/StatuteText?article=gtg§ion=10-211&enactments=false" def formula(tax_unit, period, parameters): - # § 10-211(a) and (b)(1) allow an exemption for each filer and for each - # dependent "as defined in § 152 of the Internal Revenue Code". A - # person who can be claimed on another return is a dependent taxpayer - # (filing status 6): "You do not get an exemption for yourself". Under - # IRC 152(b)(1) a return on which the filer (or, if joint, either - # spouse) can be claimed has no dependents; Maryland requires such a - # couple to file separate returns, where each spouse claims their own - # exemption and they split "the overall number of dependents" of the - # federal return. The federal exemption count applies exactly these - # rules. + # § 10-211(b)(1): the per-exemption amount for each exemption allowed + # under § 10-211(a). md_personal_exemption = tax_unit("md_personal_exemption", period) - exemptions = tax_unit("exemptions_count", period) + exemptions = tax_unit("md_personal_exemptions_count", period) return md_personal_exemption * exemptions From 5459eee8f8dc115118c101fd46a8378ff4dd35ea Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 12:19:32 -0400 Subject: [PATCH 4/4] Test the split inputs, the filing exception and the unchanged case YAML cases for a filer who can be claimed but is not claimed (Iowa exemption and tax reduction, Kansas 2021-2023 exemptions) and for a claimant who meets the filing exception (Iowa dependent credit, Kansas 2024 dependent exemption, Louisiana dependent exemption, Maryland exemption count, CTC and pro forma EITC, and the poverty line credit, which the exception does not restore). New md_personal_exemptions_count.yaml. The property test now draws claimable, claimed and filing-exception patterns, checks the unchanged-when-nobody-is-claimable identities (review r1 finding 3) and adds a filing-exception scope test. Also: the 2021 Iowa exemption anchor is page 38, not 37; Louisiana's 2023 instructions are cited; 422.13(1)(a) is labelled as the filing requirement. Co-Authored-By: Claude Opus 5.5 --- .../tax_exempt/dependent/income_limit.yaml | 2 +- ...aimable_filer_ia_ks_ky_la_md_invariants.py | 131 ++++++++-- .../ia/tax/income/ia_exemption_credit.yaml | 87 +++++++ ..._income_tax_before_refundable_credits.yaml | 29 +++ .../ia/tax/income/ia_is_tax_exempt.yaml | 83 ++++++ .../exemptions/ks_count_exemptions.yaml | 90 +++++++ .../tax/income/exemptions/ks_exemptions.yaml | 28 ++ .../personal/la_dependents_exemption.yaml | 28 ++ .../md/tax/income/credits/ctc/md_ctc.yaml | 30 +++ .../federal_eitc_without_age_minimum.yaml | 25 ++ .../md_poverty_line_credit_earned_income.yaml | 29 +++ .../md_personal_exemptions_count.yaml | 239 ++++++++++++++++++ .../states/ia/tax/income/ia_is_tax_exempt.py | 2 +- .../personal/la_dependents_exemption.py | 1 + 14 files changed, 775 insertions(+), 29 deletions(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.yaml diff --git a/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml b/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml index 9ffc3a42678..c77e74e354e 100644 --- a/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml +++ b/policyengine_us/parameters/gov/states/ia/tax/income/tax_exempt/dependent/income_limit.yaml @@ -7,7 +7,7 @@ metadata: period: year unit: currency-USD reference: - - title: Iowa Code 422.13(1)(a) + - title: Iowa Code 422.13(1)(a), filing requirement for a claimed dependent href: https://www.legis.iowa.gov/docs/code/2026/422.pdf#page=46 - title: 2021 IA1040 Income Tax Return instructions href: https://revenue.iowa.gov/media/2650/download?inline#page=38 diff --git a/policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py b/policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py index fb2aa551c3e..4060289d371 100644 --- a/policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py +++ b/policyengine_us/tests/core/test_claimable_filer_ia_ks_ky_la_md_invariants.py @@ -2,16 +2,15 @@ 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)), so these states' dependent exemptions and credits, -Kansas's food sales tax credit child route and Maryland's child tax credit -count none. A claimed filer keeps Iowa's personal credit and, from 2024, -Kansas's filing-status allowance, but gets no Kansas exemptions in 2021-2023, -no Iowa low-income exemption above $5,000 or tax reduction, and no Maryland -personal exemption, poverty line credit or childless EITC; on a joint return -Maryland's poverty line credit stays for the spouse who cannot be claimed. +dependents unless the would-be claimant meets the filing exception (IRC +152(b)(1), Publication 501), so these states' dependent exemptions and credits, +Kansas's food sales tax credit child route, Maryland's child tax credit and the +childless pro forma EITC follow that test. Iowa's low-income exemption and tax +reduction and Kansas's 2021-2023 exemptions turn on an actual claim; Maryland's +own exemption and poverty line credit turn on claimability (filing status 6). -For couples drawn by Hypothesis and a seeded population in these states, with -either, both or neither spouse claimed: +For couples drawn by Hypothesis (claimable, claimed and filing-exception +patterns) and a seeded population in these states: 1. Swap invariance: each output is the same under either head/spouse labelling. @@ -19,15 +18,20 @@ MONOTONE. This holds for the drawn inputs, which have no self-employment losses: on separate Maryland returns a claimable spouse's loss no longer offsets the other spouse's earnings, which is intended. -3. Identities: with a claimable filer there is no Louisiana dependent - exemption, Maryland aged dependent exemption or child tax credit, and no - pro forma federal EITC without a child; with no claimable filer the - poverty line credit's earned income and poverty level are the unchanged - EITC earned income and tax unit poverty guideline. +3. Identities: with a filer claimable outside the filing exception there is no + Louisiana dependent exemption, Maryland aged dependent exemption or child + tax credit, and no pro forma federal EITC without a child; with every filer + claimable, no poverty line credit. 4. Differential: wherever the federal EITC's eligibility holds, Maryland's pro forma federal EITC without the minimum age equals the federal credit - before take-up, so the two eligibility paths agree, including on the - claimable-filer bar. + before take-up and filing. +5. Unchanged when nobody can be claimed: Maryland's exemption count is the tax + unit's size, the poverty line credit's earned income and poverty level are + `eitc_earned_income` and `tax_unit_fpg`, and Louisiana's dependent + exemption is $1,000 per dependent. +6. Filing exception scope: the exception never lowers the 152(b)(1) amounts in + EXCEPTION_RESTORES and does not change the claimability and actual-claim + rules in EXCEPTION_NEUTRAL. """ import numpy as np @@ -35,6 +39,7 @@ from hypothesis import HealthCheck, given, settings from hypothesis import strategies as st +from policyengine_us import Simulation from policyengine_us.tests.core.test_claimable_filer_federal_invariants import ( check_monotone, check_swap, @@ -44,7 +49,9 @@ TOLERANCE, _calc, _crafted_cases, + _exception_variants, _seeded_couples, + _situation, adults, dependents, ) @@ -60,6 +67,7 @@ "ks_exemptions", "ks_fstc", "la_dependents_exemption", + "md_personal_exemptions_count", "md_total_personal_exemptions", "md_aged_dependent_exemption", "federal_eitc_without_age_minimum", @@ -78,38 +86,77 @@ "md_income_tax", "state_income_tax", ] +# 152(b)(1) amounts that the claimant filing exception restores. +EXCEPTION_RESTORES = [ + "ia_exemption_credit", + "ks_exemptions", + "ks_fstc", + "la_dependents_exemption", + "md_personal_exemptions_count", + "md_aged_dependent_exemption", + "federal_eitc_without_age_minimum", + "md_ctc", +] +# Rules on claimability or an actual claim, which the exception leaves alone. +EXCEPTION_NEUTRAL = [ + "ia_is_tax_exempt", + "md_poverty_line_credit_earned_income", +] @st.composite def couples(draw): + claimable = draw(st.sampled_from(CLAIM_PATTERNS)) + claimed = tuple(can_claim and draw(st.booleans()) for can_claim in claimable) return { "state": draw(st.sampled_from(STATES)), "adults": [draw(adults()), draw(adults())], "dependents": draw(st.lists(dependents(), max_size=2)), - "claimed": draw(st.sampled_from(CLAIM_PATTERNS)), + "claimed": claimed, + "claimable": claimable, + "exception": tuple( + not is_claimed and draw(st.booleans()) for is_claimed in claimed + ), } def _identities(sim, year): - claimed = _calc(sim, "head_or_spouse_is_dependent_elsewhere", year) > 0 + claimable = _calc(sim, "head_or_spouse_is_dependent_elsewhere", year) > 0 + no_dependents = ( + _calc( + sim, "head_or_spouse_is_dependent_elsewhere_without_filing_exception", year + ) + > 0 + ) every = _calc(sim, "every_filer_is_dependent_elsewhere", year) > 0 childless = _calc(sim, "eitc_child_count", year) == 0 for name in ["la_dependents_exemption", "md_aged_dependent_exemption", "md_ctc"]: - assert not _calc(sim, name, year)[claimed].any(), name + assert not _calc(sim, name, year)[no_dependents].any(), name pro_forma = _calc(sim, "federal_eitc_without_age_minimum", year) - assert not pro_forma[claimed & childless].any() + assert not pro_forma[no_dependents & childless].any() assert not _calc(sim, "is_eligible_md_poverty_line_credit", year)[every].any() # Each tax unit has its own household, in the same order. - md = np.asarray(sim.calculate("state_code_str", year)) == "MD" - nobody = md & ~claimed + state = np.asarray(sim.calculate("state_code_str", year)) + md, la = state == "MD", state == "LA" + # 5. Unchanged when nobody can be claimed. + nobody = ~claimable + np.testing.assert_array_equal( + _calc(sim, "md_personal_exemptions_count", year)[md & nobody], + _calc(sim, "tax_unit_size", year)[md & nobody], + ) np.testing.assert_allclose( - _calc(sim, "md_poverty_line_credit_earned_income", year)[nobody], - _calc(sim, "eitc_earned_income", year)[nobody], + _calc(sim, "md_poverty_line_credit_earned_income", year)[md & nobody], + _calc(sim, "eitc_earned_income", year)[md & nobody], atol=TOLERANCE, ) np.testing.assert_allclose( - _calc(sim, "md_poverty_line_credit_income_level", year)[nobody], - _calc(sim, "tax_unit_fpg", year)[nobody], + _calc(sim, "md_poverty_line_credit_income_level", year)[md & nobody], + _calc(sim, "tax_unit_fpg", year)[md & nobody], + atol=TOLERANCE, + ) + np.testing.assert_allclose( + _calc(sim, "la_dependents_exemption", year)[la & nobody], + 1_000 * _calc(sim, "tax_unit_dependents", year)[la & nobody], atol=TOLERANCE, ) # 4. Differential: the federal credit before take-up and filing. @@ -126,7 +173,7 @@ def _identities(sim, year): @settings( - max_examples=2, + max_examples=3, deadline=None, derandomize=True, suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large], @@ -141,3 +188,33 @@ def test_ia_ks_ky_la_md_claimable_filer_rules_seeded_population(year): units = _seeded_couples(STATES, per_state=3) + _crafted_cases(STATES) check_swap(units, year, OUTPUTS, _identities) check_monotone(units, year, MONOTONE, _identities) + + +@pytest.mark.parametrize("year", [2022, 2025]) +def test_ia_ks_ky_la_md_filing_exception_scope(year): + # Each unit runs four times with nobody actually claimed: claimable + # without the exception (both labellings), then with it. + units = [ + unit + for unit in _seeded_couples(STATES, per_state=3) + _crafted_cases(STATES) + if any(unit["claimed"]) + ] + sim = Simulation(situation=_situation(units, year, _exception_variants)) + for name in EXCEPTION_RESTORES + EXCEPTION_NEUTRAL: + copies = _calc(sim, name, year).reshape(-1, 4) + np.testing.assert_allclose( + copies[:, 0::2], copies[:, 1::2], atol=TOLERANCE, rtol=0 + ) + without, with_exception = copies[:, :2], copies[:, 2:] + if name in EXCEPTION_NEUTRAL: + np.testing.assert_allclose( + with_exception, + without, + atol=TOLERANCE, + rtol=0, + err_msg=f"The filing exception changes {name}", + ) + else: + assert not (with_exception < without - TOLERANCE).any(), ( + f"The filing exception lowers {name}" + ) diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml index 10b114c96eb..b8272632bc7 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_exemption_credit.yaml @@ -183,3 +183,90 @@ output: # $80 + $40 for the child = $120. ia_exemption_credit: 120 + + +- name: 2024 single filer whose claimant meets the filing exception gets the dependent credit + period: 2024 + input: + people: + person_a: + age: 30 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: IA + output: + # The would-be claimant meets the filing exception (Publication 501, + # Dependent Taxpayer Test), so the return keeps its dependents. + # $40 personal + $40 dependent. + ia_exemption_credit: 80 + +- name: 2024 joint return whose claimable spouse's claimant meets the filing exception gets the dependent credit (the claimable spouse is the head) + period: 2024 + input: + people: + person_a: + age: 30 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: IA + output: + # The would-be claimant meets the filing exception (Publication 501, + # Dependent Taxpayer Test), so the return keeps its dependents. + # $80 + $40 = $120. + ia_exemption_credit: 120 + +- name: 2024 joint return whose claimable spouse's claimant meets the filing exception gets the dependent credit (the claimable spouse is the spouse) + period: 2024 + input: + people: + person_b: + age: 30 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: IA + output: + ia_exemption_credit: 120 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml index 1034f2e50d7..a167d3ffe96 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_income_tax_before_refundable_credits.yaml @@ -205,3 +205,32 @@ state_code: IA output: ia_income_tax_before_refundable_credits: 700 + + +- name: 2022 single filer who can be claimed but is not claimed has tax reduced to income above $9,000 + period: 2022 + input: + people: + person_a: + age: 30 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + ia_income_tax_before_credits: 700 + ia_non_refundable_credits: 0 + ia_is_tax_exempt: false + ia_modified_income: 9500 + households: + household: + members: [person_a] + state_code: IA + output: + # The filer can be claimed but nobody claims them; this rule turns on + # being claimed. + # min($700, $9,500 - $9,000) = $500. + ia_income_tax_before_refundable_credits: 500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml index 9d00a475797..32a371bd840 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ia/tax/income/ia_is_tax_exempt.yaml @@ -288,3 +288,86 @@ output: # $4,000 + $15,750 standard deduction added back = $19,750 > $9,000. ia_is_tax_exempt: false + + +- name: 2022 single filer who can be claimed but is not claimed keeps the ordinary exemption + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 6000 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: IA + output: + # The filer can be claimed but nobody claims them; this rule turns on + # being claimed. + # $6,000 <= $9,000 single limit. + ia_is_tax_exempt: true + +- name: 2022 joint return with one spouse who can be claimed but is not claimed is exempt (the claimable spouse is the head) + period: 2022 + input: + people: + person_a: + age: 30 + ia_net_income: 3000 + 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: 30 + ia_net_income: 3000 + 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: IA + output: + # The filer can be claimed but nobody claims them; this rule turns on + # being claimed. + # $3,000 + $3,000 = $6,000 <= $13,500. + ia_is_tax_exempt: true + +- name: 2022 joint return with one spouse who can be claimed but is not claimed is exempt (the claimable spouse is the spouse) + period: 2022 + input: + people: + person_b: + age: 30 + ia_net_income: 3000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 30 + ia_net_income: 3000 + 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: IA + output: + ia_is_tax_exempt: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml index be183a06f9c..cc2c1332922 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_count_exemptions.yaml @@ -139,3 +139,93 @@ # 2 + 1 child = 3 exemptions x $2,250 = $6,750. ks_count_exemptions: 3 ks_exemptions: 6750 + + +- name: 2022 single filer who can be claimed but is not claimed keeps the own exemption but no dependent + period: 2022 + input: + people: + person_a: + age: 20 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: KS + output: + # The filer can be claimed but nobody claims them; this rule turns on + # being claimed. + # The child is not the filer's dependent (IRC 152(b)(1)): 1 x $2,250. + ks_count_exemptions: 1 + ks_exemptions: 2250 + +- name: 2022 joint return with one spouse who can be claimed but is not claimed keeps both own exemptions but no dependent (the claimable spouse is the head) + period: 2022 + input: + people: + person_a: + age: 20 + 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: 20 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: KS + output: + # The filer can be claimed but nobody claims them; this rule turns on + # being claimed. + # No dependents (IRC 152(b)(1)): 2 x $2,250 = $4,500. + ks_count_exemptions: 2 + ks_exemptions: 4500 + +- name: 2022 joint return with one spouse who can be claimed but is not claimed keeps both own exemptions but no dependent (the claimable spouse is the spouse) + period: 2022 + input: + people: + person_b: + age: 20 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 20 + claimable_as_dependent_on_another_return: true + claimed_as_dependent_on_another_return: false + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: KS + output: + ks_count_exemptions: 2 + ks_exemptions: 4500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml index 1b8fddc1dd6..7e0dfa1daf6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ks/tax/income/exemptions/ks_exemptions.yaml @@ -188,3 +188,31 @@ output: # $18,320 + $2,320 = $20,640. ks_exemptions: 20640 + + +- name: 2024 single filer whose claimant meets the filing exception gets the dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 8 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: KS + output: + # The would-be claimant meets the filing exception (Publication 501, + # Dependent Taxpayer Test), so the return keeps its dependents. + # $9,160 + $2,320 = $11,480. + ks_exemptions: 11480 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml index 4edcc03dd03..f2b2136f23a 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.yaml @@ -180,3 +180,31 @@ output: # 1 dependent x $1,000. la_dependents_exemption: 1000 + + +- name: 2024 single filer whose claimant meets the filing exception gets the dependent exemption + period: 2024 + input: + people: + person_a: + age: 20 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: LA + output: + # The would-be claimant meets the filing exception (Publication 501, + # Dependent Taxpayer Test), so the return keeps its dependents. + # 1 dependent x $1,000. + la_dependents_exemption: 1000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml index 479bdff52c7..e3442dc81a1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/ctc/md_ctc.yaml @@ -725,3 +725,33 @@ # One child under 6, AGI $1,000 <= $15,000: $500. md_ctc_eligible: true md_ctc: 500 + + +- name: 2025 single filer whose claimant meets the filing exception gets the child tax credit + period: 2025 + input: + people: + person_a: + age: 20 + employment_income: 1000 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # The would-be claimant meets the filing exception (Publication 501, + # Dependent Taxpayer Test), so the return keeps its dependents. + # One child under 6, AGI $1,000: $500. + md_ctc_eligible: true + md_ctc: 500 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml index 52987e5fa59..8ee69fb8f2f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/eitc/federal_eitc_without_age_minimum.yaml @@ -268,3 +268,28 @@ # $76.50; married refundable match .45 x $76.50 - $0 tax = $34.425. federal_eitc_without_age_minimum: 76.5 md_married_or_has_child_refundable_eitc: 34.425 + + +- name: 2025 single filer whose claimant meets the filing exception gets the pro forma federal EITC + period: 2025 + input: + people: + person_a: + age: 21 + employment_income: 1000 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + households: + household: + members: [person_a] + state_code: MD + output: + # Publication 596: the childless EITC is allowed when the would-be + # claimant meets the filing exception. $1,000 x .0765 = $76.50. + federal_eitc_without_age_minimum: 76.5 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml index f91325b0b1d..650852ce7a9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/credits/poverty_line/md_poverty_line_credit_earned_income.yaml @@ -534,3 +534,32 @@ md_poverty_line_credit_potential: 50 md_local_poverty_line_credit: 32 md_poverty_line_credit_income_level: 21150 + + +- name: 2025 single filer whose claimant meets the filing exception still gets no poverty line credit + period: 2025 + input: + people: + person_a: + age: 30 + employment_income: 1000 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + tax_units: + tax_unit: + members: [person_a] + filing_status: SINGLE + md_income_tax_before_credits: 200 + md_married_or_has_child_non_refundable_eitc: 0 + households: + household: + members: [person_a] + state_code: MD + output: + # Filing status 6 covers any person who "can be claimed"; the filing + # exception does not change that. + md_poverty_line_credit_earned_income: 0 + is_eligible_md_poverty_line_credit: false + md_poverty_line_credit_potential: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.yaml b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.yaml new file mode 100644 index 00000000000..f932316e09f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/md/tax/income/exemptions/md_personal_exemptions_count.yaml @@ -0,0 +1,239 @@ + + +- name: 2025 single filer who can be claimed has no Maryland exemptions + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # Filing status 6: "You do not get an exemption for yourself"; IRC + # 152(b)(1) leaves no dependents. + md_personal_exemptions_count: 0 + +- name: 2025 single filer whose claimant meets the filing exception has an exemption for the child only + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, child] + filing_status: SINGLE + households: + household: + members: [person_a, child] + state_code: MD + output: + # Still filing status 6 ("can be claimed"), so no own exemption; the + # filing exception keeps the dependent: 1 x $3,200. + md_personal_exemptions_count: 1 + md_total_personal_exemptions: 3200 + +- name: 2025 joint return with one claimable spouse counts only the other spouse (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # Each spouse claims their own exemption on a separate Maryland + # return; the federal return has no dependents. + md_personal_exemptions_count: 1 + +- name: 2025 joint return with one claimable spouse counts only the other spouse (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: MD + output: + md_personal_exemptions_count: 1 + +- name: 2025 joint return whose claimable spouse's claimant meets the filing exception counts the other spouse and the child (the claimable spouse is the head) + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # The would-be claimant meets the filing exception (Publication 501, + # Dependent Taxpayer Test), so the return keeps its dependents. + # 1 own + 1 dependent = 2 x $3,200. + md_personal_exemptions_count: 2 + md_total_personal_exemptions: 6400 + +- name: 2025 joint return whose claimable spouse's claimant meets the filing exception counts the other spouse and the child (the claimable spouse is the spouse) + period: 2025 + input: + people: + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_a: + age: 23 + employment_income: 1000 + claimable_as_dependent_on_another_return: true + dependent_claimant_filing_exception: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_b, person_a, child] + filing_status: JOINT + households: + household: + members: [person_b, person_a, child] + state_code: MD + output: + md_personal_exemptions_count: 2 + md_total_personal_exemptions: 6400 + +- name: 2025 joint return with both spouses claimable has no Maryland exemptions + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 23 + employment_income: 1000 + claimed_as_dependent_on_another_return: true + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + md_personal_exemptions_count: 0 + +- name: 2025 joint return with no claimable spouse counts every member + period: 2025 + input: + people: + person_a: + age: 23 + employment_income: 1000 + is_tax_unit_head: true + is_tax_unit_spouse: false + person_b: + age: 23 + employment_income: 1000 + is_tax_unit_head: false + is_tax_unit_spouse: true + child: + age: 4 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person_a, person_b, child] + filing_status: JOINT + households: + household: + members: [person_a, person_b, child] + state_code: MD + output: + # 2 filers + 1 child. + md_personal_exemptions_count: 3 diff --git a/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py b/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py index d089f5d6997..3d19a8d7851 100644 --- a/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py +++ b/policyengine_us/variables/gov/states/ia/tax/income/ia_is_tax_exempt.py @@ -8,7 +8,7 @@ class ia_is_tax_exempt(Variable): definition_period = YEAR reference = ( "https://revenue.iowa.gov/sites/default/files/2022-01/IA1040%2841-001%29.pdf", - "https://revenue.iowa.gov/media/2650/download?inline#page=37", + "https://revenue.iowa.gov/media/2650/download?inline#page=38", "https://revenue.iowa.gov/sites/default/files/2023-01/2022IA1040%2841001%29.pdf", "https://revenue.iowa.gov/media/2721/download?inline#page=37", "https://revenue.iowa.gov/media/2811/download?inline#page=12", diff --git a/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py b/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py index 19d6b430d18..87e5c0b34b4 100644 --- a/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py +++ b/policyengine_us/variables/gov/states/la/tax/income/exemptions/personal/la_dependents_exemption.py @@ -9,6 +9,7 @@ class la_dependents_exemption(Variable): "https://dam.ldr.la.gov/taxforms/6935(11_02)F.pdf#page=1", "https://dam.ldr.la.gov/taxforms/IT540iWEB(2022)D1.pdf#page=2", "https://dam.ldr.la.gov/taxforms/IT540i(2021)%20Instructions.pdf#page=3", + "https://dam.ldr.la.gov/taxforms/IT540i%20WEB(2023)%20INSTRUCTIONS.pdf#page=3", "https://dam.ldr.la.gov/taxforms/IT540i%20WEB%20(2024)D18%20INSTRUCTIONS.pdf#page=3", ] # Even though the tax computation worksheet refers "dependent exemption" as credits, the instructions for