Calculation catalog › Accounts and growth
Accounts net worth annual
Modeled total net worth at the end of a projection year.
Field: Net worth Unit: US dollars Basis: nominal dollars Computed by: Engine Status: Complete chain
Appears in: csv (netWorth); report (headlineResults); results-table (Net worth column); report (year-ledger block netWorth and ReportPage year table); scenarios-page (Annual "Net worth")
Calculation records
-
Annual net worth, with the non-recourse HECM cap Composition record, justified by derivation
Purpose: The year-end balance sheet, including the homes and the debts the investable total leaves out.
Statement: projection/internal/annualYearResultAssembly.ts#annualYearResultAssembly publishes projection/internal/types/result.ts#YearResult.netWorth as snapshot.investableTotal + snapshot.propertyTotal - snapshot.debtTotal + snapshot.insuranceCashValueTotal + ladderValue - snapshot.hecmEffectiveDebt, in that left-to-right association. projection/internal/annualSnapshot.ts#annualSnapshot supplies hecmEffectiveDebt as the sum over open HECM lines of min(loanBalance, the matching property value), the non-recourse limit; the uncapped loan total is published separately as hecmLoanBalance and is never the net-worth subtrahend. Units: nominal USD at year end. Rounding: none; the association is part of the contract.
Formula:
netWorth = investableTotal + propertyTotal - debtTotal + insuranceCashValueTotal + ladderValue - sum over HECM lines of min(loanBalance, propertyValue)-
propertyTotal: Sum of owned property values at year end (unit: usd) (domain: nonnegative) -
debtTotal: Sum of ordinary debt balances (unit: usd) (domain: nonnegative; subtracted) -
insuranceCashValueTotal: Permanent-life cash values (unit: usd) (domain: nonnegative) -
ladderValue: Remaining TIPS-ladder principal at nominal book value (unit: usd) (domain: nonnegative) -
hecmEffectiveDebt: HECM loans capped line by line at the matching home value (unit: usd) (domain: nonnegative; subtracted)
Timing: once per projection year, at the year-result assembly
Rounding: none
Limits:
- The worksheet's case is asserted at annualSnapshot and annualYearResultAssembly, the two functions that compute the cap and the composition, because the worksheet states HECM loan balances of $420,000 and $50,000 as year-end facts: a HECM balance is an accrual of draws, interest and mortgage-insurance premium that no plan can set directly, so those two figures are not a state a plan produces
- Only the cap is capped: a loan above its home's value is limited to that value, while a loan below it is subtracted in full, which is why the worksheet's two homes need two different branches of the same min
- Ordinary debt is subtracted, not added; adding it is the worksheet's third wrong reading and moves the answer by twice the debt
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: accounts-net-worth-annual.md Mutation receipt: accounts-net-worth-annual.mutation.md
Evidence tests: annualYearResultAssembly.evidence.test.ts
Implemented in: annualYearResultAssembly.ts; annualSnapshot.ts; result.ts
Is the number of: accounts-net-worth-annual
-
Records that feed this number
-
Annual investable total Composition record, justified by derivation
Purpose: The year-end balance a plan can actually spend from, and what is deliberately left out.
Statement: projection/internal/annualSnapshot.ts#annualSnapshot opens the investable fold at unassignedCash and adds every investable balance in simulator order (cash, taxable, equity-compensation, traditional, Roth and HSA accounts), publishing the sum as projection/internal/types/result.ts#YearResult.investableTotal. Property values, ordinary debts, HECM loans and permanent-life cash values are folded into their own separate totals and are not members; the TIPS ladder value is computed outside the snapshot and is likewise not a member. netWorth adds those channels. Units: nominal USD at year end. Rounding: none; the additions are left in their original loop order because regrouping binary floats can move the last bit.
Formula:
investableTotal = unassignedCash + sum over investable balances of balance-
unassignedCash: Cash with no modeled account to land in; opens the fold (unit: usd) (domain: nonnegative) -
balance: One investable account's year-end balance (unit: usd) (domain: nonnegative) -
insuranceCashValueTotal, propertyTotal, debtTotal, ladderValue: Separate channels, excluded here (unit: usd) (domain: nonnegative; members of netWorth only)
Timing: once per projection year, at the end-of-pass snapshot
Rounding: none
Limits:
- The worksheet's case is asserted at annualSnapshot, the function that computes the field, because unassigned cash and a cash or taxable account cannot coexist in a real plan: simulatePlan only tracks cash as unassigned when there is no cash or taxable account for surplus to land in, so the worksheet's $2,000 of unassigned cash alongside $15,000 of cash accounts and $120,000 of taxable accounts is not a state a plan produces
- The member list is separately asserted on a real simulatePlan run carrying the worksheet's six account balances plus a permanent-life policy: the published investableTotal is the six balances and excludes the policy cash value and the property, both of which the same row publishes
- Equity compensation is a member whether or not it has vested; the vesting mode gates spending, not the balance total
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: accounts-investable-total-annual.md Mutation receipt: accounts-investable-total-annual.mutation.md
Evidence tests: annualSnapshot.evidence.test.ts
Implemented in: annualSnapshot.ts; result.ts
Is the number of: accounts-investable-total-annual
Feeds: accounts-net-worth-annual, projection-result-ending-investable
-
-
Annual HECM draw, including the last-resort backstop Formula record, justified by derivation
Purpose: What an open reverse-mortgage line actually lends the household this year.
Statement: projection/internal/types/result.ts#YearResult.hecmDraw is the accepted coordinated draw plus any backstop draw planned by projection/internal/annualHecmBackstop.ts#annualHecmBackstopPlan against a true portfolio shortfall. With the coordinated draw zero, the backstop is min(true shortfall, available open line), where the available line is max(0, principalLimit - loanBalance); draw policy does not gate it, because every open line is a last backstop before the household is reported depleted. Units: nominal USD per year. Rounding: none.
Formula:
backstop = min(shortfall, max(0, principalLimit - loanBalance)); hecmDraw = coordinated + backstop; shortfallAfterHecm = max(0, shortfall - backstop)-
shortfall: True portfolio shortfall before the backstop (unit: usd) (domain: above the annual funding tolerance) -
principalLimit: HECM line principal limit (unit: usd) (domain: nonnegative) -
loanBalance: Amount already drawn on the line (unit: usd) (domain: nonnegative)
Timing: once per projection year, after the accepted withdrawal plan
Rounding: none
Limits:
- Asserted twice: at the exported backstop planner with the worksheet's open line, 40,000 shortfall and 25,000 available line verbatim, and as the published hecmDraw of a real simulatePlan year built from the same inputs (a last-resort line on a 500,000 primary residence at the schema's minimum 5-percent principal limit and a zero growth rate, so the available line is exactly 25,000, against a 40,000 lifestyle need with no portfolio at all). Plan assumptions beyond the worksheet's inputs for that ledger year: a 64-year-old filing single in KY at a zero state rate, so no Medicare or marketplace premium can change the need, and no coordinated draw is possible because the policy is lastResort
- The worksheet derives only the backstop case; the extract states no sizing formula for a coordinated draw, so this record makes no claim about one
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: hecm-draw-annual.md Mutation receipt: hecm-draw-annual.mutation.md
Evidence tests: annualHecmBackstop.evidence.test.ts
Implemented in: result.ts; annualHecmBackstop.ts
Is the number of: hecm-draw-annual
-
-
Annual permanent-life cash value and death-year settlement Model record, justified by derivation
Purpose: What a permanent-life policy is worth at year end, and what it pays in the insured's death year.
Statement: projection/internal/types/result.ts#YearResult.insuranceCashValue and #YearResult.deathBenefit, transitioned by projection/internal/annualPermanentLifeTransitions.ts#annualPermanentLifeTransitions, publish the year-end cash-value asset and the death-year settlement. While the insured is below the death age, schedule mode interpolates the illustration table linearly by attained age with endpoint clamping and flat-rate mode compounds the prior cash value by cashValueGrowthPct. In the year attained age equals the death age the policy pays max(deathBenefit face amount, cash value) and its cash value becomes 0, and it stays 0 afterwards. Units: nominal USD. Rounding: none.
Formula:
schedule: cv = v_lo + (a - a_lo)/(a_hi - a_lo) (v_hi - v_lo); flat: cv = cv_prev (1 + g); death year: payout = max(face, cv_prev), cv = 0-
a: Insured attained age (unit: years) (domain: clamped to the schedule ends) -
v_lo, v_hi: Bracketing illustration values (unit: usd) (domain: nonnegative) -
g: Flat cash-value growth (unit: 1) (domain: cashValueGrowthPct / 100) -
face: Current face death benefit (unit: usd) (domain: nonnegative)
Timing: once per projection year, per policy in plan order
Rounding: none
Limits:
- Asserted at the exported phase helper with the worksheet's two policies, their modes, schedule points, entry cash value, growth rate and face amounts verbatim. Plan assumptions beyond the worksheet's inputs: both policies are paid-up, which this transition does not read
- The first derivation put the settling policy at attained age 71 while its Claim and Arithmetic described and calculated the death-age-70 year; that derivation was corrected on 2026-09-18. The worksheet's Inputs table now states attained age 70, the death year production settles in, where the payout is max(50,000 face, 60,000 cash value) = 60,000 and the settled policy stops being a cash-value asset. Its last wrong reading moves that row to attained age 71 (the year after the death year, where the payout is null and the cash value 0) and the test asserts both, so no production-versus-worksheet discrepancy remains
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: insurance-cash-value-and-death-benefit-annual.md Mutation receipt: insurance-cash-value-and-death-benefit-annual.mutation.md
Evidence tests: annualPermanentLifeTransitions.evidence.test.ts
Implemented in: result.ts; annualPermanentLifeTransitions.ts
Is the number of: insurance-cash-value-annual, insurance-death-benefit-annual
Feeds: accounts-net-worth-annual
-
Engine source: engine/src/projection/internal/types/result.ts
(YearResult.netWorth)
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.