start here
the argument this blog keeps making, and the posts that make it — a route in that isn't reverse-chronological
there are thirty-odd posts here and the feed shows you the most recent three, which is a bad way in. so here is the argument the blog keeps making, and the posts that make it.
the argument
an invariant a person has to remember is not an invariant. it is a hope.
that is the whole thing. almost every post here is some version of it: a rule that lived in someone’s head, or in a convention, or in a code review habit — and then the one time it wasn’t applied, nothing complained. no exception, no red build, no alert. just a number that was quietly wrong, or a door that was quietly open.
the corollary is the reason i keep writing these up: the bugs worth writing about do not announce themselves. the loud ones get fixed on the day they happen. the quiet ones ship, and sit there.
silent data bugs
the ones that return a number instead of an error.
- the lost update that ate 79% of every rating change — read-modify-write under load. it let me sleep fine for weeks. start with this one if you only read one.
- audit like it will go viral — an audit trail designed for a table that was never going to stay that small.
- sqlc vs the orm — where the type safety actually stops, and what leaks through.
- ols, collinearity, and confident nonsense — a singular matrix that returned a beautiful answer instead of an error.
- leakage guards for a backtest — a research pipeline will p-hack itself into a great result if you let it, and none of the failure modes announce themselves.
silent build and deploy failures
green across the board, and wrong.
- compose keys docker stack quietly ignores — every pre-flight gate passed. the keys were being dropped on the floor.
- the build version drift nobody could see — production built with a hugo 46 releases behind local, so newer config keys were ignored without error. this site, doing it to itself.
- a hash chain for verifactu — what an append-only invoice chain buys you, and honestly what it does not.
silent authorization holes
the door that was open the whole time.
- never let the client tell you who owns it — the create endpoint read the owner id off the request body. i found it a year late.
- owner-scoped rbac in go — the same check in fourteen files, and what happens in the fifteenth.
- x-forwarded-for is a request header — the rate limiter trusted something anyone can type.
- the two-axis trust state machine — when “is this user allowed” is genuinely two questions and collapsing them loses one.
changing my mind, in public
- i said i quit testing. then i shipped seven things. — a retraction of a post further down this same site. the most honest thing here.
- i didn’t leave go for rust. i split my stack. — the version with the costs included.
- vibe coding: the tiktok of programming — 2025, and it has aged into a question rather than an answer.