The Watchtower Pattern: Platform Engineering for a Team of One


Every working session I run starts in the same folder, and it is not a project. It is a repository with no application code in it at all: a 73-line operating manual, a machine-readable roster of every project I own, a wiki that has grown to 463 pages, a bundle of runnable config artifacts, and the scripts that check all of it. I named it Watchtower back when I wrote Laravel on Lockdown, then spent that entire post on the security half. This post is about the pattern itself.

The claim, stated plain: almost nothing about this pattern is new. It is three old disciplines fused together. Golden paths supply the what, Google-style large-scale changes supply the how, and desired-state convergence supplies the loop. All three have been running in industry for a decade or three, and all three used to require a platform team to operate. I swapped out two parts: the deterministic controller became a reasoning agent, and the machine-readable policy became English. Those two swaps collapse the operating cost from a team to a person. That is the entire story, and the rest of this post is the receipts.

The room above the projects

Here is how work happens now. I open a session in Watchtower and say “in project X, fix the thing.” The agent resolves X against the roster, works in the sibling repo by absolute path, and carries the same standards into that repo it would carry into any other. When I say “audit project X against our standards,” it reads the standard, reads the app, and hands back a gap list with severities and fixes. When I approve, the fleet converges a little more. I stopped configuring my projects individually months ago. They inherit.

The folder has six load-bearing parts.

The law. A CLAUDE.md that functions as a constitution: operating rules, branch policy, deploy policy, and an index of where everything else lives. It is 73 lines and it is capped near there on purpose, because it is loaded into the agent’s context at the start of every session, and every line costs every session. Nothing in it is a fact that could go stale; facts live one layer down, and the law holds pointers. A twin AGENTS.md carries the same contract for other harnesses. The brain is the repo, and the repo does not care which agent is reading it.

The roster. One JSON file that says what projects exist, where they live on disk, who hosts them, how they branch, how they deploy, and how to run them locally. Everything that needs the project list derives it from this file through a small reader script. Nothing hand-copies it. That rule sounds fussy until you learn why it exists, which I will get to.

The memory. A markdown wiki, one concept per page, pages interlinked, each with a small frontmatter contract that a linter enforces. A zero-dependency CLI searches it and injects pages into context on demand, so the agent retrieves what it needs instead of drowning in the corpus. The standing orders are simple: search the wiki before the web, and write back what you learn. Durable knowledge compounds instead of evaporating when the session ends.

The standard. A normative specification for how every app in the fleet is configured and run: versions, static-analysis gates, test strategy, CI shape, runtime guardrails. It uses MUST and SHOULD in the RFC sense, and it carries a register of accepted deviations, so an exception is a documented decision instead of a quiet drift. The threshold values themselves do not live in the prose. They live in a bundle of runnable config files that apps copy and CI consumes, and the prose points at them. A number stated in two places is a number that will eventually disagree with itself.

The loop. A deterministic scorecard checks the mechanical facts on every app’s merged main branch: is the config at the bundle’s values, are the mandated files present, did a baseline grow. An audit procedure handles what the scorecard cannot: the agent reads the spec and the app and writes a per-app convergence roadmap, every deviation tagged with a severity and a fix. A remediation procedure then works those roadmaps on isolated branches in isolated worktrees, never in my working copy. Then a re-audit. Audit, roadmap, remediate, re-audit. Convergence is a loop, not an event.

The rails. A drift checker asserts that certain files are byte-identical across the whole fleet, because for the universal pieces, interchangeability is the point. A guard suite lints the wiki’s frontmatter, regenerates its index pages, and validates the roster’s consumers on every commit. A hook rejects any skill file that hardcodes a roster, a date, or a PR number, because procedure files that embed facts rot silently. The system is designed on the assumption that discipline fails and checks do not.

None of the intelligence lives in the agent. The agent is a commodity that gets swapped every time a better model ships. The repo is the asset.

I did not invent this

Every structural idea in that folder has a name, an author, and years of production history. Naming them is the honest move, and it also happens to be the strongest argument that the pattern works.

The standard-with-a-blessed-path is Spotify’s golden path. Pia Nilsson described it in 2020: one opinionated, supported way to build each kind of thing, introduced to fix what Spotify engineers called rumor-driven development across hundreds of teams. Netflix ran the same idea as the paved road, with a sharper edge under their freedom-and-responsibility culture: leave the road whenever you like, and own everything that happens off it. My fleet specification is a golden path with the freedom removed, which is a luxury available to a fleet with one owner.

The fan-out is Google’s large-scale change machinery. Chapter 22 of Software Engineering at Google describes Rosie, the robot that takes a change too big for any human, shards it by ownership, tests each shard, and lands the survivors. The same chapter states the Beyoncé rule: “if you liked it, you should have put a CI test on it,” meaning an LSC that breaks your untested assumption is your problem, not the LSC author’s. Hold that rule; it comes back when we get to what this pattern costs.

