Fix individual_eitc reform not responding to parameter changes#7780
Fix individual_eitc reform not responding to parameter changes#7780DTrim99 wants to merge 13 commits intoPolicyEngine:mainfrom
Conversation
- Restructure reform to check `in_effect` inside formula using `where()`, following modern reform patterns (like GA SB520, NJ budget reforms) - Rename `enabled` parameter to `in_effect` for consistency - Add `takes_up_eitc` multiplier that was missing from reform - Change AGI limit behavior: 0 now means "no limit" instead of "no EITC" - Update tests to set `in_effect: true` and use proper naming conventions - Add backward compatibility aliases for existing code Closes PolicyEngine#7779 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dc05f03 to
a8b2b85
Compare
Instead of using simulation branches (which had caching issues), compute the EITC formula directly for each spouse's individual earnings using the EITC parameters. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
722064f to
a727a7a
Compare
policyengine_us/parameters/gov/contrib/individual_eitc/agi_eitc_limit.yaml
Outdated
Show resolved
Hide resolved
- Remove baseline EITC code from winship.py (handled by in_effect parameter) - Fix agi_eitc_limit.yaml description format to single line Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Addressed review comments:
|
|
tests fail |
The formula needs to return baseline EITC when in_effect is false, since the reform replaces the eitc variable when loaded. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
policyengine_us/parameters/gov/contrib/individual_eitc/agi_eitc_limit.yaml
Outdated
Show resolved
Hide resolved
policyengine_us/parameters/gov/contrib/individual_eitc/in_effect.yaml
Outdated
Show resolved
Hide resolved
The test loaded the reform but set in_effect: false, expecting baseline behavior. This is not a supported use case - if baseline behavior is desired, the reform should not be loaded. Removes the baseline EITC logic from the reform formula per reviewer feedback. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bc20cc0 to
0438ad9
Compare
PR ReviewShould Address
To auto-fix issues: |
- Apply joint bonus only to joint filers using is_joint check - Update test case 5 to use income within EITC range (20k) to actually verify the no-limit behavior when agi_eitc_limit: 0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Addressed Review CommentsAll issues from the review have been fixed: 1. Joint bonus only applies to joint filers ✅Added is_joint = tax_unit("tax_unit_is_joint", period)
joint_bonus = eitc_params.phase_out.joint_bonus.calc(child_count)
phase_out_start = (
eitc_params.phase_out.start.calc(child_count) + is_joint * joint_bonus
)2. Eligibility checks preserved ✅The reform uses
3. uv.lock regression ✅Reverted uv.lock - no longer included in PR changes. 4. Test Case 5 now properly tests no-limit logic ✅Changed income from 100k (which was past phase-out) to 20k (within EITC range). Now the test verifies that |
Summary
Fixes the
individual_eitc(Winship) reform which was not responding to parameter changes in the app.Root cause: The reform checked
enabledat creation time, not simulation time. Since structural reforms are created with base parameters before user modifications, settingenabled: truein the app had no effect.Solution: Restructured the reform to follow modern patterns:
in_effectinside the formula usingwhere()(like GA SB520, NJ budget reforms)enabled→in_effectfor consistencytakes_up_eitcmultiplierChanges
policyengine_us/reforms/winship.py- Restructured to checkin_effectinside formulapolicyengine_us/parameters/gov/contrib/individual_eitc/in_effect.yaml- New parameter (replacesenabled.yaml)policyengine_us/parameters/gov/contrib/individual_eitc/agi_eitc_limit.yaml- Updated descriptionpolicyengine_us/tests/policy/reform/winship.yaml- Updated tests with proper structureTest plan
in_effect: trueto verify reform activatesin_effect: falseCloses #7779
🤖 Generated with Claude Code