Calculation catalog › Cash flow and summary
Spending debt service annual
Principal and interest paid on modeled debts during the projection year.
Field: debtService Unit: US dollars Basis: nominal dollars Computed by: Engine Status: Complete chain
Appears in: csv (debtService); chart (Spending by category "Debt payments"); cash-flow-drilldown (debtService use line)
Calculation records
-
Annual debt service under the grow-then-pay convention Formula record, justified by derivation
Purpose: What the year's debts actually cost, once interest is charged before the payment.
Statement: projection/internal/types/yearLedger.ts#YearExpenses.debtService, planned by projection/internal/annualDebtAndLongTermCare.ts#annualDebtServiceRows, is the sum over debt accounts with a positive balance of the year's payment, where the opening balance first grows by 1 + interestPct/100 and the year then pays the whole grown balance when payoffYear is set and reached, else min(grown balance, monthlyPayment x 12). The level payment is never inflated and self-caps at the balance. Units: nominal USD per year. Rounding: none; the ordered fold is a binary float.
Formula:
grown_i = B_i (1 + r_i); pay_i = payoff ? grown_i : min(grown_i, 12 m_i); debtService = sum_i pay_i-
B_i: Opening balance of debt i (unit: usd) (domain: positive) -
r_i: Annual interest rate (unit: 1) (domain: interestPct / 100) -
m_i: Level monthly payment (unit: usd/month) (domain: nonnegative) -
payoff: Scheduled payoff reached (unit: boolean) (domain: year >= payoffYear)
Timing: once per projection year, before the funding solve
Rounding: none
Limits:
- Asserted twice: at the exported phase helper with the worksheet's two debts verbatim, and as the published expenses.debtService of a real simulatePlan 2030 row carrying the same two debts. Plan assumptions beyond the worksheet's inputs for that ledger row: a single 60-year-old filing single in KY at a zero state rate, zero general inflation, zero account returns, and one 500,000 cash account large enough that the payments are funded without a portfolio sale
- The worksheet's third wrong reading (ignoring payoffYear) coincides with the right answer at these inputs, so the test discriminates the first two numerically and states the third as a rule
- Restated 2026-09-29 under decision D-2027-ROLLOVER (review L4): a payoff year before the projection start year is reached in the first year, so the ledger pays the whole grown balance then, as it always did; nothing moves. The projection now names it (projection/preStartEvents.ts#preStartEvents) with the amount paid, the balance with a year of interest, and says to set the balance to $0 if the debt was paid. From a 2027 start the reviewer's mortgage with a 2026 payoff moved ending net worth by -$189,695.85 with nothing said
Provenance: derived by
codex, implemented byclaude.Independent review:
grokGates (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-debt-service-annual.md Mutation receipt: spending-debt-service-annual.mutation.md
Evidence tests: annualDebtAndLongTermCare.evidence.test.ts
Implemented in: yearLedger.ts; annualDebtAndLongTermCare.ts; preStartEvents.ts
Is the number of: spending-debt-service-annual
Feeds: spending-total-annual
-
Engine source: engine/src/projection/internal/types/result.ts
(YearResult.expenses.debtService)
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.