The loop is desired-state convergence, and it is the oldest idea in the room. Mark Burgess built CFEngine on it in 1993 and later formalized it as promise theory: autonomous agents repeatedly converging a system toward a declared end state from wherever it happens to be. Puppet and Chef industrialized it. The control repo, one versioned repository holding the desired configuration of everything, is the direct structural ancestor of my Watchtower. GitOps then restated the idea for clusters, and the OpenGitOps project boiled it to four principles: desired state that is declarative, versioned and immutable, pulled automatically, continuously reconciled. Read those four words against the folder I just described. The pattern matches almost clause for clause.

The agent-facing parts have a lineage too, a much younger one. Andrej Karpathy sketched the memory idea: a plain-markdown wiki that the model itself maintains under a written contract, with a lint and a search tool, so an LLM becomes a disciplined librarian of its own knowledge instead of a goldfish. And over the past year a wave of writers independently converged on the workspace idea under names like meta-repo, repo-of-repos, and polyrepo synthesis: a repo above your repos that holds shared instructions, a manifest, and cross-repo procedures for a coding agent. The AGENTS.md convention that most coding agents now read made the instruction layer portable across tools. If you build a watchtower today, you are late to a small crowd, and that should comfort you. Patterns that get independently reinvented a half-dozen times in a year are patterns with a real force behind them.

So what is left that is mine? The fusion, and the two swaps.

The two swaps

Every convergence system before this one had a deterministic actuator. Rosie executes a codemod. A Puppet agent applies a catalog. A GitOps operator diffs manifests. The policy, likewise, had to be machine-readable before the machine could enforce it: Rego rules, conformance packs, scorecard predicates. Both constraints priced small operators out. Writing codemods and policy predicates for a five-app fleet is a platform team’s work, and nobody staffs a platform team for five apps.

Swap one: the controller can read. The actuator in my loop is a reasoning agent, which means I fan out intent, not diffs. Rosie needs the transformation specified exactly; I say “bring this app to the standard” and the agent derives each repo’s diff itself, because each repo’s distance from the standard is different. The same intent produces different patches in an app with a deep domain layer and an app that is four controllers in a trench coat, and both land on spec. No codemod author required. The LLM is the Rosie of a personal fleet.

Swap two: the policy is written in English. My specification is prose. Not YAML that a policy engine evaluates, prose that an agent interprets, with MUSTs and SHOULDs and documented exceptions. That is the sharpest break from everything in the lineage, because every prior system demanded the standard be encoded as an executable predicate before enforcement could begin. The encoding step is exactly where small fleets gave up. Prose costs nothing to write and nothing to amend, and an interpreter that can read means prose is now enforceable.

And here is the rule that makes swap two survivable, because on its own it is reckless: anything the prose mandates that can be checked mechanically gets a mechanical check. The scorecard, the drift checker, the baseline guard, the CI gates in every repo: those are not vestiges of the old way. They are the boundary of trust around the new way. The agent interprets the standard; the rails bound the interpretation; the residue that genuinely requires judgment is the only thing left to judgment. I did not design it that way on day one. I watched prose-only convergence wobble, and I added a rail every time it did.

There is a third principle hiding in the wiki, and I think it is the one most people will miss. The standards repo is also the operator’s memory. Single source of truth is an old idea about storage; this is a newer idea about behavior. When the agent learns something durable, it writes the page; when it works, it reads the pages; so every improvement to the repo is an improvement to the operator. Documentation stopped being a cost center the day it became the thing my workforce thinks with.

What it buys

The concrete case first. In one project I spent an afternoon making the CI test job fast: a throwaway in-memory Postgres, parallelized tests, a warm static-analysis cache. The test job went from twelve and a half minutes to under five, and the static-analysis step from nine minutes to three seconds warm. In the old world that recipe would have lived and died in that repo. Instead it got written into the specification, the config bundle got the artifacts, and the loop rolled it out to the other four apps. Every rollout PR came back green on the first run.

Learn once, converge everywhere. The marginal cost of the fourth app was almost nothing.

Those two sentences are the whole pattern. Everything else in this post is machinery for making them true on purpose instead of occasionally.

Cross-boundary work is the capability I did not fully anticipate. A deploy here crosses four systems: an app repo’s CI builds an image, a registry holds it, a commit bumps a tag in the cluster repo, and the GitOps operator rolls it out. When a deploy stalls, the agent traces the whole chain in one session, because the topology is documented in its memory and every repo is within reach. Same when a bug spans a backend and a frontend, or an incident needs evidence from three services and a log stream. The watchtower session holds the map. Investigations that used to be a tab-juggling afternoon are now one conversation.

New projects are born converged. The fleet’s starter templates sit under the same drift checker as the production apps, so the standard reaches them before a new app takes its first breath. Drift you prevent at birth is drift you never remediate.

And the aggregate effect, the one the subtitle promises: one person operates the fleet. My operating doctrine sorts every event into three tiers. Machines handle what machines can handle: reconciliation, self-healing, dependency updates. The agent triages what needs reading: alerts, errors, audits, convergence chores. I decide what is genuinely mine to decide: merges to production, pricing, product bets, anything irreversible. The design test for every new piece of automation is whether it shrinks the surface of things only I can do. A converged fleet is what makes the middle tier trustworthy, because an agent triaging five identical systems is working one problem, not five.

