September 29, 2026·2 min read

The house rules only showed up at the gate

My feature was done, the types compiled, and then CI told me about two rules I'd never read.

By Andrew Pyle

I thought the page was finished right up until the pipeline introduced me to two rules I had never read.

01Done, I thought

Green on my machine

I added a new page to a large app: a route, a component, a link in the navigation. The TypeScript compiled clean, the build produced its bundle, and by every check I knew to run, the work was finished. I pushed it and let the real pipeline have a look.

It failed. Not on my code — on a rule I did not know existed. The repo keeps a manifest of every route the app serves, and a blocking check compares the routes in the code against that manifest. Add a route without updating the file and the build stops and tells you to regenerate it. One command, one committed file, and it went green.

Then it failed again, somewhere else entirely.

02A number that only goes down

The ratchet caught one character

The second failure was a mobile-layout check. The repo counts a specific set of layout anti-patterns across the whole codebase and holds the line at a baseline: your change may lower the count, never raise it. Mine raised it by exactly one. I had written a fixed minimum width on a flex child to make some text truncate — a completely ordinary thing — and the ratchet does not care about ordinary. It cares about the number.

The fix was to get the same truncation a different way, one that the pattern-counter does not flag, and the baseline held. Annoying in the moment. Correct in the aggregate. A thousand reasonable one-offs are how a codebase ends up unusable on a phone, and no single reviewer is going to catch the thousandth one by reading a diff.

03Where rules should live

A rule in your head is a rule you'll forget

Both of these could have been a line in a style guide, a paragraph in an onboarding doc, a thing a senior person reminds you of. That is where rules go to be politely ignored. The version that actually holds is the one wired into the gate, where it is not advice — it is the difference between merged and not merged.

I came in thinking I knew when the work was done. The pipeline had a more complete definition, and it was right both times. The lesson I keep relearning is that "done" is not a feeling you have about your diff. It is a contract someone wrote down — and the best place to write it down is somewhere that can say no.

Have something you need built or fixed?

I build production Django / Next.js platforms and human-supervised AI-agent systems. Solo, senior, and fast. Tell me what you are building.

Start a project