Skip to content

Measure the capital gains marginal tax rate on long-term gains - #10058

Open
MaxGhenis wants to merge 8 commits into
mainfrom
fix-cg-mtr-measurement
Open

MaxGhenis wants to merge 8 commits into
mainfrom
fix-cg-mtr-measurement

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

What was wrong

marginal_tax_rate_on_capital_gains measured a person's rate by raising capital_gains by $1,000 in a branch and differencing household net income. capital_gains adds short- and long-term gains. Overriding it reaches adjusted gross income (as a source in irs_gross_income) but not long_term_capital_gains or net capital gain, so the extra $1,000 was taxed as ordinary income, except where taxable income was below net capital gain and the preferential computation took the rise anyway (main is right for the $100,000 and $300,000 filers below). The capital gains realization response scales with the change in this rate between baseline and reform policy, so it mostly did not see the rates on gains.

Household runs for 2026, Texas, single, on main 75cdd801 and on this branch:

Filer Main This PR Statute
$100,000 of long-term gains 0.150 0.150 15%
$300,000 0.188 0.188 15% + 3.8% net investment income tax (NIIT)
$1M 0.298 0.238 20% + 3.8%
$20M 0.298 0.238 same
$100M 0.296 0.2379 same
$60,000 of wages, $200,000 of gains 0.308 0.188 15% + 3.8%

For the $20M filer, measured through the behavioral response branches under a reform that sets the top capital gains rate (gov.irs.capital_gains.rates.3):

Top rate Main: reform rate − baseline rate This PR Statutory change
25% 0 0.050 0.05
28% 0 0.080 0.08
30% 0.040 0.100 0.10
40% 0.110 0.170 0.17 (see the 37% cap below)

So on main a rise in the top rate from 20% to 28% produced no realization response for this filer.

The same formula also lost precision for large households. household_net_income is a float32, which resolves $8 at $100 million, so a $1,000 rise resolved that household's rate only to 0.008.

Fix

  1. Raise long_term_capital_gains. This is the change Make branch-measured marginal tax rates match fresh re-simulation #9698 makes inside its wider rework of marginal-rate branches; this PR lands it alone, on main's current branch code. The branch sets the aggregate rather than long_term_capital_gains_before_response, so it reaches the gains whether they are stored on the aggregate or derived from the pre-response input. A reform simulation's baseline is branched by core before this package moves long_term_capital_gains to the pre-response input, so it keeps the situation's value on long_term_capital_gains, and a rise in the pre-response input never reaches it (the baseline rate then measures 1.0, which is what revenue_curve_patched.py in the evidence folder ran into). The override also holds any behavioral response at its value in the simulation, the convention d1021 kept.
  2. Raise a capital_gains total that was given as an input. capital_gains adds short- and long-term gains, and adjusted gross income reads it. A situation can give the total directly (15 test files do, 4 of them API-partner contract files), and so can a later set_input. It is then stored as given, for every person in the simulation (zero for those it was not given for), rather than added up again. The branch raises the parent's total by the same amount whenever set_input stored one for the period, which core records for the situation, a dataset and later calls alike (tools.period_branch.has_input). Without this a household that gave the total at construction measured 0.84 to 1.0 instead of 0.188, and one that set it later measured 73.4 or 231.9 (supplied.py, review_repro.py). An unpushed local commit from 10/6 (183cecb919, branch cg-mtr-reads-capital-gains) handled the construction-time case; this takes that part of it.
  3. Drop values calculated for periods an input was not given for. The branch keeps variables given as inputs by name, as the other marginal-rate branches do. A variable given for 2025 only therefore kept its calculated 2026 value too, which the branch could not change: a filer with adjusted gross income given for 2025 measured 0.000 for 2026. The branch now runs drop_inherited_values (already on main, in tools/period_branch.py) over those variables, so each keeps only the periods it was given for. drop_inherited_values gains an optional list of variables for this.
  4. Neutralize the hours response in the behavioral response measurement branches, as Make branch-measured marginal tax rates match fresh re-simulation #9698 does. Hours read the labor supply response. Branches measured during the labor supply response return zero for it through that response's re-entry guard, but branches measured first for the capital gains response calculated it, and its measurements, again wherever a program reads hours after the response (Texas child care eligibility, tx_ccs_work_requirement_eligible, and 23 other state programs): with both elasticities set, requesting the capital gains response first raised CycleError on main for a single Texas filer with wages and gains. Labor-first requests already got zero there, so nothing that ran before changes.
  5. Scale the rise. It is $1,000, or 0.1% of the larger of the absolute values of the household's net income and the person's long-term gains where that is more (capital_gains_mtr_rise). Households under $1 million keep $1,000. At the seven sizes I ran from $1 million to $5 billion of gains, measured rates are within 0.0001 of statute; the property test holds them within 0.00025.
  6. Divide by the rise as stored, after float32 rounding.

