learn-model-risk-with-phoebe / Practitioner session 8 of 10
Learn Model Risk with Phoebe · Practitioner session 8 of 10

Ongoing monitoring

Brackwater's aggregate calibration gap on the later vintage is -0.006. It would pass any threshold anybody has ever written down. By band, the same model in the same quarter is out by +0.061 at the safe end and -0.142 at the risky end, and the two halves cancel. A monitoring pack reporting one number per model per quarter would have shown this model healthy right up to the quarter the cancellation stopped, at which point it would have shown a model that broke overnight. Nothing broke overnight. The pack was measuring something that could not fail for the right reason, and a metric that cannot fail for the right reason is decoration.

🟠 Advanced Validators and the second line Data scientists who own a live model 45 min
0-3 · Welcome 3-16 · What to watch 16-27 · Thresholds that fire 27-45 · Build-along and Q&A
Part 0

Where this sits in the practitioner track

Session 6 compared predicted against actual by band and found the aggregate hiding the bands. Session 7 scored the frozen model on a year it had never seen, watched discrimination fall from 0.772 to 0.682, and found a book that had moved toward exactly the borrowers the model has least evidence about. Both of those were validator tests, run once, by somebody with a mandate and a deadline. Tonight they become a standing control that runs when nobody is looking, which is a different design problem with a different failure mode: a validator who finds nothing has done a bad review, and a monitoring pack that finds nothing looks like good news. Session 9 turns what fires into a finding somebody has to answer. The worked example is Brackwater's consumer scorecard throughout, 4,000 development applications at a bad rate of 0.292 and 2,000 from the following year at 0.324.

Live = presented in the 45 minutes Self-study = the full depth, after class 🔍 Every diagram zooms

★ What you walk out with tonight. A test for whether a monitoring metric is worth reporting: can it fail for the right reason, on this model, given what you already know moves. The four parts every trigger needs before it counts as a control rather than a chart. A worked monitoring specification for Brackwater with seven rows, three of which fire on the later vintage and four of which do not. And the boundary of the whole technique, which matters more than any of it: monitoring compares the model against the world, so it is structurally blind to a model that is wrong in a way the world confirms.

LiveWhat ongoing monitoring is, and what it obliges4 min▶

Ongoing monitoring is the third of the three components of validation, and the revised interagency guidance of 17 April 2026 defines it as "an evaluation of the extent to which a model is performing as expected given potential changes in products, exposures, activities, clients, data relevance, or market conditions". Read the list of things that might have changed: products, exposures, activities, clients, data relevance, market conditions. Not one of them is a property of the model. Every one of them is a property of the world the model was fitted to, which is the clue to what the pack should contain.

A model that is no longer performing as expected "may warrant overlays, adjustment, or redevelopment". That sentence is doing more work than it looks like. It names three different repairs of three very different costs, which means the monitoring result is expected to be specific enough to choose between them. A pack that can only say "red" cannot.

An effective plan also includes "regularly assessing any model limitations at the development stage and over time, along with procedures for responding to any issues". The limitations are written at development time, before anything is running, and the procedure for responding is written then too. And the frequency and scope of monitoring reports depend on the nature of the model, the availability of new data or modelling approaches, and model materiality. Frequency is a risk decision, not a calendar convenience.

Real world

Brackwater's monitoring pack had one page per model: a population count, an approval rate, and a single calibration number. It was produced quarterly, circulated to eleven people, and had never once produced an action item in two years. That is not a pack nobody read. It is a pack that could not say anything.

Self-studyMonitoring, revalidation and a validator's test are three different things4 min▶
  • A validator's test. Run once, by somebody independent, against a question they chose. Sessions 3 to 7 were all of these. It can be as expensive and as bespoke as the question deserves, because it happens once.
  • Ongoing monitoring. Runs on a schedule, unattended, against questions chosen in advance. It has to be cheap enough to run every quarter forever and specific enough that a breach means something. Those two pressures pull in opposite directions and the design is the compromise.
  • Periodic revalidation. The whole review done again, on a cycle set by materiality. Monitoring is what tells you whether the cycle is fast enough, and a monitoring trigger is what pulls a revalidation forward.
  • An overlay. An adjustment applied to model output while the underlying model is unchanged. It is a repair, not a monitor, and it is the cheapest of the three repairs the guidance names. A model running on an overlay that nobody has revisited is its own finding.

