Back in May I put four posts online in quick succession — a Claude Code workflow built on a ten-step SDLC pipeline, my AI-native homelab, the Home Assistant architecture underneath it, and a rig for running Dungeons and Dragons out of Obsidian. Four systems, and every one of them already worked the day I wrote it up.
Those posts were the before. What I want to write down here is the eleven weeks after — the stretch where one hard-won idea kept forcing the same redesign in one thread after another, until the machinery I’d built to catch my mistakes started catching its own.
The weeks a failure forced the redesign
By the second week of May the research agent — the thing that fetches sources and writes a vault note — was one agent doing six jobs: fetch, rank, synthesize, copyedit, fact-check, validate. The notes looked right, and that was the problem: an agent grading its own homework catches typos and nothing else. On the fourteenth I split it into six specialists run by an orchestrator that does none of the writing. Author and reviewer were finally different agents, and the notes got better that afternoon. The Research Workflow has the pattern. Once I’d watched a monolith lose to a fan-out of narrow specialists, I started seeing monoliths everywhere.
flowchart LR F["A monolith that looks right"] --> S["Fan out into specialists — author ≠ reviewer"] S -.reused by.-> R["Research notes"] S -.reused by.-> D["D&D content"] S -.reused by.-> G["Godot game"]
Three days later the homelab taught me the same lesson through a louder door. On the seventeenth, Syncthing — the daemon that mirrors my vault across a laptop, a phone, and two servers — faithfully propagated a disaster. A cleanup tool had run over vault files whose contents were evicted to iCloud, seen empty placeholders, and tidied accordingly. Syncthing did exactly its job: 2,657 deletions and roughly 74,000 lines, to every device, in minutes. Nothing was broken. Everything was working. That’s what made it a disaster instead of a bug.
I migrated to LiveSync that same day in a panic, and it failed on its own terms within a day. The shove landed me somewhere sturdier: a star topology with one authoritative hub, a delete-rate alarm, and ZFS snapshots so a bad sync is an inconvenience, not an extinction event. When Syncthing Faithfully Shipped a Disaster is the full autopsy. Two failures, three days apart, in two threads, pointed at one thing: watch the blast radius, not the intent.
Hardening spreads across the threads
Through late May and June, quieter work: each thread took the lessons and built guardrails.
The pipeline grew a second lane. Not every change needs eleven steps of ceremony, so on the twenty-fifth I added a fast path for small, single-surface work. The two lanes hand off now — a full run downshifts when the architect calls a change trivial, and the fast lane upshifts the moment it touches a paid API, an LLM prompt, or a security surface.
The homelab hardened alongside it — internal TLS, Proxmox journals shipping into VictoriaLogs, a bridge from Home Assistant into Prometheus so the house finally had real observability instead of vibes, and an Alertmanager dead-man’s switch that fires when the other alerts go quiet. You build that plumbing once you’ve watched a silent failure run as long as it liked.
The workflow thread had already learned to isolate itself — on the seventeenth of May, the day Syncthing ate the vault, every pipeline run got its own throwaway git worktree so two runs could never clobber each other. Then on the eleventh of June agent authoring became first-class: creating or changing an agent now routes through the same review machinery as any other code, docs writer and docs reviewer split apart so no agent both writes and grades its own documentation. The recursive loop from Bootstrapping Agentic OS was no longer a party trick. It was governed.
The night one NPC bombed at the table
Then the creative thread had its Syncthing moment — live, in front of players.
In mid-June I ran an NPC named Sedge the Tallyman, written days earlier and never stress-tested. On paper he was fine. At the table he was a disaster in miniature: no read-aloud text, so I improvised his voice cold, and a clue buried three sentences deep in a stat block, so the party walked straight past the thing the whole scene existed to deliver. The session survived; Sedge did not. Sitting there afterward, I recognized the shape — the research monolith again, content that had passed my own eyes and no one else’s.
So on the fourteenth the D&D thread got the same surgery the research thread had: ground every piece in campaign canon, draft it, then fan it out to adversarial reviewers whose whole job is to find what’s missing — absent read-aloud text, buried clues, illegal stat blocks, tone and safety. I named the completeness checker the anti-Sedge guarantee, without irony.
The systematic version earned its place because the quick version didn’t. I’d patched Sedge’s voice by hand first, and at the very next session his dialogue still came out stiff and archaic. One heroic fix doesn’t hold, because the gap returns at the next table unless something catches it every time. So a week later I made the routing mechanical — a hook that physically blocks hand-authored D&D content from landing outside the pipeline. A rule you have to remember is a rule you’ll skip at 11pm the night before a session.
The machine turns on itself
By late June the three threads had become one system with three faces. In the first week of July, it turned that watching on itself.
It started with distillation. On the third I ran an evidence-gated promotion of the fleet’s heaviest agents to a stronger model and — more interesting — a push to distill their reasoning so the cheaper, token-efficient models could hit the same ceiling. The point wasn’t to spend more but to encode the framework so tightly that a cheap model produced what an expensive one used to. The machine was reading its own best work and writing down how it got there.
Two days later it went further and started watching the instructions themselves. I built a minimalism ladder for the pipeline and wired up monitoring of the prompts, so a prompt that starts underperforming gets flagged like any other regression. It’s the whole post in a single feature. I’d spent these weeks building watchers: reviewers that grade each other’s drafts, an alarm that trips when files vanish, a validator that hunts for the clue a scene forgot. Now there was a watcher for the watch-builders.
The threads keep multiplying
That inward turn wasn’t the only thing happening, and it would flatter the story to pretend it was. The same weeks the machine folded inward, it also spread outward.
I made the harness portable. After months against a single model provider, I brought up a second — Codex — to parity between the tenth and fourteenth of July: security parity, a proxy-aware sandbox transport, a Codex engine behind the agent graph, native plugins. That isn’t recursion; it’s the same machine learning to run somewhere new.
And the creative thread jumped its banks. On the twenty-ninth of June, Deep Void Extraction quietly opened — a tactical roguelike in Godot. The tabletop work had spilled out of Obsidian into an actual game: by early July, a combat-feel prototype, its own Godot SDLC agents, a live-validation rail, and — the part that still makes me grin — running on a Steam Deck. Three threads had become four while I wasn’t counting.
Why this post exists
Two things from this stretch I haven’t placed yet, and they’re the real reason this post exists.
The first is that the blog became part of the machine. On the eleventh of July I gave it a content model — a garden and a stream. The stream is dated posts like this one; the garden is living pages tended over time instead of frozen at publish. The four posts I started with this spring each grew a garden twin, and this retrospective is the stream entry that hangs off all four. So the blog is no longer something I write about the homelab; it’s a surface of it, and this post went through the same fan-out of adversarial reviewers as everything else.
The second is the birds. Back on the third of May, a bird-detection pipeline in the house had gone dark; every sensor read unknown. The birds were singing the entire time. Every detection made the full trip through the network and got turned away at the doorstep, because one auto-generated template fell back to the wrong sentinel — else this.state, which wrote the literal string unknown into a slot that demanded a number. A silent failure of exactly the kind I’d spent these weeks learning to catch, sitting in my own house, chirping. It took ten weeks to run down, and published on the eighteenth of July as The Birds Were There the Whole Time. The birds were never quiet. I just wasn’t watching the right thing.
The end state, once I sat down and counted: thirty-seven skills, a dual eight- and eleven-step pipeline, a six-agent research pipeline, knowledge-graph search across five thousand notes, a governed D&D pipeline, a Godot game on a Steam Deck, this garden-and-stream blog, and a harness that runs on more than one model provider — all bootstrapped from a single agent-creator skill I wrote by hand.
That’s a highlight reel, and I should say plainly that it is one. It’s easy to write these weeks as a clean chain of failures that each made me stronger, because the failures I’m telling you about are the ones I caught. The watchers have costs this tally hides: the delete-rate alarm that will cry wolf on a legitimate cleanup, the ceremony tax on a change that never needed eleven steps, the fix to Sedge that didn’t take the first time. So the honest claim is narrow. A system that looks healthy at every hop can still be quietly wrong, and watching for the failure directly is the best defense I’ve found. I spent these weeks building those watchers. Next stretch, I find out what they still miss.