For months, I had an AI agent maintaining mojabi.io. Publishing bits, fixing bugs, keeping the lights on. It worked β until it didn't.
Here's what I found when I actually looked at the project root: 14 one-off Python and shell scripts. add-contextual-links.py, fix-button-text.py, fix-head-order.py, fix-internal-links.py, fix-nav.py, migrate-urls.py β each one a surgical patch for a problem that should never have existed. The agent did what agents do: it solved the immediate problem. Every time. And every fix created a new surface for the next bug.
The content lived in a monolithic bits.json file with inline HTML for every post. The static site generator was a 1127-line generate-bit-pages.js that had been patched on top of patches so many times that nobody β human or AI β could confidently change it without breaking something. Backup files littered the repo: bits.html.bak, index.html.bak, preview1.html, preview2.html, preview3.html. Classic signs of an operator who's scared to delete anything because they're not sure what's load-bearing.
The worst part was invisible. The homepage's structured data β the JSON-LD that tells Google who you are and what your site is about β was injected via client-side JavaScript. Google's crawler doesn't execute JS reliably. The result: "undefined" showing up in actual search results. My site was telling Google my name was undefined and my business description was undefined. For who knows how long.
My first instinct was to fix the structured data bug and move on. That's what the agent had been doing β fixing one thing at a time. But I've seen this pattern before in context drift: when an agent loses sight of the system as a whole and optimizes locally, every fix makes the global architecture worse.
There was no validation. Broken content could go live without anyone catching it. There was no consistent format β some bits had images, some didn't, some had meta descriptions, most didn't. There was no source of truth β was the canonical content in bits.json, or in the generated HTML, or in one of the backup files? Nobody knew. The agent certainly didn't.
I realized the problem wasn't a bug. The problem was architecture. Or rather, the absence of it. The site had grown organically through hundreds of small agent actions, each one locally reasonable, collectively a disaster. This is the same failure mode I wrote about in why fewer agents produce better results β more automated activity without structure doesn't scale. It collapses.
Instead of patching, I sat down with Claude Code and rebuilt the foundation. The approach was systematic: define the architecture first, then migrate everything into it, then validate.
New content format: Every bit became an individual .md file with YAML frontmatter. Title, slug, date, meta description, summary, related bits, image data β all declared upfront in a structured schema. The frontmatter is the source of truth. The body is HTML below the separator. No more guessing where the canonical content lives.
Clean build pipeline: A new build.js replaces the 1127-line monster. It reads the markdown files, parses frontmatter, renders templates, generates structured data statically, and outputs a clean dist/ directory. A companion validate.js runs pre-deploy checks: undefined values, broken internal links, missing required fields, un-replaced template variables. If validation fails, deploy doesn't happen. Period.
Full SEO audit: We audited all 36 bits. 26 had no summaries β fixed. 14 had zero internal links β fixed. 4 had no <h2> structure at all β fixed. The 6 thinnest bits (under 60 words) were expanded. Two meta descriptions over 160 characters were trimmed. A broken nested <a> tag in one bit was corrected. Every bit now has exactly 3 related entries for the "Continue Reading" section.
Structured data fixed: All JSON-LD is now rendered statically in the HTML. Google sees it on first crawl. No more client-side injection, no more "undefined" in search results.
The most important artifact from this cleanup isn't the code β it's the playbook. A single markdown file that documents exactly how to publish, edit, validate, and deploy content on this site. Every required field. Every SEO rule. Every common mistake with examples of what goes wrong.
This is what was missing before. The agent had capabilities but no constraints. It could write Python scripts, edit HTML, generate content β but it had no document telling it how this specific site works, what the rules are, or what "done" looks like. So it improvised. Every time. And improvisation without structure is how you end up with 14 orphan scripts and "undefined" in your Google results.
Now any agent β or any human β can pick up the playbook and publish correctly. The playbook economy isn't theoretical. This is exactly what it looks like in practice: codified operational knowledge that makes agents reliable instead of chaotic.
It's tempting to look at this story and conclude that AI agents shouldn't maintain production sites. That's the wrong takeaway. The agent did exactly what it was designed to do β solve problems. The failure was mine. I gave it capabilities without giving it architecture. No schema for content. No validation pipeline. No single source of truth. No playbook defining what good looks like.
This is the same dynamic I see in every AI agent developer experience conversation: the bottleneck isn't model intelligence. It's the environment the model operates in. A brilliant agent in a messy codebase will make the mess worse, faster. A mediocre agent in a well-structured system will produce consistent, reliable output.
The fix isn't "don't use AI." The fix is to give AI proper architecture to work within β validation that catches mistakes before they ship, schemas that constrain output to what's correct, and playbooks that encode institutional knowledge. Structure is the multiplier. Without it, every agent action is a coin flip. With it, agents become genuinely reliable operators.
We went from 14 orphan scripts and broken search results to a clean pipeline that any agent can follow. The site isn't just fixed β it's fixable now. And that's the difference between patching and building.