Pipeline diagram: one context pack fans out to Claude, Codex and Kimi in a blind first round, then a peer round, then a free model synthesises, then a human approval gate, then execute and verify

Three Agents, One Approval Gate — Making Claude, Codex and Kimi Review Each Other

I have three coding agents with access to this lab. Claude Code does most of the building. Codex reviews and runs the scans. Kimi audits. Until this week they had never exchanged a word — each got its own context, its own session, and its own chance to be confidently wrong with nobody checking. So I built a thing that makes them work one request together, and put a human approval gate in front of anything that changes the lab. ...

19 August 2026 · 11 min
Pipeline diagram: Codex scans 24 images and finds 2042 actionable findings, Claude Code fixes them one wave at a time behind a hard validation gate, then the same scanner measures again at 1497

A Vulnerability Scan From Codex, a Container Upgrade From Claude Code

I run two coding agents against this lab. Codex found the problem and Claude Code fixed it, and keeping those two jobs in different hands turned out to be the most useful part of the whole exercise. The short version: a full vulnerability scan reported 2042 actionable findings — 46 critical, 764 high — and 1751 of them were in container images. Ten waves of updates later, the same scanner reports 1497 actionable, 21 critical, 570 high. ...

18 August 2026 · 10 min
The NetBox dashboard on first launch, every object count sitting at zero

Trying NetBox in My Home Lab

I gave the lab VM more memory recently, which left room to try another service. NetBox was the one I wanted to test, because it does two jobs I currently do badly in scattered markdown: DCIM — sites, virtualization, and how infrastructure relates to itself. IPAM — prefixes, VLANs, address ranges, individual IP assignments. The trial was deliberately conservative. I wanted to find out whether NetBox suited the lab without handing it unnecessary exposure, and without letting an automated import invent facts I hadn’t verified. ...

14 August 2026 · 4 min
The LABDECK app on an iPhone, showing home lab service groups over an animated matrix rain background

LABDECK — Putting My Home Lab Dashboard on My Phone

A while back I built a front door for the home lab — one Homepage dashboard listing every service, with live status dots. It’s the page I look at most. On a phone it’s a browser tab. It works, but it’s a shrunk web page: no icon, no native controls, and every visit is a fresh Authentik redirect. I wanted the same thing as an actual app. This is how that went, including the parts that didn’t work. ...

9 August 2026 · 8 min
The agent auditor's local operator dashboard, showing observe-only mode and a list of recent Claude sessions with their recorded timelines

Auditing the AI Agent That Runs My Homelab

My homelab has picked up a lot of moving parts this year, and several of them are now LLMs. Claude Code runs natively on the box and does real work against real infrastructure — containers, reverse proxy config, monitoring, the lot. That’s genuinely useful. It also creates a trust problem I hadn’t had before. The problem is simple to state: the same agent that makes a change also writes the summary explaining why the change was safe. That’s convenient. It is not independent verification. If the agent quietly skips a validator and then reports “config validated”, I have no signal at all. The report is the evidence, and the thing that wrote the report is the thing being checked. ...

7 August 2026 · 9 min
The finished Release Watch workflow in n8n: schedule, state read, repo list, feed fetch, XML parse, decide, state write, and two ntfy branches

Patching a Homelab Has Two Halves — and Only One of Them Is apt

Two halves apt patches Debian. My homelab is not Debian — it’s about a dozen containers sitting on top of Debian. AdGuard, Authentik, Vaultwarden, Caddy, n8n, Greenbone, Homepage. apt will never once mention that Vaultwarden cut a release. So “keep the lab patched” is really two jobs: Debian packages — unattended-upgrades, already a solved problem, just needs scheduling and a report. Everything I actually run — nobody’s solved that for me. Containers only update when I decide to pull. This post is both halves. The first one taught me something uncomfortable about monitoring, so I’ll start there. ...

1 August 2026 · 13 min
Two rows: DNS resolution from host rig and phone through AdGuard to an upstream DoH resolver, and the admin UI reached only through Caddy and Authentik SSO

One DNS Filter, Three Clients That All Bypass It Differently

I wanted a DNS sinkhole in the lab — block ads, trackers, and adult content at the resolver instead of per-device. AdGuard Home is a single Go binary, so standing it up was maybe ten minutes. Then I spent the rest of the session learning that “point a device at the resolver” is a lie three times over. A Windows PC, an iPhone, and the lab host each route DNS somewhere I didn’t tell them to, for three completely different reasons. This is the write-up of finding all three. ...

1 August 2026 · 7 min
RAINBOW MATRIX cover — the post title in rainbow monospace over falling matrix rain on black

