Skip to content

Strengthen QBID net capital gain regression and parity coverage - #10077

Merged
MaxGhenis merged 1 commit into
mainfrom
hub-qbid-net-capital-gain-1010
Oct 11, 2026
Merged

MaxGhenis merged 1 commit into
mainfrom
hub-qbid-net-capital-gain-1010

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

At branch creation, main (12ea587) already fixed the QBID income limit by using section_199a_net_capital_gain and 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 fetched main (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_gain variable would also be incorrect because it applies the Form 4952 election.

Legal basis

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_gain and 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_gains already includes Schedule D distributions; non_sch_d_capital_gains supplies the separate no-Schedule-D amount.

Extend the vectorized Hypothesis checks:

  • section_199a_net_capital_gain is nonnegative and matches the Form 8995 oracle; elections and dependents do not alter the filer's amount.
  • For consistent component-derived inputs, the 199A gain is at least 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.
  • In 2025, QBID never exceeds 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 uses max(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 unrelated spm_calculator.geoadj import 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. Current main already contains the corrected formulas; no case is presented as failing current main. 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.

Form 8995 cap case Hand-worked QBID Assigned snapshot e4363903f3a5 Controlled legacy cap Corrected formula (identical on main and branch) Expanded branch file
1250 gain: line 11 $100,000; line 12 $40,000 $12,000 Import blocked FAIL: $18,000 PASS: $12,000 (5-case file) PASS: $12,000 (17-case QBID file)
28% gain: line 11 $150,000; line 12 $60,000 $18,000 Import blocked FAIL: $28,000 PASS: $18,000 (5-case file) PASS: $18,000 (17-case QBID file)
Form 4952 election: line 11 $100,000; line 12 $60,000 $8,000 Import blocked FAIL: $12,000 PASS: $8,000 (5-case file) PASS: $8,000 (17-case QBID file)
Net ST loss: line 15 $30,000; line 16 $20,000; dividends $5,000 $15,000 Import blocked FAIL: $18,000 PASS: $15,000 (5-case file) PASS: $15,000 (17-case QBID file)
No Schedule D: line 7a $8,000; dividends $2,000; line 11 $40,000 $6,000 Import blocked PASS: $6,000 PASS: $6,000 (5-case file) PASS: $6,000 (17-case QBID file)
File / check, each run alone in one foreground process Before After
section_199a_net_capital_gain.yaml 11 passed, pytest 53.88 s; process 261.095 s; peak RSS 2,331,787,264 bytes 12 passed, pytest 124.22 s; process 1,607.178 s; peak RSS 2,068,725,760 bytes
qualified_business_income_deduction.yaml 15 passed, pytest 65.68 s; process 243.160 s; peak RSS 2,679,144,448 bytes 17 passed, pytest 52.82 s; process 920.07 s; peak RSS 2,581,987,328 bytes
test_section_199a_net_capital_gain_invariants.py 2 passed, pytest 161.40 s; process 179.565 s; peak RSS 1,093,697,536 bytes; existing Linux CI also 2 passed 2 passed, pytest 1,011.34 s; process 1,906.038 s; peak RSS 842,432,512 bytes
Existing dependent safeguards / state consumers / reforms Existing dependent/election cases retained Dependent/election invariants passed; static consumers audit complete; no state/reform production change
make format / diff checks — Passed (ruff 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 direct adjusted_net_capital_gain consumers 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_limit imports us: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, labelled pe-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 defa292e3b this PR changes tests (three YAML cases and a Hypothesis property file), reference metadata and a comment in section_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.

@MaxGhenis
MaxGhenis marked this pull request as ready for review October 11, 2026 10:12
@MaxGhenis
MaxGhenis merged commit 24e008d into main Oct 11, 2026
33 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

US + core hub merge audit, us#10077 at defa292e3bea87e654058a3b4406070e36f6a696 (squash): strengthen QBID net capital gain regression and parity coverage.

  • Origin: a hub build that set out to rescue a cut-off session's QBID fix found the fix already on main (Subtract section 199A net capital gain, not adjusted net capital gain, in the QBI income limit #9886, merged 2026-10-07) and reduced this PR to added coverage.
  • Review: independent GPT-6.1 Sol review r1 approves this exact head, with no P1 or P2. It recomputed the new YAML cases by hand and confirmed the law (Treas. Reg. 1.199A-1(b)(3), TD 9847, Form 8995 line 12).
  • Scope: tests, reference metadata, a comment and a changelog fragment. No formula, parameter or input changes, so no simulation output changes and no microsimulation was run.
  • Gates checked live at merge: gh pr checks exits 0; the latest Pull request run at the head concluded success; MERGEABLE, not a draft, no CHANGES_REQUESTED; the semantic-overlap guard; head pinned.
  • Axiom: TheAxiomFoundation/rulespec-us#1515 queued (the issue filed for Subtract section 199A net capital gain, not adjusted net capital gain, in the QBI income limit #9886).
  • --admin: used only because a required approving review is the sole block.

@MaxGhenis
MaxGhenis deleted the hub-qbid-net-capital-gain-1010 branch October 11, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant