Display tax free gains room annual
The largest additional long-term gain realizable this year without raising the year's federal income tax, as the engine's federal calculator computes it with the gain netted through any loss carryforward first.
Field: Tax-free gains room Unit: US dollars Basis: nominal dollars Computed by: UI transformation Status: Complete chain
Appears in: results-table (Tax-free gains room column)
Calculation records
-
Tax-free gains room: extra long-term gain at no extra federal tax Model record, justified by derivation
Purpose: How much more long-term gain the year could realize without raising the year's federal income tax.
Statement: projection/yearFigures.ts#taxFreeGainsRoom publishes the largest extra long-term capital gain whose realization, netted through the capital-loss carryforward by applyCapitalLossCarryforward and priced by computeFederalTax on the year's published advisory input, does not raise the year's federal income tax (regular tax, AMT and NIIT). The opening pool is rebuilt from the published netting. The search doubles an upper bound from $1 until tax rises by more than $0.000001, then bisects to a $0.01 bracket and returns its lower end. Null when the row carries no advisory federal tax input. premiumTaxCreditYear marks the years with a modeled ACA premium credit, which the room does not price. Units: nominal USD of additional gain. Rounding: the bisection's lower end.
Formula:
R = max{ g >= 0 : F(h) <= F(0) for every h in [0, g] }; F(g) = computeFederalTax({ ...I, capitalGains: N(g), realizedCapitalGainsBeforeCarryforward: G + g }).totalTax; N(g) = applyCapitalLossCarryforward(P, I.ordinaryIncome, G + g, L).netCapitalGain; P = remaining + usedAgainstOrdinary + usedAgainstGains - max(0, -G)-
I: The year's advisory federal tax input (YearResult.advisoryFederalTax.input) (unit: tax input) (domain: published by every ledger row) -
G: The year's signed realized gain before netting (unit: usd) (domain: finite) -
P: Opening carryforward pool, rebuilt from the published netting (unit: usd) (domain: nonnegative up to binary rounding) -
L: The year's capital loss offset limit (unit: usd) (domain: 3,000) -
R: Published room (unit: usd of extra long-term gain) (domain: in [R - 0.01, R + 1e-6/m], m the marginal rate just past R)
Timing: annual, on top of everything the year already realized
Rounding: bisection to $0.01 with a $0.000001 tax tolerance; the lower end is published
Limits:
- Federal income tax only. State income tax on the gain is not included, nor a smaller ACA premium tax credit (the ledger books it as a higher net premium; if the credit was paid in advance, the part lost is paid back as federal tax at filing; the years with a modeled credit are marked), nor a Medicare premium surcharge two years later
- This year only: gains the carryforward absorbs reduce what carries into later years
- Everything else in the year is held fixed (withdrawals, the funding solve, state tax); the recomputation starts from the advisory input, whose federal tax can differ from the settled tax of the funding solve
- Exact when federal tax does not fall as a gain is added, which holds for every input except an itemized charitable deduction bound by a percentage-of-AGI ceiling; there the search returns a gain at which tax has not risen, not necessarily the first point at which it would
- The engine's carryforward limits apply: a single pool with no short- and long-term split, the $3,000 limit for every filing status, and no 1212(b)(2) preservation of a deduction unused in a zero-income year
- The opening pool is rebuilt from the published netting; exact in real arithmetic, within a few units in the last binary place otherwise
- Owner decision R2 (2026-09-25): before this record the page showed the 0% band room plus the remaining carryforward. That overstated the room at no tax whenever the gain would make Social Security taxable, use up the $3,000 loss deduction, shrink the senior deduction, or reach the net investment income tax threshold (the last two are not indexed while the 0% band is). year-result-ltcg-zero-headroom stays published as the 0% band room
Provenance: derived by
claude, implemented byclaude-subagent.Independent review:
codexGates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass
Worksheet: display-tax-free-gains-room-annual.md Mutation receipt: display-tax-free-gains-room-annual.mutation.md
Evidence tests: yearFigures.taxFreeGainsRoom.evidence.test.ts
Implemented in: yearFigures.ts; federalTax.ts; result.ts
Is the number of: display-tax-free-gains-room-annual
-
Records that feed this number
-
Capital-loss carryforward netting Composition record, justified by derivation
Purpose: Spend a capital-loss pool against current gains first, then report the annual ordinary-offset slice on the capital-gain line.
Statement: tax/federalTax.ts#applyCapitalLossCarryforward applies an annual capital-loss pool first against current gains, then reports up to the annual ordinary-offset limit as a negative capital-gain-line amount without changing ordinary income, and carries the unused pool forward. The offset is not capped by ordinary income. Units: nominal USD. Rounding: none.
Formula:
usedAgainstGains = min(C, max(G, 0)); availableLoss = C - usedAgainstGains + max(-G, 0); usedAgainstOrdinary = min(availableLoss, L); netCapitalGain = max(G, 0) - usedAgainstGains - usedAgainstOrdinary; remaining = availableLoss - usedAgainstOrdinary-
C: Opening carryforward pool (unit: usd) (domain: nonnegative after the max(0, .) floor) -
G: Signed current capital result; a loss is negative (unit: usd) (domain: any finite number) -
L: Annual ordinary-offset limit, year2026.federalTax.capitalLossOrdinaryOffsetLimit (unit: usd/year) (domain: nonnegative after the max(0, .) floor)
Timing: one tax year; the projection threads the depleting pool year to year
Rounding: none
Limits:
- Ordinary income is never reduced directly: the deductible loss rides the capital-gain line, so subtracting the offset from ordinary income instead publishes a different AGI cascade
- One pool, no short-term / long-term split, and the section 1212 preservation of a deduction wasted in a year with no taxable income to absorb it is not modeled; both are stated planning simplifications on the function
Provenance: derived by
codex, implemented byclaude.Independent review:
cursorGates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass
Worksheet: capital-loss-carryforward-netting.md Mutation receipt: capital-loss-carryforward-netting.mutation.md
Evidence tests: federalTax.evidence.test.ts
Implemented in: federalTax.ts
Is the number of: tax-loss-carryforward-remaining-annual, tax-loss-carryforward-used-against-gains-annual, tax-loss-carryforward-used-against-ordinary-annual
Feeds: tax-total-annual, display-loss-carryforward-used-annual, display-tax-free-gains-room-annual
-
-
Today's dollars by the ledger's own inflation factor Formula record, justified by derivation
Purpose: How a year's nominal amount becomes start-year dollars on every page, and how a start-year figure such as the FI target is placed in a year's dollars.
Statement: projection/dollarBasis.ts converts a nominal amount x of projection year y to start-year dollars as x / f(y), and a start-year amount to year-y dollars as x * f(y), where f(y) is the ledger's published YearResult.inflationScale: the left-to-right product of (1 + inflationPct/100) taken y - startYear times from 1, exactly 1 in the start year. projectionDollarBasis reads the factors from a projection's rows; planDollarBasis runs the same recurrence for a page that holds no projection rows and is bit-identical to a deterministic run's factors. nominalForDisplay shows a nominal amount in the page's mode (converted in today's-dollar mode, unchanged in nominal mode) and todayForDisplay shows a start-year amount (unchanged in today's-dollar mode, times f(y) in nominal mode), so the FI target line is fiNumber itself in today's-dollar mode and fiNumber * f(y) in nominal mode. A year outside the projection, or a fractional year, is refused. Units: USD. Rounding: none.
Formula:
f(s) = 1; f(y) = f(y - 1) * (1 + i/100); today(y, x) = x / f(y); nominal(y, x) = x * f(y); FI target in year y = fiNumber (today mode) or fiNumber * f(y) (nominal mode)-
i: General inflation rate, plan.assumptions.inflationPct (unit: percent per year) (domain: finite, above -100) -
s: Projection start year, the first ledger row (unit: calendar year) (domain: integer) -
y: Year of the amount (unit: calendar year) (domain: integer in [s, endYear]) -
x: Amount converted (unit: usd) (domain: finite) -
f(y): Cumulative general-inflation factor, YearResult.inflationScale (unit: ratio) (domain: f(s) = 1)
Timing: annual; one factor per calendar year, applied to every amount of that year
Rounding: none
Limits:
- planDollarBasis is the plan's assumed rate and matches only a deterministic run: a Monte Carlo path grows by its own inflation series, so its rows are converted with projectionDollarBasis on that path's own result
- Start-year dollars in whole-year steps: an amount paid in December and one paid in January of the same year carry the same factor
- General inflation only: the healthcare inflation premium and the Social Security cost-of-living adjustment are separate assumptions and are never the basis
- Years outside the projection are refused, never extrapolated; a projection whose horizon ends before its start year has an empty basis in which every year is refused
- Owner decision R19 (2026-09-25): the planner pages used to compound the plan's rate with Math.pow from the page's start year. The ledger's factor is a product built one year at a time, which differs from the power in the last binary digit in some years (21 of 41 years at 2.5 percent, one unit each), so a whole-dollar figure can change only on an exact half-dollar tie; the FI target in today's-dollar mode becomes exactly fiNumber instead of fiNumber * f / f
- The FI target is recorded here rather than in a record of its own: it is projection-summary-fi-number placed in a year through todayForDisplay
- Since B2-P1 slice 2 the spending page converts nothing itself: each published withdrawal rule's ending estate is converted by that rule's own run (decisions/swrComparator.ts#compareSwrRules publishes endingAfterTaxEstateTodayDollars), and the solver's evidence estate by the answer run's own factors; planDollarBasis remains for the relocation page
Provenance: derived by
claude, implemented byclaude-subagent.Independent review:
codexGates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass
Worksheet: display-dollar-basis-conversion.md Mutation receipt: display-dollar-basis-conversion.mutation.md
Evidence tests: swrComparator.evidence.test.ts; dollarBasis.evidence.test.ts
Implemented in: dollarBasis.ts; detectorProjection.ts; result.ts; swrComparator.ts
Is the number of: display-dollar-basis-conversion, display-fi-target-annual
Feeds: display-balance-by-category-annual, display-net-care-cost-annual, display-tax-free-gains-room-annual, display-tax-plus-penalties-annual, display-total-spending-annual, display-upside-shortfall-annual, display-upside-spending-annual
-
Transformations
- Bisection on the recomputed federal tax of the year's advisory input with the extra gain netted through the carryforward (projection/yearFigures.ts#taxFreeGainsRoom, owner decision R2), then apply the selected dollar basis; years with a modeled ACA premium credit carry a marker.
The evidence links on this page (each record's worksheet, mutation receipt, evidence tests
and implementation, and the source links) are pinned to engine commit
2624dbdba9fd, committed 2026-10-11.
The live calculation index and
output-family census links point at the repository's main
branch, so you can check this snapshot against them.