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

    Independent review: grok

    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: 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.