Keeping them apart matters because the common failure is to promise the second and deliver nothing, on the grounds that the first was thorough. A thorough validation in March says nothing about September, which is the entire reason the third component exists.

Part 1 · covers the design problem and what to watch

Design the metric so it can fail

13 min live

The usual way a monitoring pack gets built is to list the metrics somebody can compute cheaply and put them in a table. The better way is to start from what you already know can move on this model, and design each metric so that when the thing moves, the number moves too. Brackwater is the perfect teaching case because the evidence is already in hand: session 6 established that the errors are large, systematic and opposed, and session 7 established which part of the population shifted. Any metric that survives both of those facts and still reads as healthy is a metric that was never going to say anything.

One number per model per quarter, and this model passes. Aggregate calibration gap, later vintage: predicted 0.330 against an actual 0.324 One row in the pack. Nothing to escalate, and nothing to read twice. -0.006 · passes The same quarter, the same model, banded by predicted risk. Quintile 1 (safest) +0.061 Quintile 2 +0.068 Quintile 3 +0.035 Quintile 4 -0.054 Quintile 5 (riskiest) -0.142 -0.150 -0.100 -0.050 0.000 +0.050 +0.100 Blue: the model under-predicts the band. Red: it over-predicts. The two sides cancel in the top panel. A monitoring metric that cannot fail for the right reason is decoration.
🔍 Click to zoom - the top panel and the bottom panel are the same model, the same quarter and the same data. Only one of them is in the pack.
LiveThe five things worth watching on this model, and where each came from5 min▶

None of these is on the list because it is a standard metric. Each one is on the list because something in sessions 3 to 7 showed it capable of moving on this model, which is the only defensible way to build the list.

  • The banded outcome comparison, never the aggregate. Predicted against actual, by quintile of predicted risk, every band reported. Session 6 is the whole argument: -0.006 in aggregate over band gaps of +0.061, +0.068, +0.035, -0.054 and -0.142. The aggregate row can stay in the pack for continuity, as long as nobody is allowed to act on it alone.
  • The population fields that actually drive the score. Thin-file share, which moved from 19.0 to 34.0 percent. Prior delinquency, 34.0 to 36.8 percent. Mean utilisation, 0.448 to 0.464. Three fields, because those are the three the development testing was thinnest about, not because three is a nice number.
  • Discrimination on a recent window. Development gave 0.772 for the honestly refit champion and the later vintage gave 0.682. A monitoring metric here needs a window with matured outcomes, which is why this row runs on a slower cycle than the population rows.
  • The bad rate itself. 0.292 on development and 0.324 out of time. It is not a model metric at all, and that is exactly why it belongs: it separates a model that has degraded from a book that has got riskier, and those two have different repairs.
  • The approval rate and the bad rate among approved. Not a model metric either. It is what the business actually experiences, and a monitoring pack with no business row is a pack the business has no reason to read.
LiveWhy the aggregate survives in every pack you will ever see4 min▶

It is worth being fair to the aggregate, because the reasons it dominates monitoring packs are good reasons and it will lose the argument faster if you pretend otherwise. One number per model fits on one row. One row per model fits fifty models on a page, and fifty models on a page is what a committee can actually look at. The aggregate is stable, cheap, comparable across models and across quarters, and it does not need a decision about how many bands or where to cut them.

The problem is not that the aggregate is a bad number. It is that the aggregate is the average of the thing you care about, and averaging is precisely the operation that destroys the signal here. Under-prediction at the safe end and over-prediction at the risky end are the signature of a model whose relationship has moved, and it is a signature made entirely of opposing errors. Averaging opposing errors is how you get to -0.006.

So the practical design is not to delete the aggregate. It is to make the worst band the row that carries the threshold, and let the aggregate sit next to it as context. The committee still gets one number per model. It is just a number that can go red.

The one-line test for any proposed monitoring metric. Name a specific way this model could go wrong, then ask whether this metric would move if that happened. If you cannot name the failure, you do not yet know what the metric is for. If you can name it and the metric would not move, the metric is decoration and putting it in the pack is worse than leaving it out, because it will be cited as evidence of health.

Self-studyFrequency follows materiality, not convenience4 min▶

