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/il-sb3567.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add an Illinois SB3567 (104th General Assembly) contributed reform, opt-in via `gov.contrib.states.il.sb3567.in_effect`, that boosts the child tax credit for low-AGI filers.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
description: Illinois SB3567 modifies the child tax credit formula and makes the credit nonrefundable if this is true.

values:
0000-01-01: false

metadata:
unit: bool
period: year
label: Illinois SB3567 child tax credit reform in effect
reference:
- title: Illinois SB3567 (104th General Assembly) full text
href: https://ilga.gov/Legislation/BillStatus/FullText?DocNum=3567&DocTypeID=SB&GAID=18&LegId=166617&Print=1&SessionID=114
5 changes: 5 additions & 0 deletions policyengine_us/reforms/reforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@
from .states.id.s1450 import (
create_id_s1450_reform,
)
from .states.il.sb3567 import (
create_il_sb3567_reform,
)
from .states.ky.eitc import (
create_ky_eitc_reform,
)
Expand Down Expand Up @@ -440,6 +443,7 @@ def create_structural_reforms_from_parameters(parameters, period):
ga_eitc = create_ga_eitc_reform(parameters, period)
id_eitc = create_id_eitc_reform(parameters, period)
id_s1450 = create_id_s1450_reform(parameters, period)
il_sb3567 = create_il_sb3567_reform(parameters, period)
ky_eitc = create_ky_eitc_reform(parameters, period)
ms_eitc = create_ms_eitc_reform(parameters, period)
nd_eitc = create_nd_eitc_reform(parameters, period)
Expand Down Expand Up @@ -553,6 +557,7 @@ def create_structural_reforms_from_parameters(parameters, period):
ga_eitc,
id_eitc,
id_s1450,
il_sb3567,
ky_eitc,
ms_eitc,
nd_eitc,
Expand Down
1 change: 1 addition & 0 deletions policyengine_us/reforms/states/il/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .sb3567 import create_il_sb3567_reform
5 changes: 5 additions & 0 deletions policyengine_us/reforms/states/il/sb3567/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .il_sb3567_reform import (
create_il_sb3567,
create_il_sb3567_reform,
il_sb3567,
)
78 changes: 78 additions & 0 deletions policyengine_us/reforms/states/il/sb3567/il_sb3567_reform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from policyengine_core.periods import period as period_
from policyengine_us.model_api import *


def create_il_sb3567() -> Reform:
class il_ctc(Variable):
value_type = float
entity = TaxUnit
label = "Illinois Child Tax Credit"
unit = USD
definition_period = YEAR
reference = (
"https://ilga.gov/Legislation/BillStatus/FullText?DocNum=3567&DocTypeID=SB&GAID=18&LegId=166617&Print=1&SessionID=114",
"https://www.ilga.gov/legislation/ilcs/fulltext.asp?DocName=003500050K244",
)
defined_for = StateCode.IL

def formula(tax_unit, period, parameters):
p = parameters(period).gov.states.il.tax.income.credits
ctc = p.ctc
person = tax_unit.members
age = person("age", period)
age_eligible_child = age < ctc.age_limit
federal_ctc_eligible_child = person("ctc_qualifying_child", period)
eligible_child = age_eligible_child & federal_ctc_eligible_child
eligible_child_present = tax_unit.any(eligible_child)

actual_credit = tax_unit("il_eitc", period) * ctc.rate

# SB3567 keys the maximum credit amount to the dependent count.
# The bill cites IRC § 152, but here we use the tax unit's child
# dependent count, capped at 3 to match the federal EITC schedule.
dependent_count = min_(tax_unit("tax_unit_child_dependents", period), 3)
federal_eitc = parameters(period).gov.irs.credits.eitc
federal_maximum = federal_eitc.max.calc(dependent_count)
phase_in_rate = federal_eitc.phase_in_rate.calc(dependent_count)

# The bill's "income threshold to qualify for the maximum federal
# EITC" is the end of the phase-in range (start of the plateau).
max_federal_eitc_threshold = federal_maximum / phase_in_rate
max_credit = federal_maximum * p.eitc.match * ctc.rate

agi = tax_unit("adjusted_gross_income", period)
return eligible_child_present * where(
agi <= max_federal_eitc_threshold,
max_credit,
actual_credit,
)

class reform(Reform):
def apply(self):
self.update_variable(il_ctc)

return reform


def create_il_sb3567_reform(parameters, period, bypass: bool = False):
if bypass:
return create_il_sb3567()

