Repository navigation
Conversation
Three guides under docs/, asked for at the 2026-10-08 BLS Consumer Expenditure seminar. Their reference tables are generated from the code by scripts/generate_docs_reference.py, and tests fail when they drift. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed tables Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Temporary files: deletion is attempted, not guaranteed; test leftovers. - Pre-2021 records: state checks do not apply, state -1 returns a wrong answer, idtl 5 does not work, marginal rates are 0. - Maryland: the bundled TAXSIM build includes county tax. - tfica includes employee state payroll taxes on PolicyEngine rows. - Linux TAXSIM build needs glibc 2.34 (generated from the binary). - Examples: do not round identifiers; Stata stores IDs as double and checks inputs before running. - Say what the network test covers and what it cannot see. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The emulator applies self-employment tax to pbusinc and sbusinc, as NBER's input documentation describes. The bundled taxsimtest build (cd2026081819) does not, and applies the net investment income tax instead. Taxsim #1254 asks TAXSIM's author which is intended. - tests/test_pbusinc_self_employment_tax.py pins both treatments, with expected values from the bundled binary, and adds property tests that pbusinc is interchangeable with psemp in both input paths. - docs/design.md and the pbusinc entry of the input reference say what each engine does and link the open question. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Quote the taxsimtest page's post-FICA note and 26 U.S.C. 1411(c)(1)-(2) next to item 26, name the page and retrieval date, and say the page does not settle the question on its own. - Say the bundled Windows build (cd2026081318) agrees; CI ran the binary pins on all three platforms. - Pin self-employment tax on pprofinc in the bundled builds, and add a differential test that the emulator's scorp row equals the builds' pbusinc row, which the design document now offers as the way to get their result. - Sample years in the interchangeability property, and use tolerances that allow for the emulator's float32 outputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
force-pushed
the
pbusinc-seca-treatment
branch
from
October 10, 2026 01:50
63087ce to
4486fde
Compare
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
The emulator and the bundled TAXSIM-35 executable disagree on
pbusinc/sbusinc(active qualified business income). The emulator applies self-employment tax to it. The bundled builds (cd2026081819 for macOS and Linux, cd2026081318 for Windows) do not, and apply the net investment income tax instead.This PR does not change the mapping. It documents the difference accurately, pins both sides in tests, and links the open question. The question is already with TAXSIM's author on #1254, and neither NBER's documentation nor his reply there settles it (details below).
Stacked on #1419, which adds the two documents this PR edits. Until #1419 merges, the diff here includes its commits; only the last two commits are this PR.
What was checked
Engine output is treated as a hypothesis here, not as evidence of intent. The documentary sources are NBER's input pages and the author's public replies.
NBER's input page lists SECA, and now NIIT too; one of its notes points the other way
NBER, "Internet TAXSIM Test Version", https://taxsim.nber.org/taxsimtest/, section "Incomes", under "The following are for the TCJA Business Tax Deduction. but are ordinary income 1960-2017." Retrieved 2026-10-10 00:56 UTC; page footer "Date last modified: 28 February 2026"; HTTP
Last-Modified: Fri, 04 Sep 2026 13:29:27 GMT:The Internet Archive's capture of the same URL dated 2026-04-17 (footer "Date last modified: 2 April 2025") has an earlier wording of the same items:
So the page was revised: "NIIT" was added to item 26 and SECA was kept. The capture date does not date the revision (the footer and the HTTP header disagree with each other too).
The same page has a second footer, "Date last modified: August 23, 2024", after its "Random Notes" section, which says:
That note reads toward no SECA on
pbusinc. But it is in both Internet Archive captures (2025-08-21 and 2026-04-17), from when the bundled builds applied SECA topbusinc, and it also coverspprofinc, which every bundled build taxes. So the page does not settle the question on its own.NBER's production page, "Internet TAXSIM Version 35", https://taxsim.nber.org/taxsim35/, retrieved the same minute; footer "Date last modified: May 20, 2022"; HTTP
Last-Modified: Thu, 03 Sep 2026 15:22:47 GMT:The three taxes item 26 now lists cannot all fall on active business income. 26 U.S.C. § 1411, subsection (c) "Net investment income" (LII, retrieved 2026-10-10). Paragraph (1)(A)(ii) counts:
and paragraph (2), "Trades and businesses to which tax applies":
Paragraph (6), "Special rule":
So NIIT on income labelled "active" conflicts with (c)(2) whether or not SECA applies, and SECA would rule it out again under (c)(6). The emulator matches the SECA and Additional Medicare half of item 26. The bundled builds match the NIIT half.
The executable changed between the May and August 2026 builds
Every macOS build this repository has bundled that still runs, plus the September build in #1206, on one record: single, age 40, California, 2023, $100,000 of
pbusinc,idtl2.fiitaxficav10qbidIn the first three, the
pbusincrow equals thepsemprow in these columns (v30differs). In the last two it equals thescorprow in every column. #1254 reports the same result for cd2026092410 and cd2026092717, which were not re-run here.In cd2026081819 and cd2026090910 the result holds for 2021 through 2025, for $1,000 to $1 million, and for
sbusincon joint returns (70 records each, none with SECA; in cdate-20260521 all 70 bear it). Above the threshold the build charges NIIT and no Additional Medicare Tax (single, 2024, $300,000:niit3,800.00,addmed0.00, against 0.00 and 693.45 forpsemp).pbusincis notscorpunder another name, though. On 4,000 random records (2021 to 2025, all states, single and joint, with wages, interest and gains), replacingpbusinc+sbusincwith the same total inscorpleftfica,tfica,addmed, AGI and the EITC unchanged on every record, but changed some other output on 294 of them: state tax alone on 190 (in 20 states), and federal amounts on 104, of which 90 are joint returns with positivepbusincand negativesbusinc, or the reverse.Reproduce:
The bundled Linux build has the same stamp as macOS (cd2026081819); the bundled Windows build is older (cd2026081318). Neither was run locally (the Docker VM was not running, and there is no Windows machine). CI checked both: on this PR's first head (63087ce), the
test (ubuntu-latest, 3.10)andtest (windows-latest, 3.10)jobs rantests/test_pbusinc_self_employment_tax.pyand passed, so all three bundled builds give the pinned figures to the cent.The author's replies
FICA and QBI income #384, 2026-03-28: a proposed table with
pbusincas QBI, not passive, SECA/FICA "yes".Map pass-through inputs to QBID-bearing PolicyEngine variables #1051 (merged 2026-07-05) records his June 2026 comparison, in which TAXSIM-35 gave
pbusincthepsempresult, and mappedpbusincaccordingly.Does taxsimtest skip SECA on pbusinc? #1254 (opened 2026-09-29) reports the missing SECA with NBER's sentence. His reply the same day:
Nobody has answered those two questions on the issue yet. PolicyEngine does have one:
scorpmaps topartnership_s_corp_income, which bears no SECA.Should the emulator assume sufficient W-2 wages for the QBI deduction, as TAXSIM does? #1404, 2026-10-07: "rather than bringing up each of these provisions as a separate issue, we should discuss them all together".
Conclusion
The author's reply indicates the builds' treatment is intentional, and he has a reason for it. But it is not settled: he asked to decide all seven pass-through inputs together, NBER's item 26 still lists SECA, and NIIT on active income conflicts with § 1411(c)(2). So the emulator keeps item 26's SECA for now, and the difference stays listed as a known difference with a test on each side.
Users who want the bundled builds' result can enter the amount as
scorp: for the pinned records the emulator'sscorprow (passive, the default from policyengine-us 2.10.1) equals the builds'pbusincrow to the cent, and a test pins that. The design document says so.No new issue was opened, because #1254 already carries the report and the author asked for no more per-variable issues.
Changes
tests/test_pbusinc_self_employment_tax.py(new):pbusincthe result taxsimtest givespsemp(expected values from the bundled binary'spsemprows);scorprow equals taxsimtest'spbusincrow on the pinned records (a differential test against the live binary);test_taxsimtest_*pin the bundled binary: SECA and Additional Medicare onpsempandpprofinc; none onpbusinc, with NIIT; thepbusincrow equals thescorprow on the pinned records; no SECA onpbusinc/sbusincfor 2021 to 2025 and $1,000 to $1 million. A refreshed build that changes this fails with a message naming what to revisit;scorpalternative.docs/design.md: the "Active business income" entry under "Known differences from TAXSIM-35" now says what each engine does, quotes item 26 and the post-FICA note, gives thescorpalternative, and links Does taxsimtest skip SECA on pbusinc? #1254.docs/reference/input_variables.yamland the regenerateddocs/input-guide.md: thepbusincentry, which now also says apbusincloss offsetspsemp.tests/test_passthrough_qbid.py: a docstring note that its TAXSIM-35 figures are from June 2026.Invariants
pbusincintopsempandsbusincintossempleaves every input of the dataset the emulator builds unchanged (test_pbusinc_is_interchangeable_with_psemp, Hypothesis). The simulation-stage overrides in_run_chunkdo not readpbusinc, so this covers the whole emulator path.generate_household) and the Microsimulation runner both putpsemp + pbusincon the primary taxpayer andssemp + sbusincon the spouse (test_single_household_path_sums_them_like_the_runner, Hypothesis).No counterexamples were found. The new module passes locally on Python 3.11 (policyengine-us 2.38.0) and 3.10 (policyengine-us 1.783.0).
Review
Independent review (Opus 5.5 on a Subfleet lane, as the Codex lanes were closed) on 63087ce: changes requested. Addressed in the second commit: the post-FICA note and § 1411(c)(1)-(2) quoted, the #1254 reply quoted in full, the source page and retrieval date named, "in these columns" where rows were not identical, the Windows docstring claim removed (CI showed all three builds agree), a
pprofincpin, thescorpdifferential test, years sampled in the invariant, and float32-aware tolerances.Impact
No change to any emulator output.
axiom: n/a: emulator documentation and tests only.
🤖 Generated with Claude Code