The frequency and scope of monitoring reports depend on the nature of the model, the availability of new data or modelling approaches, and model materiality. Every one of those three is a property of the situation, and none of them is the reporting calendar. In practice almost every monitoring pack in existence is quarterly, and almost none of them can explain why.

The nature of the model sets the floor on how fast anything can be known. Brackwater's outcome window means a default takes time to appear, so a discrimination row cannot be refreshed monthly no matter how material the model is: there is nothing new in the data. The population rows have no such constraint, because an application's features are known on the day it arrives. That alone splits the pack into two cycles, and a pack that runs everything on one cycle is either late on the fast rows or empty on the slow ones.

Materiality sets the appetite. A model driving the approval cutoff on a consumer book is a different proposition from one ranking leads for a call list, and the tiering call from session 1 is where that judgement was already made and written down. Reusing it here is the point of having made it. The availability of new data or modelling approaches is the one people forget: if a materially better approach became available, that is a reason to look again even when every row in the pack is green.

Part 2 · covers triggers, and the blind spot

A threshold with no stated action is an observation

11 min live

Choosing what to watch is half the job and the easier half. The half that decides whether the pack does anything is the part after the number: what level counts as a breach, over what population and window, who is named, and what happens. Four parts. A row with a level and nothing else produces a chart that goes up and down and a meeting that notices. A row with all four produces a consequence somebody agreed to in advance, which is the only kind of consequence that survives contact with a busy quarter.

A threshold is a number. A trigger is that number plus three other things. Level How far from the approved baseline before it counts Window Which population, and over how much of the book Owner A named person, not a team inbox. Somebody is woken. Consequence What happens on breach, chosen before the breach The consequence comes from a fixed list, and the list escalates. investigate find out why, no change overlay adjust the output recalibrate refit the levels redevelop build it again withdraw stop using it escalating cost, escalating approval, and every step is one somebody already agreed to Write all four before the model goes live. A level set after a breach is a negotiation, and the person negotiating is the person who owns the model.
🔍 Click to zoom - level, window, owner, consequence. Three of the four are usually missing, and the pack still gets circulated.
LiveWhere the level comes from, given that nothing sets one for you4 min▶

No supervisory text sets a number. There is no threshold in the guidance, there is no industry constant, and anybody who tells you the level is 0.05 because it is always 0.05 is quoting a habit. The level is a choice, it is the bank's choice, and the only thing that makes it defensible is that the reasoning is written down next to it.

Three ways to reason about it, in rough order of how well they survive being questioned. The first is consequence: how far can this quantity move before the decision the model drives becomes a decision you would not have made. That is the best argument and the hardest work, because it needs the business to say what it would do differently. The second is historical variation: how much does this quantity move quarter to quarter when nothing is wrong, so that a level can sit above the noise. That needs history, which a new model does not have. The third is the development baseline plus a stated tolerance, which is weak reasoning but honest, and it is what most first versions are.

What matters more than which of the three you use is that the level is attached to a baseline you can point at. Brackwater's baselines are the development figures the model was approved on: thin-file share 0.190, prior delinquency 0.340, mean utilisation 0.448, discrimination 0.772, bad rate 0.292. A trigger that says "moves by more than five points from the number in the approved model document" is a sentence anybody can check. A trigger that says "deteriorates materially" is not a trigger.

LiveWrite the triggers before go-live, because afterwards it is a negotiation4 min▶

The sequencing point is the most practically useful thing tonight and it costs nothing to apply. Before a model goes live, the level is an abstract question and everybody in the room can afford to be principled about it. After a breach, the level is a question about whether a specific model that a specific team built and a specific business depends on has to be taken off the road this specific quarter. The same number, asked in two different rooms, and the second room has a stake in the answer.

This is why the validation report is the right place to propose the thresholds, and why session 7 ended by telling you to draft one while the number was uncontroversial. A threshold written into a report that has been signed is a level that was agreed when nobody knew which way it would break. A threshold written after the pack turns red is an agreement about that particular quarter, and it will be revisited the next time it is inconvenient.

The same logic applies to the consequence. Deciding in advance that a breach of the worst-band calibration trigger means recalibration is a cheap decision. Deciding it in the meeting where the breach has just been reported means deciding it against a person who will explain, accurately, that recalibration takes eight weeks and the quarter ends in three.

