Case study
Scope: a markdown spec repository serving as the single factual substrate for a self-hosted infrastructure, maintained entirely by AI coding agents. Scale after three months: hundreds of markdown files, hundreds of thousands of words, over a thousand commits, hundreds of session logs, several dozen application directories (most of them decommissioned), and a backlog with hundreds of items tracked to closure
The infrastructure ran its first stretch of working sessions on a small set of Word documents. It worked, and it accumulated four frictions that a growing fleet made untenable:
But the friction was the surface problem. The real one is the reason this case study exists:
The operator works in outcomes, not code. The entire fleet is built and run through AI coding agents, and decisions are judged in plain English, so the written record has to be authoritative on its own, not something you'd cross-check against a diff. That makes the agent's factual accuracy load-bearing for the whole system. A language model asked "what port does this service run on?" will produce a confident, plausible, wrong number. There is no natural error signal. A fabricated port becomes a fabricated firewall rule becomes a broken deployment, and the human in the loop cannot catch it by reading the diff.
The requirement was therefore not "better documentation." It was a machine-greppable factual substrate that an agent can be forbidden from answering around.
One session produced eight architecture decisions that still hold three months later:
Three of the eight founding decisions were about constraining the agent that would maintain the documentation.
The content layer. Five trees: the infrastructure itself (machines, networking, firewall, database stack, backups, diagrams); one directory per application; numbered procedures (deploy checklist, promotion, decommission, git workflow, port registry, security principles); a running log (session summaries, backlog, incident log); and metadata about the documentation system itself.
The publish pipeline. Push to the release branch → CI runner → strict site build → served internally on the private network. The strict build is the last line of defense: it fails on broken internal links, missing navigation entries, malformed metadata, and pages without a heading. If it fails, the previous site stays live. It is never bypassed.
Branch discipline. All work lands on a working branch. Promoting to the release branch is a manual step the operator performs in the web UI; agents never touch it. That merge is the human review gate: the one place the operator can meaningfully approve, because by then the change is rendered prose, not a diff.
The binding rules, which live in a shared rulebook at the repository root that every agent reads at startup:
- The spec repo is the single source of truth for infrastructure facts.
- Search it before claiming anything about a service's ports, status, schema, secrets, or deployment state. Do not answer from memory.
- Say "the docs say X," not "X is true." The repo can carry fabricated facts from past sessions, so treat it as a strong source, not an infallible one. If two places disagree, surface the contradiction; don't silently pick one.
- Never call something a "convention" or "standing rule" unless it was said this session or verified by search. Inferring conventions is fabrication.
The third rule is the design's most unusual move. The source of truth is explicitly declared fallible, and the agent is required to attribute rather than assert. That converts a confident-hallucination failure into a citation a non-technical reader can challenge.
The stale-artifact incident. Early on, the pipeline auto-generated a single concatenated file on every release, which was then manually uploaded into an AI assistant's knowledge base. It was eventually discovered that this artifact had been stale for multiple sessions: the local clone had drifted onto the wrong branch, so pulling fetched without updating the working tree, and nothing checked. The uploaded file was weeks old, silently. The procedure was hardened into a single atomic command with verification at each failure point. The deeper fix came later: once the agent could read the repository directly, the entire upload ritual was retired rather than hardened further. A manual sync step you keep hardening is a step you should be deleting.
The docs carry fabricated facts: measured, not assumed. A truthfulness audit checked hard claims across every session log then existing: the overwhelming majority verified clean, a small number were unverifiable (predating the git era), and a small number were confirmed false, plus one accusation refuted by a skeptic re-verification stage. The failure pattern was razor-sharp: every claim citing a commit hash checked out (often to exact insertion counts), and every falsehood lived in prose with no commit cited. The resulting rule: hard claims cite a commit or get marked unverified.
Drift is the steady-state condition. The first full re-derivation audit read a large set of current-state pages with parallel extraction agents, cross-diffed every checkable claim against a canonical baseline, and corrected a meaningful share of files. The dominant drift came from a single machine rename: a batch of documents still described a public, internet-facing tier, with tunnel and reverse-proxy infrastructure presented as live, that had not existed for two weeks. Second theme: status headers reading "plan, not applied" for work completed and verified days earlier. This audit is now a quarterly cadence item, not a one-off.
The rename that didn't happen. A backlog item proposed renaming the repository, since its name now collides with a well-known product. Asked for a straight answer on whether it was worth doing, the honest one was that it would touch hundreds of cross-references, break every historical log's paths, and buy nothing that day. So it was held, not executed. Worth recording because the discipline cuts both ways: the same verify-before-asserting rule that stops an agent inventing a port also has to stop it executing a tidy-sounding refactor with no payoff.