<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel>
  <title>michaelz.dev — writeups</title>
  <link>https://www.michaelz.dev/blog/</link>
  <description>Homelab war stories, build logs and debugging tales from a self-hosted lab.</description>
  <language>en</language>
  <atom:link xmlns:atom="http://www.w3.org/2005/Atom" href="https://www.michaelz.dev/blog/feed.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>The four systems that run my house</title>
      <link>https://www.michaelz.dev/blog/four-systems.html</link>
      <guid>https://www.michaelz.dev/blog/four-systems.html</guid>
      <pubDate>Sat, 25 Jul 2026 18:00:00 +0200</pubDate>
      <description>I gave an AI agent permission to restart exactly one service without asking me. Getting there took four systems: a deterministic engine with no AI in it, an agent that watches, a HUD that can veto it, and a folder of markdown as memory — plus the breaker nobody builds, for a fix that succeeds forever while the thing stays broken.</description>
    </item>
    <item>
      <title>It Was the ISP (and I Could Prove It): diagnosing an outage from the inside</title>
      <link>https://www.michaelz.dev/blog/it-was-the-isp.html</link>
      <guid>https://www.michaelz.dev/blog/it-was-the-isp.html</guid>
      <pubDate>Mon, 20 Jul 2026 14:00:00 +0200</pubDate>
      <description>The internet vanished from my apartment with everything on my side healthy. A WAN capture showed my DHCP requests leaving and nothing answering — while the ISP's gateway was alive on the wire and a neighbour was failing too. The proof it was upstream: a static-IP bypass the access network refused by design.</description>
    </item>
    <item>
      <title>The Dishwasher That Wouldn't Move: two sessions to change one VLAN</title>
      <link>https://www.michaelz.dev/blog/the-dishwasher-that-wouldnt-move.html</link>
      <guid>https://www.michaelz.dev/blog/the-dishwasher-that-wouldnt-move.html</guid>
      <pubDate>Mon, 20 Jul 2026 13:30:00 +0200</pubDate>
      <description>Moving a Siemens dishwasher onto an IoT VLAN meant fighting Home Connect's "at home" gate — which needs your phone on the appliance's current network, the exact thing VLAN isolation removes. Plus a band change, a static-IP prompt, and an IPv6 toggle that all didn't matter.</description>
    </item>
    <item>
      <title>The Outage That Wasn't: when my own tools lied to me</title>
      <link>https://www.michaelz.dev/blog/the-outage-that-wasnt.html</link>
      <guid>https://www.michaelz.dev/blog/the-outage-that-wasnt.html</guid>
      <pubDate>Mon, 20 Jul 2026 13:00:00 +0200</pubDate>
      <description>Testing DNS failover, my checks reported total failure and I nearly took the house down chasing it — until dig and netstat showed everything was fine. BusyBox's pgrep and nslookup had lied in unison. The failover worked; strict-order was the one real bug.</description>
    </item>
    <item>
      <title>Bricked by Someone Else's Outage: when a CDN wouldn't let my house boot</title>
      <link>https://www.michaelz.dev/blog/bricked-by-a-cdn.html</link>
      <guid>https://www.michaelz.dev/blog/bricked-by-a-cdn.html</guid>
      <pubDate>Sun, 12 Jul 2026 12:00:00 +0200</pubDate>
      <description>A routine Home Assistant point update left the whole apartment stuck NOT_RUNNING — because at boot, a core version change re-fetches its Python wheels from a CDN that was returning 522, and rollback needs the same dead server.</description>
    </item>
    <item>
      <title>Connected, and Completely Dead: the TV that lied about its WiFi</title>
      <link>https://www.michaelz.dev/blog/connected-and-dead.html</link>
      <guid>https://www.michaelz.dev/blog/connected-and-dead.html</guid>
      <pubDate>Sun, 12 Jul 2026 11:30:00 +0200</pubDate>
      <description>Full signal bars and 100% packet loss: a living-room TV wedged into a WiFi zombie state after a DFS radar eviction on channel 100. A one-line deauth revives it; moving off DFS to channel 44 ends it for good.</description>
    </item>
    <item>
      <title>Everyone Looks Local: the reverse proxy that lied about my friends</title>
      <link>https://www.michaelz.dev/blog/everyone-looks-local.html</link>
      <guid>https://www.michaelz.dev/blog/everyone-looks-local.html</guid>
      <pubDate>Sat, 11 Jul 2026 12:00:00 +0200</pubDate>
      <description>My friends' Jellyfin streams kept buffering and the remote bitrate cap did nothing — because behind a reverse proxy, every client looks local until you teach the app to trust the proxy and read the forwarded address.</description>
    </item>
    <item>
      <title>Half a Terabyte of Déjà Vu: the torrent client that cloned my library</title>
      <link>https://www.michaelz.dev/blog/half-a-terabyte-of-deja-vu.html</link>
      <guid>https://www.michaelz.dev/blog/half-a-terabyte-of-deja-vu.html</guid>
      <pubDate>Sat, 11 Jul 2026 11:30:00 +0200</pubDate>
      <description>My media pool was filling up with nothing new — every film existed twice, seeding and imported. Hardlinks can't cross a filesystem boundary, and I'd drawn one straight between downloads and media.</description>
    </item>
    <item>
      <title>Ghosts in the Machine, Part II: the WiFi that wouldn't roam</title>
      <link>https://www.michaelz.dev/blog/wifi-ghost.html</link>
      <guid>https://www.michaelz.dev/blog/wifi-ghost.html</guid>
      <pubDate>Sat, 14 Jun 2026 11:00:00 +0200</pubDate>
      <description>Chasing a flaky WiFi-roaming bug across two OpenWRT access points — an amnesiac daemon, a phantom radio, a port poltergeist, and the watchdog that fixed it.</description>
    </item>
    <item>
      <title>The cat is not allowed to trigger automations</title>
      <link>https://www.michaelz.dev/blog/cat-vs-automations.html</link>
      <guid>https://www.michaelz.dev/blog/cat-vs-automations.html</guid>
      <pubDate>Sun, 14 Jun 2026 09:00:00 +0200</pubDate>
      <description>Designing a smart home around a cat named Pixel — and why every scene in my apartment is a manual button.</description>
    </item>
    <item>
      <title>My homelab fixes itself</title>
      <link>https://www.michaelz.dev/blog/homelab-fixes-itself.html</link>
      <guid>https://www.michaelz.dev/blog/homelab-fixes-itself.html</guid>
      <pubDate>Sun, 14 Jun 2026 09:00:00 +0200</pubDate>
      <description>Building an autonomous operations brain for a homelab — events, a knowledge graph, guarded workflows, and a junior SRE that never sleeps.</description>
    </item>
    <item>
      <title>No Docker. On purpose.</title>
      <link>https://www.michaelz.dev/blog/no-docker-on-purpose.html</link>
      <guid>https://www.michaelz.dev/blog/no-docker-on-purpose.html</guid>
      <pubDate>Sun, 14 Jun 2026 09:00:00 +0200</pubDate>
      <description>Running ~24 homelab services as native systemd in unprivileged LXC — no containers in sight, and why it&#x27;s been worth it.</description>
    </item>
    <item>
      <title>Photo Memories: phone → cloud → living-room TV</title>
      <link>https://www.michaelz.dev/blog/photo-memories.html</link>
      <guid>https://www.michaelz.dev/blog/photo-memories.html</guid>
      <pubDate>Sat, 13 Jun 2026 09:00:00 +0200</pubDate>
      <description>Building a private photo-memories loop: phone to self-hosted cloud to the living-room TV — without the screenshots tagging along.</description>
    </item>
    <item>
      <title>The Calendar Saga: a war story against FullCalendar</title>
      <link>https://www.michaelz.dev/blog/calendar-saga.html</link>
      <guid>https://www.michaelz.dev/blog/calendar-saga.html</guid>
      <pubDate>Sat, 13 Jun 2026 09:00:00 +0200</pubDate>
      <description>A multi-hour fight to get a Google-style month calendar with spanning event bars into Home Assistant — and the one CSS line that won it.</description>
    </item>
    <item>
      <title>The Ghost in the NIC: chasing an e1000e hardware hang</title>
      <link>https://www.michaelz.dev/blog/e1000e-nic-hang.html</link>
      <guid>https://www.michaelz.dev/blog/e1000e-nic-hang.html</guid>
      <pubDate>Sat, 13 Jun 2026 09:00:00 +0200</pubDate>
      <description>A backup node that kept vanishing from the network, an Intel driver bug, and a three-word fix.</description>
    </item>
</channel></rss>
