The Decision Ledger
Every decision is a row that cannot be retconned: the question, the pinned as-of context, the full recommendation, and an expected outcome frozen before the world answers. When the actuals land, expected-vs-actual is computed server-side against that frozen expectation — and the variance becomes the raw material of learning.
Frozen before the outcome
record_recommendation() freezes the expectation; record_decision() makes the row immutable, with the human approval verified server-side for anything medium-risk or above (invariant I6). Months later there is no arguing about what was promised — the same discipline that makes a Brier score honest: the call is committed before the outcome, so the score means something.
Variance becomes judgment
record_outcome() writes the actuals and the server does the scoring. propose_learning() then queues what the variance taught — an edge-confidence update, a superseded belief, a lesson — and humans approve what compounds. review_calibration() is the honest mirror over all of it: error distributions over time, hit rates by decision type, and the repeated patterns worth fixing.