Real world

Brackwater's pack had no thresholds at all, which is the most common arrangement and the one that produces the fewest arguments. Every number was reported as a number. The calibration gap of -0.006 was true, correctly computed, and circulated to eleven people, none of whom had been given a level against which to read it.

Self-studyWhat monitoring cannot see, and why session 2 comes first4 min▶

Ongoing monitoring compares the model against the world. That is its definition and its entire mechanism: is the model performing as expected given what has changed in products, exposures, clients, data relevance or market conditions. Which means the one defect it can never detect is a model that is wrong in a way the world confirms.

Brackwater is the example, and it is a clean one. The leaked collections field is a count of contacts logged after the outcome window opens. Run the champion as submitted in production, monitor it forever, and every row in the pack stays green: the field keeps being populated, it keeps being related to default at the same strength, the discrimination it produces keeps reproducing, and the model keeps predicting default in people who are about to be recorded as defaulting. There is no quarter on which that stops working. The relationship is real. It is a relationship with the future, and outcomes keep confirming it because it was built out of outcomes.

No threshold catches this. No banding catches it, no population comparison catches it, no amount of frequency catches it. The only thing that catches it is somebody reading the feature list and asking when each value is written, which is conceptual soundness, which is the first component and session 2 of this track. That ordering is not an accident of curriculum design. A monitoring programme built on top of an unexamined model is an expensive way to confirm that the model is consistent with itself.

The general form, worth carrying past credit scoring: monitoring answers "has anything changed since we approved this". It cannot answer "was the thing we approved ever right". Those are different questions and only one of them gets easier with more data.

Part 3 · build-along

Write the specification, then run the quarter against it

18 min build-along

A monitoring specification is a table, and the discipline is entirely in which columns it has. Metric, band, level, window, owner, action. Six columns, and a row that cannot fill all six is not ready to be a control. Build the table first, with no data anywhere near it, then score the later vintage against it and read out what fires. Doing it in that order is the whole exercise: a spec written while looking at the data is a spec that agrees with the data.

List what can go wrong with this specific model, before listing any metric. Three or four sentences, each naming a failure: the relationship moves, the book shifts toward a segment with thin evidence, outcomes arrive later than assumed, an upstream field changes meaning. The metrics come from this list, and a metric with no failure attached to it does not go in the pack.

For each failure, pick the quantity that would move if it happened. Then check the direction and the size you would expect. If the honest answer is "it would move a bit, probably", the metric is too blunt for the failure and you need a band, a segment or a different quantity.

Band anything that can be wrong in opposite directions at once. Calibration is the standing example and Brackwater is the proof: -0.006 in aggregate over band gaps from +0.061 to -0.142. Put the worst band on the threshold and leave the aggregate next to it as context, never as the control.

Write the baseline each level is measured from, and say where it came from. The development figures in the approved model document, quoted exactly. A trigger measured against last quarter drifts with the thing it is supposed to detect, which is how a book can move fifteen points without any row ever turning red.

Set the level, and write the sentence justifying it in the same row. Consequence-based if the business will tell you what it would do differently, historical-variation-based if you have the history, baseline-plus-tolerance if you have neither. Any of the three is defensible. The absence of a written reason is not.

Give each row a window that respects how fast the data can actually know. Population rows can run as fast as applications arrive. Anything that needs a matured outcome runs slower, and a row refreshed faster than its outcomes mature is reporting an artefact of incompleteness.

Name a person and pick the action from the fixed list. Investigate, overlay, recalibrate, redevelop, withdraw. A person, not a team, not a function, not the committee. The list is short on purpose: a free-text action column fills up with "review at next cycle", which is the written form of doing nothing.

Run the spec against a period you already understand, and check that something fires. A spec that passes everything on a quarter you know was bad is broken, and you will not find that out later, because a silent control and a healthy model look identical from the outside. Brackwater's later vintage is the test case: three of seven rows should fire.

★ Try it now - the monitoring specification, written before any data is loaded
import pandas as pd

# Six columns. A row that cannot fill all six is not a control.
# No supervisory text sets a level: these are Brackwater's choice,
# written into the validation report before the model went live.

