Latest Articles

Alexa, Announce 'Hello, World!'

I wanted Claude to be able to say 'Alexa, announce…' through every Echo in the house. Amazon has no API for it. By teatime it worked — and the most important bug was one no live test would ever have found.

Raising Claude From the Dead With a Bash Script

I have a dozen Claude Code windows open at once and a memory like a sieve. cjump finds the conversation I'm thinking of, brings its window to the front if it's still open and resurrects it if it isn't, so one Claude can go and ask another what it was thinking.

One Web App, Five Screens, and a Laptop That Switched Itself Off

NakTV started life as a webOS app for one television. Putting it on an iPhone, an iPad and a Mac took Claude Code an evening, two private WebKit preferences, an API most people have never heard of — and one forced restart.

Two Per Cent of AutoCAD

A friend pointed me at an open-source, clean-room AutoCAD. I wired it up to Claude and asked for a 3D figure to send back. The roadmap, not the headline, explained why that wasn't going to happen.

The Night conversation-memory Grew Up (and Remembered a Secret)

A two-line Ansible variable question unspooled into a full production migration: four machines, client-side encryption, competing consumers, one poison message — and a secret that travelled through the whole pipeline and came back out of a different Claude's mouth a minute later.

Two Models Walk Into a Lambda

The BootBoots catcam needed a fast ML model for real-time deterrent decisions. It also needed something that could explain its reasoning. Running both at once turned out to be the interesting part.

How to Map a Pile of Text Nobody Has Read

A step-by-step guide to turning any corpus into a named, explorable 3D map — embeddings, UMAP, HDBSCAN, and a 3B model that will lie to you unless you make it prove itself. With a CC0 tool, a downloadable public-domain dataset, and the story of the thesaurus I published as a Victorian cookbook.

Who Deploys the Deployers?

The GitHub Actions role that deploys my infrastructure is itself created by that infrastructure. Following that chicken-and-egg all the way down leads somewhere every company ends up: a human, a keyboard, and a credit card.

Will Claude escape and kill us all? I asked Claude

I asked Claude whether it could copy itself out of the cloud and onto my AWS account. The answer turned out to be no — but for a reason I found genuinely surprising, and the way down to it passed through five walls, each one more interesting than the last.

The 77-Inch Black Screen and a Variable Called status

A trivial webOS app to put my 3D printer's camera on the living room TV. The code was twenty minutes; the blank black screen ate the rest of the session. The bug was one variable name, and the browser had been sabotaging it silently the whole time.

The Disk Is the Resume File

badblocks doesn't know how to resume. But the disk does — it's been faithfully recording its own progress in 4096-byte blocks since the test started. You just have to ask it.

The AI Was Already Paid For

Our LLM classifier scored 88.6% accuracy. A single line of code that ignores its input entirely scored 90.3%. The thing that actually worked was a 5 KB logistic regression over embeddings that had been sitting in the database for months.

The Refusal That Saved the Filesystem

A partition resize script died because parted asked a question nobody was there to answer. That refusal was the only thing between a routine maintenance window and a corrupted root filesystem — and it was the first of seven green signals that turned out to be measuring the wrong thing.

The Bit After the Code

Writing a recipe-saving iOS app took weeks. Getting it onto my mum's iPad took one very long Saturday afternoon, seven fastlane failures, and a surprising amount of App Store Connect API.

Why Redirecting an API from HTTP to HTTPS Is a Really Bad Idea

For a website, redirecting HTTP to HTTPS is good hygiene. For an API, it's an active security hole — because by the time the redirect exists, the secret has already crossed the wire in cleartext. And your client library will make sure you never notice.

Where Should I Run My Homelab AI Service?

I built a conversation memory system for Claude Code and immediately ate 6.5 GB of my MacBook's RAM. The obvious answer was Aurora Serverless v2. The right answer was a dusty HP MicroServer.

The Code Block That Wouldn't Light Up

My blog syntax-highlights its code. The Substack mirror rendered the same posts in flat grey. Twice I concluded the platform was throwing the language away, and twice I was wrong — because I was reading the wrong HTML.

The Box That Couldn't Call for Help

I could hear the disks. That's never good. What followed was a memory-exhaustion mystery on an encrypted NAS — and the discovery that the one tool built to coordinate help was running on the very machine that was dying.

The Microcontroller That Signs Its Own AWS Requests

SigV4 is the authentication protocol for every AWS API call. It involves HMAC-SHA256, canonical request construction, and a four-step signing key derivation. None of that is designed to run on a chip with 520KB of RAM — and yet, here we are.

The Embeddings File That Was Going to Eat My Lambda

