Skip to content

Commit 593e2d9

Browse files
Merge pull request #7428 from DTrim99/fix-ny-a06774-circular-dependency
Fix circular dependency in NY A06774 Enhanced CDCC reform
2 parents 52abebe + 5d41b47 commit 593e2d9

3 files changed

Lines changed: 188 additions & 3 deletions

File tree

changelog_entry.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- bump: patch
2+
changes:
3+
fixed:
4+
- Fix circular dependency in NY A06774 Enhanced CDCC reform by using cdcc_potential
5+
instead of cdcc, which avoids the income_tax_before_credits dependency cycle.

policyengine_us/reforms/states/ny/a06774/ny_a06774_enhanced_cdcc.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ def formula(tax_unit, period, parameters):
2727
p = parameters(period).gov.contrib.states.ny.a06774
2828
ny_agi = tax_unit("ny_agi", period)
2929
income_threshold = p.income_threshold
30-
# Calculate the enhanced credit (110% of federal CDCC)
31-
federal_cdcc = tax_unit("cdcc", period)
32-
enhanced_cdcc = federal_cdcc * p.match
30+
# Calculate the enhanced credit (110% of federal CDCC potential)
31+
# Use cdcc_potential instead of cdcc to avoid circular dependency
32+
# (cdcc depends on cdcc_credit_limit which depends on income_tax_before_credits)
33+
federal_cdcc_potential = tax_unit("cdcc_potential", period)
34+
enhanced_cdcc = federal_cdcc_potential * p.match
3335

3436
# Calculate the standard NY CDCC
3537
cdcc_max = tax_unit("ny_cdcc_max", period)

