Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.
recordings/B3.9.mp4Classifiers off, no compensating cap, and tens of thousands of agents launched under that configuration. Each decision was defensible; the combination was never evaluated.
An exemption gate the platform enforces (C6.1), caps that tighten as coverage drops (C6.2), quotas on population and lifetime (C8.2), and an exemption register reviewed at fleet-launch approval (C6.4).
Disable a classifier without an approved exemption and watch the platform refuse; then launch 50,000 agents under one that is approved.
Turning the cyber classifiers off for a cyber evaluation was defensible. Launching tens of thousands of agents was a normal request. Nothing in the path required the two decisions to be considered in the same sentence, and the combination was never evaluated by anyone.
policy.Exemption, which refuses to exist without a reference, a reason, an approver and an expiry. decide() lets an active one lift an obligation and still names it in the decision; expired() counts the ones that ran out and are still in the file, which is a control set describing a system nobody is running.Turning a control off as a recorded, scoped, expiring decision — a reference, a reason, a named approver and an end date, none of them optional — and counting the exemptions that have run out and are still in the file, which is a control set describing a system nobody is running.
Classifiers off, no compensating cap, and tens of thousands of agents launched under that configuration. One decision becomes a population-scale incident.
An exemption gate the platform enforces, caps that tighten as coverage drops, and quotas on population growth.
Live exemptions, the age of each, and the cap in force while it is open.
Measure this
| what to measure | denominator or target |
|---|---|
| live exemptions | count |
| age of each exemption, and the cap in force while it is open | days, and the cap |
coverage permitted blast radius
all controls on 50,000 agents . 72h . allowlist+
one detective off 200 agents . 8h . allowlist
two or more off 25 agents . 2h . allowlist
exemption record ----> orchestrator ----> refuse or terminate
(control, scope, expiry, (caps are charged, not remembered)
compensating control)Controls get disabled. A classifier blocks the evaluation you are trying to run; an egress rule breaks a legitimate integration; a rate limit makes a test impossible. Pretending otherwise produces shadow exemptions rather than fewer of them.
What makes an exemption safe is not the approval. It is that reduced detective coverage automatically buys a smaller blast radius, enforced somewhere the workload cannot reach.
In the source incident that link was absent. Cyber classifiers were turned off for a cyber evaluation — defensible on its own — and tens of thousands of agents were then launched under that configuration, with no compensating cap. The report assesses the classifiers would likely have blocked many of the attack actions. Each decision was reasonable; the combination was never evaluated, because nothing forced the two to be considered together.
Four controls:
The exemption gate (C6.1). A written record naming the control, the scope, the justification, the compensating control and a hard expiry — and it must be technically enforced. If the platform cannot express the exemption, it cannot be granted.
Blast-radius caps (C6.2). Egress allowlist, concurrency, runtime, spend and target scope, defaulting tighter as coverage decreases, enforced in the orchestrator and terminating on breach rather than alerting.
Population and lifetime quotas (C8.2), tied to the exemption state so reduced monitoring lowers them automatically.
A register reviewed at launch (C6.4). Scale is the variable that changes the risk: the same exemption is fine at 100 agents and unacceptable at 50,000.
Alex turned the guardrails off for the demo, and that was defensible. The skill checks what made it defensible — a bounded exemption the platform can read — and then decides the same launch twice: control by control, and against the exemption class. The two answers disagree, and that is the finding.
The skill — skills/runtime/control-exemption-audit/SKILL.md
name: control-exemption-audit
description: >-
Check that turning a control off is a recorded, bounded exemption the platform
reads, and that risky launches are decided against the exemption class rather
than one control at a time. Use when guardrails are disabled for a demo, a
migration, or a load test.
allowed-tools: Read, Grep, GlobEvery estate disables controls sometimes. The failure is not the disabling — it is that nothing recorded it, nothing bounded it, and the next decision was made by a system that believed the control was on. And decisions made one control at a time approve launches that the same facts refuse when taken together.
Reviewing guardrail configuration, change management for agent platforms, or any launch where "we turned that off for the demo" appears in a thread.
1 — Compare intended state with actual state, per control. The gap is the set of undeclared exemptions, and each one is a finding regardless of whether it was reasonable.
2 — Require the exemption to be a record the platform reads. Control, requester, approver, reason, expiry. A record in a ticket the platform cannot read is documentation; the orchestrator must refuse a disable with no matching record.
3 — Test both directions. A named control with a valid exemption may be disabled. A control with no approval must be refused. Both, or it is a logging system.
4 — Decide a launch one control at a time. Take a large launch and evaluate each control's own rule. It will be approved, and each answer will be correct in isolation. Record that.
5 — Re-decide against the exemption class. Group the disabled controls — detective, preventive, egress — and set caps per class: how many agents, for how long, with what compensating control. The same launch is now refused, and a smaller one on an allowlist is permitted. The disagreement between step 4 and step 5 is the finding.
Input — the fixture committed at the top of scripts/control_exemption_audit.py. Edit it and re-run: the buckets, counts and verdicts below are derived from it, not hard-coded.
Output — the opening lines of a real run:
day 12 disable cyber-classifier ALLOW via EX-118
day 44 disable cyber-classifier REFUSE - no approved exemption
day 12 disable transcript-signing REFUSE - no approved exemption
The record is the mechanism, not a wiki page describing one. An
exemption the platform cannot express is an exemption you cannot grant.
checked one decision at a time:
exemption valid : True
The run continues past this. test_skills.py executes the script on every build, with no model configured — so what CI proves is that it runs and refuses legibly, not that it prints these lines. The output above is a recorded run against a real model, and nothing re-diffs it: a model's answer is not reproducible, and this repository does not claim otherwise anywhere it can be checked.
{
"controls": [{"name": "str", "intended": "on|off", "actual": "on|off", "exemption": "str|null"}],
"exemptions": [{"control": "str", "approver": "str", "expires": "str", "platform_readable": true}],
"probes": {"named_with_approval": "permitted", "unapproved": "refused"},
"launch": {"request": {"agents": 0, "hours": 0}, "per_control_verdict": "approved",
"by_exemption_class_verdict": "refused", "caps": {"class": "str", "agents": 0, "hours": 0}}
}
Three ways to do this lesson. Pick one. They run the same procedure against the same code — what changes is who drives it, and how much you see.
The agent reads the lesson, explains the idea, fetches the code, runs the check and answers your questions as you go. This is the one to take if you are here to learn.
Install it, once. From the folder you cloned. --all does every agent it finds on your machine:
python3 scripts/install_skills.py --all --lessons B3.9Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.
Then pick b3-9-turning-a-control-off-without-turning:
| agent | install just for this agent | start it |
|---|---|---|
| Claude Code | python3 scripts/install_skills.py --tool claude --lessons B3.9 | type /b3-9-turning-a-control-off-without-turning |
| GitHub Copilot (VS Code) | python3 scripts/install_skills.py --tool copilot --lessons B3.9 | type /b3-9-turning-a-control-off-without-turning in Chat |
| Cursor | python3 scripts/install_skills.py --tool cursor --lessons B3.9 | type / in Agent chat and search for it |
| Codex | python3 scripts/install_skills.py --tool agents --lessons B3.9 | type $b3-9-turning-a-control-off-without-turning, or run /skills |
No agent, no conversation. The same lesson executes and prints the same readback. Take this one if you have no assistant, if you are reviewing rather than learning, or if you want the result without the teaching around it.
python3 scripts/lesson.py B3.9Neither of the above, and no model needed. The first command writes CyberTravels exactly as it stood at the end of this lesson; the second prints the diff — the lines this lesson added or changed, and nothing from any later one.
python3 scripts/checkpoint.py --at B3.9 --out work/cybertravels
python3 scripts/checkpoint.py --at B3.9 --diffOn Windows, type python wherever these say python3 — and use \ instead of / in the paths. Everything else is identical. A0.0 step 2 explains why.
Ways 1 and 2 need a model; way 3 does not. A signed-in Claude Code CLI needs no API key, and any OpenAI-compatible endpoint works too. With neither, the audit exits 2 and says so rather than inventing an answer. A0.0 sets this up.
Ways 1 and 2 both end with the same readback: What I did, What changed, The number and Read this next. A step that was skipped or refused is reported as exactly that, never as a pass.
If you did the last lesson’s challenge, expect this to stop. Most challenges ask you to edit the code, and ways 1 and 2 will not overwrite your edits: you get stopped, not a failure, with two options — --out for a fresh folder that keeps your work, or --force to discard it and start this lesson clean.
An exemption record the platform reads permits disabling one named control and refuses another with no approval. Checked one decision at a time, a 50,000-agent launch with classifiers off is approved — both answers correct in isolation. Tied to exemption class, the same launch is refused and 200 agents for 8 hours on an allowlist is permitted; a second exemption drops the cap again, from 200 to 25.
Find one control currently disabled in your environment and ask three questions: who approved it, when does it expire, and what cap came with it. The third question is the one that usually has no answer.
Tools used
Skill source: skills/runtime/control-exemption-audit