Blog

Notes on AI engineering, LLM agents, and shipping production software.

TT
13 min

The tests that passed against code I deleted: four shapes of a test that cannot fail

I removed the one element on a dashboard that says where the money went, ran the suite, and all 867 of its tests passed. That is mutation testing: change the production code on purpose and see whether anything goes red. The survivors clustered into four recognisable shapes, each with a fix you can copy: a lone negative assertion with no positive twin, a denylist that does not cover its own space, a test satisfied by the library's own fallback, and a wire between two files that each have green tests. Every mutation here was applied by hand and re-run against two trees, before the fixes and after, with the numbers from today's run.

Sanitising is not identifying: deriving a filename from untrusted data without collisions

12 min

You take a title and an id from a remote API and build a filename out of them. Sanitising the title is right. Sanitising the id is what makes two different items overwrite each other, because sanitising is lossy on purpose and an identifier has to survive intact. Five real collisions, percent-encoding as the fix, and the six bytes of a 255-byte budget that are not in the name at all.

Why Postgres ignores your trigram index: sargability, UPPER(), and an ORM that rewrites your query

10 min

You add a pg_trgm GIN index, the substring query gets no faster, and EXPLAIN shows a sequential scan. The operator is usually not the problem: pg_trgm serves ILIKE from the index perfectly well. What breaks it is a function wrapped around the column, and on Django that function is one your ORM adds for you. Measured at four table sizes, with the three fixes and what each costs.

Generating branded social-preview images at build time

8 min

Every page wants its own 1200×630 social card. Instead of designing each one by hand, drive headless Chrome over a parameterized HTML template at build time, then shrink the output ~80% with a PNG8 palette step whose key move is turning dithering off on flat graphics.

Sub-second triage: tiering LLMs for latency-critical paths

14 min

I benchmarked a tiered LLM safety gate with 800 real API calls: a fast model on the hot path, a larger one for the cases that need reasoning, plus circuit breakers and a caution-biased fallback. The measurements upended my reasons for tiering. On current models the fast and large tiers run at nearly the same speed, so the real payoffs are cost and, more importantly, catching the emergencies the cheap model quietly gets wrong.

A fast molecular-dynamics simulator in pure NumPy

11 min

A naive molecular-dynamics loop is O(N²) and dies past a few hundred particles. With cell lists, a cutoff Lennard-Jones potential, velocity-Verlet integration, and reduced units, you can simulate thousands of particles in pure NumPy and watch a gas equilibrate.