This is the one that ties the rest together. budget-training — live at train.jbledger.com — is an interactive, step-by-step program on how federal money actually moves, built on the eight open projects from this blog. Eleven modules, 48 narrated steps, deep-linkable to any step, progress kept in the browser, and a homepage dashboard that tracks completion across the whole program.

The modules

#ModuleWhat it teaches
m0The mental modelbudget authority → obligation → outlay; unliquidated balances
m1The data spinethe 15-table public-data database; a flow stepper over real FY2026 VA periods
m2The Excel workbenchthe VBA macros + Python twins; the macro-driven close
m3Reconciliationa two-ledger matching game with a $5,000 materiality tolerance
m4The flow simulatorthe scenario lab: sequester, CR, lapse, outlay lag
m5The quizfifty-forty-five: five questions, then three ways to go deeper
m6Power BIthe semantic model, the four DAX patterns, pins + twin verification (19/19)
m7dbt + DuckDB18 models / 82 tests in three layers; the $0 in-process warehouse
m8Forecastingthe walk-forward backtest, linear vs damped Holt-Winters, the tie band
m9CBO scorecardvintage-aware CBO 10-Year vs actuals, FY2024–FY2025
m10The copilotthe deterministic NL→SQL router; named refusals; the no-fabrication contract

m0–m5 are the money-mechanics core; m6–m10 are the same eight projects taught as working sessions — each one embeds a live widget driven by that project’s frozen data: the Power BI cards, the dbt model/test explorer, the backtest chart, the CBO vintage picker, the copilot with its answer grid.

How the numbers stay honest

Same contract as every project in the portfolio, one direction:

frozen sources (the project repos + the budget database)
   → data/build_training_data.py   (stdlib only; asserts shapes and values)
   → data/site/*.json              (the ONLY data the page reads)
   → index.html + app.js           (vanilla JS, no npm, no API calls, no build step)

The build fails on shape drift, row-count drift, internal-pattern (CUI) hits, or a database hash mismatch. Then two frozen script copies — engine.js (the simulator’s scenario engine) and copilot.js (a verbatim copy of the NL→SQL router) — self-test in the console on every page load: the engine re-derives its pins from the shipped JSON, and the copilot re-runs its full 20-question evaluation (12 answers + 8 named refusals). If anything drifted, the page tells you instead of teaching you stale numbers. The whole thing is verified end-to-end by a 50-check browser test suite.

The narration

Every one of the 48 steps has a spoken narration — pre-generated (Kokoro-82M, voice af_heart) and shipped with the app as MP3s, so the audio bar follows the loaded step with no speech synthesis at view time. Numbers are spoken the way they’re read in the room — “five hundred twenty-five billion dollar,” agency codes digit by digit — because the program is built to be worked through out loud.

How to use it

Start at m0 if you’re new to the mechanics; the reconciliation game (m3) and the quiz (m5) are where it stops being a slideshow. If you came from a specific post, deep-link straight in: the CBO post’s numbers are m9, the backtest post is m8, the copilot’s refusal table is m10. And because every widget reads the same frozen JSON the standalone project does, the training program doubles as the fastest tour of the whole portfolio — the posts explain, the repos prove, and this is where you drive it.

The series started with why this blog exists; this is where the “the repos prove” half of that promise gets assembled.

— Joanna