The blog

Building better small-business websites, out loud

Field notes, guides, and ideas on speed, AI search, design, and what actually grows a small business online.

Customer sites don't belong on your domain
Field notes

Customer sites don't belong on your domain

We moved 28 customer sites off our main domain to stop sharing one reputation with them. Why the risk is real, and how the move took about half an hour.

Read →
Moving config into the database — without trusting the database
Field notes

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 →
Instruction rot: why your AI agent quietly does the wrong thing
Field notes

Instruction rot: why your AI agent quietly does the wrong thing

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 →
An engineer you manage from a group chat
Field notes

An engineer you manage from a group chat

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 →
What actually breaks when you drop the old column
Field notes

What actually breaks when you drop the old column

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 →
The cache that never hit
Field notes

The cache that never hit

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 →
Is Meta sending your WhatsApp ad click IDs? Your database already knows
Field notes

Is Meta sending your WhatsApp ad click IDs? Your database already knows

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 →
When your AI agent's memory overrules the user
Field notes

When your AI agent's memory overrules the user

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 →
How we isolate Claude Code skills per client (it wasn't --setting-sources)
Field notes

How we isolate Claude Code skills per client (it wasn't --setting-sources)

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 →