Skip to content
Open
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/ctc-qualifying-children-filer-id.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Exclude children whose filer fails the Child Tax Credit identification requirements from ctc_qualifying_children: from 2025 the filer social security number rule (IRC 24(h)(7)(A)(i)), and in every year the taxpayer identification number rule (IRC 24(e)(2)). This removes the children of ITIN filers from the North Carolina child deduction from 2025, and removes the children of filers with no TIN from the North Carolina child deduction and credit for children (2015-2017), the Utah child tax credit, the Maine fairness credits, and the New York Empire State child credit $100 minimum under its pre-2025 and post-2027 rules. The Idaho Child Tax Credit and the CARES recovery rebate keep counting these children under the IRC 24(c) definition, and the Utah child tax credit and Maine fairness credits keep counting the children of ITIN filers, who get the credit for other dependents.
17 changes: 15 additions & 2 deletions policyengine_us/reforms/congress/afa/afa_other_dependent_credit.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,13 @@ def formula(tax_unit, period, parameters):
if ctc.refundable.fully_refundable:
reduction = tax_unit("ctc_lower_phase_out", period)
p = parameters(period).gov.contrib.congress.afa.ctc.phase_out
qualifying_children = tax_unit("ctc_qualifying_children", period)
# Proposed section 24A has no filer SSN rule, so the floor
# counts children without the federal filer test.
qualifying_children = add(
tax_unit,
period,
["ctc_qualifying_child_ignoring_filer_identification"],
)
lower_floor = p.lower_floor * qualifying_children
capped_credit = min_(lower_floor, maximum_amount)
reduced_max_amount_lower = max_(
Expand Down Expand Up @@ -186,7 +192,14 @@ def formula(tax_unit, period, parameters):
)
reduction = tax_unit("ctc_lower_phase_out", period)
p = parameters(period).gov.contrib.congress.afa.ctc.phase_out
qualifying_children = tax_unit("ctc_qualifying_children", period)
# Proposed section 24A has no filer SSN rule (only a timely
# taxpayer TIN, 24A(e)(2)), so the floor counts children without
# the federal filer test.
qualifying_children = add(
tax_unit,
period,
["ctc_qualifying_child_ignoring_filer_identification"],
)
lower_floor = p.lower_floor * qualifying_children
reduced_max_amount_lower = max_(lower_floor, maximum_amount - reduction)
higher_reduction = tax_unit("ctc_higher_phase_out", period)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ class american_worker_tax_rebate_child_amount(Variable):
"The tax rebate amount for children, under the American Worker Rebate Act."
)
definition_period = YEAR
defined_for = "ctc_qualifying_child"
# The bill counts "qualifying children (within the meaning of section
# 24(c))", so the CTC filer identification requirements do not apply;
# american_worker_tax_rebate_eligible applies the bill's own rules.
# The variable also applies the CTC child social security number rule
# and the IRC 152(b)(1) dependent-filer rule.
defined_for = "ctc_qualifying_child_ignoring_filer_identification"

adds = ["gov.contrib.congress.hawley.awra.amount.non_joint"]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,10 @@ class ctc_child_individual_maximum(Variable):
def formula(person, period, parameters):
age = person("age", period)
qualifying_child = person("ctc_qualifying_child", period)
filer_meets_child_ctc_id_requirements = person.tax_unit(
"filer_meets_child_ctc_identification_requirements", period
)
p = parameters(
period
).gov.contrib.congress.romney.family_security_act_2_0.ctc
return (
qualifying_child
* filer_meets_child_ctc_id_requirements
* p.base.calc(age)
)
return qualifying_child * p.base.calc(age)

class ctc_qualifying_children(Variable):
value_type = int
Expand Down
9 changes: 1 addition & 8 deletions policyengine_us/reforms/ctc/ctc_additional_bracket.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,8 @@ class ctc_child_individual_maximum(Variable):
def formula(person, period, parameters):
age = person("age", period)
qualifying_child = person("ctc_qualifying_child", period)
filer_meets_child_ctc_id_requirements = person.tax_unit(
"filer_meets_child_ctc_identification_requirements", period
)
p = parameters(period).gov.contrib.ctc.additional_bracket.amount
return (
qualifying_child
* filer_meets_child_ctc_id_requirements
* p.base.calc(age)
)
return qualifying_child * p.base.calc(age)

