DEV Community

Cover image for I wrote an article about enforcing rules with machines. Two days later one of the rules enforced me
Oleg.Kostrikin-Dev
Oleg.Kostrikin-Dev

Posted on

I wrote an article about enforcing rules with machines. Two days later one of the rules enforced me

I keep a shelf. Rules I haven't earned the pain for yet go on it — because my own rule says a rule is born from an incident, not from someone else's "best practice." Import a rule you haven't bled for, and you'll be the first one to route around it.

On the shelf sat a rule with its trigger condition written down, word for word:

The first merged PR with a green DoD checklist and a flow that doesn't actually work.

I put it there a couple of weeks ago, thinking "this'll come in handy someday." It came in handy two days after I published an article about this very method. The trigger fired. Word for word.

What happened

The PR merged. CI green. Every DoD box checked. And the flow didn't work — not for one second, not in a single real stack. Three bugs in a cascade, and every one of them invisible to CI by construction.

One. A module read a JSON registry from a shared/ folder at import time, on app startup. Works in CI — full checkout there, shared/ is present. But the production image is built from a narrow context that doesn't include that folder. The container crash-looped on its very first start. And you know the best part? CI never ran the image at all. It ran the tests on the host. Green.

Two. Two migrations merged the same day and got the same version. And the version is the primary key in the applied-migrations table. A local db reset died on the second row: duplicate key. Columns never got created. CI didn't see this one either — it runs migrations through a bare psql loop, no duplicate check.

Three was just a consequence: no columns, endpoints return 500.

Every check was honestly green. All three bugs would've been caught by one attempt from a live human to hit the endpoint on a running stand. One.

The lesson, one paragraph

Deterministic checks catch structure: the test file exists, the status is set, migrations are listed, the linter is clean. What they can't see, by construction, is whether the flow works in the stack where the product actually lives. Green CI and a working app are two different facts. The gap between them is exactly where the incident crawled in.

What now

Took the rule off the shelf. Every feature PR now carries "launch evidence" — an artifact of a real run from the stand. A curl with the response body. A screenshot from the stand, not from Storybook. The tail of an actual db reset. If the flow doesn't work, you can't produce the evidence, so you can't open the PR. Costs five minutes.

Plus a mechanical CI step on top: build the image exactly the way prod does, without shared/, and import the app inside the image. Discipline can paint a plausible output and never raise the stand. docker build can't. Automation doesn't know how to lie — that's the whole point.

The funny part

The rule I wrote an article about — "enforce rules with machines" — enforced me. The trigger I wrote down on the shelf two weeks ago predicted its own firing, down to the wording. The method ate its own dog food, and the one who got bitten was the author.

And honestly, that's the best thing that could've happened. I wrote that trigger down because I suspected the "green CI / dead app" gap would come for me eventually. It came in two days. Now I couldn't route around this rule if I tried — the pain is real, not imported. And a rule you haven't bled for isn't a rule. It's a good intention with a checklist.

Top comments (1)

Collapse
 
sam762161 profile image
sam

checkout my articles too