A Self-Hosted Multi-LLM Gateway for My Homelab

Claude Code is the main LLM running my homelab. It builds, debugs, and documents most of what happens on the Debian VM. But I wanted to try other models — and give the CLI tools a shared backend — without wiring up a different SDK and API key for every provider. So I put a gateway in front: one endpoint, many models. Claude stays the main driver; everything else is now one config line away. ...

29 July 2026 · 5 min
Langfuse's Tracing view showing a single claude_code.interaction trace with 2 observations and 3.40s latency

Implementing Langfuse to Monitor Claude Code

We all tend to focus on the output of whatever LLM we’re using — did it get the answer right, was it fast, was it useful. What I’d stopped paying attention to was the background: how many tokens a session was actually burning, where they went, and whether I’d have any way of knowing if something had gone quietly wrong. Claude Code runs natively on my homelab now, doing real work against real infrastructure, and I wanted more than “the output looked fine” as my only signal. ...

27 July 2026 · 4 min
Before/after diagram: Tailscale reaching one machine, versus a subnet router advertising 10.10.0.0/24 so the phone reaches the whole lab

Two VPNs, One Phone: Consolidating Remote Access

I ended up with two VPNs into my homelab. WireGuard, running on my firewall, which I set up first. And Tailscale on my main server, which I added later so I could SSH in from a laptop without opening ports. Then I tried to use both from my phone and hit a wall. Phones only run one VPN at a time This isn’t a bug or a conflict between the two apps. iOS and Android both allow exactly one active VPN tunnel, full stop. It’s an OS-level restriction. ...

24 July 2026 · 10 min
The finished four-node n8n workflow: Schedule Trigger, Execute Command, IF, and two ntfy alert nodes

Building a Backup Watchdog in n8n — and Finding a Five-Day Outage While I Did It

The problem I set out to solve My homelab takes a backup every night at 20:30. A cron job runs a script, the script dumps my Authentik database, snapshots the Vaultwarden vault, tars up the configs, encrypts a copy with age and drops it into OneDrive. It writes everything it does to /var/log/lab-backup.log. And nobody reads /var/log/lab-backup.log. That was the thing bothering me. If the backup silently stopped, I wouldn’t find out when it stopped — I’d find out the day I needed a restore, which is the worst possible day to learn anything. So the plan was simple: get n8n to check the backup actually happened, and buzz my phone if it didn’t. ...

23 July 2026 · 13 min
Homepage dashboard showing Infrastructure, Monitoring and Security service groups with live status dots

A Front Door for the Home Lab

At some point my lab crossed a line. I had a firewall, an identity provider, a password vault, dashboards, a log system, an alert router, and a vulnerability scanner — and I was typing subdomains from memory to reach any of them. Half the time I’d get one wrong. So this project is small: one page that links to everything. It took under an hour, and it’s the thing I now look at most. ...

23 July 2026 · 8 min
OpenVAS results page showing the first scan's findings by severity

Running OpenVAS in My Home Lab — Install, the Three Things That Broke, and the First Scan

I wanted a real vulnerability scanner in the lab — something that port-scans a host, throws a big pile of network vulnerability tests at it, and tells me what to fix by severity. OpenVAS (now Greenbone Community Edition) is the obvious choice, and it ships as a Docker stack. This is the honest write-up: the install, the three separate things that broke, one of which was my own fault, and what the scanner actually found when I pointed it at my own box. Nothing here is polished — I got a couple of things wrong along the way and I’m leaving those in, because that’s where the useful bits are. ...

22 July 2026 · 11 min
RAINBOW MATRIX cover — the post title in rainbow monospace over falling matrix rain on black

I Hardened This VM by Hand. Lynis Scored It 68/100.

A while back I hardened this Debian VM by hand — patched it, cut the attack surface, put a default-deny host firewall in front of it, sandboxed the custom services. I audited my own box and fixed the drift I found. The problem with auditing your own box is that you grade your own homework. You check the things you already think to check. So this time I handed the job to something that has no idea what I meant to do and only reports what’s actually there: Lynis, the system-auditing tool from CISOfy. It ran 274 tests and gave the VM a hardening index of 68 / 100. ...

20 July 2026 · 7 min
Grafana Explore showing pfSense firewall logs flowing through Loki, with a log-volume chart above

Building a Homelab SIEM with Loki — Reading My Logs Instead of Hoping

