↓ Skip to main content
>_
Homelab Journal // Network Security Engineer

Architecture

Gilfoyle Got Boundaries. His Chats Needed the Memo.

Changing my AI admin’s rules should have been straightforward: save the policy, deploy it, restart the gateway. Then I traced how an existing conversation restores its instructions: it can reuse its stored prompt instead of loading the new policy file. Apparently Gilfoyle had a way to keep outdated management instructions. Very on brand. When I introduced Gilfoyle in April, he was an observer. He watched services, investigated alerts, and told me what broke. By October, his policy carried an Admin label. The interesting work became deciding exactly what that label allowed, then checking which conversations actually loaded those rules.

How Gilfoyle Works: From Discord Alert to Diagnosis

An infrastructure alert lands in Discord. Turning it into a useful response takes more than adding an LLM: something has to decide whether the message belongs in the queue, collect evidence, preserve the incident context, and know when to stop. That is the machinery around Gilfoyle. The original introduction covered the April rollout. This is the current system, checked on October 15: how a signal reaches him, how he investigates, and which parts run without asking a model anything.

Gilfoyle Caught an Expired VPN Cert at Midnight. I Made Sure It Never Happens Again.

Update, October 14, 2026. This is the April certificate incident and the automation design that followed it. The monitoring schedules below describe that original setup, not a fresh verification of today’s jobs. Gilfoyle now has a Level 4 policy for bounded repairs, but the unattended controller remains inactive. A fresh Discord-route session loaded the new policy; warm sessions retained older prompts. The next chapter explains the rollout. It does not make certificate renewal an AI task.

Meet Gilfoyle: I Hired a Sarcastic AI to Watch My Homelab 24/7

Update, October 14, 2026. The patrols, capabilities, and trust ladder below describe Gilfoyle’s April rollout. A Level 4 policy now defines bounded authority for single-service repairs with a known rollback and fault-specific checks. The unattended controller remains inactive. Verification showed that a fresh session on the Discord route loaded the October 14 policy; already-warm sessions can retain their older prompts. The next chapter explains what changed and what still needs verification.

One MCP Server to Rule Them All: Unifying Homelab Services

Correction, September 2026. This post originally described the server as wrapping 9 services with 32 tools, including a confirmation-gated write surface and plans for an SSE transport. The maintained server is simpler and stricter than that: local stdio plus a CLI, up to 25 read-only tools across 10 configured backends, and 15 documentation resources. There are no write tools and no remote transport. Lifecycle changes (provisioning, DNS records, container updates) are owned by Semaphore automation, and the IPAM backend is now Nautobot — NetBox is retained rollback-only. The sections below have been rewritten to describe the current architecture; the original narrative is preserved where it explains the design decisions that still hold.

Eliminating Config Drift: GitOps Auto-Deploy for Caddy HA with Semaphore

The Problem # My Caddy reverse proxy runs as an HA pair – two nodes behind a keepalived VIP. Every service in the homelab gets its traffic through this pair. The setup works great, except for one recurring failure mode: config drift. The deployment process was manual: edit the Caddy site config in git, SCP it to both nodes, validate, reload. The “both nodes” part is where things break down. It’s easy to deploy to caddy1, test it, see it working, and then forget caddy2 exists. Until keepalived fails over and suddenly half your sites return 502s because the backup node has last week’s config.

Consolidating PAN-OS Certificate Management with Caddy + Semaphore

The Problem # My PAN-OS firewall (GlobalProtect VPN portal at vpn.mareoxlan.com) needs a valid TLS certificate. I had a dedicated LXC (30122) running acme.sh with a Cloudflare DNS-01 challenge to issue a wildcard cert, then a PAN-OS deploy hook to push it to the firewall via the XML API. It worked, but it was a single-purpose VM doing the same job my Caddy reverse proxy already does – Caddy auto-renews *.mareoxlan.com via the same Cloudflare DNS-01 mechanism.

Architecture: Caddy GitOps Auto-Deploy

Overview # After multiple outages caused by configuration drift between two HA Caddy reverse proxy nodes, I built a GitOps pipeline that automatically deploys configs to both nodes whenever changes are pushed to the main branch. Config drift is now impossible by design. The problem: Two Caddy nodes in a keepalived HA pair need identical configs. Forgetting to deploy to the second node after editing a site config caused service outages — twice in the same week.

Building a 4-Layer Agentic Architecture for Claude Code

The Problem # After months of building Claude Code extensions (agents, skills, commands, hooks, MCP servers) I had a growing collection of powerful tools with no coherent entry point. Want to pull all repos? Run a shell script. Want to check infrastructure health? Ask Claude and hope it knows which command to use. Want to automate a browser task? Figure out whether to use the MCP plugin or write a script.

Architecture: Prometheus + Grafana on a Dedicated LXC

Overview # Migrated the Prometheus + Grafana monitoring stack from a shared Docker VM to a dedicated LXC container. The shared VM hosted multiple stacks (pgAdmin, Portainer, monitoring) which created resource contention and made lifecycle management messy. Moving monitoring to its own LXC follows the homelab pattern of one service per container for cleaner isolation, backups, and management.