Things that differ from the brief

  • Neither Make branch-measured marginal tax rates match fresh re-simulation #9698 nor Measure a branch's behavioural responses against baseline policy, with its own cache #9913 is needed for this. With the rise on long_term_capital_gains, the baseline and reform measurement branches of a reform simulation both see it on today's main. Measure a branch's behavioural responses against baseline policy, with its own cache #9913 fixes something else: a branch or early clone of a reform simulation measuring its responses against reform policy. Both PRs stay open with the US hub.
  • A top capital gains rate above the top ordinary rate does not bind for large gains, and that is the law as modeled. 26 U.S.C. 1(h)(1) says the tax "shall not exceed" the tax at the capital gains rates, so limit_to_tax_at_main_rates takes the smaller of that and the tax on all taxable income at the ordinary rates (Schedule D Tax Worksheet line 47). With a 40% top capital gains rate, a filer with $20M of gains faces 37% + 3.8% = 0.408, while a filer with $1M, whose tax at the capital gains rates is still the smaller, faces 0.438. The ordinary-rate tax becomes the smaller at a top rate of 37.43% for $20M of gains and 37.08% for $100M. The 0.408 the evidence file reported for 40%, 60% and 80% was this cap, not part of the defect. A reform that taxes gains above 37% needs more than this parameter.
  • The alternative minimum tax (AMT) shows up in the rate. It does not allow the standard deduction, so a single filer owes it once the exemption has phased out to less than the standard deduction. Between $648,000 and $680,200 of gains, each dollar of gains also removes 50 cents of exemption and the rate is 0.338, not 0.238. Above that the AMT is a constant 20% × $16,100 = $3,220 and adds nothing at the margin. The tests derive both edges from parameters.
  • A wider rise widens the window around a cliff. Any finite difference spreads a cliff over the rise. A New York single filer with $24,985,000 of gains crosses the state's $25 million threshold, above which ny_supplemental_tax taxes all income at the top rate, and measures 6.345 with the scaled $24,985 rise; with $1,000 the same filer measures 0.342, and a filer within $1,000 of the threshold 150.3. So the scaled rise puts more filers in the window (0.1% of income instead of $1,000), each with a spike that much smaller. Below $1 million, where the benefit cliffs are, the rise is $1,000 as before. A YAML case pins the New York example.

Invariants

  1. Statutory rate. For a Texas single filer whose only income is long-term gains in the 15% or 20% bracket, the measured rate is the bracket rate, plus the NIIT rate above its threshold, plus the AMT phase-out term inside its window, to within 0.00025.
  2. Reform tracking. With the top rate set to r, a top-bracket filer's rate is r + NIIT while the tax at the capital gains rates is the smaller regular tax, and 37% + NIIT after that. Through the measurement branches, reform rate − baseline rate equals that less 20%.
  3. Differential. The rate measured in a branch equals the finite difference between new simulations of the same households with the same rise, to 1e-6, including households that give a capital_gains total at construction or later, whether or not it equals their short- plus long-term gains. The new simulations use the same rise function, so this checks the branch, not the choice of rise.
  4. Order. With labor supply and capital gains elasticities both set, requesting either response first gives both the same values.
  5. Rise. At least $1,000; exactly $1,000 when the household's net income and the person's gains are both within $1 million; positive after float32 rounding and within 1.2e-4 of itself. Checked on the function, not through simulations.