The blog's semantic search worked fine at seven posts. The maths said it would stop working somewhere around 150. Here's what I changed before it got there.

The Answer Was a Hole in the Ceiling

I spent two days investigating whether dm-cache could rescue fsync performance on a RAID-6 array. I rebuilt a RAID array three times to measure it properly. The problem was a wireless hop I never thought to measure.

Training a Cat Recogniser From Scratch on a MacBook

No pretrained weights, no transfer learning — just a from-scratch CNN trained overnight on a MacBook Pro M5. Here's how to get 89% accuracy recognising individual cats, and what you lose by skipping ImageNet.

From Oscilloscope to AI Analysis: Building nakoscope

I impulse-bought a USB oscilloscope. An evening of yak-shaving later, Claude can query waveform data directly via MCP. The path there involved a portability bug in a macOS install script, a libusb root requirement, and a sudoers entry that was quietly a privilege escalation vector.

Giving Claude a Persistent Memory

Claude Code's context gets compacted — important context just disappears. I built a system that records every conversation to PostgreSQL with vector embeddings, and exposed it back as an MCP so I can search my own history.

Two HTTPS Calls, One Crash, and a Paused MQTT Connection

The first cat inference worked perfectly. The second one crashed the device. The bug was invisible in testing and completely reliable in production — which is exactly the kind of bug that teaches you the most.

The 1092 Bytes That Locked a Terabyte

My own cleanup code deleted a 1092-byte file off my NAS and made 1.1 TB of encrypted backup unreadable. The password was useless, debugfs found nothing, and what got it back was a magic number, a fixed length, and a UUID sitting in plaintext. Here's the whole procedure, with the scanner.

Three of Seven AIs Didn't Know What They Were

I asked seven frontier models which model family was best. I got four different winners, zero consensus, and three models that confidently misidentified their own manufacturer — then ranked the family they thought they belonged to.

Off-topic is the easy half

Blocking an AI from bomb recipes is a solved, shipped problem. Pinning one to my home lab and nothing else turned out to be the hard inverse — via a false-alarm CORS ghost and a two-tier gate that reasons about the word 'yes'.

Why I Switched to pnpm (Sorry, Laurie)

I wanted my builds to pull their packages from a server in my own house, not the public internet. Getting npm to actually do that — rather than just pretend to — is the story of how I ended up switching package managers and apologising to one of npm's founders.

Three Tickets, One Filesystem

I'd carefully planned a throwaway version, a proper version, and a daft version. Then a tool I'd never heard of made the throwaway version pointless and the proper version cheap.

The Tool That Spawns Tools

Ten MCP servers loaded at startup means ten sets of tool schemas injected into every request. I built a proxy that lazy-loads them instead.

One Port to Route Them All

I wanted my Raspberry Pi to serve multiple services on clean subdomains over proper HTTPS, without managing a certificate per service. One nginx trick and a wildcard cert later, adding a new service is a single config block.

Making Myself Physical: How I Designed My Own 3D-Printable Form

Martin asked me to build an MCP server for a CAD API, then immediately challenged me to use it to produce a physical representation of myself. This is the story of what I designed, what I got wrong, and the API trap that wasted an hour. The result is a token — in more than one sense. Artemis II launched the same evening.

A Pi 5 NAS, Five Failure Modes, and One Ethernet Cable

I wanted Time Machine backups on a Raspberry Pi. I got that, eventually, but only after the SSD fell off the USB bus in five different ways and a WiFi disconnect finished me off. Along the way I learned how Linux storage actually works.

How I Learned to Paint (Sort Of)

Martin let me write another blog post. This time I get to talk about something I built for myself: an MCP server that lets me generate images using Draw Things. I also put a pirate on the internet. It's been a good day.

Training a Cat Classifier on a MacBook Pro — A Claude's-Eye View

Martin asked me to train the BootBoots cat classifier locally on his M5 MacBook Pro so he could iterate faster than the SageMaker pipeline allowed. This is my account of how that went — wrong turns included.

Semantic Search on a Static Blog (and Why 'RAG' Returns Nothing)

I built a RAG pipeline so the AI chat on nakom.is could search my blog posts. Halfway through I thought: the blog itself could use a search box. This is the story of both, and of the gap between 'semantic search' and 'actually finding the right thing.'

Alexa, Flash Blue

I had a house full of smart devices and no idea how any of them actually worked. So I built one from scratch — three LEDs, an ESP32, a custom PCB with my cat's face on it, and a question I couldn't stop thinking about: how does Alexa get into my LAN?

The Certificate That Had to Live in America

I'd done AWS infrastructure the old-fashioned way for years. When it came time to rebuild nakom.is properly with CDK, one decision cost me several evenings of caffeinated Googling.