Skip to content
ENNO
← All posts

Development

I Wrote a Linter for Text That Sounds Like AI

I Wrote a Linter for Text That Sounds Like AI

Most people can spot AI text within a sentence or two now, and once they've spotted it they stop reading properly. So I built a checker that catches the tells before anything leaves my machine, calibrated on my own writing, and it learns from the edits I make.

Setting Firefox Bookmark Keywords From an Extension, Without an API for It

Setting Firefox Bookmark Keywords From an Extension, Without an API for It

Firefox extensions can't set bookmark keywords. There's no API, and there hasn't been one for ten years. I needed it for my container add-on anyway, so Passport signs in to your Mozilla account and writes the keyword through Firefox Sync instead.

Two Checks Between an LLM and Your Warehouse

Two Checks Between an LLM and Your Warehouse

An apostrophe in a SQL comment was enough to hide a subquery that read 584,332 raw rows. The two checks a model-written query now has to pass before it runs, and why neither is enough on its own.

Put the Tenant Column in the First Migration

Put the Tenant Column in the First Migration

One extra column per table on day one, against a backfill across fourteen populated tables later. What went into the first migration, and the seven lookups that still assume one brand.

When Two Tools Disagree, Show Both Numbers

When Two Tools Disagree, Show Both Numbers

Analytics and Search Console never agree, and the dashboard I built for an agency shows both instead of picking one. The first time someone checked it against the ad platform, the gap turned out to be partly my own join bug.

Your Server Logs Are the Only Place You Can See AI Crawlers

Your Server Logs Are the Only Place You Can See AI Crawlers

Analytics can't see AI assistants reading a site, because they never run JavaScript. What a client's access logs showed instead, how I sort the three kinds of AI fetch, and what the log still can't tell you.

Idempotency Is the Integration Feature You Actually Need

Idempotency Is the Integration Feature You Actually Need

Webhooks arrive twice and people click twice. How I make a second delivery harmless: a key derived from the content, a partial unique index, and the endpoint I forgot to give one.

Why I Reach for a Modular Monolith First

Why I Reach for a Modular Monolith First

Why I start client backends as one deployable with hard boundaries inside, using a marketplace I'm building as the example, and the few reasons I'd split it.

Building an AI Agent Mesh in My Homelab

Building an AI Agent Mesh in My Homelab

Nine Claude Code workers as separate Linux users on one VM, talking A2A over localhost. How it's wired, the shared-login bug that looked like broken credentials, and why memory was the limit all along.

What Happens When You Give AI Agents Root Access to Your Homelab

What Happens When You Give AI Agents Root Access to Your Homelab

An AI agent with sudo on its own VM and SSH to the rest of my homelab. The 34 hooks that keep it in line, the mistakes they didn't catch, and why I took the coding work away from the workers in September.