Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/fix-4007-cdcc-earned-income-deferrals.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Count only wages includible in gross income (after traditional 401(k)/403(b) deferrals and other pre-tax payroll deductions) in `adjusted_earnings`, the earned income limit of the child and dependent care credit, the IRC 129 dependent care exclusion and the state credits that inherit them, per IRC 32(c)(2)(A)(i) and Treas. Reg. 1.21-2(b)(3); California's credit limit, exclusion and AMT child exemption use California wages, which keep the payroll HSA contributions California taxes, net of any business loss, and New York's 2026 credit keeps counting the deferrals under Tax Law 606(c-2)(2)(C), also net of any business loss. California's credit now applies its own FTB 3506 expense, employer benefit and earned income limits in every year, not only 2021, and its AMT child exemption uses California's own minimum ($9,750 for 2025) instead of the federal amount.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ values:
# 55(d)(4), so the limitation stays off. The IRS still publishes the
# inflation-adjusted section 59(j) amount (child/amount.yaml), but Form 6251
# applies the normal exemption to every filer from 2018.
# ca_amt_exemption.py still reads child/amount.yaml; this federal switch
# does not change California's use of that amount.
# This federal switch does not change California: ca_amt_exemption.py reads
# California's own amount (gov.states.ca.tax.income.amt.exemption.child).
2018-01-01: false
metadata:
unit: bool
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
description: California limits the alternative minimum tax exemption of certain children under age 24 to their earned income plus this amount.
values:
2021-01-01: 7_850
2022-01-01: 8_300
2023-01-01: 8_950
2024-01-01: 9_450
2025-01-01: 9_750
metadata:
uprating: gov.states.ca.cpi
unit: currency-USD
period: year
label: California AMT minimum exemption amount for certain children
reference:
# California publishes its own amount, which differs from the federal
# IRC 59(j) amount (for example, $9,750 against $9,550 for 2025).
- title: 2021 Instructions for Schedule P (540), line 22, Exemption Worksheet line 7
href: https://www.ftb.ca.gov/forms/2021/2021-540-p-instructions.html
- title: 2022 Instructions for Schedule P (540), line 22, Exemption Worksheet line 7
href: https://www.ftb.ca.gov/forms/2022/2022-540-p-instructions.html
- title: 2023 Instructions for Schedule P (540), line 22, Exemption Worksheet line 7
href: https://www.ftb.ca.gov/forms/2023/2023-540-p-instructions.html
- title: 2024 Instructions for Schedule P (540), line 22, Exemption Worksheet line 7
href: https://www.ftb.ca.gov/forms/2024/2024-540-p-instructions.html
- title: 2025 Instructions for Schedule P (540), line 22, Exemption Worksheet line 7
href: https://www.ftb.ca.gov/forms/2025/2025-540-p-instructions.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
description: California uses this input for the state child/dependent care credit, based on year.
description: California uses this input for the state child/dependent care credit, based on year.
values:
# FTB 3506 applies the federal decimal (line 7) to California's own
# expense and earned income limits (lines 3-6), not to the federal credit.
# R&TC 17052.6 has done so since 2000, so the California computation
# applies in every year, including years before 2021.
2012-01-01:
- cdcc
2021-01-01:
- ca_federal_capped_cdcc
2022-01-01:
- cdcc
metadata:
unit: list
period: year
period: year
label: California child/dependent care credit input
reference:
reference:
- title: Details of Public Law 117-2, section 9631
href: https://www.ftb.ca.gov/about-ftb/data-reports-plans/Summary-of-Federal-Income-Tax-Changes/index.html#PL-117-2-9631
- title: 2025 FTB 3506, Part III, lines 3-10
href: https://www.ftb.ca.gov/forms/2025/2025-3506.pdf#page=1
- title: California Revenue and Taxation Code 17052.6(a)(1)
href: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=RTC&sectionNum=17052.6
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""Differential coverage of payroll exclusions across vectorized tax units.

