Phase 1 — fix stale state after strong migration (Phase 1+2, 2026-07-05)
- README: corrected IPs (jellyfin 206→246, arriman 132→245, etc.),
added missing containers (128 trmnl, 129 house, 133 seanime, 134 romm,
124 authentik), updated last-refreshed date, added strong host context
- containers/101-jellyfin.md: IP 206→246, host hubris→strong, mount
/mnt/library→/mnt/media_local, GPU 760M→680M+RX7600, privilege→priv
- containers/118-elementsynapse.md: IP 239→242, added Host: strong
- containers/122-arriman.md: IP 132→245, mount→/mnt/media_local, added Host
- containers/129-house.md: IP 212→244, added Host: strong
- containers/130-grimmory.md: IP 213→247, mount→/mnt/media_local, added Host
- containers/121-caddy.md: fixed site list (books→grimmory, removed auth→VPS,
added house, roms, teddy, trmnl)
- hosts/strong.md: updated At-a-glance to reflect 7 LXCs hosted
- containers/123-claudio-bot.md, 127-mule-photos-new.md: archived to
containers/archive/ (were destroyed LXCs with living pages)
- inventory.yaml: verified correct — no changes needed
Phase 2 — structural cleanup
- infrastructure/index.md: one-page overview of all cross-cutting systems
- runbooks/: moved runbook-budget-from-csv.md and runbook-dpkg-interrupted.md
from operations/ with YAML frontmatter added
- plans/done/: moved 4 completed plans out of active view; updated index
- vms/index.md: added VM index page
Phase 3 — navigation & discoverability
- GLOSSARY.md: term definitions (Authentik, Caddy, LXC, VAAPI, etc.)
- README: added table of contents, links to glossary + infrastructure index
- investigations/: archived 2 resolved cases (crash-loop, authentik-migration)
to investigations/archive/; updated index with active vs archived sections
Phase 4 — ongoing discipline
- CONTRIBUTING.md: documented same-session update rule with explicit checklist
- README: replaced full LXC table with summary + link to containers/index.md
(single source of truth; de-duplication)
16 KiB
Deprecate claudio-bot (LXC 123) — Hermes Agent now serves as control plane
Goal
Phase out the claudio-bot ecosystem (LXC 123, claudio-monitor, IPC server) now that Hermes Agent is configured and running on mac-mini. Hermes replaces claudio-bot's role as the homelab control plane — accepting commands, relaying alerts, and answering queries about infrastructure state.
What is claudio-bot
A three-component ecosystem deployed 2026-04-20:
| Component | Location | Purpose |
|---|---|---|
| claudio-bot | LXC 123 (192.168.8.230) | Matrix bot @claudio:avispero — slash commands, NL queries, infra notifications |
| claudio-monitor | hubris (PVE host) | 5-min watchdog → sends alerts to claudio-bot's IPC server |
| IPC server | LXC 123:9090 | /notify, /propose, /status endpoints — used by monitor + backup wrapper |
Dependencies:
- Matrix synapse on LXC 118 (elementsynapse) — claudio-bot connects to
192.168.8.239:8008 - Gitea auto-deploy webhook → LXC 123:9797 (pipeline
dtoro/claudio-bot) - LLM backend: LM Studio on mac-mini (192.168.8.174:1234) or Anthropic API
- Secrets at
/etc/claudio-bot/(config.yaml, matrix.token, anthropic.key, lmstudio.key, ipc.token)
What Hermes replaces
| claudio-bot function | Hermes replacement |
|---|---|
| Matrix slash commands | Hermes CLI + send_message for outbound notifications |
| NL infrastructure queries | Hermes with homelab CLI + MCP tools (already working) |
| Monitor alert relay | Hermes-native: (a) on-demand homelab health via extended skill, (b) cronjob every 15 min with actionable alerts (not just passive notifications) |
| IPC server (port 9090) | Retired — Hermes doesn't need a separate IPC layer; monitoring runs directly via SSH + send_message |
| LLM backend | Already handled by Hermes (OpenRouter → deepseek/deepseek-v4-pro) |
| Auto-deploy webhook (9797) | Retired — repo archived |
Full blast radius (files referencing claudio)
Homelab-context repo (/opt/homelab-context/)
Core topology
inventory.yaml:275—claudio-bot:host entry (LXC 123, matrix-agent)hosts/claudio-bot.yaml— auto-generated host file (delete).sops.yaml:47— placeholder comment listing claudio-bot/claudio-monitor
Documentation (containers)
containers/123-claudio-bot.md— full container doccontainers/index.md:17— LXC table rowcontainers/118-elementsynapse.md:3,36,39—@claudio:avisperoreference, disk reading, direct connection notecontainers/103-paperless.md:27— disk reading from claudio-monitor
Documentation (infrastructure)
infrastructure/monitoring.md— ENTIRE FILE is about claudio-monitor → claudio-bot pipelineinfrastructure/backups.md:74,94,98— IPC notify, thermal monitoring moved out, related linkinfrastructure/auto-deploy.md:23,41,50,61,120,138-139— Gitea webhook target, pipeline table, port 9797infrastructure/ssh-access.md:134— LXC table rowinfrastructure/homelab-context.md:4,16,143— client list, integration note
Other
operations/commands.md:17—pveshbulk query note (passive reference, can stay)README.md:32,40,64— LXC table, monitoring link, tracked configs mentionmcp/deploy/webhook/webhook.py:5-6— port comment (9797, 9799)hosts/hubris.md:57,96—/opt/claudio-monitorcheckout, LXC 109 cleanup note (passive)vms/108-haos.md:30— claudio-monitor MQTT removal note (historical, can stay)investigations/2026-04-21-hubris-crash-loop.md:27— historical reference (keep)
External repos (Gitea)
dtoro/claudio-bot— the bot itselfdtoro/claudio-monitor— the watchdog scripts
External state (hubris)
/opt/claudio-bot/— bot checkout (LXC 123)/opt/claudio-monitor/— monitor checkout (hubris host)/etc/claudio-bot/— secrets directory/etc/claudio-deploy/— deploy git credentials/etc/claudio-monitor/— thresholds + bot.token/var/lib/claudio-monitor/— state files (.alert, .counter)claudio-bot.service— systemd unit (LXC 123)claudio-monitor.timer+.service— systemd timer (hubris)- Gitea webhook id 6 (claudio-bot-deploy) + webhook for claudio-monitor (9799) on apps LXC 105
External state (workstations)
- Nothing on mac-mini, republic-laptop, or ludo-mini references claudio directly
Phased deprecation plan
Phase 1 — Stop & verify (low-risk, reversible)
Goal: Stop claudio services, verify nothing breaks, keep LXC 123 paused (not destroyed).
-
Stop claudio-monitor on hubris
ssh hubris systemctl disable --now claudio-monitor.timerThe 5-minute watchdog stops. Home Assistant still gets PVE metrics independently via its own integration — no alerting gap there.
-
Stop claudio-bot on LXC 123
ssh claudio-bot systemctl stop claudio-botThe Matrix bot goes offline. Nobody can send slash commands to
@claudio:avispero. -
Pause LXC 123 (not destroy yet)
ssh hubris pct shutdown 123IPC server (port 9090) and deploy webhook (port 9797) become unreachable.
-
Verify no breakage (run for 24-48h)
- Check Gitea webhook logs — the
dtoro/claudio-botwebhook will 404 on pushes (non-fatal) - Check Caddy logs — no upstream errors for claudio-related paths (there shouldn't be any — no public hostname)
- Check DNS — no queries for claudio-bot.hubris.network (doesn't have a public hostname)
- Confirm Hermes works normally for all homelab operations
- Check Gitea webhook logs — the
Phase 2 — Hermes-native health monitoring (replaces claudio-monitor)
Goal: Two capabilities that together exceed what claudio-monitor did:
- On-demand health check — user asks "how's the homelab?" → Hermes runs a comprehensive check across all hosts/LXCs and reports results conversationally.
- Cron-based watchdog — runs every 15 minutes, checks thresholds, raises alarms with actionable options (not just passive alerts). User can respond and Hermes takes action directly.
Key difference from claudio-monitor: The old system was a bash script that POSTed JSON to an IPC server that a Matrix bot reformatted into a flat message. The Hermes-native approach gives the LLM the raw metrics and lets it reason about what's important before alerting — and crucially, the user can reply to an alert and Hermes can SSH into hubris to resize a rootfs, restart a service, or investigate deeper.
2a. Extend homelab-hardware-health skill
The existing skill covers CPU/NVMe temps. Expand it to be the single homelab health check skill covering:
- Hardware: CPU temps (sysfs), NVMe/SATA SSD temps (smartctl), block device inventory
- LXC resources:
pvesh get /cluster/resources --type vm --output-format json→ disk %, CPU %, RAM usage per container - Service health: Check key services respond (gitea:3000, caddy:80/443, synapse:8008, paperless, nextcloud, jellyfin)
- System drift:
apt list --upgradablecounts per host, docker image pull digests on apps LXC 105
Thresholds (from old /etc/claudio-monitor/thresholds.env):
| Metric | Warning | Critical |
|---|---|---|
| LXC disk usage | > 80% | > 90% |
| NVMe temp | > 60°C | > 70°C |
| CPU temp | > 70°C | > 80°C |
| Apt upgradable | > 10 | > 50 |
| Service down | any | 2+ services |
Update the skill file at devops/homelab-hardware-health/SKILL.md with:
- Expanded trigger phrases ("check homelab health", "how's the lab", "health report")
- LXC resource check commands
- Service health check commands
- Thresholds table
- "If you find issues, present options to the user" instruction
2b. Create Hermes cronjob homelab-health-watchdog
hermes cron create \
--schedule 'every 15m' \
--name 'homelab-health-watchdog' \
--prompt 'Load skill homelab-hardware-health. Run a full health check across all hosts (hubris + all LXCs). Check: (1) hardware temps, (2) LXC disk/CPU/RAM via pvesh, (3) service reachability for gitea, caddy, synapse, paperless, nextcloud, jellyfin, (4) apt upgradable counts. Compare against thresholds in the skill. If nothing is critical, say nothing (no message = healthy). If anything breaches thresholds, send a concise alert with: what broke, current value vs threshold, and 2-3 actionable options the user can reply to. DO NOT send routine "all clear" messages.'
This runs every 15 minutes (Hermes cron is LLM-driven, heavier than a bash script — 15 min is appropriate vs claudio-monitor's 5 min). When thresholds are clean, the agent stays silent. When something breaches, the user gets a message like:
⚠️ LXC 103 (paperless) disk at 91% (> 90% critical)
Options: [resize rootfs to 16 GiB] [investigate what's using space] [snooze 24h]
User picks an option → Hermes takes action (SSH into hubris, run pct resize,
grow the filesystem inside the container).
2c. Add homelab-health alias to homelab CLI
For quick on-demand checks from the terminal:
homelab health # runs the skill inline via Hermes
# or equivalently:
hermes --prompt "Load homelab-hardware-health, run full health check"
Phase 3 — Documentation & inventory cleanup
Goal: Update homelab-context to reflect claudio deprecation, without destroying history.
Files to edit
| File | Action |
|---|---|
inventory.yaml |
Mark claudio-bot entry as deprecated (comment + status: deprecated). Do NOT remove — keeps historical ID mapping. |
containers/123-claudio-bot.md |
Add deprecation banner at top, changelog entry |
containers/index.md |
Change status from "running" to "stopped (deprecated)" |
infrastructure/monitoring.md |
Rewrite to document new Hermes-based monitoring. Keep claudio-monitor section as "legacy (deprecated 2026-06-04)". |
infrastructure/auto-deploy.md |
Mark claudio-bot and claudio-monitor webhook entries as deprecated |
infrastructure/backups.md |
Update notification section (IPC path no longer available). Note: backups themselves are still disabled — this is forward-looking. |
infrastructure/ssh-access.md |
Mark LXC 123 as "offline (deprecated)" |
infrastructure/homelab-context.md |
Remove claudio-bot from client list |
containers/118-elementsynapse.md |
Note @claudio:avispero is decommissioned |
containers/103-paperless.md |
Remove stale disk reading reference (already resolved — rootfs grew to 16 GiB 2026-05-15 per 118 doc) |
README.md |
Update LXC table, remove monitoring link |
hosts/claudio-bot.yaml |
Add deprecation banner (or delete if auto-generated — it is, so just update inventory) |
.sops.yaml |
Remove claudio-bot from placeholder comment |
Files to leave untouched (historical)
| File | Reason |
|---|---|
investigations/2026-04-21-hubris-crash-loop.md |
Historical investigation — claudio-monitor is factual context |
vms/108-haos.md:30 |
Historical note about MQTT removal — factual |
mcp/deploy/webhook/webhook.py:5-6 |
Comment only — harmless, keep for port mapping context |
operations/commands.md:17 |
Passive reference — harmless |
Phase 4 — Purge (after confirmation window)
Goal: Full removal after confirming Phase 1-3 is stable for ≥2 weeks.
-
Destroy LXC 123
ssh hubris pct destroy 123 --purgeFrees 8 GiB rootfs, 512 MiB RAM, 1 core.
-
Remove claudio-monitor from hubris
ssh hubris rm -rf /opt/claudio-monitor /etc/claudio-monitor /var/lib/claudio-monitor ssh hubris systemctl disable claudio-monitor.timer # already done in phase 1 -
Archive Gitea repos
- Archive
dtoro/claudio-bot(mark read-only in Gitea) - Archive
dtoro/claudio-monitor(mark read-only in Gitea)
- Archive
-
Remove Gitea webhooks
- Remove claudio-bot-deploy webhook (id 6) from Gitea
- Remove claudio-monitor webhook (9799) from apps LXC 105
- Remove
192.168.8.230from Giteaapp.iniALLOWED_HOST_LIST
-
Final documentation cleanup
- Remove
containers/123-claudio-bot.md(or move tocontainers/_destroyed/) - Remove
hosts/claudio-bot.yaml - Remove claudio-bot row from
containers/index.md - Update all cross-references (see blast radius above)
- Remove
Files changed by phase
Phase 3 (documentation)
/opt/homelab-context/inventory.yaml/opt/homelab-context/containers/123-claudio-bot.md/opt/homelab-context/containers/index.md/opt/homelab-context/infrastructure/monitoring.md/opt/homelab-context/infrastructure/auto-deploy.md/opt/homelab-context/infrastructure/backups.md/opt/homelab-context/infrastructure/ssh-access.md/opt/homelab-context/infrastructure/homelab-context.md/opt/homelab-context/containers/118-elementsynapse.md/opt/homelab-context/containers/103-paperless.md/opt/homelab-context/README.md/opt/homelab-context/hosts/claudio-bot.yaml/opt/homelab-context/.sops.yaml
Phase 4 (destruction)
- Proxmox: LXC 123 destroyed
- Gitea:
dtoro/claudio-botarchived,dtoro/claudio-monitorarchived - Gitea webhooks removed (apps LXC 105)
- hubris:
/opt/claudio-monitor/,/etc/claudio-monitor/,/var/lib/claudio-monitor/removed containers/123-claudio-bot.md→ moved to_destroyed/or deleted
Risks & tradeoffs
| Risk | Mitigation |
|---|---|
| Monitoring gap — no alerts during Phase 1-2 transition | Phase 1 stops the old timer but Phase 2 builds the Hermes-native replacement immediately. If there's a gap, keep claudio-monitor.timer running until the Hermes cronjob is verified with a test alert. |
| Backup notifications — the backup wrapper's IPC notify path is dead | Backups are already DISABLED. When re-enabled, wire them to the new Hermes monitoring pipeline instead. |
Matrix @claudio:avispero — users may still try to interact |
The bot just won't respond. Could leave a notice in the Matrix room. |
Gitea webhook failures — pushes to dtoro/claudio-bot will 404 |
Non-fatal. Archive the repo in Phase 4 to stop pushes entirely. |
| Losing monitoring history — state files on hubris | Keep /var/lib/claudio-monitor/ until Phase 4. No rush. |
| LM Studio dependency — claudio-bot was using mac-mini's LM Studio | Hermes already uses OpenRouter. LM Studio on mac-mini can stay for other uses or be reclaimed. |
Open questions
-
Should the Matrix
@claudio:avisperoaccount be deactivated or left as-is? It has no public hostname and was invite-only to a private room. -
Are you OK archiving
dtoro/claudio-botanddtoro/claudio-monitoron Gitea (read-only, preserved), or do you want them fully deleted? -
Should LXC 123 be paused (reversible) or destroyed immediately? Recommend pause for at least 2 weeks as a safety net.
-
Which messaging platform should the health watchdog deliver alerts to? Currently Hermes is connected via CLI (mac-mini). To get push alerts, we need a
send_messagetarget — Telegram, Discord, or Matrix are available. Which do you prefer?
Verification
After Phase 1:
ssh hubris systemctl is-active claudio-monitor.timer→inactivessh claudio-bot systemctl is-active claudio-bot→inactive(or unreachable if LXC stopped)ssh hubris pct status 123→stoppedcurl -s http://192.168.8.230:9090/status→ connection refused (IPC dead)
After Phase 2:
hermes cron listshowshomelab-health-watchdogrunning every 15 min- "check homelab health" → Hermes runs comprehensive check, reports temps + LXC resources + service status + apt drift
- Force an alert:
NVME_WARN_TEMP_C=1on hubris → watchdog catches it on next 15-min tick → alert arrives via Hermes messaging with actionable options - Alert format includes 2-3 options user can reply to, not just passive notification
After Phase 3:
- All cross-references in homelab-context point to deprecated/removed status
grep -r 'claudio' /opt/homelab-context/ --include='*.md' --include='*.yaml' | grep -v '_destroyed\|investigations\|changelog'→ only historical references remain
After Phase 4:
ssh hubris pct list | grep 123→ no outputssh hubris ls /opt/claudio-monitor→ no such file- Gitea
dtoro/claudio-bot→ archived badge