Moving config into the database — without trusting the database
We moved billing-currency config into an admin-editable table while keeping a copy in code — bound together so any drift between them fails loudly.
Read →Field notes, guides, and ideas on speed, AI search, design, and what actually grows a small business online.

We moved billing-currency config into an admin-editable table while keeping a copy in code — bound together so any drift between them fails loudly.
Read →
We audited the instructions our agents rely on and found around forty places where they no longer matched the codebase. Nothing failed loudly — but the drift was changing behaviour. Here's what we found and what we changed.
Read →
We built a coding-agent loop from Claude Code, Linear, Telegram, and git worktrees — no framework. Tickets become reviewable PRs, with a human approving every step. Day one, it shipped two merged fixes.
Read →
Dropping our mirrored status column was easy in the model code. The real work was scripts, migration-graph conflicts, deploy timing, and NULL semantics.
Read →
A unique job ID slipped into our cache key, giving a paid-API cache a 0% hit rate for weeks — no error, just quietly paying twice. Here's how we found it and what belongs in a cache key.
Read →
We thought our Click-to-WhatsApp ads weren't sending ctwa_clid. One query on our own leads table showed the exact day it switched on.
Read →
Our build agent kept a persistent memory. A customer asked to change a dull background colour; the agent recalled an older "no bright colours" preference and ignored them. Here's why that happens, and what we changed.
Read →
We assumed --setting-sources project isolated Claude Code skills per client. It only scopes settings, not skill discovery. The real boundary came from per-workspace git roots and a fail-closed allowlist copy step.
Read →
We moved lifecycle state to a new model without rewriting every query. The trick was keeping the old status column as a mirror and migrating the writers first.
Read →