Calculation catalog › Longevity
Longevity last funded year
The last plan year the portfolio fully funds: the year before the depletion year, or the plan's last year when it never depletes.
Field: Last fully funded year Unit: calendar year Basis: no dollar basis Computed by: Engine Status: Complete chain
Appears in: results-headline (Depletion sentence "Money lasts through L"); results-headline (KpiBar "Money lasts" value "through L", or "short from S" when the first year is short); report (Printed report KPI "Money lasts" value "through L", or "short from S" when the first year is short); report (Downloadable HTML report headline "Money lasts" "Through L (runs short in D)"); ss-page (Bridge comparison "Money lasts" "through L" / "full plan"); compare-page (Money lasts row "through L" / "short from S" / "full plan through E")
Calculation records
-
Money lasts: the last funded year and the years short of the plan's end Formula record, justified by derivation
Purpose: One convention for how long the money lasts: the last fully funded year, and how many plan years the money falls short of the plan's end.
Statement: projection/moneyLasts.ts#moneyLasts publishes lastFundedYear = depletionYear - 1, or endYear when the projection never depletes, and yearsShortOfPlanEnd = endYear - lastFundedYear: 0 when it never depletes and endYear - depletionYear + 1 when it does, so a plan short only in its final year reads 1. A depletion year outside the projection's years is refused. The decision and optimizer money-lasts deltas are differences of lastFundedYear. Units: calendar year; count of years. Rounding: none.
Formula:
L = D - 1 when D is not null, else E; N = E - L-
D: Depletion year: first year with a funding shortfall above half a cent after any HECM backstop (unit: calendar year) (domain: integer in [startYear, E], or null) -
E: The plan's inclusive last year (unit: calendar year) (domain: integer) -
L: Last fully funded year (unit: calendar year) (domain: startYear - 1 when the first year is short) -
N: Years short of the plan's end (unit: years) (domain: integer, 0 when D is null)
Timing: the ledger's annual rows
Rounding: none
Limits:
- A distance, not a count of shortfall years: a year after the depletion year can be funded again if income resumes
- Deterministic ledger only; the Monte Carlo pages have their own depletion distribution
- Owner decision R15 (2026-09-25): the Results sentence used to read endYear - depletionYear years before the end (0 for a plan short only in its final year), the KPI bar and the printed report named the depletion year as the year the money lasts until, and the decision code counted a non-depleting plan as lasting through endYear + 1. Every surface now names the last funded year and counts endYear - lastFundedYear. The decision and optimizer deltas did not move: both conventions shift every result by the same one year
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-years-before-plan-end.md Mutation receipt: display-years-before-plan-end.mutation.md
Evidence tests: moneyLasts.evidence.test.ts
Implemented in: moneyLasts.ts; evaluateCandidate.ts
Is the number of: display-years-before-plan-end, longevity-last-funded-year
Feeds: compare-plan-deltas
-
Records that feed this number
-
Depletion year: the first projection year whose shortfall clears the funding tolerance Model record, justified by derivation
Purpose: The year the headline results call the plan depleted, or null when every year was funded.
Statement: ProjectionResult.depletionYear is the first projection year, in year order, whose YearResult.shortfall (the funding shortfall left after every withdrawal and any HECM backstop draw) is strictly greater than projection/moneyTolerance.ts#ANNUAL_FUNDING_TOLERANCE_PLAN_DOLLARS ($0.005, the ledger's own residual budget). A residual at or below that budget is not depletion; once a year is recorded the value is never replaced by a later one; and the field is null when no year exceeds the tolerance. Units: calendar year, or null. Rounding: none; the comparison is strict.
Formula:
depletionYear = min{ y : shortfall_y > ANNUAL_FUNDING_TOLERANCE_PLAN_DOLLARS }, else null-
shortfall_y: Year y's funding shortfall after every withdrawal and any HECM backstop draw (unit: usd) (domain: shortfall_y >= 0) -
ANNUAL_FUNDING_TOLERANCE_PLAN_DOLLARS: The funding fixed point's accepted residual (unit: usd) (domain: 0.005) -
depletionYear: First qualifying calendar year (unit: year) (domain: a projection year, or null)
Timing: annual; tested in each year's funding-and-close phase, in year order
Rounding: none; strictly greater than the half-cent tolerance
Limits:
- Beyond the worksheet's inputs the evidence plan fixes: one cash account (so no market shock and no taxable yield reach it), a 51-year-old single filer under 65 (no Medicare premium, no early-withdrawal exposure), zero income, zero inflation and zero return, base spending as the only expense, and an explicit horizonEndYear of 2028 so the three rows are exactly 2026-2028
- The tolerance is a residual budget, not a balance test: a year that closes at exactly zero with every dollar of spending funded is not depletion, which is why the $30,000 opening balance against the same $10,000 gap still publishes null
- The field records the FIRST qualifying year only; later shortfalls do not move it, and a plan that recovers after a shortfall year still reports that year
- The comparison is strict (>), so a shortfall of exactly $0.005 is accepted as a rounding residual rather than depletion; the evidence does not pin that boundary, which would need a plan whose funding residual lands on the tolerance exactly
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: longevity-depletion-year.md Mutation receipt: longevity-depletion-year.mutation.md
Evidence tests: simulate.depletionYear.evidence.test.ts
Implemented in: simulate.ts; annualFundingApplicationAndClosePhase.ts
Is the number of: longevity-depletion-year
Feeds: display-years-before-plan-end, longevity-last-funded-year
-
Engine source: engine/src/projection/moneyLasts.ts
(MoneyLasts.lastFundedYear)
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.