What it costs

I will not sell you this pattern without the invoice.

Your auditor is non-deterministic. An agent interpreting prose can misread it, over-apply it, or confidently report conformance that is not there. Run this pattern without mechanical rails and you have governance by vibes with a beautiful wiki. The rails are not optional hardening, they are the admission price. Budget for building them, and remember the Beyoncé rule cuts against you now: if you liked an invariant, you should have put a check on it, because your enforcement layer is a language model with a good vocabulary.

Context is a tax on everything. The law is 73 lines because every line is paid for in every session. The wiki needs a search tool because 463 pages do not fit in a context window and never will; retrieval has to be the default and the whole corpus the exception. A fat watchtower does not fail loudly. It just makes every task a little slower and a little dumber, and you will not notice for a month.

The garden must be tended. One fact, one owner; dated news kept out of timeless pages; index pages generated, never hand-curated. This is real recurring work, and skipping it recreates the disease. I know because my roster once lived in three places, and all three disagreed. Every drift incident this system has ever had traced back to a duplicated fact. The cure was mechanical: one machine-readable roster, every consumer deriving from it, a linter that fails the commit when they do not. Duplication is not a tidiness problem. It is the root cause.

The blast radius is the whole fleet. An agent homed in the watchtower can write to every repo you own. Mine operates under standing law: branch and push freely, never merge, never touch production, do remediation in isolated worktrees that never disturb a working copy. Those rules carry real weight, and I still treat the arrangement as what it is, a single-operator pattern. Handing a team this much shared write reach without a real authorization story would be negligent. I have one owner, so my authorization story is me.

Prose goes stale silently. A Rego policy that no longer matches reality fails a pipeline and gets fixed. A normative page that no longer matches reality just sits there being wrong, and the agent will cheerfully enforce the wrong thing. The mitigations are structural: dated status lives in logs, never in normative pages; every page carries an updated stamp; procedure files are forbidden from embedding facts. It helps. It is still weaker than an executable policy, and I consider that the standing debt of swap two.

The loop is not free. A full-fleet audit reads every app’s merged main against the whole specification and spawns a small crowd of agents to do it. It costs real minutes and real tokens. I scope runs to one app or one dimension when I can, and you should too.

Notice what is not on the list: the pattern does not replace CI, code review, or the gates I described in Laravel on Lockdown. The watchtower converges configuration and knowledge. Each repo’s own pipeline remains the enforcement backstop, standing there precisely for the day the interpreter has a bad afternoon.

Building one

Do not build mine. Build stage zero, live in it, and let each stage earn the next.

Stage zero, the folder and the law. A repo above your projects. A CLAUDE.md or AGENTS.md with three or four operating rules and a roster, even as a table. Address siblings by absolute path. This alone gets you “in project X, do the thing,” and it takes an hour.

Stage one, memory. A markdown wiki with a tiny frontmatter contract and a search script. One concept per page. Standing orders: search before the web, write back what you learn.

Stage two, anti-rot. Split law from news. Generate your index pages. Add a linter and a pre-commit hook. Give machine data one machine source and make everything else derive from it.

Stage three, the standard. Write down the way your projects should be configured, as MUSTs and SHOULDs, with a register for exceptions. Put every threshold value in a runnable config file and point the prose at it.

Stage four, the loop. A deterministic scorecard for what can be checked mechanically. An audit procedure for what takes judgment. A remediation procedure that works on isolated branches. Then re-audit, and enjoy the specific pleasure of a fleet that gets more uniform while you sleep.

The through-line at every stage: the agent gets standing authority to read, write, branch, and propose, and no authority to merge or deploy. Judgment stays with you. That boundary is the pattern’s load-bearing wall, and it is not negotiable at any stage.

Where this lands

If you are an IC with more than two side projects, build stage zero this weekend. One folder, one law file, one roster. You will feel the difference the first time you fix the same bug in two repos with one sentence.

If you lead a team, your golden-path documents are already prose, which means the audit move works today: point an agent at your standards doc and one service, ask for the gap list with severities, and grade the output. You will learn more about your standards’ actual clarity in an hour than a quarter of compliance meetings will teach you.

If you are a VP, director, or sponsor, this pattern is an argument about where standards should live: in one versioned place with a loop that enforces them, not in the heads of your senior engineers and re-decided in every new codebase. The economics that made that a platform-team luxury just changed. Fund the repo and the rails, not another round of convention debates.

Platform engineering was never really about platforms. It was about deciding things once. For thirty years the price of deciding once was a team that encoded every decision into a machine-enforceable shape, so only organizations with platform teams got to have golden paths, convergence loops, and fleets that stay uniform. A controller that can read just repriced all of it. The watching is cheap now. Deciding what the fleet converges toward is the part that was never for sale.