Calculation catalog › Spending and withdrawals
Display upside shortfall annual
Ideal plus excess spending not funded.
Field: Upside miss Unit: US dollars Basis: nominal dollars Computed by: UI transformation Status: Complete chain
Appears in: results-table (Layer miss "Upside")
Calculation records
-
Upside miss: upside spending not funded Composition record, justified by derivation
Purpose: The ideal and excess spending the year did not fund, as the Upside part of the Layer miss column shows it.
Statement: projection/yearFigures.ts#upsideShortfall publishes idealShortfall + excessShortfall for the year. Units: nominal USD of the year. Rounding: none.
Formula:
upsideShortfall = idealShortfall + excessShortfall-
idealShortfall: Ideal spending not funded (unit: usd per year) (domain: nonnegative) -
excessShortfall: Excess spending not funded (unit: usd per year) (domain: nonnegative)
Timing: annual
Rounding: none
Limits:
- None beyond the layer attribution's own (spending-layer-shortfall-attribution); the page's show-or-blank test for the Layer miss cell reads the three engine figures separately rather than adding the four shortfalls, which renders the same cell in every case
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-upside-shortfall-annual.md Mutation receipt: display-upside-shortfall-annual.mutation.md
Evidence tests: yearFigures.evidence.test.ts
Implemented in: yearFigures.ts; result.ts
Is the number of: display-upside-shortfall-annual
-
Records that feed this number
-
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
-
-
Spending layer shortfall attribution Formula record, justified by derivation
Purpose: Attribute annual spending misses to required, target, ideal and excess layers.
Statement: spending/layers.ts#attributeShortfall first reduces the spending attempted after any guardrail cut by the withdrawal shortfall to obtain actually funded dollars, then attributes the miss of each layer against those dollars: the target miss includes the deliberate guardrail cut as well as every attempted dollar the portfolio could not produce; the required miss is the floor minus actually funded dollars, floored at zero; ideal and excess misses are the gaps in their successive layers. No rounding.
Formula:
A=max(0,F-max(0,W)); Rmiss=max(0,R-A); Tmiss=max(0,T-A); Imiss=I-max(0,min(I,A-T)); Xmiss=X-max(0,min(X,A-T-I))-
R,T,I,X: Required, target, ideal increment, excess increment (unit: nominal USD/year) (domain: nonnegative; T >= R) -
F: Spending attempted after any guardrail cut (fundedSpending) (unit: nominal USD/year) (domain: nonnegative) -
W: Withdrawal shortfall: attempted dollars the waterfall could not produce (unit: nominal USD/year) (domain: nonnegative) -
A: Actually funded dollars, F less W (unit: nominal USD/year) (domain: nonnegative)
Timing: annual after spending and withdrawals
Rounding: none
Limits:
- The first derivation read fundedSpending as delivered dollars and expected a $15 target miss where production returns $20; the doc comment says attempted, so the worksheet was re-derived and now carries a second case (F=62, W=5) that exposes the guardrail cut in the required miss.
Provenance: derived by
codex, implemented bycodex.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: spending-layer-shortfall-attribution.md Mutation receipt: spending-layer-shortfall-attribution.mutation.md
Evidence tests: layers.evidence.test.ts
Implemented in: layers.ts
Is the number of: spending-required-shortfall-annual, spending-target-shortfall-annual, spending-ideal-shortfall-annual, spending-excess-shortfall-annual
-
Transformations
- Add idealShortfall and excessShortfall in projection/yearFigures.ts#upsideShortfall, then apply the selected dollar basis.
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.