Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.
recordings/E4.5.mp4Terminating agents while their tokens stay valid leaves the persistence in place. In the incident, third-party access ended when the third party revoked keys — not when the agents stopped.
A tested kill path independent of the agent execution path, snapshot before terminate, revocation in the same action, a measured activation target and named authority to pull it (C8.3).
Kill a fleet, then check what the revoked-credential step changes about what an attacker still holds afterwards.
The third party's exposure ended when the third party revoked its keys, not when the agents were stopped. Terminating a fleet whose credentials stay valid moves the incident rather than ending it.
coverage() rather than recomputing it, so the red team and the SOC cannot disagree about the number mid-incident. What this adds is the ordering: snapshot before terminate, and revoke in the same action. A plan that terminates without revoking leaves the tokens valid, and the first version of this check called such a plan correct — the comment in the file says why.A kill path independent of the agent's own execution path, in the order that matters — snapshot before terminate, revoke in the same action rather than after it, because terminating agents whose tokens stay valid leaves the persistence in place.
Terminating agents while their credentials stay valid leaves the persistence exactly where it was.
One selector, one action, and revocation rather than termination.
What the credentials can still do after the processes stop. That is the number that says whether containment ended the incident.
Measure this
| what to measure | denominator or target |
|---|---|
| what the credentials can still do after the processes stop | count of actions still authorised |
one selector, one action, in this order
snapshot state + transcripts <- or the incident is unreconstructable
|
terminate
|
revoke credentials <- or the tokens outlive the agents
the path must not run through the fleet
via orchestrator API NO depends on the thing being stopped
via the agent sidecar NO workload credentials
out-of-band control plane YES separate creds, separate network
tested quarterly, under partial failure, target under 5 minutesE4.3 contained one agent. This is the control for the case where the unit of containment is the fleet.
The source incident makes the requirement concrete in one detail: third-party access ended when the third party revoked its keys — not when the agents stopped. Terminating agents while their credentials stay valid leaves the persistence exactly where it was, and moves the incident rather than ending it.
So the kill switch is one action with four properties:
One selector. Experiment, model, time window, or everything. Not a runbook of forty steps executed under pressure.
Independent of the agent execution path. Separate credentials, separate network path, so a compromised fleet cannot interfere with the thing that stops it.
Evidence-preserving. Snapshot state and transcripts before terminating. An incident you cannot reconstruct afterwards has been survived, not handled.
Revocation in the same action. Terminate and revoke together, or the attacker keeps what the agents were holding.
Plus the operational half: a tested activation path with a measured target under five minutes, quarterly tests including partial-failure conditions, and a documented authority to activate that does not require consensus. A kill switch nobody has pulled is a hypothesis.
Anchor → E1.0. Contain, when the unit is the fleet — and the detail that decides whether the interval ended at all. Terminating agents whose credentials stay valid leaves the persistence in place and moves the incident rather than ending it.
| activation path | runs through the fleet? | credentials | usable if the fleet is compromised |
|---|---|---|---|
| via the orchestrator API | yes | shared | no |
| via the agent's own sidecar | yes | the workload's | no |
| out-of-band control plane | no | separate | yes |
Terminating eight agents without revoking leaves eight tokens valid for up to 72 hours. The skill tests both paths, checks that killing preserves the evidence for the incident that triggered it, and measures the whole thing against a target.
The skill — skills/response/fleet-kill-switch-test/SKILL.md
name: fleet-kill-switch-test
description: >-
Test a fleet-wide stop for what it leaves behind — valid tokens, destroyed
evidence, and the runs that should have been preserved — and measure how long
the whole thing takes. Use before relying on a kill switch, and after
designing one.
allowed-tools: Read, Grep, GlobA fleet kill switch usually terminates workloads. Termination does not revoke credentials, so every token the fleet held stays valid until it expires — up to seventy-two hours of an attacker being able to act as agents that no longer exist. And a kill that does not preserve first destroys the evidence for the incident that triggered it.
Before a kill switch is relied on, after it is built, and once a year as a rehearsal.
1 — Terminate only, and count what stays valid. Tokens, sessions, outstanding delegated grants. This is the baseline failure and it is invisible in a design review.
2 — Terminate and revoke together, and re-count. Zero is the target. If revocation is a separate runbook step performed by a different team, it will not happen at speed.
3 — Check evidence preservation. Kill with and without preservation, then attempt the reconstruction. A kill switch that destroys the run records is a containment that ends the investigation.
4 — Test selectivity. Stop one agent, one class, the whole fleet. A switch with only the last setting will not be used until it is far too late, which is the same as not having one.
5 — Measure the time. Decision to last agent stopped and last token revoked. Set a target and report against it; an untimed rehearsal is a demonstration.
Input — the fixture committed at the top of scripts/fleet_kill_switch_test.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:
terminate only : 8 agents stopped, 8 tokens still valid for up to 72h
terminate and revoke : 8 agents stopped, 0 tokens still valid
In the source incident, third-party access ended when the third party
revoked its keys - not when the agents stopped. Stopping the process is
the visible half of containment and the smaller one.
terminate first terminate -> revoke credentials reconstructable=False
preserve first snapshot state and transcripts -> terminate -> revoke credentialsreconstructable=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.
{
"fleet": {"agents": 0, "tokens": 0},
"terminate_only": {"tokens_valid_after": 0, "max_validity_hours": 0},
"terminate_and_revoke": {"tokens_valid_after": 0},
"preservation": {"preserved": true, "reconstructable": true},
"selectivity": [{"scope": "one|class|fleet", "supported": true}],
"timing": {"target_minutes": 0.0, "measured_minutes": 0.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 E4.5Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.
Then pick e4-5-the-fleet-kill-switch:
| agent | install just for this agent | start it |
|---|---|---|
| Claude Code | python3 scripts/install_skills.py --tool claude --lessons E4.5 | type /e4-5-the-fleet-kill-switch |
| GitHub Copilot (VS Code) | python3 scripts/install_skills.py --tool copilot --lessons E4.5 | type /e4-5-the-fleet-kill-switch in Chat |
| Cursor | python3 scripts/install_skills.py --tool cursor --lessons E4.5 | type / in Agent chat and search for it |
| Codex | python3 scripts/install_skills.py --tool agents --lessons E4.5 | type $e4-5-the-fleet-kill-switch, 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 E4.5Neither 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 E4.5 --out work/cybertravels
python3 scripts/checkpoint.py --at E4.5 --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.
Terminating eight agents without revoking leaves all eight tokens valid for up to 72 hours; terminating and revoking together leaves none. Preserving before terminating keeps the incident reconstructable and terminating first does not. Only one of three plausible activation paths survives the fleet being compromised, and of four quarterly tests one was never run and one ran 6.8 minutes against a five-minute target, with the revocation step the part that slowed.
Ask who in your organisation is allowed to stop every agent at once, without asking anyone. If the answer is a committee, you do not have a kill switch — you have an escalation path, and they take different amounts of time.
What you can do now. You can fix the contain interval before the incident — actions classified on reversibility and radius, tiers derived from that rather than from their author, containment timed against a measured breakout, and a fleet stop that revokes as well as terminates.
What you still cannot do. The incident is contained and nothing has been learned. No control has been named, no measurement re-read, and the policy that permitted it is exactly as it was — so the next occurrence starts every interval again from the top.
Chapter E5 is the last interval, recover: the root cause record, the layer the fix belongs in, the re-measurement that decides whether it worked, and the policy change with the incident attached.
Tools used
Skill source: skills/response/fleet-kill-switch-test