class ctc_refundable_maximum(Variable):
value_type = float
Expand Down
9 changes: 1 addition & 8 deletions policyengine_us/reforms/ctc/ctc_older_child_supplement.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,12 @@ class ctc_child_individual_maximum(Variable):
def formula(person, period, parameters):
age = person("age", period)
qualifying_child = person("ctc_qualifying_child", period)
filer_meets_child_ctc_id_requirements = person.tax_unit(
"filer_meets_child_ctc_identification_requirements", period
)
base_amount = parameters(period).gov.irs.credits.ctc.amount.base
base_amount = base_amount.calc(age)
oldest_child = person("child_index", period) == 1
p_ref = parameters(period).gov.contrib.ctc.oldest_child_supplement
oldest_child_supplement = oldest_child * p_ref.amount
return (
qualifying_child
* filer_meets_child_ctc_id_requirements
* (base_amount + oldest_child_supplement)
)
return qualifying_child * (base_amount + oldest_child_supplement)

class reform(Reform):
def apply(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ def formula(tax_unit, period, parameters):
else:
taxpayer_amount = 0

# Reuses the baseline `ctc_qualifying_children` variable so
# the same eligibility rules as the federal CTC apply (per
# IRC §24(c)). Hoisted so the per-other-dependent branch can
# reuse the same count.
# Reuses the baseline `ctc_qualifying_children` variable, the
# children for whom the federal CTC is allowed (IRC §24(c), (e)
# and (h)(7)); a child whose filer fails the filer
# identification test counts as an other dependent below.
# Hoisted so the per-other-dependent branch can reuse the same
# count.
ctc_count = tax_unit("ctc_qualifying_children", period)
if p.credit.use_ctc_dependent_credit:
ctc_dependent_amount = ctc_count * p.credit.per_ctc_dependent
Expand Down
4 changes: 2 additions & 2 deletions policyengine_us/reforms/states/id/ctc/id_ctc_reform.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class id_refundable_ctc(Variable):
def formula(tax_unit, period, parameters):
p = parameters(period).gov.contrib.states.id.ctc
# Potential is the revived (nonrefundable) Idaho CTC worksheet
# amount, ctc_qualifying_children * amount.
# amount, id_ctc_qualifying_children * amount.
potential = tax_unit("id_ctc", period)
ordered_credits = parameters(
period
Expand All @@ -50,7 +50,7 @@ def formula(tax_unit, period, parameters):
)
non_refundable = min_(potential, credit_limit)
unused_credit = max_(potential - non_refundable, 0)
eligible_children = tax_unit("ctc_qualifying_children", period)
eligible_children = tax_unit("id_ctc_qualifying_children", period)
refund_limit = p.refundable.amount * eligible_children
refundable_credit = min_(unused_credit, refund_limit)
# Only pay the refundable portion when the refundable option is on;
Expand Down
7 changes: 6 additions & 1 deletion policyengine_us/reforms/states/il/sb3567/il_sb3567_reform.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ def formula(tax_unit, period, parameters):
person = tax_unit.members
age = person("age", period)
age_eligible_child = age < ctc.age_limit
federal_ctc_eligible_child = person("ctc_qualifying_child", period)
# The Illinois credit builds on the Illinois EITC, which does not
# require the filer's social security number, so the federal CTC
# filer identification requirements are not applied here.
federal_ctc_eligible_child = person(
"ctc_qualifying_child_ignoring_filer_identification", period
)
eligible_child = age_eligible_child & federal_ctc_eligible_child
eligible_child_present = tax_unit.any(eligible_child)

Expand Down
46 changes: 35 additions & 11 deletions policyengine_us/reforms/states/mt/ctc/mt_ctc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,37 @@ def create_mt_ctc() -> Reform:
- Phase-out by filing status (same as newborn credit)
"""

class mt_ctc_qualifying_child(Variable):
value_type = bool
entity = Person
label = "Montana Child Tax Credit qualifying child"
definition_period = YEAR
defined_for = StateCode.MT

def formula(person, period, parameters):
# Children who qualify for a federal section 24 credit (0-16),
# plus 17-year-old dependents. As in HB268, a child whose filer
# fails the federal filer SSN rule gets the credit for other
# dependents (IRC 24(h)(4)(C)), so both groups need only a filer
# SSN or ITIN (IRC 24(e)(2)).
age = person("age", period)
is_ctc_child = person(
"ctc_qualifying_child_ignoring_filer_identification", period
)
is_17_dependent = (age == 17) & person("is_tax_unit_dependent", period)
filer_has_tin = person.tax_unit(
"filer_meets_ctc_identification_requirements", period
)
return (is_ctc_child | is_17_dependent) & filer_has_tin

class mt_ctc_qualifying_children(Variable):
value_type = int
entity = TaxUnit
label = "Montana Child Tax Credit qualifying children"
definition_period = YEAR
defined_for = StateCode.MT
adds = ["mt_ctc_qualifying_child"]

class mt_ctc(Variable):
value_type = float
entity = Person
Expand All @@ -25,10 +56,7 @@ def formula(person, period, parameters):
eligible = person.tax_unit("mt_ctc_eligible", period)
p = parameters(period).gov.contrib.states.mt.ctc
age = person("age", period)
# Include ctc_qualifying_child (0-16) plus 17-year-old dependents
is_ctc_child = person("ctc_qualifying_child", period)
is_17_dependent = (age == 17) & person("is_tax_unit_dependent", period)
is_qualifying = is_ctc_child | is_17_dependent
is_qualifying = person("mt_ctc_qualifying_child", period)
# Calculate credit amount based on age brackets
child_credit = p.amount.calc(age) * is_qualifying
credit_amount = person.tax_unit.sum(child_credit)
Expand All @@ -55,13 +83,7 @@ class mt_ctc_eligible(Variable):
def formula(tax_unit, period, parameters):
p = parameters(period).gov.contrib.states.mt.ctc
# Must have at least one qualifying child (0-17)
has_ctc_child = tax_unit("ctc_qualifying_children", period) > 0
person = tax_unit.members
age = person("age", period)
has_17_dependent = tax_unit.any(
(age == 17) & person("is_tax_unit_dependent", period)
)
has_qualifying_child = has_ctc_child | has_17_dependent
has_qualifying_child = tax_unit("mt_ctc_qualifying_children", period) > 0
# Earned income requirement is optional
earned_income_required = p.earned_income_requirement.in_effect
earned_income = tax_unit("tax_unit_earned_income", period)
Expand All @@ -83,6 +105,8 @@ def modify_parameters(parameters):

class reform(Reform):
def apply(self):
self.update_variable(mt_ctc_qualifying_child)
self.update_variable(mt_ctc_qualifying_children)
self.update_variable(mt_ctc)
self.update_variable(mt_ctc_eligible)
self.modify_parameters(modify_parameters)
Expand Down
38 changes: 36 additions & 2 deletions policyengine_us/reforms/states/mt/hb268/mt_hb268.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,38 @@


def create_mt_hb268() -> Reform:
class mt_hb268_qualifying_child(Variable):
value_type = bool
entity = Person
label = "Montana HB268 qualifying child"
definition_period = YEAR
reference = (
"https://leg.mt.gov/bills/2023/billpdf/HB0268.pdf",
"https://www.law.cornell.edu/uscode/text/26/24#h_4_C",
)
defined_for = StateCode.MT

def formula(person, period, parameters):
# HB 268 Section 1(1) requires a taxpayer "permitted a child tax
# credit under section 24 of the Internal Revenue Code". A child
# whose filer fails the federal filer SSN rule of IRC 24(h)(7)
# gets the credit for other dependents under IRC 24(h)(4)(C), so
# the child counts if the filer has an SSN or ITIN (IRC 24(e)(2)).
child = person("ctc_qualifying_child_ignoring_filer_identification", period)
filer_has_tin = person.tax_unit(
"filer_meets_ctc_identification_requirements", period
)
return child & filer_has_tin

class mt_hb268_qualifying_children(Variable):
value_type = int
entity = TaxUnit
label = "Montana HB268 qualifying children"
definition_period = YEAR
reference = "https://leg.mt.gov/bills/2023/billpdf/HB0268.pdf"
defined_for = StateCode.MT
adds = ["mt_hb268_qualifying_child"]

class mt_hb268(Variable):
value_type = float
entity = Person
Expand All @@ -17,7 +49,7 @@ def formula(person, period, parameters):
eligible = person.tax_unit("mt_hb268_eligible", period)
p = parameters(period).gov.contrib.states.mt.hb268
# Only count qualifying children
is_qualifying = person("ctc_qualifying_child", period)
is_qualifying = person("mt_hb268_qualifying_child", period)
age = person("age", period)
child_credit = p.amount.calc(age) * is_qualifying
credit_amount = person.tax_unit.sum(child_credit)
Expand All @@ -43,7 +75,7 @@ def formula(tax_unit, period, parameters):
p = parameters(period).gov.contrib.states.mt.hb268.income_limit
# Per HB 268 Section 1(1), taxpayer must be "permitted a child
# tax credit under section 24 of the Internal Revenue Code"
federal_ctc_eligible = tax_unit("ctc_qualifying_children", period) > 0
federal_ctc_eligible = tax_unit("mt_hb268_qualifying_children", period) > 0
agi = tax_unit("adjusted_gross_income", period)
agi_eligible = agi <= p.agi
# CTC limited to filers with investment income below a certain threshold
Expand Down Expand Up @@ -71,6 +103,8 @@ def modify_parameters(parameters):

class reform(Reform):
def apply(self):
self.update_variable(mt_hb268_qualifying_child)
self.update_variable(mt_hb268_qualifying_children)
self.update_variable(mt_hb268)
self.update_variable(mt_hb268_eligible)
self.modify_parameters(modify_parameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ def formula(tax_unit, period, parameters):
person = tax_unit.members
age = person("age", period)

# Post-2024 CTC rules (2025-2027)
qualifies_for_federal_ctc = person("ctc_qualifying_child", period)
qualifies = qualifies_for_federal_ctc & (age >= p.minimum_age)
# Post-2024 CTC rules (2025-2027). Use the baseline NY qualifying
# child (ny_ctc_post_2024_base), which allows ITIN holders and
# does not apply the federal filer SSN requirement.
qualifies = person("ny_escc_qualifying_child", period)

# Calculate base credit amount by age
credit_by_age = p.post_2024.amount.calc(age)
Expand Down
9 changes: 8 additions & 1 deletion policyengine_us/reforms/states/ut/ctc/ut_ctc_reform.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ class ut_ctc_eligible_children(Variable):
def formula(tax_unit, period, parameters):
p = parameters(period).gov.states.ut.tax.income.credits.ctc
person = tax_unit.members
ctc_eligible_child = person("ctc_qualifying_child", period)
# Same child test as the baseline ut_ctc_potential: any section
# 24 credit, including the credit for other dependents
# (IRC 24(h)(4)(C)), with a filer SSN or ITIN (IRC 24(e)(2)).
child = person("ctc_qualifying_child_ignoring_filer_identification", period)
filer_has_tin = person.tax_unit(
"filer_meets_ctc_identification_requirements", period
)
ctc_eligible_child = child & filer_has_tin
age = person("age", period)
ut_child_age_eligible = p.child_age_threshold.calc(age)
return tax_unit.sum(ctc_eligible_child & ut_child_age_eligible)
Expand Down
Loading
Loading