Every number in the engine is computed from the bank's own monthly summaries. Nothing is a black box: each one fits in a sentence.
| I | Typical monthly money in | Median of money_in |
| F | Typical fixed costs | Median of household_bills + insurance + loan_payments |
| S | Typical monthly spending | Median of money_out |
| B | Buffer | Mean of avg_daily_balance over the account's last 6 months |
| H | Household bills | Median of household_bills (rent & utility shocks scale this) |
| P | Loan payment | monthly_payment if the loan is still running at end of 2025 (status C or D), else 0 |
buffer_left = B − one_off_costs gap = spending_after_shock − income_after_shock if buffer_left <= 0: runway = 0 elif gap <= 0: runway = "no shortfall (120+)" else: runway = min(buffer_left / gap, 120), rounded to 1 decimal
A Python reference engine (pandas, the judges' definitions verbatim) and the in-browser TypeScript engine are compared on 36,000 cases: all 4,500 accounts × the brief's three example twists, a no-shock baseline and four random mixes of shocks. Zero mismatches to one decimal, including Python's round-half-to-even and the edge cases (14 accounts with no income, 77 with no spending, 23 with a negative buffer).