An autonomous ops platform
The system I built to run a portfolio of live production services by myself, safely. It senses events, plans and drafts fixes with LLMs, opens pull requests that a policy-gated merge workflow either merges or hands to me, and learns from every outcome.
The problem
I run a portfolio of live products by myself. There is no team to catch a bad deploy, watch the dashboards, or triage a failing build at 2am. So I built the ops layer I would otherwise need to hire: an event-driven system that does the first pass on everything and escalates to me only what its merge workflow will not accept, never asking me to clean up.
The loop
Events (GitHub webhook / scheduled health check / alert)
├
Dispatcher ──► triage agent ──► policy engine (shadow mode)
(confidence 0–100) (auto / batch /
├ interrupt / escalate)
▼
Specialized workflow (pr_review · ci_diagnose · health_triage · …)
├
▼
SENSE → PLAN → ACT → LEARN
sense validate task, check repo state, simulate change
plan build a structured plan (typed schema)
act execute step by step, git checkpoint per step,
per-step recovery ladder, run tests in a sandbox
learn store the outcome as a deduped lesson
├
▼
Draft PR opened ──► merge workflow (kill switch · size cap · protected paths · required checks)
──► merge, or escalate to a human
The policy engine runs in shadow mode: it records the decision it would make so I can measure it before it enforces anything. What enforces today is the tool-permission deny list, the protected paths, the kill switch, and the merge workflow.
Safety by design
I came up through application security, so the controls are the point, not an afterthought. Defense in depth:
- Merge authority is outside the agent. The agent can only label a pull request. A GitHub Actions workflow checks the kill switch, a diff-size cap (500 lines, 20 files), and the protected-path list, and asks GitHub to merge only when required checks are green. Anything that fails a check, touches a protected path, or cannot be measured goes to a human. Tool permissions deny the merge command outright. Each merge or reject is a labeled outcome the system learns from.
- Blast-radius control. The executor works in git branches only, scans for dangerous patterns (rm -rf , force-push, DROP TABLE) before applying edits, and honors do-not-touch paths (
.env*, secrets, migrations, mainnet). - Kill switch. A file checked at the top of every handler halts all autonomous action, no restart needed.
- Rate limits and a circuit breaker. Caps on commits per hour and PRs per day, and it stops after three consecutive failures on the same repository to prevent restart storms.
- Prompt-injection defense. Untrusted text (issues, PR comments, CI logs) is fenced and marked as data, and known injection patterns are stripped. I treat that as a speed bump, not a boundary. The boundary is what the agent is allowed to do: tool permissions deny merge and file copy outright, and protected paths cannot change without a human.
- Secrets and integrity. Secrets pulled from a secret manager at start, mode-600, never in git; webhooks verified with HMAC-SHA256; hardened systemd sandboxing and key-only SSH.
Decisions I'd defend
Planner, executor, and learner are separate, not one ReAct loop.
A planner emits a structured plan, an executor runs it step by step with a git checkpoint per step, and a learner records the outcome. If step 3 fails, it recovers just step 3 through a ladder (retry, simplify, skip, escalate) instead of unwinding the whole task. That is the difference between a reliable agent and one that spirals into hallucination.
A cost-optimized, multi-provider LLM router with failover.
Each task goes to the cheapest tier that can handle it and falls back across providers on rate-limit or overload. 12 models across 6 providers, with real per-token prices and per-call cost tracking in code.
SQLite with WAL and a single writer thread, not Postgres or Kafka.
One database for the event queue, the lessons, and the task log. WAL mode for concurrent reads and a dedicated writer thread so there is never a locked database. When you are solo, operational simplicity is a feature; right-sizing is a skill.
By the numbers
- About 17 live services across 6 hosts, operated from one place
- ~3,000 automated tests and about 9 required CI gates; a PR merge is the only path to production
- Pull requests the agent opened between July 28 and September 21, 2026 (states read October 12, 2026): 77 opened; 74 merged, 23 of them by the merge workflow on its own and 51 under my account; 2 closed without merging; 1 still open. The workflow refused 8 of the 77 and sent them to me; all 8 were later merged under my account. The window starts after the May 2026 incident that moved merge authority out of the agent
- Disaster recovery tested monthly, restoring into an ephemeral Docker container with canary checks
- Drift detection for schema, service registry, secrets, and configuration, with alerting