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 by claude-subagent.

    Independent review: codex

    Gates (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 by claude.

    Independent review: cursor

    Gates (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.