Where invariant 1's or 2's reference does not apply, the tests stay out:

  • Bracket edges and cliffs, where the rate averages the two sides or spreads a cliff over the rise (above).
  • Two narrow ranges of the top rate that the test's reference, which models only the 1(h)(1) limit, does not cover: 37% to 38%, around where the ordinary-rate tax takes over (37.43% at $20M of gains, 37.08% at $100M), and 28% to 29%, where for a sliver of rates (28.38% to 28.40% at $20M, 28.074% to 28.078% at $100M) the AMT's flat 26%/28% computation is the tentative minimum tax, the filer still owes AMT, and the rate is genuinely 28%.

Input contract

The rate reaches the gains wherever the situation or dataset gives them: long_term_capital_gains or long_term_capital_gains_before_response, and a capital_gains total at construction or set later. Three limits, all as on main:

  • An input set after construction on another variable (say adjusted gross income) is calculated again in the branch, as in every marginal-rate branch: user_set_variables keeps later set_input calls only for IRA contributions, because formulas also call set_input.
  • A long_term_capital_gains set after construction on a reform simulation does not reach its baseline, which core branched earlier; the behavioral response measurements copy only the pre-response inputs into it.
  • An input given above the gains (adjusted gross income, net capital gain, market income) holds that part of the calculation fixed, so the rate cannot see the rise through it.

Tests

  • YAML (policyengine_us/tests/policy/baseline/household/marginal_tax_rate_on_capital_gains.yaml, 12 cases): each 2026 Texas bracket (15%, 15% + NIIT, 20% + NIIT, the AMT band at 0.338), $20M and $100M of gains, $60,000 of wages under $200,000 of gains, joint filers (both spouses), a capital_gains total given with and without long-term gains, adjusted gross income given for 2025 only (0.188 for 2026; 0.000 before), and the New York threshold example (6.345).
  • Python (policyengine_us/tests/core/test_capital_gains_mtr_measurement.py, 9 tests), for what YAML cannot do:
    • Hypothesis over gains from $65,550 to $3 billion (invariant 1);
    • Hypothesis over the top rate from 20% to 40%, measured directly in the reform simulation, and the measurement-branch path at 28% and 40% for $1M, $20M and $100M filers (invariant 2);
    • Hypothesis over households in TX, CA, NY, MA and PA, single and joint, wages from $0 to $2M, gains from −$50,000 to $200M and an optional capital_gains total, with the given-total households pinned as examples, plus totals set after construction (invariant 3);
    • both orders of requesting the two responses, with both elasticities set, for a filer whose response to a 15% → 20% rate is nonzero (invariant 4);
    • Hypothesis over float32 net income and gains up to ±$69 billion (invariant 5), and a check that the parameters behind the expectations are the 2026 schedule.
  • test_override_branches.py: one test that drop_inherited_values limited to some variables leaves the rest alone and that has_input reports the periods set_input stored.

Against the previous head the order test raises CycleError and the late-total test fails (73.4 and 231.9). Against main's formula at fdd7062905 (a copy of the Python file with the rise helper stubbed in, since main lacks it, and shrinking off), the 7 tests that run a simulation fail and the 2 that do not pass (on_main.log). On this branch all pass, and so do the 14 tests in test_behavioral_response_measurements.py. The differential property found one counterexample in its own reference while I wrote it: when one spouse gives a capital_gains total and the other does not, the simulation stores a zero total for the other, which the reference has to raise too. It is pinned as an @example.

CI cost. The Python file is simulation-heavy (each reformed household simulation builds a reformed system; the measurement-branch cases also compute the earnings marginal rate in both branches), so it runs in the heavy-a Rest group, not core; the Makefile comment records why, and code_health/test_rest_python_groups.py and test_make_test_matches_ci.py pass. No job, group or runner was added. From the Rest job's JUnit and GNU time reports:

