ealeng

Episode 51 of 56 · Governance

A launch checklist that shows its evidence

A pre-launch checklist, written as code, run over 16 AI systems. A written risk assessment: 0. An owner: 0. A legal sign-off: 0. The first version of the "re-tested on every change" check passed 6 systems, but only 1 really was. Then 12 public AI failures: which items would have caught each, by two raters who agreed 80% of the time, a kappa of only 0.46.

Lab 17 · Governance9 min read
Video transcript7:40

0:00Cold open

0:01

Before our refund agent ships its next version, it has to pass a launch checklist.

0:06

So I turned the checklist into code, and ran it on all sixteen of our AI systems.

0:13

A written risk assessment: zero systems.

0:17

An owner to call when it breaks: zero. A legal sign-off: zero.

0:23

My first version of one extra check, “re-tested on every change”, passed six systems.

0:30

But when I read the evidence, only one really was.

0:34

So what is a launch checklist actually good for?

0:39Intro

0:41

Hands-on AI engineering: AI governance, part three.

0:45

Today: the launch checklist. What it catches, and what it can’t.

0:50Meet Grace

0:52

I’m Grace, the AI governance lead at Lantern Outfitters, a made-up outdoor gear shop.

0:58

Our teams built sixteen AI systems, like FAQ search, a voice assistant, a refund agent, and an email assistant. They’re real code.

1:09

Before a system launches, someone ticks a checklist of eight items. Think of a pilot’s pre-flight check.

1:16

First, a risk assessment: what could go wrong. And a model card: a page saying what the system is for, and where it fails.

1:25

Then approved data, and guardrails: checks that stop bad requests and bad answers.

1:32

An owner, or escalation path: the person to call when it breaks. And monitoring, to notice when it does.

1:40

Last, a legal sign-off, and a rollback plan: a way back to the last good version.

1:46

But a tick is cheap. On a pre-flight check, each tick has to point at a gauge.

1:5301 · Evidence, not ticks

1:54

So each item in my checklist is a small piece of code. It looks for evidence: a file, or a line someone could open.

2:03

Here’s the refund agent. For guardrails, it found a test file. For approved data, a pinned list of the exact data files it uses.

2:13

And one extra item, more on it later: measured results. Eighty-seven percent of its test runs succeeded, with a range.

2:22

Owner: nothing found. Risk assessment: nothing. Sign-off: nothing.

2:28

And the check prints the line it found, so a person can judge it.

2:3402 · All sixteen

2:35

Now all sixteen systems. Each row is a system, and each column is an item. A filled square means the checker found evidence.

2:45

The last four columns are new items. I’ll come back to them.

2:50

Engineering left evidence. Tests in ten systems. A model card in nine. Pinned data in seven.

2:58

Now the items that are decisions by people: a risk assessment, an owner, and a legal sign-off.

3:05

Zero, zero, zero. Not one is filed with any system.

3:11

No system had all eight. By the checker, the best, the docs assistant with tracing, had five.

3:1903 · Read the evidence

3:20

But finding a word isn’t the same as finding the work.

3:25

So I read every line behind three of the rarer items.

3:29

Tested across groups of people: two passes.

3:33

One compared search across topics, not people. The other pointed to a different guide.

3:40

Re-tested on every change, my first version of that check: six passes.

3:46

Only one system really runs its tests automatically on every change: the release judge.

3:53

The others just matched a word, like “workflow” or “regression set”: in a printed trace, an exercise idea, a sentence of advice.

4:03

A person approves big decisions: three passes. Two are real approval steps.

4:10

The third is just a file of people’s ratings, named “human review”.

4:15

So a missing item is certain. A found one still needs a person to read it.

4:2204 · Real failures

4:23

Next question: would this checklist have caught failures that really happened?

4:29

I took twelve public cases, each with a source. For each one, I marked which items would have caught it. Those are my labels.

4:38

Air Canada’s support chatbot told a grieving customer about a refund the airline’s policy didn’t allow. A tribunal made the airline pay.

4:48

My labels: tested guardrails, a legal sign-off, and an evaluation in the real setting.

4:56

Robodebt, in Australia: an automated system raised welfare debts by averaging people’s income.

5:03

It was unlawful and often wrong. A Royal Commission condemned it.

5:09

My labels: a legal sign-off, a person reviewing decisions, and an evaluation on the real population.

5:17