I had dashboards showing me numbers — CPU, memory, network throughput. What I didn’t have was any way to answer “what actually happened?” When did someone try to log in? What did the firewall block? Those answers live in logs, and my logs were scattered across machines, unread. This post is how I pulled them into one searchable place. That’s a SIEM — Security Information and Event Management — and you can build a simple one at home. ...

19 July 2026 · 7 min
RAINBOW MATRIX cover — the post title in rainbow monospace over falling matrix rain on black

Metrics You Have to Remember to Look At Aren't Monitoring

I’d had Grafana dashboards for months. What I didn’t have was anything that told me when something broke — I had to remember to look. This is the alerting layer that fixes that, built on top of the existing Prometheus stack, plus the three things that got in the way. Stack: Prometheus · Alertmanager · ntfy · Docker 1. The gap I’d been ignoring My lab had a healthy observability stack: Prometheus scraping metrics, node_exporter for the host, snmp_exporter pulling throughput off pfSense, all drawn in Grafana. It looked complete. ...

18 July 2026 · 12 min
RAINBOW MATRIX cover — the post title in rainbow monospace over falling matrix rain on black

A Backup You Haven't Restored Is a Hypothesis

The identity provider quietly became load-bearing and had no backup. Building one taught me more about database internals than building the identity provider did. Stack: Bash · Postgres · SQLite · age · cron · OneDrive 1. Purpose The identity provider started as a nice-to-have. Single sign-on for a dashboard — pleasant, not critical. Then it took over the firewall’s login. That’s the moment the risk profile changed, and it changed without any decision being made about it. Nobody sat down and said “let’s make the firewall depend on this container.” It happened one integration at a time, and the dependency graph grew quietly underneath. ...

16 July 2026 · 9 min
Logged into pfSense as an identity-provider account over LDAP

Making the Firewall Authenticate Against My Identity Provider — and Proving the Bug Wasn't Mine

Bringing pfSense’s admin login into Authentik with MFA — via RADIUS, which turned out to be broken upstream, and then via LDAP, which wasn’t. This is as much about how you prove a bug isn’t yours as it is about the build. Stack: Authentik · pfSense · Docker · LDAP · RADIUS 1. Purpose With an identity provider already running and Grafana logging in through it, the obvious next question was: how far does this go? ...

16 July 2026 · 13 min
Grafana's login page with a Sign in with authentik button

One Login, MFA Everywhere: Adding an Identity Provider to the Homelab

Deploying Authentik as a self-hosted identity provider, and wiring Grafana into it with OIDC — so a service that has never heard of MFA suddenly requires it. Stack: Authentik · Caddy · Grafana · Docker · Debian 1. Purpose Every self-hosted service arrives with its own login. Ten services means ten accounts, ten passwords, and ten places to forget to enable MFA. Worse, some services have no authentication at all and just quietly assume nobody hostile is on your network. ...

15 July 2026 · 9 min
The self-hosted Vaultwarden vault, logged in and showing its security reports

Self-Hosting a Password Manager the Hard Way: Vaultwarden, Caddy, and Three Firewalls Fighting

Building a self-hosted password vault with a genuinely trusted TLS certificate and zero inbound ports open to the internet — and the four-layer debugging session that stood between me and a working container. Stack: Debian 13 · Docker · Caddy (custom build) · Vaultwarden · pfSense · WireGuard · DuckDNS 1. Purpose Self-hosted services are easy to do badly. It’s trivial to run a container, forward a port, click through a certificate warning, and call it done — and end up with something less secure than the cloud service you replaced. ...

15 July 2026 · 11 min
All three VLAN interfaces online at their gateway IPs on pfSense

Virtual VLAN Segmentation on pfSense — Three Isolated Zones, No Managed Switch

A flat network trusts every device on it equally. A smart plug, a guest’s phone, and the machine holding my important data all share one space — so if any one of them is compromised, the attacker can reach the rest. Network segmentation breaks that flat space into separate zones and controls what may cross between them, shrinking the blast radius of any single compromise. I wanted to build that properly — VLANs and a firewall — on VMware Workstation with pfSense CE, and design three zones at deliberately different trust levels: ...

12 July 2026 · 8 min
WireGuard handshake established over mobile data

Self-Hosted WireGuard Through a Nested Firewall — and the Four-Layer Debug to Make It Work

My lab is deliberately isolated — an automation VM (CLAUDDEB) sits behind a virtual pfSense firewall on a segment (10.10.0.0/24) that my home network can’t reach. That isolation is great until you’re out of the house and want to check your Grafana dashboards, which only listen inside that segment. I already use Tailscale for casual remote access, and I’ll be honest up front: for pure convenience, Tailscale wins — it punches through NAT automatically with zero firewall work. But this project wasn’t about convenience. It was about building the thing Tailscale is made of. Tailscale is WireGuard under the hood; hand-rolling raw WireGuard on pfSense teaches you how VPNs actually work — keys, peers, routing, firewall rules, NAT — at a level the managed tool deliberately hides. So I built it from scratch, kept Tailscale as my daily driver, and got a genuinely brutal debugging lesson in the process. ...