CI run (head) This file heavy-a wall, peak RSS Notes
38056548883 (a926b5209a, in core) 246 s 5:57, 5.4 GB (without it) core: 13:58, 7.1 GB with it
38141803955 (d692879443) 231 s 9:55, 8.1 GB fixed cases moved to YAML
38157151942 (2881f93749) 463 s 15:19, 8.1 GB adds the order test (150 s); every group ran about 25% slower than in the run above

heavy-b peaks at 8.5 GB and policy and remaining at 13.8 and 14.7 GB on the 16 GB runner. core's peak went from 7.1 GB to 13.3 GB between the first two runs, but its only module changes were this file leaving and four test files main added (test_ssi_resource_deeming_invariants, 85 s, the largest), so that rise is not from this PR. Locally (macOS, a shared host under load) the file took 117 s of test time and 100 s of CPU at d692879443 (pytest6.log); a separate, slower run of it peaked at 5.2 GB RSS (rss_run.log). The new test in test_override_branches.py takes 1.2 s.

Impact on model outputs

marginal_tax_rate_on_capital_gains itself changes wherever it is requested, baseline simulations included. Scores change only through the capital gains realization response, which is zero unless a reform sets gov.simulation.capital_gains_responses.elasticity (default 0), so static scores do not move. With a nonzero elasticity, a person's response changes wherever their measured baseline or reform rate changes:

  • Reforms to capital gains rates now produce the response they should. For the $20M Texas filer at an elasticity of −0.7, a 28% top rate gives a response of −$3.67M of realizations (main: $0), and 25% gives −$2.50M (main: $0).
  • Reforms that change only ordinary rates stop producing one for filers whose gains are taxed at the preferential rates.

Paired runs of main 75cdd801 and this branch at a926b5209a for 2026, on the 10,000-household subsample of the default dataset that the repo's heavy behavioral tests use (sim.subsample(10_000), the same households in every run). Each cell is one simulation. These are subsample estimates of federal income tax, not full-population scores: full-data dynamic runs are gated on the shared host (the US hub's for #9698 have waited since 10/8), so none was made.

Reform, with a capital gains elasticity of −0.62 Static Main This PR
Top capital gains rate 20% → 28% +$76.8bn +$55.0bn (realizations −$66.1bn) +$24.6bn (realizations −$160.4bn)
Top ordinary rate 37% → 47% +$93.5bn +$85.8bn (realizations −$31.6bn) +$93.4bn (realizations −$0.2bn)
  • Under the capital gains reform, 188 of the 882 sampled people with gains see their rate change by more than 0.001 (72 on main), and the response is 2.4 times main's.
  • Under the ordinary-rate reform, 1 does (76 on main). Main's −$31.6bn was a response to a rate that long-term gains do not pay.
  • The gains-weighted mean baseline rate among people with gains is 0.276 (0.371 on main).
  • Baseline ($2,652.3bn) and static results are identical on main and this branch.

Scripts and outputs: impact.py, impact_main.jsonl, impact_fix.jsonl in the evidence folder. The same runs at main 065d0e9560 and this branch at 59ddba8718, after the round-1 review fixes, are queued on the shared host and will replace this table when they finish.

Relation to other PRs

  • Make branch-measured marginal tax rates match fresh re-simulation #9698 changes the same lines to call its create_perturbed_branch. When it rebases, its version of the loop replaces this one; it should keep capital_gains_mtr_rise, the stored-rise divisor and the raise of a given capital_gains total, which it does not have. Its hub has the resolution recipe.
  • Add semi-elasticity and net-of-tax forms for capital gains realization responses #10054 adds the semi-elasticity and net-of-tax forms. It edits a different part of the same file and applies cleanly on top of this branch. Its docs page has a "Known limitation" section describing this defect, and a test of the semi-elasticity form's revenue peak needs its semi_elasticity parameter. Both are written and pass on a tree with both PRs (on that tree, with β = 1/0.30, a Texas filer with $20M of gains pays the most federal income tax at a top rate of 25.25% on a quarter-point grid, against 25.23% solved from the closed form). They go into whichever PR merges second: docs_rewrite.patch and revenue_peak_test_section.py in the evidence folder.