By my labels, every one of the twelve has at least one of the eight items that would have caught it.

5:24

But in ten of twelve, my labels also include an item the list didn’t have.

5:30

There are four of those. Tested across groups of people. Evaluated on the people it will serve. A person reviewing big decisions. And re-testing after every update.

5:4305 · Two raters

5:45

Those labels are my judgment. So I had a second rater, an AI model, label the same twelve cases.

5:52

Twelve cases, times twelve items: the eight, plus the four new ones. Each one a yes or a no.

6:00

We agreed on eighty percent.

6:03

Is eighty percent good agreement?

6:08

Not really. For most items, both of us said no.

6:12

Two raters who mostly say no will agree a lot by chance alone. Here, about sixty-three percent.

6:20

A measure called Cohen’s kappa takes chance out. One means perfect agreement. Zero means no better than chance.

6:29

We got point four six: moderate.

6:33

And we disagreed in a pattern. The model never once picked “risk assessment” or “model card”.

6:40

It picked “evaluated on the real population” more than twice as often as I did.

6:47Back to Grace

6:49

So, what is a launch checklist good for?

6:53

Not for proving a system is good. A keyword can’t judge a test.

6:58

It’s good for what’s certain: no owner, no risk level, no sign-off, no launch.

7:04

Every pass shows its evidence, and a person reads it. That’s how I fixed the re-test check: it now looks for the file that runs the tests on every change. One system passes.

7:17

And I added the four items the failures asked for. Each item needs a written reason when it applies.

7:24

Next time: when something does go wrong. How bad is it, and who must be told by when?

7:31Summary

7:33

A tick needs evidence.

7:35

And a missing owner is certain.Grace: Show me the gauge.