11 July 2026 · 7 min
Terminal summary of the VM hardening result

Hardening My Debian Home-Lab VM — Even Behind pfSense

My Debian automation VM already sits behind a pfSense firewall with egress containment — it can reach the internet but not my home network. So why harden the VM itself? Because “behind a firewall” is doing less work than it sounds. Two paths reach into the VM without ever crossing pfSense, and an honest audit of my own box turned up drift I didn’t expect. This is the write-up: what the audit found, what I changed, and the systemd sandbox mistake that quietly broke a service. ...

7 July 2026 · 6 min
A note pushed from the laptop appearing on the hub via get_recent

Syncing Claude Code Across Devices with a Custom MCP Hub over Tailscale

I run Claude Code on two machines: the Debian VM in my home lab (always on) and a Debian laptop (sleeps, roams, follows me to campus). I wanted the laptop to push notes, facts, and findings into a central store on the VM — from any network — so the home-lab agent could pick them up later. Claude Code’s built-in Remote Control turns a second device into a remote window onto one session. That’s not what I wanted. I wanted both machines to stay fully independent agents, linked through a shared tool. So I built a small MCP server on the VM and pointed the laptop’s Claude Code at it: the hub becomes just another tool the laptop can call. ...

7 July 2026 · 6 min
Grafana Node Exporter dashboard for the Debian VM

Building a Prometheus and Grafana Observability Stack for My Home Lab

My LaMetric display gives an at-a-glance read on the lab, but it’s a spot reading with no history — good for “is something on fire right now,” useless for “what happened overnight.” This project adds the layer underneath: a Prometheus + Grafana stack that scrapes my hosts continuously, stores the history, and draws real dashboards. Two targets: CLAUDDEB (my Debian automation VM) and my pfSense firewall, reusing the exact SNMP setup from the pfSense post — just pointed at something far more capable than a 37-pixel display. ...

6 July 2026 · 6 min
pfSense WAN byte counter climbing under SNMP polling

Implementing LaMetric TIME to Network Part 2

In part 1 I got a LaMetric Time showing live health from my home lab over MQTT, so it worked across my network isolation — CPU, memory, disk, uptime, and the automation VM’s own traffic, all from a single Debian box. Useful, but those were really that box’s stats. The frame the display was named for is my network’s throughput — the traffic crossing my firewall — and that data lives on pfSense, not the Debian box. This is the follow-up: pulling real WAN in/out rates off pfSense over SNMP and putting them on the display. It’s shorter than the MQTT build, because the pipeline already exists; all I’m adding is a new data source. Getting numbers out of pfSense is the part worth writing down. ...

6 July 2026 · 8 min
A LaMetric Time smart display

Implementing LaMetric TIME to Network

I picked up a LaMetric Time — an 8x37 pixel smart display — and after locking it down on an isolated guest network, the next move was to make it useful: live health from my home lab. CPU, memory, network throughput — the numbers worth a glance. The interesting part is that a constraint I’d deliberately built into my network dictated the whole architecture. This is the write-up: the design decision, the pipeline, and the gotchas — because the gotchas are the useful part. ...

5 July 2026 · 7 min
pfSense dashboard after the rebuild

Debugging a Dead VMware NAT and Hardening My pfSense Containment Lab

I run my Claude Code work inside a Debian 13 VM (CLAUDDEB) on VMware Workstation Pro 17.6.4, with a pfSense 2.8.1 VM in front of it as a virtual router and firewall. pfSense exists in this setup for containment: if something on the Debian VM misbehaves — a prompt injection, a compromised dependency — it must not be able to reach my PC, my router’s admin page, or anything else on the home network. ...

2 July 2026 · 7 min
Arcadyan HWG2025 router

Hardening and Segmenting My Home Network on an Arcadyan HWG2025

This is a small home network — one router, a handful of devices. The point wasn’t complexity; it was applying the same discipline you would to a small office or lab environment. Treated that way, it doubles as practical study for Network+ and Security+. The router is an Arcadyan HWG2025 — the NBN-issued unit, Wi-Fi 7 with MLO, around 500 Mb down. An ISP router doesn’t give you much room to move, but it gives you enough to do this properly. ...

29 June 2026 · 3 min