Writing
Everything I've published, newest first. Nothing goes up until I can explain it without hedging, which is why the list is short.
2026
Keys and Types the Database Can Actually Check
My status columns were text with a TypeScript union on top, and my ids came in three kinds. What Postgres enforces, what it only pretends to, and what I changed.
· 5 min · views
5 min viewsWhat Should Disappear When a User Is Deleted?
Every foreign key forces a decision about deletion. I went through MetaMove's tables one by one: cascade, restrict, or set null, and where none of them is the right answer.
· 6 min · views
6 min viewsMy Claude Code Status Line Is a Mod Now
My status line was a bash script that printed a line of text. Now it's a Claude Code mod with live gauges. What a mod is, how to build a small one, and what tripped me up.
· 23 min · views
23 min viewsOne Table Doing Two Jobs
member_assignments was my roster and my plan assignment at the same time. Two facts in one row gave the database two ways to be wrong, and a copy-pasted twin table made it worse.
· 6 min · views
6 min viewsMy Junction Table Had an Id and No Foreign Keys
Auditing one table in my fitness app taught me when a many-to-many table deserves its own id, why Drizzle relations are not constraints, and what rule the table actually needed.
· 7 min · views
7 min viewsMy Blog Was 672 Pixels Wide on a 430-Pixel Phone
Every paragraph in my posts wrapped off-screen on mobile. The code block looked guilty, overflow-x: clip couldn't help, and the real cause was one auto margin on a flex item.
· 6 min · views
6 min viewsWhy <Await> Crashes on Cloudflare Workers
React Router v7's streaming pattern silently breaks on Cloudflare. Here's the non-obvious reason and the one-line fix.
· 3 min · views
3 min viewsUnderstanding DNS in Plain English
How the internet figures out where to send you when you type a URL.
· 1 min · views
1 min views