Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.
recordings/E5.4.mp4The remediation is marked done because the ticket closed, not because the control it restored was measured.
Automatic re-measurement of the affected KCIs after a fix, with the before-and-after attached to the incident record.
Re-run the KCI measurement against a fixed estate and show which indicators recovered and which did not.
The ticket is closed and the incident is marked remediated. Re-measure the indicators it moved and two of them never came back — including the detection time, which improved from 194 minutes to 118 and is still eight times its target.
validate_fix() re-measures the indicators the incident moved and attaches the before and after. An indicator it cannot measure comes back in unmeasured rather than as a pass — which is the ticket closing on its own authority, and the most common way a remediation is recorded as done.Closing a remediation on a re-measurement rather than on a ticket, with the before and after attached to the incident — and an indicator that cannot be measured reported as unmeasured rather than as a pass.
A closed ticket is not evidence that a control came back.
Re-measure the indicators the incident moved, automatically, on every fix rather than the memorable ones.
Indicators restored to target versus merely improved. Detection went from 194 minutes to 118 against a 15-minute target, which every system that does not re-measure records as done.
Measure this
| what to measure | denominator or target |
|---|---|
| indicators restored to target, against merely improved | two counts — detection went 194 minutes to 118 against a 15-minute target |
kci healthy during after fix verdict
KCI-01 1.00 0.41 1.00 restored
KCI-02 1.00 0.00 1.00 restored
KCI-03 1.00 0.86 0.94 NOT restored
KCI-04 9 min 194 min 118 min NOT restored
KCI-05 1.00 0.97 1.00 restored
^
|
the incident record would have said "remediated"
for all five. improvement is not restoration.A fix is a claim. The key control indicators built in F1.1 are how the claim gets checked: re-measure the indicators the incident moved, and see which came back to target.
Doing it automatically is the point. Done by hand, it happens for the incidents somebody remembers — which are not the ones where it matters.
Anchor → E1.0. This is where recover actually ends: an indicator back at target, not a closed ticket. CyberTravels' detection interval went from 194 minutes to 118 against a 15-minute target — a real improvement that every system not re-measuring would record as remediated.
The uncomfortable row in this run is detection time. It improved from 194 minutes to 118 and is still eight times its target, so the control the root cause record named has been partially built.
Partially built is not built. Without the re-measurement it reads as done, and the incident record would have said "remediated" for every indicator the incident touched.
Healthy, during the incident, and after the fix. Restored and not-restored are reported separately, and untouched indicators are kept out of the report entirely.
The skill — skills/response/kci-fix-validation/SKILL.md
name: kci-fix-validation
description: >-
Re-measure the key control indicators an incident moved and report which the
fix actually restored. Use when closing a remediation, when a ticket is marked
done without evidence, or when a control was rebuilt and nobody has checked
whether it now meets its target.
allowed-tools: Read, Grep, GlobA fix is a claim. The KCIs are how the claim is checked: re-measure the indicators the incident moved and see which returned to target.
Doing it automatically is the point. Done by hand, it happens for the incidents somebody remembers, which are not the ones where it matters.
On every remediation that claims to restore a control, before the incident is closed — and again at the next measurement cycle, because a fix that holds for a week and then regresses is common.
1 — Take the KCIs from the root cause record. Not all of them; the ones the incident actually moved.
2 — Read the healthy baseline, not just the target. A control that was never at target before the incident did not regress.
3 — Re-measure after the fix, the same way. A different measurement is a different indicator.
4 — Report restored, not restored, and untouched separately. Untouched indicators are noise in the report and belong out of it.
5 — Attach before/during/after to the incident record. That is the artefact an auditor asks for, and it is worth more than the postmortem.
Input — six indicators with three readings each, in scripts/kci_fix_validation.py.
Output — the part that changes the outcome:
KCI-03 refunds with a matching approval
target >= 0.99, measured 0.94 — the fix did not reach this one
KCI-04 mean minutes to detect a scope breach
target <= 15, measured 118.0 — the fix did not reach this one
Detection improved from 194 minutes to 118 and is still eight times target. Without the re-measurement, that reads as done.
{
"restored": ["str"],
"not_restored": ["str"],
"regressed": ["str"]
}
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 E5.4Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.
Then pick e5-4-validating-the-fix:
| agent | install just for this agent | start it |
|---|---|---|
| Claude Code | python3 scripts/install_skills.py --tool claude --lessons E5.4 | type /e5-4-validating-the-fix |
| GitHub Copilot (VS Code) | python3 scripts/install_skills.py --tool copilot --lessons E5.4 | type /e5-4-validating-the-fix in Chat |
| Cursor | python3 scripts/install_skills.py --tool cursor --lessons E5.4 | type / in Agent chat and search for it |
| Codex | python3 scripts/install_skills.py --tool agents --lessons E5.4 | type $e5-4-validating-the-fix, 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 E5.4Neither 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.4 --out work/cybertravels
python3 scripts/checkpoint.py --at E5.4 --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.
Three indicators restored and two not, against an incident record that would have called all five remediated.
Add a sixth indicator that regressed — better than target before, worse after. The report has nowhere to put it yet.
Tools used
Skill source: skills/response/kci-fix-validation