[draft] Align federal SALT to state income-tax liability (#1058)#1060
Draft
PavelMakarchuk wants to merge 1 commit into
Draft
[draft] Align federal SALT to state income-tax liability (#1058)#1060PavelMakarchuk wants to merge 1 commit into
PavelMakarchuk wants to merge 1 commit into
Conversation
Deduct the state income-tax LIABILITY (not PE's imputed withholding, ~19% higher) in the federal SALT base, matching the TAXSIM-35 convention. Uses a two-sim flow: pass 1 computes state_income_tax; pass 2 set_inputs state_withheld_income_tax to that liability and provides the federal columns, while state-output columns come from pass 1 (state tax is unaffected — Hawaii reads state_withheld_income_tax directly, so routing state from pass 1 keeps every state output byte-identical). Inert under --disable-salt. Fixes the federal residual on itemizing records (#974, #973). NOTE: inert on the current eCPS (mortgage/proptax = 0 for all records → nobody itemizes); validated on NY #974 (fiitax = binary exactly). Convention change — do not merge without sign-off. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Collaborator
|
On Sun, 5 Jul 2026, Pavel Makarchuk wrote:
**Draft ? do not merge without sign-off on the convention.**
## What The emulator's federal SALT deduction uses PE's imputed
`state_withheld_income_tax` (~19% above the actual liability); the
TAXSIM-35 binary uses the state income-tax **liability**. This aligns PE
to the liability via a two-sim flow (pass 1 computes `state_income_tax`;
pass 2 set_inputs `state_withheld_income_tax` = liability and provides
the federal columns; state-output columns come from pass 1 so state tax
is byte-identical ? Hawaii reads `state_withheld_income_tax` directly).
Inert under `--disable-salt`.
To clear, in production Taxsim iterates 3 times calculating state and
federal tax for each other's itemized deduction schedules. This would make
comparison testing impossible, so when option(30)==1, there is no
iteration and no deduction for income taxes on any state or federal
return. I would not favor using an estimate of withholding in place of the
iteration for production but I could add 5% of agi to "other deductions"
to get a larger number of itemizers, if you thought that was useful. When
testing the state treatment of itemizing I have been adding 50,000 for the
mortgage deduction on every record. Crude, but helpful.
## Status / honest caveats
- ? **Correct + regression-free:** NY #974 ? `fiitax` = 22921.64 (binary exact); full suite **175 passed**; **zero** state-tax change (verified 0/2000 records differ after routing state columns from pass 1).
- ?? **Inert on the eCPS:** every eCPS record has `mortgage = proptax = 0` ? nobody itemizes ? the state-income-tax SALT component never enters the deduction. Fed match unchanged (2021 80.4%, 2023 81.2%, 2025 84.5%). It only helps records that **itemize** (feenberg's #974/#973).
- ?? **Convention change:** withholding-vs-liability is a modeling decision (#1058) ? needs @feenberg's sign-off.
- ?? **Cost/size:** a ~350-line runner refactor (two-sim) and ~2x compute on the itemizing path.
I can see how it would be a 350 line refactor. In Taxsim, I have a loop
that is essentially:
do i=1,3
call nlaw(d,law)
state_tax_in=stata_tax_out
enddo
It triples the calculating cost for Taxsim but that isn't very significant
for Taxsim. I would be glad to reduce 3 iterations to 2, if that helped
your costs. Or, you could save the difference between the standard and
itemized deductions from the federal calculation, and leave the loop after
the first iteration if state tax was less than the shortfall of itemized
deductions without state income tax compared to the standard deduction.
That would eliminate the loop for most taxpayers.
Given it's inert on the main data and a convention change, I'm **not**
recommending merge ? opening as a tested option for review. Fixes the
federal residual on #974/#973 if adopted.
Maybe we should concentrate on bugs for the time being.
Dan
…
Closes #1058 (if merged).
? Generated with [Claude Code](https://claude.com/claude-code)
You can view, comment on, or merge this pull request online at:
#1060
-- Commit Summary --
* Align federal SALT to state income tax liability (draft, #1058)
-- File Changes --
A changelog.d/fix-salt-liability-alignment.fixed.md (1)
M policyengine_taxsim/runners/policyengine_runner.py (352)
M tests/test_performance.py (4)
A tests/test_salt_liability_alignment.py (86)
-- Patch Links --
https://github.com/PolicyEngine/policyengine-taxsim/pull/1060.patch
https://github.com/PolicyEngine/policyengine-taxsim/pull/1060.diff
--
Reply to this email directly or view it on GitHub:
#1060
You are receiving this because you were mentioned.
Message ID: ***@***.***>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft — do not merge without sign-off on the convention.
What
The emulator's federal SALT deduction uses PE's imputed
state_withheld_income_tax(~19% above the actual liability); the TAXSIM-35 binary uses the state income-tax liability. This aligns PE to the liability via a two-sim flow (pass 1 computesstate_income_tax; pass 2 set_inputsstate_withheld_income_tax= liability and provides the federal columns; state-output columns come from pass 1 so state tax is byte-identical — Hawaii readsstate_withheld_income_taxdirectly). Inert under--disable-salt.Status / honest caveats
fiitax= 22921.64 (binary exact); full suite 175 passed; zero state-tax change (verified 0/2000 records differ after routing state columns from pass 1).mortgage = proptax = 0→ nobody itemizes → the state-income-tax SALT component never enters the deduction. Fed match unchanged (2021 80.4%, 2023 81.2%, 2025 84.5%). It only helps records that itemize (feenberg's NY joint 2025 210Kintrec #974/CA 2025 joint 168Kintrec #973).Given it's inert on the main data and a convention change, I'm not recommending merge — opening as a tested option for review. Fixes the federal residual on #974/#973 if adopted.
Closes #1058 (if merged).
🤖 Generated with Claude Code