Evidence (scripts and outputs): ~/reviews/crfb-m4a-2026-10/cg-mtr-measurement/.

axiom: n/a: simulation machinery (how the behavioral response measures a marginal rate); no policy provision changes

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 10, 2026 09:26
marginal_tax_rate_on_capital_gains raised capital_gains, the sum of short-
and long-term gains. That reaches adjusted gross income but not net capital
gain, so the rise was taxed as ordinary income: a Texas filer with $1 million
of long-term gains measured 0.298 instead of 0.238, and raising the top
capital gains rate from 20% to 28% left a top-bracket filer's rate, and so
the realization response, unchanged.

Raise long_term_capital_gains instead (the change PR #9698 makes inside its
wider rework of marginal-rate branches), and scale the rise to 0.1% of the
household's net income or the person's gains above $1 million, because a
$1,000 rise resolves a $100 million household's float32 net income only to
0.008 of rate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…00 million of gains

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.55%. Comparing base (909176a) to head (59ddba8).
⚠️ Report is 404 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##              main   #10058      +/-   ##
===========================================
- Coverage   100.00%   96.55%   -3.45%     
===========================================
  Files            4        2       -2     
  Lines           76      116      +40     
  Branches         2        7       +5     
===========================================
+ Hits            76      112      +36     
- Misses           0        2       +2     
- Partials         0        2       +2     
Flag Coverage Δ
unittests 96.55% <100.00%> (-3.45%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

MaxGhenis and others added 3 commits October 11, 2026 08:50
capital_gains adds short- and long-term gains, and adjusted gross income
reads it. A situation that gives the total keeps it as given, so raising
only long_term_capital_gains never reached such a household's income and
its rate measured 0.84 to 1.0 instead of 0.188. Raise the given total by
the same amount, and cover it in the branch-versus-new-simulation property.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s in heavy-a

Fixed household examples (each 2026 Texas bracket, the alternative minimum
tax band, $20M and $100M of gains, wages under gains, joint filers, and
capital_gains totals given as inputs) are YAML cases now, per the repo's test
design rules. The Python file keeps what YAML cannot do: the Hypothesis
properties, reforms read through the measurement branches, and the
differential against new simulations, whose reference now raises a stored
capital_gains total for every adult when any adult gives one (it found a
household where one spouse gave a zero total). The direct reform property
runs three examples instead of four.

The file took 246 s of the core Rest group in CI run 38056548883, so it moves
to heavy-a, which had the lowest time and peak memory of the groups there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 11, 2026
Address the independent review of the semi-elasticity and net-of-tax forms:

- Compare single-rate revenue to within a relative 1e-12 plus an absolute
  1e-15, since 1 + expm1(x) is accurate only to about 2e-16 absolutely, and
  pin the review's two counterexamples as Hypothesis examples.
- Reject a semi-elasticity or net-of-tax elasticity that is negative, above
  50 or 5, or not finite, at the policy level and for person-level values,
  and raise if a new form's response is not finite. The maxima keep float32
  dollar responses finite for gains below $10 quadrillion; a property test
  checks that across both domains. The log-rate form is unchanged.
- Qualify the revenue peaks as single-rate results (beta > 1; e >= 0.003),
  document and test the net-of-tax cap's tail and float32 round trips, and
  state bounds for the multiplier 1 + f.
- Move the household simulations next to the existing behavioral-response
  simulations (Rest heavy-b): fold the default-path differential into the
  existing channel test and drop the conflict simulation. Read defaults from
  the shared system. Compare differentials by bit pattern.
- One reference entry per source with page lists in quoted titles; dated CRS
  attribution; Agersnap and Zidar's ranges; Yale wording; the measurement
  limitation now cites #10058.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits October 11, 2026 12:40
…'s branch

Review r1 of #10058 found two ways the branch lost an input:

- A capital_gains total set through set_input after construction is not
  among the construction inputs the branch keeps, so the branch dropped it
  and rebuilt the total from long-term gains: 73.4 and 231.9 instead of
  0.188. The branch now raises the parent's total whenever set_input stored
  one for the period, at construction or later (tools.period_branch.has_input).
- A variable given for one period kept every period's array, so a 2026
  value calculated before branching survived when the input was for 2025
  (adjusted gross income for 2025 measured 0.000). The branch now drops what
  was calculated for periods the input was not given for
  (drop_inherited_values limited to those variables).

Also neutralize the hours response in the behavioral response measurement
branches, as #9698 does: a capital-gains-first request with labor supply
elasticities otherwise re-entered the measurements through hours and raised
a CycleError. In labor-first order those branches already returned zero for
it through the labor supply response's re-entry guard.

Tests: a late-set total (Python), an input for another year and New York's
$25 million threshold, which the scaled rise spreads over $24,985 (YAML).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…keep inputs by period

- test_responses_do_not_depend_on_which_is_requested_first: with labor supply
  and capital gains elasticities set, requesting either response first gives
  both the same nonzero values. At the previous head the capital-gains-first
  request raised CycleError.
- test_drop_inherited_values_limited_to_variables: limited to some variables,
  drop_inherited_values leaves every other array alone, and has_input reports
  the periods set_input stored, from the situation or later.
- Correct comments: SNAP reads hours before the labor supply response, so
  Texas child care is the program named.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in #10092, which drops main's stale il_aabd entry from the person-adds
ratchet that failed this branch's Rest job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 12, 2026
…n responses (#10054)

* Add semi-elasticity and net-of-tax forms for capital gains responses

The capital gains realization response scaled realizations as the rate to
the power of the elasticity, so revenue had no interior maximum for any
elasticity above -1, and its 0.001 rate floor removed nearly all gains for
anyone starting at a 0% rate. Add a semi-elasticity form (revenue peaks at
1 / semi_elasticity; defined at a 0% rate) and a net-of-tax form, each
selected by setting its parameter. The log-rate elasticity form is
unchanged and remains what a reform setting only `elasticity` gets.

Document the forms, their floors and clips, and calibration to JCT's 1990
coefficient (3.51, a 28.5% peak) and the 3.1 CRS reports JCT now uses.
Add unit, Hypothesis property and differential tests, including a frozen
copy of main's formula that the log-rate path matches bit for bit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Validate capital gains response parameters and fix the revenue tests

Address the independent review of the semi-elasticity and net-of-tax forms:

- Compare single-rate revenue to within a relative 1e-12 plus an absolute
  1e-15, since 1 + expm1(x) is accurate only to about 2e-16 absolutely, and
  pin the review's two counterexamples as Hypothesis examples.
- Reject a semi-elasticity or net-of-tax elasticity that is negative, above
  50 or 5, or not finite, at the policy level and for person-level values,
  and raise if a new form's response is not finite. The maxima keep float32
  dollar responses finite for gains below $10 quadrillion; a property test
  checks that across both domains. The log-rate form is unchanged.
- Qualify the revenue peaks as single-rate results (beta > 1; e >= 0.003),
  document and test the net-of-tax cap's tail and float32 round trips, and
  state bounds for the multiplier 1 + f.
- Move the household simulations next to the existing behavioral-response
  simulations (Rest heavy-b): fold the default-path differential into the
  existing channel test and drop the conflict simulation. Read defaults from
  the shared system. Compare differentials by bit pattern.
- One reference entry per source with page lists in quoted titles; dated CRS
  attribution; Agersnap and Zidar's ranges; Yale wording; the measurement
  limitation now cites #10058.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Qualify the state-rate revenue peak and drop the Hypothesis deadline

Address the second review of the capital gains response forms:

- The analytical federal peak at 1 / semi_elasticity with a fixed state rate
  holds only before the clip binds; state that it is the maximum only when
  beta * (1 - s) - ln(beta) > 1 (a state rate below about 31% to 36% for
  beta of 3.1 to 3.51), and add beta > 1 to the changelog.
- Remove Hypothesis's 200 ms deadline from the two float32 array properties,
  which once took 253 ms to generate on a loaded machine.
- Say a new form's response can also stop being finite when gains exceed
  the documented $10 quadrillion bound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Make capital-gains round-trip precision checks portable

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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