Exitcode0 - Executed without error
Welcome to exitcode0, the friendly homelab notebook.

- Role
- IT pro: infra, ops, security
- Director
- DataSolace - Business Automation
- Kit
- Proxmox, Ollama, vLLM, Docker
- Location
- UK
- Uptime
- since 2019, 85 posts
Welcome to exitcode0, the friendly homelab notebook.


My study has five things that glow: two desk monitors, a wall-mounted dashboard screen, a strip light and a custom Home Assistant display frame I built from a cheap Android photo frame. Every time I got up to make a coffee, all five stayed on and lit an empty room. Now they notice I’ve gone. A minute after I stand up, everything fades down together, and when I sit back down it all comes back. Not at 3am, though. ...

I run Claude Code on a dev VM and drive it from T3 Code on whatever I’m sat at. The dumb terminal post covers that setup. It works well until you have a few threads going, look away, and miss the one that’s been sitting on a question. So I wanted voice control in both directions: say the prompt, hear the reply. The catch is that Claude Code runs on a headless server, and the microphone and speakers are on my Windows PC. Claude Code’s own /voice needs a local microphone and only covers the talking-to-it half. I built the other half. voiceloop is a free, open-source Windows app that reads Claude Code’s replies aloud on your PC, wherever Claude Code is running. It lives at voiceloop.dev, with the code on GitHub. ...

Everything AI-related on this site runs on one Proxmox host in a cupboard. A GPU in an LXC container serves Ollama, a web front end sits on a VM next to it, Home Assistant talks to local speech models for voice, and my coding agents work from an always-on VM that I reach over Tailscale. None of it costs per token, none of it leaves the house, and the whole stack has survived every host reboot since I built it. ...

Claude Code speaks the Anthropic API. Ollama now speaks it too. Point one at the other with three environment variables and Claude Code runs against a model on your own GPU. No API key, no per-token bill, and the prompts stay on your network. Whether it’s any good is a different question. I ran it against three models on an RTX 3060 with two small coding tasks each. One model did well at both. One was the best at one and the worst at the other. Treat what follows as a smoke test, not a benchmark, but the differences were big enough to matter. ...

Home Assistant’s own Assist can already turn a light on. It matches your sentence against a list of templates and runs the one that fits. Say something it has no template for and you get “Sorry, I couldn’t understand that”. Point Assist at an LLM and that stops being true. “It’s too dark in the living room” works. The catch is that the model has to call Home Assistant’s tools correctly, and plenty of local models can’t. I ran three models against the same 18 commands to see which ones can. ...

On 27 October Anthropic published an exploit chain that gets a root shell on a Linux server across the network, with no credentials and no clicks. The bug behind it is CVE-2026-98432, a use-after-free in the IPv4 TCP handshake. The kernel’s own CVE team scores it 9.8. Ubuntu has no fixed kernel yet. I run an Ubuntu 22.04 VM in a colo that hosts a UniFi Network controller in Docker. When this landed I wanted three answers: is the box vulnerable, can I reduce the risk before Canonical ships a kernel, and has anything already been at it? This post is what I checked, what the first-party sources actually say, and the mitigations I tested. ...

More of my reading now goes through a coding agent. I ask it to fetch a page, and it works from whatever it gets back. For a blog that’s a problem. A typical post is 22 to 50 KB of HTML, wrapped around 5 to 17 KB of content. The agent has to pull the content out of the wrapper first. So I made every post on this site available as plain Markdown at the same URL with index.md on the end, and added an llms.txt that lists them. Both are Hugo output formats, about twenty lines in total. This post has the config, both templates, the sizes I measured on the live site and the things that bit me. ...

Small Zigbee and Bluetooth sensors tend to ship with a sticky pad and nothing else. The pad fails the first time you move house or the wall is cold and damp, and the sensor ends up behind the radiator. A printed bracket fixes that, but I’d rather not spend an evening in CAD for a plastic box. OpenSCAD is the opposite of CAD. The model is a text file, so Claude Code can write it, render it and check it in a loop. This post has the file I ended up with, the checks I ran, and the one that caught a mistake the obvious check missed. ...

I handed two Claude Code subagents a research job. Both ran on Haiku to keep the cost down, and both came back with tidy tables, exact quotes and source URLs. Then I opened the sources, and a fair amount of what they’d told me was wrong. This post is what I found, and the small script I now use before acting on anything a cheap subagent tells me. What I asked them I had a Claude Code session working through SEO and AdSense compliance on this blog, and I spun two background subagents off it with the model set to Haiku: ...

A Home Assistant voice assistant needs three parts. Something to turn speech into text, something to turn a reply back into speech, and Assist in the middle to work out what you meant. The first two can run on plain CPU in Docker, so nothing you say has to leave the house. I built the whole stack from scratch on 11 October 2026 on Home Assistant 2026.10.1, ran text and spoken commands through it, and timed the result. This post has the compose file, the settings, the numbers and the two things that tripped me up. ...

Wes Bos put out a video about rooting a $50 Amazon photo frame and running a family dashboard on it. The frames are Android tablets with a vendor app bolted on, and his photo-frame-dashboard repo is written so you can point a coding agent at it and let it do the fiddly bits. I wanted the same thing for Home Assistant, so I ordered the UK listing of the frame he linked and spent a day on it with Claude Code. ...

With a baby in the house, the question at bedtime is always the same: which sleeping bag, and what goes under it? The usual answer is a room thermometer and a tog chart, which means reading one, then looking up the other, often in the dark. Home Assistant already had a temperature sensor in every room, so I got it to do the lookup. The result is one card per room. It shows the temperature, a sleeping bag in the band’s colour with its tog on it, the clothes to put underneath, and a status line saying whether the room is in the safe range. It’s a single button-card template, so the temperature bands are defined once and every room uses them. ...

A couple of weeks ago I asked Claude, via the Chrome extension on my Windows laptop, to find me the best-value used M1 MacBook Air on eBay. It was properly good at it. It searched with sensible filters, opened listings, read the descriptions for battery cycle counts and “cracked screen” small print, and left the three best tabs open for me to look through. Then I tried to picture doing the same from my phone on a day I’ve left the laptop at home, talking to the agents on my always-on dev VM. There’s no browser there. Claude Code’s web fetch tool gets blocked or served a stripped-down page by most retailers, eBay included. So I gave the VM its own browser: a real, headful Chromium in a Docker container. Claude drives it through Playwright MCP, I can watch and take over from my phone over VNC, and it’ll crop screenshots straight into this blog. Every image in this post came out of it, the cover included. ...