Repository navigation
Strengthen QBID net capital gain regression and parity coverage - #10077
Merged
Merged
Conversation
MaxGhenis
marked this pull request as ready for review
October 11, 2026 10:12
Contributor
Author
|
US + core hub merge audit, us#10077 at
|
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.
At branch creation,
main(12ea587) already fixed the QBID income limit by usingsection_199a_net_capital_gainand contains the election, dependent, and minimum-deduction safeguards. The rescued WIP is already represented in main through #9886, so it was not cherry-picked again. This draft adds Treasury reference metadata, three regression cases, stronger comparison invariants, and a changelog fragment. Latest fetchedmain(c1606b8) retains the same fixed formulas. Production formulas remain unchanged.The original defect used adjusted net capital gain, excluding unrecaptured section 1250 gain and 28% rate gain and allowing too much QBID when the taxable-income cap bound. Reusing the section 1(h)
net_capital_gainvariable would also be incorrect because it applies the Form 4952 election.Legal basis
max(0, min(Schedule D lines 15, 16)), or Form 1040 line 7a without Schedule D. Form 8995-A, p. 2, lines 33–37 and its instructions, p. 7, Line 34 use the same calculation.The saved 2025 IRS sources from the rescued session agree with these primary-source links.
Changes and invariants
Add the TD 9847 preamble as reference metadata for
section_199a_net_capital_gainand explain its explicit election treatment in a formula comment.Add two hand-worked QBID cap cases for a net short-term loss (Schedule D line 16 smaller than line 15) and a return without Schedule D. Add a distribution memo-input case to guard against counting the same capital gain distribution twice: current
long_term_capital_gainsalready includes Schedule D distributions;non_sch_d_capital_gainssupplies the separate no-Schedule-D amount.Extend the vectorized Hypothesis checks:
section_199a_net_capital_gainis nonnegative and matches the Form 8995 oracle; elections and dependents do not alter the filer's amount.adjusted_net_capital_gain, so the corrected deduction does not exceed a comparison deduction using the legacy adjusted-gain cap. Current gain variables both exclude dependents; the comparison retains current filer aggregation and deduction-floor rules.20% × max(0, taxable_income_less_qbid − section_199a_net_capital_gain). For 2026, the existing section 199A(i) minimum can exceed that cap; the property usesmax(cap, maximum statutory minimum)as its ceiling, and the legacy comparison retains the same floor rules. Public Law 119-21, section 70105(b)-(c), PDF pp. 91-92 establishes the $400 minimum for eligible taxpayers starting in 2026.Validation
The assigned snapshot (
e4363903f3a5) precedes the fix, but its attempted run stopped at an unrelatedspm_calculator.geoadjimport error before any cases executed; that failure is preserved as evidence. A controlled legacy-cap reform with the current production deduction isolates only the old adjusted-gain subtraction: 4 expected failures and 1 pass, pytest 118.98 s; process 1,179.155 s; peak RSS 2,891,923,456 bytes. Its actual outputs are retained in untracked evidence. Currentmainalready contains the corrected formulas; no case is presented as failing currentmain. Every changed test file passed alone: 12 gain-variable YAML cases, 17 QBID YAML cases, and both expanded Hypothesis tests (2025 and 2026). The controlled former-cap comparison and all baseline test files have also completed: baseline 26 YAML cases and 2 Python tests passed, versus branch 29 YAML cases and 2 expanded Python tests passed. The separate five-case corrected-cap confirmation also passed: 5 passed, pytest 29.64 s; process 171.360 s; peak RSS 2,379,300,864 bytes. All planned foreground file runs completed with the expected exit status. Source-cache-assisted local verification uses exact archived model sources plus the changed production source overlay, with test sources read live; no formula or expected result is replaced. Third-party pytest plugin autoload is disabled. The local filesystem and interpreter startup are exceptionally slow; these measurements are macOS results, separate from Linux CI.e4363903f3a5section_199a_net_capital_gain.yamlqualified_business_income_deduction.yamltest_section_199a_net_capital_gain_invariants.pymake format/ diff checksruff format,ruff check,git diff --check)The expanded test stays in the existing
Python Tests→ Rest/core group (make test-other-python-rest), with no added jobs, matrix entries, or concurrent model processes. Existing CI run 38070802756 reports the original two invariant cases passing (JUnit testcase times of 0.882 s and 0.977 s); its complete 831-test core group took 12:11.57 and peaked at 6,857,212 KiB. Those CI group measurements cannot isolate this expansion's marginal cost. Local wall times vary substantially with filesystem startup; the expanded Python run used 26.857 s user / 4.604 s system CPU versus baseline 22.047 s / 1.886 s. Baseline tests are saved outside the package test directory (whose only conftest is empty), so these local measurements are observations, not a controlled estimate of the CI increment. Local before/after runs use saved baseline test contents against the branch's unchanged production formulas, each file in a separate foreground process.Consumer and partner audit
The federal QBID cap already points to
section_199a_net_capital_gain. There are no remaining directadjusted_net_capital_gainconsumers implementing a 199A cap. Colorado adds back federal QBID, Iowa uses each filer's share of federal QBID, and Idaho's deductions reference federal QBID. South Carolina's traditional federal-taxable-income path adds federal QBID back; its newer AGI path does not apply that deduction. These paths need no separate cap switch.Preferential capital-gains tax calculations, section 911 stacking calculations, their Biden/Harris reform copies, and Vermont's capital-gain exclusion retain adjusted net capital gain because they implement provisions distinct from 199A.
No partner contract files were edited. This follow-up changes no production behavior. The static partner scan found no case affected by these additions; partner runtime tests have not been run.
Axiom parity
axiom: TheAxiomFoundation/rulespec-us#1515 queued
rulespec-us/us/statutes/26/199A.yaml#qbi_taxable_income_limitimportsus:statutes/26/1/h#net_capital_gain. That imported formula subtracts the section 163(d)(4)(B)(iii) investment-income election, contrary to the explicit TD 9847 explanation and Form 8995 calculation. Its net-versus-adjusted distinction is correct. Existing rulespec-us#1515, labelledpe-parity, records this divergence and the missing-regulation corpus blocker. No new issue was filed in this task.Hub microsimulation impact
None, and no microsimulation was run. At
defa292e3bthis PR changes tests (three YAML cases and a Hypothesis property file), reference metadata and a comment insection_199a_net_capital_gain, and a changelog fragment. No formula, parameter or input changes, so no simulation output can change; the production fix merged earlier in #9886.