Migration log · entry 010 · September 2026

Every rule is scar tissue.

People ask how a migration this size stays coherent with (mostly) one developer. The honest answer: it isn’t discipline, and it wasn’t designed. Every gate in our pipeline exists because a specific failure happened once — and was never allowed to happen twice.

I didn’t start this project with a methodology. I started it with a legacy stack, a deadline measured in years, and the standard solo-developer confidence that I’d remember what I was doing. Fifteen months later there’s a pipeline every change passes through — standards check, review, merge, deploy gate, verification, log — and not one piece of it came from a book. Each one is a scar with a date on it.

The deploy pipeline: six gates from idea to production, each annotated with the failure that created it Standards file, in the repo consulted before any module work scar: the rules lived in uploads and heads, and the copy being consulted had gone stale Review — no matter who wrote it human, colleague, AI: same gate scar: generated code silently overwrote prices and collapsed a two-person approval into one Merge — never copy and diff every line of every merge scar: a folder copy overwrote fixes; a merge dropped one import and killed an endpoint Deploy gate: freshness check server code must match the pushed commit scar: the server ran stale code while reporting PASS — three separate times Environment checks that fail closed unset means no, not yes scar: tools that delete data wholesale arrived with nothing standing before prod Verify, then write it down database checked against disk; worklog entry scar: parallel sessions couldn’t see each other’s work, and a task silently never ran Six gates, six incidents. None of this was designed up front — every gate has a scar behind it.
The pipeline every change passes through, annotated with the failure that created each gate.

Regular readers have met most of these scars as they happened. The standards file became repo-canonical the day we realized the copy being consulted was stale — rules you can’t version aren’t rules, they’re folklore. Review applies to every author identically because generated code once arrived looking complete and carrying three blockers, and because a merge once dropped a single import line and took an endpoint offline with no error anywhere. Merges-never-copies came from watching a folder copy silently overwrite finished fixes — parallel histories can’t be reconciled by pasting files. The freshness gate exists because the deploy process reported success three separate times while the server ran last week’s code. The fail-closed environment check arrived with the first tooling that could delete data wholesale: unset means no. And the worklog was born the day two working sessions ran in parallel and neither could see what the other had done — including one task that silently never ran at all, with no artifact recording it.

Two newer scars joined the collection this month, both documented in recent entries: the probe rule — the first use of any new override pattern ships with a temporary log line proving it fired, because our own documentation once asserted something false for months — and neutralize-don’t-delete, because removing a named node from a core template turned out to break other templates that anchor to it. Suppress behavior; never delete the hook.

Here’s the part I’d underline for anyone running a small team: none of this is bureaucracy, because none of it was speculative. Every gate costs seconds and was paid for in hours. A process invented up front tends to be armor against imagined failures; a process grown from incidents is armor against your actual ones. The test I use before adding a rule is simple — can I name the incident? If I can’t, it doesn’t go in.

And the payoff turned out to be bigger than protecting one developer from himself. When a second developer joined the codebase, the pipeline didn’t need redesigning — her modules pass the same gates mine do. When AI assistants entered the workflow, same thing: their code goes through the same review, their deploys hit the same freshness check, their work lands in the same log. A process that exists only in one person’s habits can’t do that. Scar tissue, it turns out, is just memory that the process keeps — so the next person, or the next machine, doesn’t have to earn the wound again.

The cutover runbook now sits in the repo next to the worklog and the standards file. When launch week comes, we won’t be improvising from memory. We’ll be following the scars.