Repository navigation
Add S.770 section 8 investment and active income tax options - #10402
Merged
MaxGhenis merged 10 commits intoOct 28, 2026
Merged
Conversation
MaxGhenis
marked this pull request as ready for review
October 23, 2026 09:02
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10402 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 4 18 +14
Lines 76 226 +150
Branches 2 6 +4
==========================================
+ Hits 76 226 +150
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Zero the SE netting factor q = 1 - employer share x (OASDI + HI SE rates) for 2026 only, so s770_active_business_income raises its positivity error there, while 2025 keeps q = 0.9235 and excludes 9,235 / 0.9235 = 10,000 of a 100,000 S-corp profit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
deleted the
reform-s770-section8-investment-business-income-tax
branch
October 28, 2026 08:24
Contributor
Author
|
Merge audit (US + core hub), #10402 at
|
MaxGhenis
added a commit
that referenced
this pull request
Oct 28, 2026
Brings in main up to fe9ec12 (S.770 section 8 options, #10402, and the 2.75.0 bump). Neither commit touches the Montana AGI invariant test or this branch's changelog fragment, so the merge applied cleanly with no resolved hunks; the test file's resolution is the one in the previous merge, 56ec6ef. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 28, 2026
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.
Adds two independently enabled, parametric S.770 §8 options for scoring: an NII add-on and an active pass-through base. Both default off under
gov.contrib.congress.s770.section_8, each with its own start year, rate and OASDI share. Bill example rates are .124 and .162. No scenario or package-specific values are encoded.Bill and scope
Congress.gov introduced S.770, 119th Congress, §§8–9, fetched October 23, 2026:
Each excerpt is under 25 words. Section 8 has no fixed effective year: the configurable 2026 defaults illustrate an enactment assumption. Section 9(a), rather than §8, transfers 62% of all resulting §1411 tax to the merged Social Security fund from the first fiscal year beginning after enactment; fund assets transfer on January 1 of the first calendar year beginning after enactment. The independent annual transfer start does not model collection lags or fiscal-year proration.
This is the documented split pass-through model, not a complete literal-bill preset. The implementation README audits ordinary-course investment sources, active trade/business categories, business-property gains, NOL treatment and FICA/SECA exclusions. Classification of all statutory categories remains unsupported; matching rates and transfers does not close those gaps.
Tax computation and independent options
Use existing
niit_magi(including estate and §911 adjustments) and §1411(b) thresholds. Let N be signed adjusted NII, A the signed additional active base (zero if disabled), and X the positive MAGI excess. Compute:NII receives threshold room first, even with an add-on rate of zero. Both allocations are nonnegative. Active inclusion also replaces the existing 3.8% component's base with n.
net_investment_income_taxis the full resulting liability, so the new component taxes are not added again downstream.The active residual uses
partnership_s_corp_income(derived froms_corp_income + partnership_income), less passive income and already-SE active income. Head/spouse amounts are included; dependents stay on their own return. Nonpassive is only a material-participation proxy; cross-entity netting is an approximation. Validated overlap and FICA exclusion inputs avoid treating overlapping passive/SE sources or embedded wage amounts twice.The future owners-draw integration hooks implement the actual-SECA exclusion: with OASDI only, exclude capped draw net earnings / q; with uncapped HI, exclude the actual full gross draw. Above-room profits remain active with draw HI off; undrawn and floor-rejected amounts remain active in either mode. The hooks classify supplied amounts and do not themselves impose SECA.
There is no baseline federal §172 NOL deduction input/formula in NII; the Indiana NOL variables are state-specific.
s770_niit_nol_deductionaccepts a validated deduction already subtracted from supplied NII. When active inclusion and denial are enabled, the addback changes broadened NII before allocation, including the existing NIIT component. Default zero is not complete NOL coverage and ordinary signed business losses are not NOL deductions.OASDI allocation
Four transfer modes use integer choices because core has no string parameter scalars:
custom: each component share (defaults .62), without existing NIIT.combined_rate_share: OASDI rate / combined NII rate and OASDI rate / active rate. OACT 2025 F8 attributes active-tax receipts to 12.4 of 16.2 points; this convention differs from the bill's 62%. With no positive NII add-on, that custom mode transfers no existing NIIT and keeps the active transfer independent.all_addon: all NII add-on points to OASDI, plus the chosen active share.bill: .62 of all resulting §1411 tax, including a separately reported existing-NIIT transfer.Each source revenue equals its selected share times its tax. The three revenue sources sum to
s770_revenue_oasdi; aggregate each TaxUnit once alongsidetob_revenue_oasdi. Transfers have a separate start year and are zero when both provisions are off. Liability equality and OASDI-allocation equality are distinct claims.Data limitation
The certified pre-repair artifact forces S-corp income to zero, carries combined income with passive mass in the reweighted partnership column, and omits the passive subset. The formula runs on current data, but (b) overstates active income and (a) understates NII until Microcosm #1251 and #1261 repairs are present in the selected scoring artifact and the columns are verified. These limitations are also in the variables' documentation. Population scoring remains provisional.
Invariants and validation
With both options enabled, identical signed sources, exclusions, NOL treatment, MAGI, thresholds and timing, and existing + add-on = active = .162, liability equals .162 × L for every signed input. N=-$10,000, A=$20,000, X=$50,000 yields $1,620, as does N=$20,000, A=-$10,000. The latter is lower than add-on-only liability of $3,240. Activation monotonicity requires nonnegative active income and fixed NII source rules, including exclusions and NOL treatment. Activating a SECA exclusion can also lower existing NIIT with no active loss: the paired $10,000 passive/SE overlap example falls from $380 to zero. Tests pin these necessary corrections to the brief.
Hand-computed YAML covers S-corp, limited/general partners, below-threshold cases, NOL hooks, each option alone/together, signed losses, zero rates, all filing thresholds, dependent exclusion, overlap, M7 draws (including changed SECA rates and supplied zero actual draws) and transfer modes. Hypothesis covers signed equivalence, nonnegative allocations/taxes, monotonicity under its stated conditions, disjoint SECA classification, activation and transfer identities through vector helpers. One shared multi-year household simulation checks actual registration, independent timing, formula allocations, MAGI adjustments and component accounts without rebuilding the model for each generated example.
All 133 checks passed, with each file run in its own foreground process and all requested thread caps set to four:
The 19 includes the netting-factor coverage test added with the main merge. At head
8c3b927a90,test_s770_section_8.py(19 passed) andtest_ss_calculator_differential.py(8 passed) were rerun locally, and CI passes every check. The other rows were run before the main merge, which changed none of this PR's 41 files.make format(Ruff format and lint) andgit diff --checkpassed. The YAML cases are grouped into files with configuration weights 5, 3, 5 and 4, within the existing per-file limit of five. All 39 cases were preserved when split.Local macOS wall times for the four new YAML files were approximately 8.7, 4.4, 8.5 and 6.1 minutes, including model initialization and shutdown; the new Python file took 1.7 minutes. Peak RSS was unavailable because the sandbox denied kernel statistics. Linux CI resource usage was not measured locally. No microsimulation was run.
impact: none at defaults. Both options'
in_effectparameters default to false, andcreate_s770_section_8_reforminstalls the reform only if somein_effectvalue is true. Measured at8c3b927a90against main462672c1a4: 500 drawn households (5 seeds × 100; 43–53 of each 100 tax units owe NIIT and 47–54 people per batch owe SE tax) × 2025, 2026 and 2030, one year per process. Every cached array (10,748–11,124 per run) is identical, no array exists on only one side, and nos770_variable is computed. No population run for the enabled options (see Data limitation).axiom: n/a: proposed-bill reform (S. 770, 119th Congress), not enacted law
Main merge
462672c1a48b9c00f99cf73d9dff2f5ad17b353ein merge commitf47d2f9dac83bc996b85393d69e59ce6af9348a7. No conflicts or resolved hunks.gov.contrib.congress.s770togov.contrib.congress.s770.section_2, the calculator-only addition. This preserves this PR's siblingsection_8during simulation initialization. Add composable Social Security benefit levers #10400's shared benefit-lever and COLA-history namespaces remain available. The reference still removesgov.contrib.ssa.pia,gov.contrib.congress.s770.section_2,gov.ssa.social_security.pia.bend_points, andgov.ssa.social_security.cola; none contains this PR's nodes.ss_retirement_eligiblereadsgov.contrib.congress.s770.section_2.in_effect, the working case oftest_calculator_off_matches_model_without_featurefails (1 failed in 85 s, 2 GB RSS cap) withParameterNotFoundErrorforgov.contrib.congress.s770[section_2], whilesection_8remains. So the narrowed reference still catches a legacy formula that reads the calculator-only node.