Repository navigation
Keep AddMed out of fiitax in every year, add the addmed column, and fix single-household frate - #1239
Merged
Merged
Conversation
…e-household frate The bundled taxsimtest (cd2026081819) adds the Additional Medicare Tax to fiitax for 2013-2023 and not from 2024, while counting it in tfica in every year. The emulator does not copy that split: TAXSIM's author said AddMed belongs with FICA (#416) and on #1225 (2026-09-24) called its inclusion in fiitax "an error that was present in 2000-2023" that he believes he has corrected. The bundled binary predates that. - Add an `addmed` output column (idtl=2), as taxsimtest prints. - Stop adding AddMed to frate on the single-household export_household path (it did so in every year, unlike its own fiitax and the runner). - Replace comments that cited unextracted form lines and attributed the emulator's v44/addmed layout to taxsimtest; document the convention and the stitched pre-2021 caveat in the README and dashboard docs. - Make frate/srate column order deterministic and regenerate the e2e output artifacts (new addmed column; no value changes). - Rewrite tests/test_addmed_excluded_from_fiitax.py with expected values from taxsimtest output, a 2024+ binary guard, and a strict xfail that flips once resources/taxsimtest carries the #1225 correction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The bundled Windows taxsimtest (cd2026081318) reports addmed 1524.60 on $400K of wages where the macOS/Linux builds (cd2026081819) report 1800.00, so CI failed on windows-latest. The guard now checks only the convention: from 2024, fiitax == v28 with addmed > 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 tasks done
This was referenced Oct 11, 2026
MaxGhenis
added a commit
that referenced
this pull request
Oct 11, 2026
…order across hash seeds (#1427) #1239 made the frate/srate columns an ordered tuple, but nothing tested it: within one process a set of strings iterates in a stable order, so a regression only shows up across processes with different PYTHONHASHSEED. Add a test that runs PolicyEngineRunner in two subprocesses whose seeds iterate {"frate", "srate"} in opposite orders and requires identical output. Fix three other places where a set's order reached output: - api._validate_csv named whichever bad numeric column came first in hash order; it now names the first one in the uploaded header. - BaseTaxRunner.validate_required_columns returned its missing and extra lists in hash order; they now follow required_columns and the input columns, each name once. - compare's consolidated CSV listed records in set order of their IDs; it now follows the frame TaxComparator sorted by taxsimid. Each has example tests and a Hypothesis property test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully deployed
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.
Summary
For tax years 2013–2023, the bundled
taxsimtest(cd2026081819) puts the Additional Medicare Tax (AddMed) infiitax. From 2024 it leaves it out. In every year it also counts AddMed intfica.I checked whether the emulator should copy that year split. It should not:
fiitax"an error that was present in 2000-2023" and said he believes he has corrected it. The tax itself starts in 2013.The Microsimulation runner already leaves AddMed out of
fiitax(since #963). This PR:v44"), but taxsimtest's line 44 is AddMed alone, and the emulator had noaddmedcolumn.addmedoutput column.frate. It still added AddMed in every year, which contradicted that path's ownfiitaxand the runner.Evidence
Binary behavior (engine output, cd2026081819). Single filer, TX, $400K wages, idtl 2:
Probe sweeps across wages and self-employment income, several filing statuses, all 52 state codes, AMT and credit cases, and idtl 0/2/5 found that
fiitax − (v28 + v27 + niit − credits − cares)equalsaddmedfor every year 2013–2023 and is 0 from 2024. 2012 has no AddMed. The net investment income tax is infiitaxin every year. The olderresources/taxsim35build (cdate-2025Aug23) still puts AddMed in 2024fiitaxand leaves it out oftfica.TAXSIM's author:
That is what the emulator does:
income_taxincludes NIIT throughincome_tax_before_refundable_credits.taxsim_tficaincludes AddMed once, throughemployee_payroll_tax, whose components includeadditional_medicare_tax. That variable is computed on wages plus self-employment income.self_employment_taxholds only regular SECA.tficamatches the binary's to the cent in the table above.Documentation is stale on this point. https://taxsim.nber.org/taxsimtest/, "Output Results" (Last-Modified 2026-09-04):
Where the split likely comes from. This is a pointer only; the binary was built from newer, unpublished source. In the amalgamated
taxsim.fin publicfeenberg/taxsimat 359c71f (2026-04-29):nlaw(lines 39383–39387) sendsin(lawyr,1987,2023)tolaw87and later years tolaw24.law87ends withtax=tax+addmtx(line 39214).law24has no such line.sstaxaddsaddmtxtoc(75)andc(190)(lines 40002–40003).The standalone
nlaw.forandsstax.forin the same commit are older and differ. The public code also computes 1,524.60 of AddMed on $400K of wages, where the binary gives 1,800.Changes
variable_mappings.yaml: newaddmed→additional_medicare_taxoutput, idtl 2 only.taxsimtestprints anaddmedcolumn only at idtl 2.core/marginal_rates.py: single-householdfrateno longer adds AddMed. At $400K wages it was 35.9 and is now 35.0. That matches the runner and the binary's own +$100 difference on the same basis (2024: 105,299.75 − 105,264.75).runners/policyengine_runner.py:mtr_varsis an ordered tuple instead of a set, so the frate/srate output column order no longer changes with hash randomization;addmedrow. The section scopes the convention to PolicyEngine-computed rows: the default CLI'sStitchedRunnertakes pre-2021 rows from the bundled binary, and those carry the binary's inclusion until it is refreshed.addmedis marked implemented.output/*.csv: the e2e artifacts are regenerated. They add theaddmedcolumn and fix the frate/srate order; no values change.tests/test_addmed_excluded_from_fiitax.py, rewritten. The old docstring gaveaddmed = 2,355.75for the 2024 $500K case; the binary prints 2,700.00. The tests:fiitaxis the binary'sfiitaxminus itsaddmedfor 2013–2023, and the binary'sfiitaxas-is from 2024. Each case also assertsaddmedandtficaagainst the binary, andfrateagainst the binary's +$100 difference;fiitaxat idtl 0 equals idtl 2 and that idtl 0 has noaddmedcolumn;fiitax;fiitax,addmedandfrate. This test fails onmainwith frate 35.9;taxsimtestkeeps AddMed out of 2024+fiitax;raises=AssertionError) for the binary's 2013–2023 behavior. It will XPASS, and fail CI on purpose, onceresources/taxsimtestis refreshed with the Does taxsimtest count the Additional Medicare Tax twice (in fiitax and in fica/tfica)? #1225 correction. The marker and every bundled-binary note it lists get removed at that point. Open Update bundled macOS and Linux TAXSIM test binaries to the October 27, 2026 build #1206's September builds predate Does taxsimtest count the Additional Medicare Tax twice (in fiitax and in fica/tfica)? #1225, so they should keep xfailing.tests/test_performance.py: the fake-sim unit test now runs for 2021, 2023 and 2024.Testing
pytest tests/suite passes locally: Python 3.14, PE-US 2.11.3, macOS. The only non-pass is the intended xfail.addmed1,524.60 on $400K of wages, where the macOS and Linux builds (cd2026081819) report 1,800.00. That is 0.009 × (0.9235 × 400,000 − 200,000): the self-employment factor applied to wages. The binary guard therefore checks only the convention (from 2024,fiitax == v28withaddmed > 0) and does not pin the amount. The emulator tests pin the macOS/Linux values and don't run the binary. The Windows build still xfails the 2013–2023 check.Not in this PR
v43/v44differ fromtaxsimtest's idtl 5 lines 43 and 44 (NIIT; AddMed alone). The emulator'sv44is employee Medicare tax plus AddMed. Queued as a separate task.otherpropraises AGI in 2024+;frate= 0 in cd2026081819.The uncapped employer OASDI in
ficais already Does taxsimtest's fica skip the Social Security wage base for the employer share? #1224.🤖 Generated with Claude Code