p = parameters.gov.contrib.states.il.sb3567

reform_active = False
current_period = period_(period)

for _ in range(5):
if p(current_period).in_effect:
reform_active = True
break
current_period = current_period.offset(1, "year")

if reform_active:
return create_il_sb3567()
else:
return None


il_sb3567 = create_il_sb3567_reform(None, None, bypass=True)
256 changes: 256 additions & 0 deletions policyengine_us/tests/policy/contrib/states/il/sb3567/il_sb3567.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
- name: SB3567 boosts phase-in filers to the maximum one-child credit
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 30
child:
age: 8
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child]
adjusted_gross_income: 12_000
il_eitc: 200
households:
household:
members: [filer, child]
state_code: IL
output:
il_ctc: 346.24

- name: SB3567 uses the three-child EITC maximum for larger dependent counts
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 32
child1:
age: 9
ctc_qualifying_child: true
is_tax_unit_dependent: true
child2:
age: 7
is_tax_unit_dependent: true
child3:
age: 5
is_tax_unit_dependent: true
child4:
age: 3
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child1, child2, child3, child4]
adjusted_gross_income: 15_000
il_eitc: 400
households:
household:
members: [filer, child1, child2, child3, child4]
state_code: IL
output:
il_ctc: 643.68

- name: SB3567 keeps plateau filers on the actual Illinois EITC amount
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 33
child:
age: 6
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child]
adjusted_gross_income: 18_000
il_eitc: 865.6
households:
household:
members: [filer, child]
state_code: IL
output:
il_ctc: 346.24

- name: SB3567 keeps phase-out filers on 40 percent of actual Illinois EITC
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 34
child:
age: 4
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child]
adjusted_gross_income: 30_000
il_eitc: 300
households:
household:
members: [filer, child]
state_code: IL
output:
il_ctc: 120

- name: SB3567 keeps the age-under-12 eligibility gate
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 35
child:
age: 12
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child]
adjusted_gross_income: 10_000
il_eitc: 200
households:
household:
members: [filer, child]
state_code: IL
output:
il_ctc: 0

- name: SB3567 keeps the Illinois CTC refundable when EITC is zero
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 36
child:
age: 5
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child]
adjusted_gross_income: 10_000
il_eitc: 0
il_income_tax_before_non_refundable_credits: 0
il_property_tax_credit: 0
il_k12_education_expense_credit: 0
il_pass_through_withholding: 0
il_pass_through_entity_tax_credit: 0
il_use_tax: 0
households:
household:
members: [filer, child]
state_code: IL
# AGI below 1-child phase-in threshold so boost applies; il_ctc stays
# refundable per existing 35 ILCS 5/244(b), so it flows through to
# il_refundable_credits even with no tax liability.
output:
il_ctc: 346.24
il_refundable_credits: 346.24
il_income_tax: -346.24

- name: Non-Illinois filers do not receive the reform CTC
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 30
child:
age: 8
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child]
adjusted_gross_income: 12_000
il_eitc: 200
households:
household:
members: [filer, child]
state_code: CA
output:
il_ctc: 0

- name: SB3567 boosts a two-child phase-in filer to the two-child maximum
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 31
child1:
age: 7
ctc_qualifying_child: true
is_tax_unit_dependent: true
child2:
age: 5
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child1, child2]
adjusted_gross_income: 14_000
il_eitc: 250
households:
household:
members: [filer, child1, child2]
state_code: IL
# 2025 federal EITC max for 2 children = 7,152; IL match = 0.20; CTC rate = 0.4
# Boosted credit = 7,152 * 0.20 * 0.4 = 572.16
output:
il_ctc: 572.16

- name: SB3567 applies the boost at the two-child phase-in threshold
period: 2025
absolute_error_margin: 0.01
reforms: policyengine_us.reforms.states.il.sb3567.il_sb3567
input:
gov.contrib.states.il.sb3567.in_effect: true
people:
filer:
age: 32
child1:
age: 6
ctc_qualifying_child: true
is_tax_unit_dependent: true
child2:
age: 4
ctc_qualifying_child: true
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [filer, child1, child2]
# Phase-in threshold for 2 children = 7,152 / 0.40 = 17,880
adjusted_gross_income: 17_880
il_eitc: 1_430.4
households:
household:
members: [filer, child1, child2]
state_code: IL
# AGI <= threshold so boost applies; max credit = 572.16
output:
il_ctc: 572.16
Loading