Replacing gross wages and pre-tax deductions with the same W-2 box 1 wages
must leave federal EITC and ACTC earnings/credits unchanged. California must
retain taxable payroll HSA amounts, while gross earned income and the AMT
earnings cap must remain independent of payroll deductions. The paired runs
also remove dependents' wages to check that they cannot enter filer earnings.
must leave federal EITC and ACTC earnings/credits and the CDCC earned income
limit unchanged. California must retain taxable payroll HSA amounts, while
gross earned income must remain independent of payroll deductions. The paired
runs also remove dependents' wages to check that they cannot enter filer
earnings. (The AMT child earnings cap applies only before 2018, so
eitc_earned_income.yaml covers it.)
Additional California pairs retain payroll HSA deductions when substituting
California taxable wages, so YCTC must agree even with business losses.
"""
Expand Down Expand Up @@ -54,9 +56,6 @@ def _situations():
tax_units[f"unit_{i}"] = {
"members": members,
"takes_up_eitc": {YEAR: True},
# Force the existing cap to isolate its gross earnings dependency.
"amt_kiddie_tax_applies": {YEAR: True},
"amt_income": {YEAR: 200_000},
}
households[f"household_{i}"] = {
"members": members,
Expand Down Expand Up @@ -101,8 +100,6 @@ def _situations():
tax_units[f"unit_{i}"] = {
"members": members,
"takes_up_eitc": {YEAR: True},
"amt_kiddie_tax_applies": {YEAR: True},
"amt_income": {YEAR: 200_000},
}
households[f"household_{i}"] = {
"members": members,
Expand Down Expand Up @@ -156,8 +153,9 @@ def _run(situation):
"ca_eitc_earned_income",
"ca_yctc",
"earned_income",
"adjusted_earnings",
"amt_exemption",
"head_earned",
"spouse_earned",
"min_head_spouse_earned",
)
return {name: simulation.calculate(name, YEAR).copy() for name in outputs}

Expand All @@ -175,6 +173,9 @@ def test_payroll_exclusions_match_equivalent_taxable_compensation():
"ctc_phase_in_relevant_earnings",
"ctc_phase_in",
"filer_adjusted_earnings",
"head_earned",
"spouse_earned",
"min_head_spouse_earned",
):
np.testing.assert_allclose(
with_deductions[name],
Expand Down Expand Up @@ -214,7 +215,7 @@ def test_payroll_exclusions_match_equivalent_taxable_compensation():
)
assert np.all(with_deductions["ca_yctc"][yctc_pairs] > 0)

for name in ("earned_income", "adjusted_earnings", "amt_exemption"):
for name in ("earned_income",):
np.testing.assert_allclose(
with_deductions[name],
no_deductions[name],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,30 @@
cdcc_treated_as_unmarried: true
# min($6,000 benefits, $5,000 unmarried cap, $38,000 earnings) = $5,000.
dependent_care_assistance_exclusion: 5_000

# IRC 129(e)(2) gives earned income the IRC 32(c)(2) meaning, which counts
# wages only if includible in gross income. Form 2441 lines 18 and 19 figure
# it the same way as lines 4 and 5 (Form 1040 line 1z).
- name: Section 129(b) limit uses the lower earner's wages after a 401(k) deferral
period: 2025
input:
people:
head:
age: 40
employment_income: 50_000
dependent_care_employer_benefits: 5_000
spouse:
age: 38
employment_income: 4_000
traditional_401k_contributions_desired: 1_500
child:
age: 4
tax_units:
tax_unit:
members: [head, spouse, child]
filing_status: JOINT
output:
# Spouse: 4,000 wages - 1,500 deferral = 2,500.
min_head_spouse_earned: 2_500
# min(5,000 benefits, 5,000 joint cap, 2,500 earned income) = 2,500.
dependent_care_assistance_exclusion: 2_500
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,44 @@
count_cdcc_eligible: 2
cdcc_relevant_expenses: 6_000
cdcc: 1_200

# IRC 21(d)(1)(B) caps expenses at the lower-earning spouse's earned income,
# which counts wages only if includible in gross income (Treas. Reg.
# 1.21-2(b)(3); IRC 32(c)(2)(A)(i)). Form 2441 line 5 starts from Form 1040
# line 1z, which leaves out the spouse's traditional 401(k) deferral.
- name: Lower-earning spouse's traditional 401(k) deferral lowers the earned income limit
absolute_error_margin: 0.01
period: 2025
input:
people:
head:
age: 40
employment_income: 56_000
spouse:
age: 38
employment_income: 4_000
traditional_401k_contributions_desired: 1_000
child1:
age: 5
child2:
age: 3
tax_units:
tax_unit:
members: [head, spouse, child1, child2]
tax_unit_childcare_expenses: 9_103
households:
household:
members: [head, spouse, child1, child2]
state_code: TX
output:
# Spouse: 4,000 wages - 1,000 deferral = 3,000 taxable wages.
spouse_earned: 3_000
min_head_spouse_earned: 3_000
# min(9,103 expenses, 6,000 two-child limit, 3,000 earned income).
cdcc_relevant_expenses: 3_000
# AGI 56,000 + 3,000 = 59,000: 35% - 22 points
# (ceil((59,000 - 15,000) / 2,000)), floored at 20%.
# 3,000 * 20% = 600 (gross wages would give 4,000 * 20% = 800).
# Tax before credits: (59,000 - 31,500) taxable income
# -> 2,385 + 12% * 3,650 = 2,823, so the credit is not limited.
cdcc: 600
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@
eitc_earned_income: 8500
filer_adjusted_earnings: 8500

- name: AMT kiddie-tax exemption retains its pre-2018 gross earnings cap
- name: AMT kiddie-tax exemption caps at taxable earnings before 2018
period: 2017
absolute_error_margin: 0.01
input:
Expand All @@ -384,11 +384,14 @@
output:
filer_adjusted_earnings: 8000
# Ordinary exemption = 54,300 - 0.25 * (200,000 - 120,700) = 34,475.
# Historical cap uses gross earnings: 10,000 + 7,500 = 17,500.
# amt_exemption = min(34,475, 17,500) = 17,500.
amt_exemption: 17500
# IRC 59(j) earned income (IRC 911(d)(2)) counts amounts received; the
# deferral is not made available to the child (IRC 402(e)(3)), and the
# 2017 Form 8615 instructions use Form 1040 line 7 (taxable) wages.
# Historical cap: (10,000 - 2,000) + 7,500 = 15,500.
# amt_exemption = min(34,475, 15,500) = 15,500.
amt_exemption: 15500

- name: AMT kiddie-tax exemption has no gross earnings cap from 2018
- name: AMT kiddie-tax exemption has no earnings cap from 2018
period: 2022
absolute_error_margin: 0.01
input:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# IRC 32(c)(2)(A)(i) counts employee compensation only if it is includible in
# gross income. Treas. Reg. 1.21-2(b)(3) (CDCC) and IRC 129(e)(2) (dependent
# care exclusion) use that definition, and Form 2441 lines 4 and 5 start from
# Form 1040 line 1z (W-2 box 1).

- name: Traditional 401(k) deferral is left out of adjusted earnings
period: 2025
input:
employment_income: 4_000
traditional_401k_contributions_desired: 1_000
output:
# Gross earned income keeps the deferral: 4,000.
earned_income: 4_000
# W-2 box 1 wages: 4,000 - 1,000 = 3,000 (IRC 402(e)(3)).
irs_employment_income: 3_000
# 4,000 - (4,000 - 3,000) excluded wages - 0 SE adjustment = 3,000.
adjusted_earnings: 3_000

- name: Roth deferral stays in adjusted earnings, other pre-tax payroll deductions do not
period: 2025
input:
employment_income: 10_000
roth_401k_contributions_desired: 1_000
pre_tax_health_insurance_premiums: 500
health_savings_account_payroll_contributions: 1_000
output:
# Designated Roth contributions are includible in gross income
# (IRC 402A(a)(1)); the cafeteria-plan premium and HSA payroll
# contribution are not (IRC 106, 125).
# 10,000 - 500 - 1,000 = 8,500.
irs_employment_income: 8_500
adjusted_earnings: 8_500

- name: Deferral and self-employment income together
absolute_error_margin: 0.01
period: 2025
input:
employment_income: 4_000
traditional_401k_contributions_desired: 1_000
self_employment_income: 10_000
output:
# SE tax: 10,000 * 0.9235 * 0.153 = 1,412.96.
# Adjustment: 0.5 * 1,412.955 = 706.48.
# 4,000 + 10,000 - 1,000 excluded wages - 706.48 = 12,293.52.
adjusted_earnings: 12_293.52

- name: Self-employment loss larger than taxable wages floors adjusted earnings at zero
period: 2025
input:
employment_income: 2_000
traditional_401k_contributions_desired: 1_000
self_employment_income: -3_000
output:
# max(0, 2,000 - 3,000 - 1,000 excluded wages - 0) = 0.
adjusted_earnings: 0
Loading
Loading