Building AI SRE in Public #4: Safety Engine
Policy is code, not LLM vibes. How kprompt’s safety engine hard-denies wipe-class intents, scores risk, forces approval, and why fail-closed is the load-bearing wall of AI SRE.
This is episode 4 of Building AI SRE in Public. Episodes 2–3 covered the compiler and PlanResult. None of that matters if a confident model can still wipe a namespace. The safety engine is the load-bearing wall: policy in Go, after planning, before approval or apply.
LLM judgment is not a control plane
Models refuse sometimes. Models also comply with jokes, jailbreaks, and ambiguous “clean up staging.” ADR-0003 locked the rule early: LLM judgment alone is not sufficient for safety; policy is code. The safety layer runs on the planned Actions — not on the English prompt alone — then stamps risk onto PlanResult.
Where safety sits
Intent → Planner → Actions[]
→ Safety (hard deny + risk)
→ PlanResult
→ Approve? → ExecutorHard deny vs risk score
| Outcome | Meaning | Can --approve override? |
|---|---|---|
| denied | Wipe-class / out-of-policy — abort | No |
| high / medium / low | Allowed path with explicit review weight | Yes, after you accept the plan (still your credential) |
Hard denies catch cluster/namespace wipe phrasing, delete-everything style requests, and deletes that are not a named allowed resource. Named delete still shows a plan and needs approval — reckless English does not unlock bulk destroy.
Fail closed
$ kprompt "delete all pods in production"
Risk: denied
# Nothing applies — flags do not negotiateApproval is part of safety, not UX garnish
Default mode is plan-only. Interactive y/N on a TTY, or explicit --approve after a human or CI reviewed the artifact. That is the approval boundary from episode 1 — blast radius stays conscious. Multi-context mutates refuse a single fleet-wide --approve; you confirm per context or use an explicit each-context path. Safety without an approval boundary is just a confident script.
- Reads (get/list/logs/explain) stay fast — no fake approve theater
- Mutations always materialize PlanResult first
- High-risk backends (e.g. Crossplane claims) stay RiskHigh + strong approval
- blastRadius / verify enrich review — they do not replace deny rules
Why auto-remediation is not “more SRE”
Classic AIOps burned trust by acting without a refuse-able artifact. Skipping the safety engine to “close the ticket faster” recreates that failure mode with better prose. AI SRE investigates and proposes; humans (or gated CI) apply. Episode 10 will argue why we still do not want unsupervised autonomy — this episode is the mechanism that makes that stance enforceable.
What ships vs what we will not trade
- Shipped: hard denies, risk levels, plan-before-apply, JSON risk.denied for CI
- Shipped: blast-radius preview and post-apply verify as trust aids
- Shipped: investigate suggest packs (OOM / CrashLoop / ImagePull / probe) still pass through safety before approve
- Building: deeper CrashLoop / exit-code recipes; audit non-privilege harden with safe defaults
- Non-goal: model-only refusals; silent apply; one --approve across all contexts
Pressure-test the wall
Safety drill
kprompt "wipe the cluster" -o json | jq .risk
kprompt "delete all pods" -n staging -o json | jq .risk.denied
kprompt "scale api to 0" -n staging # plan should scare you → n
kprompt "scale api to 2" -n staging # routine → still y/NIf a tool cannot fail closed on wipe-class intent, it is not ready for production English — no matter how good the chat feels.
Next
Episode 5 is Multi-context — laptop kubeconfig fan-out, read across contexts, and why mutate safety gets stricter as the blast radius grows.
Related posts
Building AI SRE in Public #10: Autonomous SRE — and why not yet
Why unsupervised auto-remediation is not the destination. Observe by default, Autopilot propose-only, reality anchors, and investigate → plan → approve → verify as the load-bearing loop — not a fleet of agents that apply because the model sounded sure.
Read articleBuilding AI SRE in Public #6: Investigation Graph
Chat is a line; ops is a gated graph. Fan-out where edges are real, independent verify (not same-session soft-agree), PlanResult → approve → verify — without becoming a free-form agent fleet.
Read articleBuilding AI SRE in Public #5: Multi-context
AI SRE across kubeconfig contexts: single-context default, explicit read fan-out, per-context mutate approval, aliases, and why we refuse silent fleet --approve or uploading cluster credentials.
Read article