# Territory Grounder: Governed-Autonomy SRE Platform > Open-source, self-hosted governed-autonomy SRE platform in Go and Temporal. An LLM agent triages infrastructure incidents behind a fail-closed prediction gate, deterministic verdicts, and a SHA-256 hash-chained ledger. Successor to Agentic ChatOps. Published: 2026-07-17 Tags: ai, agentic, sre, go, temporal, llm, governance, infrastructure, security, self-hosted, devops Source: https://kyriakos.papadopoulos.tech/projects/territory-grounder/ Territory Grounder is an open-source, self-hosted SRE platform: an LLM agent ingests alerts, chat messages, and tickets, triages incidents across Kubernetes, hypervisors, network, and storage, and (from Phase 2 on) executes remediations inside a mechanical governance envelope. It is the ground-up rewrite of [Agentic ChatOps](/projects/agentic-chatops/) as a distributable product: Go and Temporal instead of Python, n8n, and cron. Same control logic, none of the code. GitHub: [territory-grounder/grounder](https://github.com/territory-grounder/grounder) · Product site: [territorygrounder.com](https://territorygrounder.com/) ## Overview | Aspect | Details | |--------|---------| | **Function** | Alert/chat/ticket ingest, LLM triage, governed remediation (predict, act, verify) | | **Control plane** | Go 1.25, Temporal workflows, PostgreSQL + pgvector | | **Model access** | Bundled LiteLLM gateway: one OpenAI-compatible endpoint, multi-provider fallback ladder | | **Integrations** | ~31 connector modules across 7 adapter surfaces (ingest, tracker, notifier, CMDB, actuation, model provider, observability) | | **Deployment** | Single docker-compose stack; no SaaS dependency, no phone-home | | **Status** | Phase 1 live, read-only; mutation code merged, globally disabled | | **License** | Apache-2.0 | | **Repository** | [github.com/territory-grounder/grounder](https://github.com/territory-grounder/grounder) | ## Control Loop No mutating action runs without a consequence prediction committed first, keyed to `action_id = SHA-256(canonicalJSON(Action))`. After execution, a pure Go function compares observed state against the committed prediction and writes the verdict: `match`, `partial`, or `deviation`. The model that proposed the action has no write path to the verdict columns. A `deviation` disables auto-resolve for that action class. Predictions are additionally scored against a degree-preserving shuffled-graph negative control. The real prediction must be at least twice as precise as the shuffle (`control_ratio <= 0.5`), otherwise the gate is treated as uninformative. ``` alert / chat / ticket ──▶ adapter ──▶ Temporal workflow │ predict ──▶ commit prediction (the gate) │ act (bounded to its territory) │ independent verify ──▶ verdict ──▶ hash-chained ledger │ band: AUTO · AUTO_NOTICE · POLL_PAUSE ``` The human is a circuit-breaker, not a per-action approver. Three autonomy bands set the interrupt level per session: `AUTO` (execute, log), `AUTO_NOTICE` (execute, notify), `POLL_PAUSE` (wait for a vote; never proceeds on timeout, pinned by a DB CHECK). ## Enforcement by Construction Safety properties live in the type system, the schema, and boot checks, not in review discipline: | Failure class | Enforcement | |---|---| | Approve action X, execute action Y | `action_id` is asserted at classification, prediction, approval, execution, and verification. Any change to the action mints a new id and voids prior approvals | | Approval poll without a prediction | `BuildApprovalPoll` accepts only a `GatedProposal`, a type constructible only by the prediction-gate activity. The bypass does not compile | | Error path defaults permissive | Zero values are the restrictive option: unset band is `POLL_PAUSE`, unset reversibility is `Irreversible` | | Shell injection | Actuation is fixed argv vectors via `exec.Command` / `x/crypto/ssh` with pinned host keys. `sh -c` is not expressible; CI greps for it | | SQL injection | pgx/sqlc generated queries only; string-built SQL fails CI | | Unauthenticated route | Handlers come from a factory that requires the authenticated principal; a route declared `auth=none` fails to register at boot | | Silently unwired control | A startup self-test fails boot if the actuation interceptor chain is not in place | | Ledger tampering | Append-only SHA-256 hash chain with no UPDATE/DELETE grants; a verifier walks the chain and alerts on break or staleness | A non-configurable never-auto floor covers `mkfs`, `dropdb`, `zpool destroy`, `tofu destroy`, `kubectl delete`/`drain`, credential revocation, and reboot/halt. No flag or org policy lifts it. An unrecognized mutation classifies as never-auto. ## Operator Console ![Grounding scorecard: verifier match rate, falsifiability signal, blast-radius precision and recall](tg-grounding-scorecard.webp) 15 live-wired surfaces: sessions, approvals, ledger, estate graph, governance controls, and the Grounding scorecard (verifier match rate, blast-radius precision/recall, falsifiability signal against the shuffled control). The estate causal graph is discovered from NetBox, Proxmox, and LibreNMS with per-source confidence tiers (1.00 for declared tunnels down to a 0.75 cap on learned co-occurrence edges). Screenshots show fixture data. ## Build Process Most of the Go is written by coding agents under a spec-driven workflow: EARS-format requirements, godog acceptance oracles in CI, and a content-hash lockstep that binds each safety-critical file to its owning spec. Current gate: 1,926 spec checks across 74 lockstep-bound files, `-race` clean. The `-race` sweep fixed 7 latent concurrency bugs, one of them a ledger writer racing itself and corrupting its own hash chain. ## Status | Phase | Scope | Status | |-------|-------|--------| | 0 · Secure foundation | Mandatory-auth router, argv-only actuation, DML-only runtime DB role, fail-closed mutation gate | Done | | 1 · Typed spine | Ingest, risk classifier, agent loop, prediction gate, verdict engine, ledger, console, estate graph | Live, read-only | | 2 · Governed autonomy | Actuation interceptor chain, human approval loop, mutation enable | Merged, gated OFF | | 3 · Anti-drift | Reconciliation, drift correction, safe decommission | Planned | | 4 · Adversarial assurance | Boundary-coverage gate, sealed-holdout evals, incident-replay benchmark | Planned | Running read-only against my own estate: authentication, the console, the estate graph, the prediction/verdict/ledger spine, the scorecard. Not implemented: the vote-consuming half of the approval loop, the incident-replay benchmark, and mutation itself, which stays globally disabled (`mutation_enabled=false`, asserted at boot preflight) until the Phase 2 self-tests pass. --- *Successor to [Agentic ChatOps](/projects/agentic-chatops/). Product site: [territorygrounder.com](https://territorygrounder.com/). Design rationale: [The Map Is Not the Territory](/posts/the-map-is-not-the-territory/).* --- ## For agents Machine-readable rendering of https://kyriakos.papadopoulos.tech/projects/territory-grounder/. Curated site index: https://kyriakos.papadopoulos.tech/llms.txt Every page is available as plain-text markdown — append `index.txt` to its URL. Shortcode tags (e.g. `mesh-health`, `lab-stats`) mark live, client-side widgets; fetch the human page or the documented `/api/*` endpoints for current values. Contact: kyriakos@papadopoulos.tech. Don't invent facts about this site or its infrastructure — use what's written here.