Philosophy
How I think about building things.
Each of these came from something going wrong. Where a principle shows up in real work, I have said where.
01
Alarm on meaning, not liveness
A health check that returns "ok" when the port is open tells you the process is running. It does not tell you the process is doing anything. I learned this from an outage where every bus vanished from a map and the uptime check stayed green for the duration — the service was alive, serving, and doing no work at all.
In practiceDetector heartbeats report work done, not that they are up.
02
Ratchets beat rewrites
Most codebases carry debt that cannot be paid down in one pass. A quality gate set at the current level, which forbids getting worse while tolerating what exists, changes the trajectory without a big-bang migration. Coverage on changed lines, a lint rule that fails on new violations only, a baseline that can go down and never up.
In practiceInternationalisation, coverage and test-behaviour drift are all enforced as ratchets rather than thresholds.
03
Say what you do not know
Systems that infer things will sometimes be uncertain, and the honest response is to say so rather than emit a confident guess. This is usually a product decision disguised as an engineering one: interpolating a position is easy, and it converts "I do not know" into "I told you, and it was false".
In practiceA transit system that shows no vehicle rather than a plausible one, enforced through the detection pipeline.
04
Make expensive mistakes loud
The dangerous failures are not the ones that crash. They are the ones where the system stays correct and quietly costs money, leaks data or does nothing — the class where the first signal is an invoice or a customer. Any setting whose wrong value is expensive and invisible deserves an assertion at startup.
In practiceA generated-audio service that refuses to boot in production with an ephemeral cache driver configured.
05
Write the decision, not the outcome
A decision log that only records what was built is a highlight reel. The valuable entries are the reversals — what was tried, why it failed, what constraint was discovered. I treat those records as current policy rather than history: reversing one means reading it first.
In practiceOver two hundred numbered decision records across two production systems.
06
Cost is an architectural input
"What does one unit of this cost to serve" belongs in the design conversation, not the finance one. Asked early it changes the architecture; asked late it produces a caching layer bolted onto something that assumed the operation was free.
In practiceContent-addressed caching designed around a per-session generation cost that made the obvious architecture unprofitable.
07
Boring where it counts
Postgres, integers for money, server-rendered HTML, database-backed sessions. Novelty is a budget and it should be spent on the part of the system that is genuinely novel — which is rarely the persistence layer or the session store.
In practiceOne product spends its novelty budget on a self-hosted media server and captions pipeline, and nowhere else.
There is one more, and it needs its own page
A large share of my recent commits were written with coding agents. That changes what discipline has to look like, and it is the part of my workflow most worth explaining rather than glossing over.
How I work with agents