Calculation catalog › Longevity
Longevity depletion year
First projection year with any spending shortfall; null when investable assets last through the horizon.
Field: Depletion year Unit: calendar year Basis: no dollar basis Computed by: Engine Status: Complete chain
Appears in: results-headline (KpiBar "Money lasts" sub "short in YEAR"); results-headline (ResultsPage narrative "This plan runs out of money in YEAR"); results-table (Balances chart "depleted" reference line and "Portfolio depletes in YEAR" callout); report (headline-results block depletionYear); compare-page (Depletion age (NAME) row: the older person's age in that year, named in the label (PlanHeadlineComparison.depletionAge, whose person PlanHeadlineComparison.depletionAgePersonId gives)); scenarios-page (Headline "Depletion year"); ss-page (Claim-age table "Depletes" column YEAR / never); survivor-page (Degenerate-timings note "runs out of money in YEAR"); relocation-page (RelocationCandidateRow.depletionYear (carried)); monte-carlo-page (Historical stress windows "Depletes" column); insights (InsightCardView flat-delta note "The base plan runs out of money in YEAR"); mcp (run_projection.summary.depletionYear); mcp (compare_scenarios.a.depletionYear); mcp (compare_scenarios.b.depletionYear); optimize-page (Couldn't-optimize well and the solver-limit note "Your plan's projection runs short of money in YEAR" (OptimizedSchedule.projectionDepletionYear, when the first solve has no solution)); mcp (run_optimizer.schedule.projectionDepletionYear (present only when the first solve has no solution))
Calculation records
-
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
-
Transformations
- Compare view differences the engine's last funded years (projection/moneyLasts.ts#lastFundedYear, re-exported by compareDeltas.ts).
Engine source: engine/src/projection/internal/types/result.ts
(ProjectionResult.depletionYear)
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.