The review that stops a bad launch
A governance review is a short, written check of an AI feature before it ships. It matters because the questions nobody asked are the ones that cause the incident, and a written record shows later who decided what.
This lesson pulls the module together into five items you can check with a program.
By the end of this lesson
Note
I can review an AI feature before it ships and write down the result.
Key words
| Word | What it means |
|---|---|
| Review | a written check made before launch |
| Sign-off | the owner agreeing the feature may ship |
| Gap | an item the review leaves out |
| Rollback | the steps that switch the feature off |
| Record | the saved result of the review |
The cells students fill in are left blank in this preview.
Five items make a review
Check five things. Is there a named owner? Are the risks written down? Are there enough eval cases? Is there a rollback? Is the result recorded?
Each item comes from this module. The owner and the risks come from rating risk and oversight. The eval cases come from feedback and from changing a model. The rollback comes from changing a model and from supplier risk.
Worked example: two reviews, minimum 5 cases
| Feature | Owner | Risks | Evals | Rollback | Record | Result |
|---|---|---|---|---|---|---|
| Refund bot | yes | 2 | 0 | yes | yes | Missing evals |
| CV screener | yes | 1 | 12 | no | no | Missing rollback, record |
The cells students fill in are left blank in this preview.
Write the result down
The result is saved with the date, the names and what was found. If the review finds a gap, the feature waits. If it passes, the owner signs it off.
Review again after a change: a new model, a new use or a new supplier. A review is a record of one day, not a permit for ever.
A common mistake
Warning
Many people think that a review is done once, at launch. The feature changes, and so do the model, the users and the rules. Repeat the review when any of them changes, and keep each result.
Write the model helper, part 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// The token counts of a reply, or null when the reply carries none.' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the model helper, part 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"status \" + res.status);' ' const data = await res.json();' ' const text = data.choices[0].message.content;' ' return { text, inTokens: count(data, \"prompt_tokens\"), outTokens: count(data, \"completion_tokens\"), recorded: false };' ' } catch (error) {' ' console.log(\"Recorded sample: no model answered (\" + error.message + \").\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' 'module.exports = { ask };' >> model.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the review check, part 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '' 'const MIN_EVALS = 5; // fewer cases than this is not enough to trust' '// Two invented reviews. A review is ready when every item is there.' 'const reviews = [' ' { name: \"Refund bot\", owner: \"Tom Reed\", risks: [\"wrong refund\", \"angry customer\"], evals: 0, rollback: \"Switch off the flag\", record: true },' ' { name: \"CV screener\", owner: \"Priya Shah\", risks: [\"unfair rejection\"], evals: 12, rollback: \"\", record: false },' '];' > review.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the review check, part 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function missing(r) {' ' const gaps = [];' ' if (r.owner.trim() === \"\") gaps.push(\"owner\");' ' if (r.risks.length === 0) gaps.push(\"risks\");' ' if (r.evals < MIN_EVALS) gaps.push(\"evals\");' ' if (r.rollback.trim() === \"\") gaps.push(\"rollback\");' ' if (r.record === false) gaps.push(\"record\");' ' return gaps;' '}' >> review.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the review check, part 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' reviews.forEach(function (r) {' ' const gaps = missing(r);' ' console.log(r.name + \": \" + (gaps.length === 0 ? \"ready\" : \"NOT READY, missing \" + gaps.join(\", \")));' ' });' ' const q = \"Write one sentence a rollback plan for a customer chat feature must contain.\";' ' const r = await ask([{ role: \"user\", content: q }], \"It names who switches the feature off, how, and how long that takes.\", 60);' ' console.log(\"One possible sentence: \" + r.text);' '}' 'main();' >> review.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run the review check
docker exec -w /home/node/project agent node review.jsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
One possible output
| Line | What it shows |
|---|---|
| Refund bot: NOT READY, missing evals | No eval cases yet |
| CV screener: NOT READY, missing rollback, record | No way back and nothing saved |
| One possible sentence: ... | Your own call. It differs each run, or says Recorded sample |
The cells students fill in are left blank in this preview.