Calculation catalog › Cash flow and summary
Spending target shortfall annual
Unfunded target lifestyle spending in the projection year.
Field: targetShortfall Unit: US dollars Basis: nominal dollars Computed by: Engine Status: Complete chain
Appears in: csv (targetShortfall); results-table (Layer miss "Target"); scenarios-page (Annual "Target shortfall" and lifetime "Target-lifestyle shortfall")
Calculation records
-
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
-
Records that feed this number
-
Annual target-layer requested spending Composition record, justified by derivation
Purpose: The full no-cut request through the target lifestyle layer.
Statement: projection/internal/annualExpenseSummary.ts#annualExpenseSummary publishes YearExpenses.targetSpending as targetSpendingBase + skippedTargetNominal + skippedRequiredNominal, where targetSpendingBase = systemRequired + requiredLifestyle + targetLifestyle + targetGoalsFunded + requiredGoalsFunded. The base carries the FULL target lifestyle layer, not the guardrail-cut amount, and carries no skipped amount; the two skipped amounts are then added once each. Equivalently, published requiredSpending already contains skippedRequiredNominal, so targetSpending is requiredSpending + targetLifestyle + targetGoalsFunded + skippedTargetNominal. Units: nominal USD per year. Rounding: none.
Formula:
targetSpending = (systemRequired + requiredLifestyle + targetLifestyle + targetGoalsFunded + requiredGoalsFunded) + skippedTargetNominal + skippedRequiredNominal-
targetLifestyle: Full target lifestyle layer before any guardrail cut (unit: usd/year) (domain: nonnegative) -
targetGoalsFunded: Target-classified goals funded this year (unit: usd/year) (domain: nonnegative) -
skippedTargetNominal, skippedRequiredNominal: Nominal amounts of skipped goals in those two layers (unit: usd/year) (domain: nonnegative; counted once each)
Timing: once per projection year, at the expense summary
Rounding: none
Limits:
- Asserted at the annualExpenseSummary seam, which is the function that computes the field, because the worksheet states its inputs as already-folded year-row components rather than as plan inputs a single year could realize at those exact values
- The full target lifestyle layer is used here even in a cutting year; the cut amount appears in baseSpending instead, so a test that substitutes the cut layer is asserting a different field
- Both equivalent forms are asserted, so the "counted once each" clause is evidence rather than prose: starting from the published requiredSpending and adding skippedRequiredNominal again is one of the worksheet's wrong readings
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: spending-target-requested-annual.md Mutation receipt: spending-target-requested-annual.mutation.md
Evidence tests: annualExpenseSummary.evidence.test.ts
Implemented in: annualExpenseSummary.ts
Is the number of: spending-target-requested-annual
-
Engine source: engine/src/projection/internal/types/result.ts
(YearResult.targetShortfall)
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.