spec = pd.DataFrame(
    [
        ("calibration gap",   "all applications", 0.050, "quarterly",   "model owner", "investigate"),
        ("calibration gap",   "worst quintile",   0.050, "quarterly",   "model owner", "recalibrate"),
        ("thin-file share",   "all applications", 0.050, "quarterly",   "model owner", "investigate"),
        ("prior delinquency", "all applications", 0.050, "quarterly",   "model owner", "investigate"),
        ("mean utilisation",  "all applications", 0.050, "quarterly",   "model owner", "investigate"),
        ("discrimination",    "matured 12 months", 0.050, "semi-annual", "model risk",  "redevelop"),
        ("bad rate",          "all applications", 0.050, "quarterly",   "credit risk", "investigate"),
    ],
    columns=["metric", "band", "level", "window", "owner", "action"],
)

# Every level is measured from the figures the model was approved on,
# quoted from the development sample of 4,000 applications.
baseline = {
    "calibration gap":   0.000,   # a gap is measured against zero
    "thin-file share":   0.190,
    "prior delinquency": 0.340,
    "mean utilisation":  0.448,
    "discrimination":    0.772,   # refit without the leaked collections field
    "bad rate":          0.292,
}

# Note what is NOT in this table: any row that would have caught the leak.
# Monitoring compares the model against the world, and the leak is a
# relationship the world keeps confirming. That one is session 2's job.
★ Try it now - score the later vintage against the spec and read out what fires
# The later vintage: 2,000 applications from the following year.
observed = {
    ("calibration gap",   "all applications"):  -0.006,  # predicted 0.330, actual 0.324
    ("calibration gap",   "worst quintile"):    -0.142,  # quintile 5: 0.694 predicted, 0.552 actual
    ("thin-file share",   "all applications"):   0.340,
    ("prior delinquency", "all applications"):   0.368,
    ("mean utilisation",  "all applications"):   0.464,
    ("discrimination",    "matured 12 months"):  0.682,
    ("bad rate",          "all applications"):   0.324,
}

spec["observed"] = spec.apply(lambda r: observed[(r["metric"], r["band"])], axis=1)
spec["move"] = (spec["observed"] - spec["metric"].map(baseline)).abs().round(3)
spec["fires"] = spec["move"] >= spec["level"]

for _, r in spec[spec["fires"]].iterrows():
    print(r["metric"], "/", r["band"], "moved", r["move"], "->", r["action"], "-", r["owner"])

# calibration gap / worst quintile moved 0.142 -> recalibrate - model owner
# thin-file share / all applications moved 0.15 -> investigate - model owner
# discrimination / matured 12 months moved 0.09 -> redevelop - model risk

print(spec.loc[~spec["fires"], ["metric", "move"]].to_string(index=False))
# calibration gap    0.006      <- the aggregate. It passes.
# prior delinquency  0.028
# mean utilisation   0.016
# bad rate           0.032

# Same model, same quarter, same pack: the aggregate calibration row passes
# and the row directly beneath it breaches by nearly three times the level.

Run the spec against the period before the one you are worried about. If nothing fires on the quarter you already know went wrong, the spec is the problem and not the model. This is the cheapest check in the whole design and it is almost never done, because a control that has never fired is indistinguishable from a control that cannot.

Check yourself

Three questions

A monitoring pack reports one calibration number per model per quarter. On Brackwater's later vintage that number is -0.006. What is the problem with the design?

The aggregate is the average of the thing that matters, and averaging is the operation that destroys this particular signal. Under-prediction at the safe end and over-prediction at the risky end is the signature of a relationship that has moved, and it is made entirely of opposing errors. Putting the worst band on the threshold is what makes the row capable of going red for the right reason.

A monitoring row reads "thin-file share, alert if it deteriorates materially". What is missing before this counts as a control?

Four parts, and this row has none of them. Deciding the owner and the action at the moment of breach is exactly the failure mode: before go-live the level is an abstract question, and after a breach it is a question about taking a particular model off the road in a particular quarter, asked in front of the people who depend on it. A level set after a breach is a negotiation.

Suppose Brackwater had shipped the champion with the leaked collections field and monitored it for three years against a well-designed pack. What would the pack have shown?