policyengine_us/tests/policy/contrib/states/ny/a06774/ny_a06774_enhanced_cdcc.yaml

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,181 @@
139139
state_code: NY
140140
output:
141141
ny_cdcc: 0
142+
143+
# Married filing jointly test - verifies reform works across filing statuses
144+
- name: Enhanced CDCC - married filing jointly with two earners
145+
period: 2025
146+
reforms: policyengine_us.reforms.states.ny.a06774.ny_a06774_enhanced_cdcc.ny_a06774_enhanced_cdcc
147+
input:
148+
gov.contrib.states.ny.a06774.in_effect: true
149+
people:
150+
person1:
151+
age: 35
152+
is_tax_unit_head: true
153+
employment_income: 25_000
154+
person2:
155+
age: 33
156+
is_tax_unit_spouse: true
157+
employment_income: 20_000
158+
child1:
159+
age: 4
160+
is_tax_unit_dependent: true
161+
tax_units:
162+
tax_unit:
163+
members: [person1, person2, child1]
164+
tax_unit_childcare_expenses: 3_000
165+
households:
166+
household:
167+
members: [person1, person2, child1]
168+
state_code: NY
169+
output:
170+
# Combined income = $45,000, below $50k threshold
171+
# Federal CDCC: $3,000 * 21% = $630
172+
# (rate is 21% at AGI $45k: 35% - (ceil((45000-15000)/2000) * 1%) = 35% - 15% = 20%)
173+
# Actually at $45k: excess = $45,000 - $15,000 = $30,000
174+
# increments = ceil(30000/2000) = 15
175+
# rate = 35% - 15% = 20%
176+
# cdcc_potential = $3,000 * 20% = $600
177+
# Enhanced: $600 * 1.1 = $660
178+
ny_cdcc: 660
179+
180+
# Test verifying cdcc_potential intermediate value is correctly used
181+
# This test explicitly checks the calculation chain
182+
- name: Enhanced CDCC - verify cdcc_potential calculation
183+
period: 2025
184+
reforms: policyengine_us.reforms.states.ny.a06774.ny_a06774_enhanced_cdcc.ny_a06774_enhanced_cdcc
185+
input:
186+
gov.contrib.states.ny.a06774.in_effect: true
187+
people:
188+
person1:
189+
age: 35
190+
is_tax_unit_head: true
191+
employment_income: 30_000
192+
child1:
193+
age: 5
194+
is_tax_unit_dependent: true
195+
tax_units:
196+
tax_unit:
197+
members: [person1, child1]
198+
tax_unit_childcare_expenses: 3_000
199+
households:
200+
household:
201+
members: [person1, child1]
202+
state_code: NY
203+
output:
204+
# At AGI $30,000:
205+
# excess = $30,000 - $15,000 = $15,000
206+
# increments = ceil(15000/2000) = 8
207+
# rate = 35% - 8% = 27%
208+
# cdcc_relevant_expenses = min($3,000, $3,000 one-child limit, $30,000 earned) = $3,000
209+
# cdcc_potential = $3,000 * 27% = $810
210+
cdcc_potential: 810
211+
# Enhanced NY CDCC = $810 * 1.1 = $891
212+
ny_cdcc: 891
213+
214+
# Test with maximum childcare expenses to stress test the fix
215+
# High expenses that would interact with tax calculations if using cdcc instead of cdcc_potential
216+
- name: Enhanced CDCC - maximum expenses stress test (verifies no circular dependency)
217+
period: 2025
218+
reforms: policyengine_us.reforms.states.ny.a06774.ny_a06774_enhanced_cdcc.ny_a06774_enhanced_cdcc
219+
input:
220+
gov.contrib.states.ny.a06774.in_effect: true
221+
people:
222+
person1:
223+
age: 40
224+
is_tax_unit_head: true
225+
employment_income: 35_000
226+
child1:
227+
age: 3
228+
is_tax_unit_dependent: true
229+
child2:
230+
age: 5
231+
is_tax_unit_dependent: true
232+
tax_units:
233+
tax_unit:
234+
members: [person1, child1, child2]
235+
# Maximum allowed childcare expense for 2 children is $6,000
236+
tax_unit_childcare_expenses: 10_000
237+
households:
238+
household:
239+
members: [person1, child1, child2]
240+
state_code: NY
241+
output:
242+
# Expenses capped at $6,000 (two-child limit)
243+
# At AGI $35,000:
244+
# excess = $35,000 - $15,000 = $20,000
245+
# increments = ceil(20000/2000) = 10
246+
# rate = 35% - 10% = 25%
247+
# cdcc_relevant_expenses = min($10,000, $6,000) = $6,000
248+
# cdcc_potential = $6,000 * 25% = $1,500
249+
cdcc_potential: 1_500
250+
# Enhanced NY CDCC = $1,500 * 1.1 = $1,650
251+
ny_cdcc: 1_650
252+
253+
# Test at income boundary just above threshold - verifies fallback to standard NY CDCC
254+
- name: Enhanced CDCC - income $50,001 just above threshold uses standard formula
255+
period: 2025
256+
absolute_error_margin: 1
257+
reforms: policyengine_us.reforms.states.ny.a06774.ny_a06774_enhanced_cdcc.ny_a06774_enhanced_cdcc
258+
input:
259+
gov.contrib.states.ny.a06774.in_effect: true
260+
people:
261+
person1:
262+
age: 35
263+
is_tax_unit_head: true
264+
employment_income: 50_001
265+
child1:
266+
age: 5
267+
is_tax_unit_dependent: true
268+
tax_units:
269+
tax_unit:
270+
members: [person1, child1]
271+
tax_unit_childcare_expenses: 3_000
272+
households:
273+
household:
274+
members: [person1, child1]
275+
state_code: NY
276+
output:
277+
# Income just above $50,000 threshold
278+
# Uses standard NY CDCC formula instead of enhanced
279+
# Federal rate at $50,001 AGI: 20% (floor rate)
280+
# cdcc_potential = $3,000 * 20% = $600
281+
cdcc_potential: 600
282+
# Standard NY CDCC applies NY rate multiplier
283+
# Since income > threshold, ny_cdcc uses standard formula
284+
# Standard calculation: min(cdcc_max, expenses * ny_rate * federal_rate)
285+
# At $50,001 AGI, NY rate is approximately 116.83%
286+
# Standard NY CDCC = min($3,000, $3,000 * 1.1683 * 0.20) = $700.88
287+
ny_cdcc: 701
288+
289+
# Low income test with high CDCC rate - verifies fix handles high rate cases
290+
- name: Enhanced CDCC - low income gets maximum CDCC rate
291+
period: 2025
292+
reforms: policyengine_us.reforms.states.ny.a06774.ny_a06774_enhanced_cdcc.ny_a06774_enhanced_cdcc
293+
input:
294+
gov.contrib.states.ny.a06774.in_effect: true
295+
people:
296+
person1:
297+
age: 28
298+
is_tax_unit_head: true
299+
employment_income: 15_000
300+
child1:
301+
age: 2
302+
is_tax_unit_dependent: true
303+
tax_units:
304+
tax_unit:
305+
members: [person1, child1]
306+
tax_unit_childcare_expenses: 3_000
307+
households:
308+
household:
309+
members: [person1, child1]
310+
state_code: NY
311+
output:
312+
# At AGI $15,000 (at phase-out start):
313+
# excess = $15,000 - $15,000 = $0
314+
# increments = 0
315+
# rate = 35% - 0% = 35% (maximum rate)
316+
# cdcc_potential = $3,000 * 35% = $1,050
317+
cdcc_potential: 1_050
318+
# Enhanced NY CDCC = $1,050 * 1.1 = $1,155
319+
ny_cdcc: 1_155

0 commit comments

Comments
 (0)