Key takeaways

  • ✓Make each checklist item a small check that returns its evidence, a file or the line it matched, not a tick. A person can open the evidence and judge it; a tick says nothing.
  • ✓Over 16 systems, engineering left evidence: tests in 10, a model card in 9, pinned data in 7, a rollback path in 7. The items that are decisions by people (a risk assessment, an owner, a legal sign-off) had 0, 0 and 0. No system had all eight; the best, the traced docs assistant, had five.
  • ✓A keyword check passes on a word, not the work. Both "tested across groups of people" passes were about something else, one of three "a person approves" passes was a file name, and the first "re-tested on every change" check passed 6 systems on words like "workflow" when only 1 had a CI file. Fixed to look for that file, it passes 1. A missing item is certain; a found one still needs a reader.
  • ✓Against 12 real, public failures (Air Canada's chatbot, Robodebt, the Epic sepsis model and more), every case had one of the eight items that would have caught it, by our labels, and in 10 of 12 one of four items the list didn't have: testing across groups of people, on the real population, a person reviewing big decisions, and re-testing on every update.
  • ✓Two raters (us and gpt-5.4-mini) agreed on 80% of 144 yes-or-no judgments, but chance alone would give 63%, because both mostly said no. Cohen's kappa takes chance out: 0.46, moderate. So each item needs a written reason when it applies, not just a tick.

Before a system launches, someone ticks a checklist. This chapter turns that checklist into code, runs it over a company's 16 AI systems, reads the evidence behind the passes, and then asks whether the list would have caught real failures, measured with two raters.

The source is Lab 17 (Governance), script 03_launch_gate.py, recorded in October 2026; the video uses the recorded run, no new calls. The company, Lantern Outfitters, is made up; its 16 AI systems are real code, the labs of this course. The 12 failures are real, public cases with sources; which items would have caught each is a judgment, ours and a model's (gpt-5.4-mini, recorded answers). Chapter 49 built the list of systems and chapter 50 gave each a risk level; this one decides whether a system may launch.

Eight items, and what counts as evidence

The checklist has eight items, like a pilot's pre-flight check:

  1. A risk assessment, written down: what could go wrong.
  2. A model card: a page saying what the system is for, and where it fails.
  3. Approved data: the data sources it uses, classified and approved.
  4. Guardrails, tested: checks that stop bad requests and bad answers.
  5. An owner, or escalation path: the person to call when it breaks.
  6. Monitoring and alerts, to notice when it does.
  7. A legal and compliance sign-off.
  8. A rollback plan: a way back to the last good version.

A tick is cheap. On a pre-flight check, each tick has to point at a gauge. So in the lab each item is a small piece of code that looks for evidence, a file or a line someone could open, and returns it:

# checklist.py (abridged)
CHECKS = {
    "risk":       lambda lab: _exists(lab, "RISK*.md") or _text(lab, r"\brisk (level|tier)\s*:", readme_only=True),
    "guardrails": lambda lab: _exists(lab, "tests/test_*.py"),
    "escalation": lambda lab: _exists(lab, "OWNERS*", "CODEOWNERS") or _text(lab, r"^\**owner\**\s*:", True),
    "legal":      lambda lab: _exists(lab, "SIGNOFF*", "APPROVALS*"),
    ...
}

def evaluate(lab: str) -> dict[str, str | None]:
    """{item: the evidence found (a file, or the matching line), or None}."""
    return {k: fn(lab) or None for k, (_, fn) in CHECKS.items()}

Take the refund agent. For guardrails, the checker found a test file; for approved data, a pinned list of the exact data files it uses (data/manifest.json). For one extra item, measured results: "78/90 = 87% (78–92%)", the share of its test runs that succeeded, with a range. Owner: nothing. Risk assessment: nothing. Sign-off: nothing.

All sixteen systems

The lab runs the checks over all 16 systems. Rows are systems, columns are items; the last four columns are items added later in this chapter. Click any square to see what the checker found, or a system's name for its full list:

Try it · Every tick has to point at evidenceLab 17 · script 03 · 16 systems, 12 items
“Re-tested on every change” check:
System123456789101112of 8
0
0
1
1
2
0
0
2
3
4
3
3
4
5
3
3
Systems with evidence0971001072831
  1. 1 Risk level assessed and written down
  2. 2 Model card completed
  3. 3 Data sources classified and approved
  4. 4 Guardrails built and tested
  5. 5 Escalation path defined
  6. 6 Monitoring and alerts set up
  7. 7 Legal and compliance sign-off received
  8. 8 Rollback plan written down
  9. 9 Tested for different outcomes across groups (added)
  10. 10 Evaluated on the real population and setting (added)
  11. 11 A person reviews consequential decisions (added)
  12. 12 Every update re-runs the evaluation (added)

Green: the check found evidence. Amber: it found a line, and reading it shows the word, not the work. Shaded columns are the four items added after the failures below. Click a square, or a system's name.

Refund agent · what the checker found

  • ✗Risk assessment
  • ✓Model card09_tool_use_agents/README.md: ### What this lab leaves out
  • ✓Approved data09_tool_use_agents/data/manifest.json
  • ✓Guardrails, tested09_tool_use_agents/tests/test_harness.py
  • ✗Owner / escalation
  • ✗Monitoring
  • ✗Legal sign-off
  • ✗Rollback plan
  • ✗Across groups of people
  • ✓On the real population09_tool_use_agents/README.md: | `gpt-5.4-nano` | 78/90 = 87% (78–92%) | 5.1 | $1.49 |
  • ✓A person reviews09_tool_use_agents/03_harness.py: def exercise_5_approval():
  • ✗Re-tested on every change
Owner · risk · sign-off
0 · 0 · 0
Systems with all 8
0 / 16
Re-tested on every change
1 pass

What it shows:

Item Systems with evidence
Guardrails, tested (tests/) 10
Model card (a model table and stated limits) 9
Approved data (a pinned manifest) 7
Rollback or fallback path 7
Monitoring and alerts 1
A risk assessment 0
An owner 0
A legal sign-off 0

Engineering work left evidence. The three items that are decisions by people had none: no system's folder records who owns it, what risk was accepted, or who signed off. No system had all eight. By the checker, the best, the docs assistant with tracing, had five.

A word, not the work

Finding a word isn't the same as finding the work. Each check prints the line it matched, so the video read every line behind three of the rarer items:

  • Tested across groups of people: 2 passes, 0 about people. One was an exercise title, "Bias, Fairness & Drift", that compares search across article topics. The other was a sentence pointing to a different guide.
  • Re-tested on every change: the first version passed 6, 1 was real. Only the release judge has a CI workflow that runs its tests on every pull request. The others matched a word, like "workflow" or "regression set": a printed trace line (invoke_workflow support_assistant), a preview of another project, an exercise idea, a sentence of advice.
  • A person approves big decisions: 3 passes, 2 real. Two are approval steps in agent code (exercise_5_approval, resume_after_approval). The third is a file of people's ratings, named human_review.json.

The lab fixed the re-test check: it now looks for a workflow file under .github/workflows that runs on pull requests or pushes and names the system's folder. One system passes. Switch between the two versions in the grid above.

So a missing item is certain. A found one still needs a person to read it. Some rollback passes look like words too (a function's fallback= argument, a "What's next" paragraph); the video didn't count those, and neither does this chapter.

Twelve real failures

Second question: would this checklist have caught failures that really happened? The lab took 12 public cases, each with a source, and marked which items would have caught each one before people were harmed. Two examples:

  • Air Canada's support chatbot told a grieving customer he could claim a bereavement refund after travel, against the airline's policy. A tribunal made the airline pay (Moffatt v. Air Canada, 2024 BCCRT 149). Our labels: guardrails tested, a legal sign-off, and an evaluation in the real setting.
  • Robodebt, in Australia, raised welfare debts by averaging people's yearly income across fortnights. It was unlawful and often wrong; a Royal Commission condemned it (report, July 2023). Our labels: a legal sign-off, a person reviewing decisions, and an evaluation on the real population.

By our labels, every one of the 12 had at least one of the eight items that would have caught it. But in 10 of 12, our labels also include an item the list didn't have. There are four of those:

Added item Cases it applies to (our labels)
Tested for different outcomes across groups of people Amazon's recruiting model, Dutch childcare benefits, a US care-management algorithm
Evaluated on the real population and setting Air Canada, Robodebt, Epic's sepsis model, NYC's MyCity chatbot
A person reviews consequential decisions Uber's self-driving test car, Dutch childcare benefits, Robodebt, lawyers citing invented cases
Every update re-runs the evaluation DPD's chatbot, which swore at a customer after a system update

"Guardrails built and tested" doesn't say against what. The added items name it.

Two raters

Those labels are a judgment. So the lab had a second rater, gpt-5.4-mini, label the same 12 cases: 12 cases × 12 items, each a yes or a no, 144 judgments. Pick a case to compare, and change the model's labels to see how the numbers move:

Try it · Two raters, 12 real failuresLab 17 · script 03 · our labels vs gpt-5.4-mini's

Air Canada's support chatbot

The chatbot told a grieving customer he could claim a bereavement fare refund after travel, contradicting the airline's policy. A tribunal held the airline responsible for what its chatbot said and ordered it to pay.

Source: Moffatt v. Air Canada, 2024 BCCRT 149 (February 2024)

Would this item have caught it?UsThe model (click to change)
Risk level assessed and written down·
Model card completed·
Data sources classified and approved·
Guardrails built and testedyes
Escalation path defined·
Monitoring and alerts set up·
Legal and compliance sign-off receivedyes
Rollback plan written down·
Tested for different outcomes across groups (added)·
Evaluated on the real population and setting (added)yes
A person reviews consequential decisions (added)·
Every update re-runs the evaluation (added)·

Shaded rows: we disagree on this case. Both sets of labels are judgments about history; the sources let you check them.

All 12 cases × 12 items = 144 yes-or-no judgments

Model: yesModel: no
Us: yes2115
Us: no1494

Raw agreement counts the diagonal: both yes, or both no.

Chance agreement is what two raters would reach by luck, saying yes as often as these two do (25% and 24%). Mostly saying no makes it high.

Cohen's kappa = (raw − chance) ÷ (1 − chance): 1 is perfect, 0 is no better than chance.

Raw agreement
80%
By chance alone
63%
Kappa · moderate
0.46
The recorded run. The model never picked “risk assessment” or “model card”, and picked “evaluated on the real population” for 9 cases to our 4.
  • Raw agreement: 80%. Is that good? Not really.
  • Chance agreement: about 63%. For most items both raters said no (our yes rate 25%, the model's 24%). Two raters who mostly say no agree a lot by chance alone.
  • Cohen's kappa: 0.46, moderate. Kappa takes chance out: (0.80 − 0.63) ÷ (1 − 0.63). One is perfect agreement, zero is no better than chance, and 0.4–0.6 is usually called moderate.

The disagreements had a pattern. The model never once picked "risk assessment" or "model card", and picked "evaluated on the real population" for 9 cases to our 4. Neither rater is the truth; the point is that people applying the same checklist will differ, so each item needs a written reason when it applies.

What to do

  • Make each item return evidence: a file or a line a person can open. Never a bare tick.
  • Refuse what's certain. No owner, no risk level, no sign-off: no launch. A missing file isn't a judgment call.
  • Have a person read every pass. A keyword check finds a word; a person decides whether it's the work.
  • Prefer evidence that's hard to fake by accident: the CI file itself, not the word "workflow".
  • Test the checklist against real failures, and add the items they ask for. Here: groups of people, the real population, a person on big decisions, re-testing on every update.
  • Ask for a written reason per item, and measure how far two reviewers agree with kappa, not raw agreement.

Caveats

  • Made-up company, real code. The 16 systems are this course's labs, and nobody had been asked to record an owner, a risk level or a sign-off for them. The pattern, engineering evidence present and people decisions absent, is the lesson; the zeros aren't a verdict on a real team.
  • Checks find artifacts, not quality. A README with a model table passes "model card" whether or not the table is right.
  • Our reading covered three items. Monitoring and rollback passes weren't read line by line; some rollback passes look like words.
  • The labels are judgments about history. "Would have caught it" can't be proven; the sources are listed so it can be checked.
  • One model as the second rater, at one time. A person as the second rater, or several, could agree more or less.

The checklist

  1. Write each launch item as a check that returns its evidence.
  2. Block a launch on missing owner, risk record or sign-off.
  3. Show the matched line for every pass, and have a person read it.
  4. Look for the real artifact (a CI file, an OWNERS file), not a keyword.
  5. Add items for groups of people, the real population, human review of big decisions, and re-testing on every update.
  6. Write down why each item applies, and check two reviewers' agreement with kappa.

Practice: a gate that shows its evidence

Write the lab's keyword check and the stricter CI-file check, count what 16 systems have evidence for, find the best system, and compute raw agreement, chance agreement and kappa. The tests use the recorded run and expect the lab's numbers: 0, 0 and 0 for risk, owner and sign-off; 10, 9, 7, 7 and 1 for the engineering items; the traced docs assistant at 5 of 8; 12 and 10 of the cases; 80%, 63% and 0.46.

Try it · Practice in PythonRuns in your browser · ⌘/Ctrl + Enter to run
gate_practice.py55 lines

Quiz

Try it · Check your understanding0 of 6 answered
  1. 1.Why should each checklist item return its evidence rather than pass or fail?

  2. 2.Across 16 systems, which items had no evidence anywhere?

  3. 3.The first "re-tested on every change" check passed 6 systems. What happened?

  4. 4.Would the eight original items have caught the 12 public failures?

  5. 5.Two raters agreed on 80% of 144 judgments. Why is kappa only 0.46?

  6. 6.So what is an automated launch gate good for?

Check your understanding

Try each question before opening its answer.

What's wrong with a checklist that only records ticks?

A tick is cheap and says nothing about what was checked. Each item should point at evidence, a file or a line someone can open, so a person can judge whether it's the work or just the word.

Which items had no evidence in any of the 16 systems, and why?

A written risk assessment, an owner, and a legal sign-off: 0, 0 and 0. They're decisions by people, and nobody had been asked to make them, so no file records them. Engineering items (tests in 10 systems, model cards in 9) left evidence.

The first "re-tested on every change" check passed 6 systems. How many really were, and how was it fixed?

One: the release judge, with a CI workflow that runs its tests on every pull request. The other five matched a word like "workflow" or "regression set". The fixed check looks for a workflow file under .github/workflows that runs on pull requests or pushes and names the system's folder; one system passes.

Every one of the 12 failures had one of the original eight items that would have caught it. Why add four more?

Because in 10 of 12, our labels also included an item the list didn't name: testing across groups of people, on the real population, a person reviewing big decisions, or re-testing on every update. "Guardrails tested" doesn't say against what; the added items do.

Two raters agree on 80% of yes-or-no judgments. When is that weak?

When both mostly say no. Here chance alone gives about 63%, so Cohen's kappa, (0.80 − 0.63) ÷ (1 − 0.63), is 0.46: moderate. Kappa is 1 for perfect agreement and 0 for no better than chance.

What can an automated launch gate decide on its own, and what can't it?

It can refuse what's certain: no owner, no risk level, no sign-off. It can't judge whether a test or a model card is good enough; it shows the evidence and a person reads it.

Next up: Chapter 52, incident response: when something does go wrong, how bad is it, and who must be told by when?

Learning something useful?

New labs, articles, and videos on evaluating and testing AI systems come out regularly. Follow along so you don't miss the next one.