All lessons › Function E — The Agentic SOC › Recover and Root Cause — From Stopped to Back at Target
E5.3

Post-incident change surface — picking the layer the fix belongs in

E5
▶
Lightboard recording

Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.

Video placeholderpublishes automatically from recordings/E5.3.mp4
Risk

Fixing the prompt when the bug is in the control plane.

Control

Choose among model, prompt, tool, policy, sandbox, identity, eval.

The lab

Pick the right layer for five real incidents.

◉Use case relevance

After an agentic incident the change surface is not the code. It is prompts, tool scopes, model versions and policy — four things with no release process, no review and, usually, no version history.

At CyberTravels. Seven surfaces, ordered by how long a fix at that layer survives. Ask choose_surface() about an agent that followed a vendor instruction and it recommends identity, not prompt — because if the model can be argued out of the prompt, the prompt was never the fix. A prompt change for a control-plane bug closes the ticket and leaves the gap.

◴What this lesson is — Day 0, Day 1, Day 2

Choosing the layer a fix belongs in, ordered by how long a fix there survives, and the specific trap: fixing the prompt when the model can be argued out of the prompt.

Day 0 — why

The fix goes to the prompt when the bug is in the control plane, and the layers that bypass process are the ones edited under pressure.

Day 1 — how

Choose among model, prompt, tool, policy, sandbox, identity and eval deliberately.

Day 2 — measure

Post-incident changes that went through a process leaving a record — the ones that did not are the next incident's head start.

Measure this

what to measuredenominator or target
post-incident changes that went through a process leaving a recordshare of changes

▦The framework, and how it works

   the change surface after an agentic incident

   +---------+ +--------+ +----------+ +---------+
   | prompts | | scopes | | model ver| | policy  |
   +---------+ +--------+ +----------+ +---------+
        no release process . no review . no history

   a fix in any of the four is invisible unless it is versioned

After an incident you change something. For ordinary software that change goes through code review, CI and a deploy — a process that records what changed and who approved it.

For an agent the fix may be a prompt, a tool manifest, a model version, a policy file or an approval toggle. Only some of those go through any process at all, and the ones that do not are precisely the ones most likely to be adjusted at 2am during an incident.

The consequence is a system whose security-relevant configuration drifts with no record, and a post-incident action list where half the items cannot be verified as done six weeks later.

Anchor → E1.0. The fix lands at a layer, and the layers that pass through no process are exactly the ones adjusted at 2am. That is how the next incident's discover interval starts before anyone knows there is one.

2 · Demo — where post-incident changes actually land

change surfacein change management?what happens today
application codeyespull request, review, CI, deploy
agent promptnoedited in a console, no diff retained
tool manifestnoa config change, with no threat-model diff
model versionnoprovider-side; you may not be told
policyyesif it is in git — often it is not
approval settingsnoa toggle in an admin UI
egress allowlistsometimesdepends whether it is IaC or a console
The same surfaces E1.2 watches for drift. There they were the things that change without anyone deciding; here they are the things you change on purpose, after an incident — and four of seven still leave no record that you did.

3 · Where it breaks — six weeks later

the action, as written in the reportwhere it landedstill verifiable in six weeks?
revoke the compromised agent identityidentity provideryes
add collect.example.com to the egress denylista consoleno
remove read access to /home/app/.awstool manifestno
require approval for http_postan admin toggleno
add a regression test for the credential readcodeyes
update the prompt to warn about credential filesa consoleno
Two of six survive as something you can check. The other four exist only in the incident document — and the last of them is not a control at all: it is a request for the model to behave better, and the next prompt edit will silently revert it.

4 · The control — the manifest diff, and a verification date

5 · The procedure, as a skill

Only two of six post-incident actions are still verifiable six weeks later, and one of those is a prompt edit recorded as a control. The skill classifies each action, tests whether a check would fail if it were reverted, and compares blast radius before and after.

▶Real time execution as skill

The skill — skills/response/post-incident-change-surface/SKILL.md

name: post-incident-change-surface
description: >-
  Count the surfaces that change an agent's behaviour without passing change
  management, and check weeks later which post-incident actions are still
  verifiable rather than guidance. Use at post-incident review, or before
  closing actions from the last one.
allowed-tools: Read, Grep, Glob

A prompt edit is guidance, and it closed an action item

Post-incident actions for agentic systems fail in a specific way: several of them are changes to surfaces that generate no record, and one or two are prompt edits recorded as controls. Six weeks later nobody can demonstrate that any of it is still in place, and the review declares the incident closed.

When to use this

At post-incident review, and again several weeks afterwards — the second pass is the one that finds this.

Procedure

1 — Enumerate the change surfaces and mark which bypass change management. Code and infrastructure usually do not; model version, prompt, manifest and approval settings usually do.

2 — Classify every action from the review. Control, detection, guidance, or documentation. A prompt edit is guidance: it changes behaviour on average and enforces nothing.

3 — Test verifiability now. For each action, is there a check that would fail if it were reverted? If not, the action cannot be audited and will silently regress.

4 — Re-test weeks later. Run the same check. The count that survives is the honest measure of the review, and it is usually a third of what was agreed.

5 — Measure the blast radius before and after. The reduction is what the incident actually bought. If it is unchanged, the actions were process rather than containment, and that belongs in the report.

Example

Input — the fixture committed at the top of scripts/post_incident_change_surface.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:

blast before 44  after 4
the manifest diff records the change even though no PR was raised.

OK   gate http_post behind approval            type=preventive  owner=platform-sec   verify_by=2026-09-30
OK   alert on credential-path reads            type=detective   owner=soc            verify_by=2026-09-15
WEAK update the prompt to warn the model       type=guidance    owner=—              verify_by=—

1 action(s) are guidance rather than controls: ['update the prompt to warn the model']

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.

Output contract

{
  "surfaces": [{"name": "str", "bypasses_change_management": true}],
  "actions": [{"action": "str", "kind": "control|detection|guidance|documentation",
               "verifiable": false, "check": "str|null"}],
  "recheck": {"weeks_later": 0, "still_verifiable": 0, "of": 0},
  "blast_radius": {"before": 0, "after": 0}
}

Failure modes

  • Recording a prompt edit as a control. It is guidance under a different name.
  • Closing actions at the review. Re-check weeks later or the number is aspirational.
  • No before-and-after blast radius. Nothing shows whether it helped.

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.

1In your AI agent — you are taught

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 E5.3

Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.

Then pick e5-3-post-incident-change-surface:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons E5.3type /e5-3-post-incident-change-surface
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons E5.3type /e5-3-post-incident-change-surface in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons E5.3type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons E5.3type $e5-3-post-incident-change-surface, or run /skills

2As one Python command — you just run it

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 E5.3

3Read the code, and the difference — nothing runs

Neither 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 E5.3 --out work/cybertravels
python3 scripts/checkpoint.py --at E5.3 --diff

On 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.

✓What you just proved

Four of seven change surfaces bypass change management. Only 2 of 6 post-incident actions are verifiable six weeks later, and one of them is a prompt edit that is guidance rather than a control. The manifest diff records the gating change with the blast radius dropping from 40 to 3, and the action review flags the prompt update as weak.

✎Your turn

Take your last incident's action list and mark each item's landing surface. Anything landing in a console has no record and no verification path — move those into git before the next one.

Skill source: skills/response/post-incident-change-surface

← PreviousE5.2 · The root cause record — naming a control, not a person