An alert tells you what broke, never why. Minus20 turns the page into a falsifiable root-cause hypothesis with its evidence, in your chat, about a minute after the alert. It runs inside your cluster, reads only, and the logs never leave.
Events, the previous container's log, the metrics around the restart, what was deployed in the last hour, and what happened last time. Gathering that by hand takes ten to thirty minutes, every time. That is what an engineering manager pays for, in sleep and in MTTR.
Alert fired to hypothesis in chat on a real EKS cluster with a cloud model (2026-09-15).
The same on a 7B model on CPU, nothing leaving the cluster: average 104 s, p95 130 s over a week.
Three different alerts in one namespace become one hypothesis that explains all of them, for two model calls.
KubeDeploymentReplicasMismatch pod=billing-apiHighErrorRate pod=m20-ingest-apiclusterERROR could not connect to postgres:5432HighErrorRate alert on a different podEvery line it relied on is quoted. If the cause is wrong you see why in seconds.
One command or one query that kills the hypothesis. A guess you can falsify fast is worth more than a confident one you can't.
Reply /wrong 4d75d9f6 <real cause>. The next similar incident is answered from what really happened, and the verdict becomes a test the benchmark replays against the next model.
Model down, over budget or wrong: the alert is delivered anyway. The AI is an overlay, never a dependency.
Engineers keep a list of agents they invoke when a task needs an expert. Minus20 is the on-call one: its read-only tools and the memory of your incidents are served over MCP, so Claude Code, Gemini CLI or Cursor can ask it what happened in this cluster before, and get the engineer's real answer from last time.
# in the cluster: helm ... --set mcp.enabled=true # then, from your laptop: kubectl -n minus20 port-forward svc/m20-mcp 8765 & claude mcp add --transport http minus20 http://localhost:8765/mcp # and ask, in your own agent: "has billing-api crashed before, and what was the real cause?"
Eight read-only tools: incidents, memory, events, pod logs (including the previous container), metrics, rollout history, node status. Nothing that can change anything, and the same redaction as the chat.
Two always-on processes inside your cluster. Neither holds a tool that can change anything.
One bounded call per alert, predictable cost: about $0.001 on a cheap cloud model, $0 locally.
Read-only credentials, no write tools, output is text and never executed. An on-call bot that can act turns every false positive into an incident.
Local Ollama, Mistral, DeepSeek, Gemini, anything OpenAI-compatible; local-first with a cloud fallback. The code never changes.
With the demo switch on, a Job breaks one pod in the release namespace (under its own service account; the product's stays read-only) and the first real hypothesis lands in your chat minutes after the images are pulled.
kubectl create namespace minus20
kubectl -n minus20 create secret generic m20-telegram --from-literal=bot-token='<token>'
helm install m20 oci://ghcr.io/maxuver/charts/minus20 -n minus20 \
--set config.notifier=telegram --set config.telegramChatId=<your chat id> \
--set config.llmProvider=ollama --set config.ollamaUrl=http://<ollama>:11434 \
--set demo.chaos.enabled=true
No Ollama? Any OpenAI-compatible key: --set config.llmProvider=openai --set config.openaiBaseUrl=https://api.mistral.ai/v1. Images are multi-arch, signed with SLSA provenance (gh attestation verify), scanned by Trivy and shipped with an SBOM. Already running it? Paste kubectl describe pod into the bot and get the same message without an alert.
| Shipped | Proof |
|---|---|
| Reflex pipeline: collectors, redaction, dedup, storm grouping, cross-alert correlation, graceful degradation | two real EKS runs, destroyed the same session; live daily on kind |
| Agent in Telegram: read-only tools, memory of verdicts, weekly review that sends itself, screenshots and pasted kubectl output | ADRs 0005-0006, 193 tests |
| The same tools over MCP for Claude Code, Gemini CLI, Cursor | live |
| Benchmark: 6 easy, 10 hard scenarios (3 AWS-specific), graded on the stated cause only | 7B local: easy 6/6, hard 6/10 · cloud: easy 6/6, hard 6 of 7 served |
Engineer verdicts become the eval set (replay --from-store) | first run 2/3; one false pass found and fixed |
| Helm chart (OCI), signed multi-arch images, Terraform for EKS | CI: tests, Trivy, gitleaks, provenance, SBOM |
| Not yet | |
| Topology-aware correlation, ranked hypotheses, OpenSearch collector, a public paste-and-ask bot | roadmap |
| Auto-remediation | never in the open version |
Nothing here has been measured on someone else's production incidents yet. That is why the eval set grows from real verdicts, and why the benchmark page lists every miss.