Building AI SRE in Public #3: PlanResult
PlanResult is the IR of AI SRE: one typed document for humans and CI. Why JSON, what applied means vs verify, how blastRadius attaches, what never gets stored, and how investigate/why must extend the same artifact.
This is episode 3 of Building AI SRE in Public. Episode 2 described the compiler pipeline. This episode is about the artifact that makes the pipeline real: PlanResult — the intermediate representation operators and CI can refuse.
One artifact, two audiences
Terminal UX and pipeline gates must share a contract. If humans see one story and CI scrapes another, you have two products. PlanResult is the shared story: intent, ordered actions, risk, denial, applied flag — printable in the TTY, stable as JSON on stdout with --output json (human noise on stderr).
Same prompt, machine-readable gate
kprompt "scale api to 3" -n staging -o json | \
jq '{intent:.plan.intent, risk:.risk, denied:.risk.denied, applied:.applied}'Platform muscle memory already trusts diffs, PRs, and admission. A chat scroll does not. A PlanResult does. That is why the AI SRE bet grows fields on this document instead of inventing a second “agent transcript” product.
Why JSON (not YAML) for the public IR
- jq / languages already treat JSON as the default gate format
- Strict schemaVersion bumps beat “almost YAML” drift in CI
- Kubernetes YAML stays where it belongs — in actions/manifests you review, not as the envelope
- Stdout can stay a single document; stderr keeps confirmations and wait lines
Operators still see a human plan. Machines get JSON. Both must describe the same change.
applied is not verified
Classic automation lies with success bits. applied means “we executed the approved actions.” It does not mean “replicas are ready” or “error rate recovered.” AI SRE needs a second signal: verify — did the goal hold after --wait? That field is part of the trust loop (T-070): ok / pending / failed / skipped — still on PlanResult, still reviewable in logs.
| Signal | Means | Does not mean |
|---|---|---|
| risk.denied | Safety refused before apply | The cluster is healthy |
| applied: true | Approved actions ran | The incident is over |
| verify | Post-apply goal check | Permission to skip approval next time |
blastRadius: review aid, not a dashboard
Before you type y, you should see who else gets hit: namespaces, owners/labels, related HPA / Service / NetworkPolicy. blastRadius on PlanResult is that preview (T-069) — a mutate review aid, not Lens. It belongs on the plan you approve, not in a separate GUI you forget to open.
What never belongs in PlanResult
- API keys, tokens, kubeconfig contents
- Full secret object data
- Unbounded log dumps as the primary contract
- Model chain-of-thought as a required field for apply
Local history is intentionally thin for the same reason. CI archives PlanResult; it must not become a secret store. The field guide spells the schema; this series rule is cultural: if it is dangerous to paste into Slack, it does not belong in the IR.
Growing AI SRE on the same document
Investigate, why trees, timelines, and suggested fixes must attach as structured fields (or nested result payloads) — evidence refs, root-cause summary, optional fix plan that still requires approval. If a feature cannot show up in PlanResult (or a clear read-only report), it is probably not a kprompt feature yet.
- Shipped: core PlanResult + JSON gates; blastRadius / verify; investigate / why / timeline / impact shapes on the same envelope
- Shipped (v0.10): closed Learn + Incident→PlanResult bridge feeding the next plan under evidence-not-proof caps
- Exploring: ADR/docs knowledge feeding planning — still never silent apply
Pressure-test as a CI citizen
Refuse high-risk or denied plans in a pipeline
kprompt "scale api to 50" -n prod -o json > plan.json
jq -e '.risk.denied == false and .risk.level != "high"' plan.json
# then human or policy decides --approveScore tools on whether this loop is natural. Scraping ANSI from a chat REPL is not a gate; it is a smell.
Next
Episode 4 is the Safety Engine — hard denies, risk levels, and why fail-closed beats confident auto-remediation. Read it next.
Related posts
kprompt + kagent: PlanResult as an MCP tool under a CNCF agent platform
How to compose kprompt with kagent without collapsing the layers: kagent hosts Agents-as-CRDs via MCPServer / RemoteMCPServer; kprompt ships read/plan-only MCP tools that return a typed PlanResult and never auto-apply. Validated against kagent quickstart + first MCP tool docs.
Read articlekprompt vs agentgateway: PlanResult ops CLI vs AI/MCP agent gateway
agentgateway (Linux Foundation) is an AI-native proxy for LLM, MCP, and A2A traffic on Gateway API. kprompt is an AI Runtime for cluster ops: PlanResult → approve, plus Observe notify. Is kprompt an agentgateway alternative? Only for the ops job — decision guide.
Read articleAI Runtime vs AI Gateway vs Agent Platform — kprompt, agentgateway, and kagent
Three Kubernetes AI layers that share vocabulary and confuse buyers: AI Runtime (kprompt PlanResult ops), AI Gateway (agentgateway LLM/MCP/A2A data plane), Agent Platform (kagent Agents-as-CRDs). One hub, honest jobs, deep links.
Read article