Ongoing monitoring evaluates whether a model is performing as expected given changes in products, exposures, activities, clients, data relevance or market conditions. It is a comparison with the world, so it is structurally blind to a model that is wrong in a way the world confirms. Collections contacts keep being logged after default, the relationship keeps reproducing, and no threshold anywhere in the pack fires. Conceptual soundness is the only component that catches it, which is why it is the first one.

Homework

Before session 9

45 min

Take the monitoring pack your team actually receives, and for every row in it write the four parts next to the number: the level, the window and population, the named owner, and the action on breach. Most rows will have one of the four and several will have none, and the count is the finding. Then do the harder half: for each row, name a specific way the model could go wrong and say whether that row would move if it happened. Any row where the honest answer is no should be marked for deletion, because it is currently being read as evidence of health. Bring the annotated pack to session 9, where what fires becomes a finding with a severity, a condition and an owner, and where the thing that gets argued about is no longer the number.

Sources covered

What tonight maps to

✓ Ongoing monitoring, in the guidance's words Under the revised interagency guidance of 17 April 2026, it is "an evaluation of the extent to which a model is performing as expected given potential changes in products, exposures, activities, clients, data relevance, or market conditions", and a model no longer performing as expected "may warrant overlays, adjustment, or redevelopment". SR 11-7 is superseded.
✓ What an effective monitoring plan includes "Regularly assessing any model limitations at the development stage and over time, along with procedures for responding to any issues." The limitations and the response procedure are written at development time, before anything is running.
✓ Frequency follows materiality The frequency and scope of monitoring reports depend on the nature of the model, the availability of new data or modelling approaches, and model materiality. None of those three is the reporting calendar, and the nature of the model sets a floor on how fast anything can be known.
✓ The design problem, with the numbers Aggregate calibration gap -0.006 out of time, over band gaps of +0.061, +0.068, +0.035, -0.054 and -0.142. A monitoring metric that cannot fail for the right reason is decoration, and averaging opposing errors is how the aggregate gets to -0.006.
✓ What to watch on this model, derived The banded outcome comparison rather than the aggregate; thin-file share 19.0 to 34.0 percent, prior delinquency 34.0 to 36.8 percent, mean utilisation 0.448 to 0.464; discrimination on a matured window, 0.682 out of time against 0.772 on development; and the bad rate itself, 0.292 to 0.324.
✓ Thresholds, triggers and the fixed action list Level, window, owner, consequence. The consequence is drawn from investigate, overlay, recalibrate, redevelop or withdraw, and it is chosen before go-live because a level set after a breach is a negotiation.
✓ What monitoring cannot see It compares the model against the world, so it is blind to a model that is wrong in a way the world confirms. The leaked collections field would keep predicting default forever and no pack would ever fire. Conceptual soundness is the only component that catches it, which is why session 2 comes first.
◐ Out-of-time testing and population stability Session 7. It produced the evidence this pack is designed around: 0.772 to 0.682, and a thin-file share that nearly doubled.
◐ Turning a breach into a finding somebody answers Session 9. Tonight produces the trigger and the owner; severity, conditions, remediation and the tracked register come next.
· Drift detection as a technique Not covered by design. learn-model-evaluation-with-phoebe owns drift and continuous evaluation. Here a quantity is specified and a level is set; the detection methods and their statistics live there.
· What AUC and calibration are Not covered by design. learn-model-evaluation-with-phoebe defines the metrics; here they appear only as evidence a validator weighs.
· Governance frameworks of every kind Not covered by design, in any session. learn-ai-governance-with-phoebe owns them.

Session 8 cheat sheet

The one-line testName a way this model could go wrong, then ask whether the metric would move. If not, it is decoration.
Brackwater in two numbers-0.006 in aggregate, -0.142 in the worst band. Same model, same quarter, one row in the pack.
Band anything two-sidedOpposing errors cancel. Put the worst band on the threshold and leave the aggregate as context.
Four parts or it is a chartLevel, window, owner, consequence. Three of the four are usually missing.
Measure from the approved baselineThin file 0.190, prior delinquency 0.340, utilisation 0.448, discrimination 0.772, bad rate 0.292.
Before go-live, alwaysA level set after a breach is a negotiation, and the person negotiating owns the model.
Frequency follows materialityNature of the model, availability of new data or approaches, and materiality. Not the calendar.
The blind spotMonitoring asks what changed since approval. It cannot ask whether what was approved was ever right.