Principles
Principles
Ten rules I keep arriving back at. All of them were earned building one product solo, end to end — so read them as what one system taught one person, not as universal law. Each came from a decision that cost something; the note underneath says what.
-
Evidence that can move after the decision isn’t evidence. It’s a rumour.
A release’s defect analytics freeze into a snapshot when it completes. Everything else was already locked read-only; defect linking stays live by design, so it was the one thing that could still rewrite history after sign-off.
-
A cache is not a dependency. If losing it takes the product down, it was a database.
Redis holds sessions and hot reads. A failed connection logs a warning and leaves the client null — every caller is written to work without it, slower.
-
Data you can’t explain should stay visible. Dropping it is not the same as handling it.
Automation results that match no known test case land in their own collection, inert — deliberately outside the one the analytics read from. Force-matching them would have been tidier and would have quietly invented coverage that nobody ran.
-
One fewer stateful thing to run beats one more clever thing to run.
The background job queue moved off a dedicated broker into the database already being operated. Every autoscaled replica drains it, so correctness rests on a leased advisory lock rather than a separate worker tier.
-
No single number answers a real question. Confidence is assembled, not calculated.
The thesis the whole product is built on — coverage, executions, defects and risk brought into one view, then read by a person.
-
New doors start locked. Opening one should take a deliberate act.
The permission layer rejects any route missing from the endpoint-to-permission map. Forgetting to declare a new endpoint’s permission fails closed and is obvious in seconds; the alternative fails open and is obvious in months.
-
The client is a convenience, never the enforcement point.
Read-only custom fields are re-checked on write. The UI disables the input; the server decides whether the value actually changed.
-
Store the instant, format at the edge.
Timestamps are UTC epoch millis everywhere in the database. Timezone is a rendering concern, and treating it as a storage concern is how reports end up a day off for half the team.
-
Every abstraction is a loan. Some are worth taking; none are free.
Written across a codebase with no team to absorb the interest, where the cost of a wrong abstraction is paid entirely by the person who wrote it.
-
Explainability beats cleverness. A system nobody can reason about can’t be trusted, only obeyed.
Applies hardest to anything that produces a number someone will make a shipping decision from.