Files
k3s-cluster/home-manager
2026-08-01 00:24:26 +02:00
..
2026-08-01 00:24:26 +02:00
2026-07-25 00:54:46 +02:00
2026-08-01 00:24:26 +02:00

Home Manager Agent — Deployment Plan

An autonomous Hermes Agent that runs inside the k3s cluster and takes care of the home by talking to Home Assistant's REST API. It mirrors the platform-engineer agent pattern but its domain is the home, not the cluster: it watches sensors, runs routines, and notifies Roger on Discord — asking before touching anything security-critical (locks, alarm, garage, HVAC).

Docs: https://hermes-agent.nousresearch.com/docs/user-guide/docker


1. Goal & operating model

  • One Hermes container in namespace home-manager, scheduled on the amd64 NUC (roger-nucbox-evo-x2, 24 GiB) — same node as platform-engineer.
  • Hermes runs in gateway mode under s6 supervision (gateway run), so the built-in cron scheduler is active and survives restarts.
  • The agent talks to the home via the Home Assistant REST API at http://home-assistant.home-assistant:80 (in-cluster home-assistant Service). Auth is a HA Long-Lived Access Token in a Secret.
  • The agent has NO k8s RBAC and NO git repo — it doesn't need them. Its only write path is HA service calls. (Contrast with platform-engineer, which remediates via git commits → ArgoCD sync.)
  • LLM calls route through the in-cluster LiteLLM proxy.
  • Notifications go to a dedicated Discord bot (separate token from the platform engineer's bot).
  • Hermes-native cron jobs make the agent run periodic checks + routines.

2. Files in this directory

File Purpose
namespace.yaml namespace home-manager
rbac.yaml ServiceAccount + Role for the cron-seed Job only (pods/exec on the hermes pod)
configmap.yaml seed config.yaml + SOUL.md (HA REST API docs + operating rules)
secret.yaml HA token, Discord token/channel, LiteLLM key, dashboard auth (PLACEHOLDERS — fill in)
pvc.yaml 5 Gi PVC for /opt/data (HERMES_HOME)
deployment.yaml Deployment (1 replica, Recreate, pinned to amd64 NUC) + Service
ingress.yaml home-manager.rogi.casa → dashboard (TLS + basic auth)
cron-seed.yaml Sync-hook Job that reconciles the Hermes cron schedule from Git (deletes + recreates each job on every run so prompt/schedule changes apply on sync)
README.md this file

3. How it differs from platform-engineer

Concern platform-engineer home-manager (this)
Domain k3s cluster health the home
Observe via Prometheus / Loki / ArgoCD HTTP APIs Home Assistant REST API
Write path git commit → push → ArgoCD sync HA service calls (POST /api/services/...)
k8s RBAC none none
git repo yes (cloned to /workspace/k3s-cluster) none
Discord bot dedicated dedicated (separate token + channel)
HERMES_WRITE_SAFE_ROOT / (needs to edit manifests) unset → defaults to /opt/data (tighter)
Image nousresearch/hermes-agent:latest same
Model deepseek-v4-flash-0731 via LiteLLM same

4. Safety & guardrails

  1. SOUL.md is the real boundary. The agent may freely toggle lights, fans, media, and non-critical switches. It must ask Roger on Discord before touching lock.*, alarm_control_panel.*, garage cover.*, risky climate.* changes, or anything tagged critical/security/safe_to_auto: false.
  2. tool_loop_guardrails.hard_stop_enabled: true — circuit-breaks a stuck gateway.
  3. yolo: true + approvals.mode: off — cron jobs aren't blocked waiting for a human. Safe because the blast radius is HA service calls and the SOUL.md encodes the confirmation gate for dangerous entities.
  4. Tirith scanner disabled — it false-positives on the in-cluster plain-HTTP HA URL and would block every query.
  5. Single replica / single-writer PVC — never scale >1. podAntiAffinity guards against an accidental co-run.
  6. No real-time event bus — the terminal tool can't hold a HA WebSocket open. The agent works on cron polling + on-demand Discord commands. (See §6 for an optional real-time hook.)

5. Deployment checklist (do in this order)

  1. Create a Home Assistant Long-Lived Access Token. In HA UI: Profile → Long-Lived Access Tokens → Create Token → label home-manager-agent. Copy the token.
  2. Create a dedicated Discord bot (separate from the platform-engineer bot), invite it to your server, and note its token + the channel ID you want it to use as its home channel.
  3. Fill in secret.yaml — base64-encode each value (echo -n 'VALUE' | base64):
    • HOMEASSISTANT_TOKEN — the HA LLAT from step 1.
    • OPENAI_API_KEY — your LiteLLM master key.
    • DISCORD_BOT_TOKEN, DISCORD_HOME_CHANNEL, DISCORD_FREE_RESPONSE_CHANNELS — from step 2 (channel ID is the same for both).
    • HERMES_DASHBOARD_BASIC_AUTH_PASSWORD and ..._SECRET — strong values.
  4. Fill in configmap.yaml — replace REPLACE_WITH_HOME_CHANNEL_ID (two places under discord:) with your numeric home channel ID. (Must match the secret's DISCORD_HOME_CHANNEL.)
  5. Tailor cron-seed.yaml schedules/prompts to your actual HA entities (your sensor names, your calendars, your todo lists). The default schedule has 4 jobs (energy anomaly, comfort check, morning briefing, evening briefing) — adjust thresholds and wording to your setup.
  6. Commit & push the whole change (including the regenerated argocd/apps/home-manager.yaml). ArgoCD will create the namespace resources, deploy the pod, and bring up the ingress at home-manager.rogi.casa.
  7. Seed the cron jobs: ArgoCD runs cron-seed.yaml as a Sync hook automatically on every sync. The hook reconciles the cron schedule to match Git: it deletes + recreates each named job, so prompt/schedule edits in cron-seed.yaml take effect on the next sync (this overwrites any live hermes cron edit changes — edit the prompts in Git instead). The schedule has exactly 4 jobs: energy-anomaly (every 4h), comfort-check (every 4h), morning-briefing (08:00 daily), evening-briefing (00:00 daily). To re-run it by hand: kubectl apply -f home-manager/cron-seed.yaml.
  8. Smoke test: trigger a check manually — kubectl exec -n home-manager deploy/hermes -- hermes cron run morning-briefing — and confirm the message lands in Discord.

6. Optional: real-time events from HA

The base setup is cron-poll + Discord. For real-time reaction (e.g. "front door opened → agent acts immediately"), you can have Home Assistant call the Hermes gateway API on an event:

  1. Enable the gateway API (port 8642) in config.yaml and set an auth token.
  2. In HA, create a rest command + an automation that fires on the event and POSTs to http://home-manager.home-manager:80/... (the in-cluster Service).

This is not enabled by default — start with cron + Discord, add webhooks once the agent is trusted.


7. What ArgoCD owns vs. what is runtime state

  • ArgoCD owns (in git): namespace, RBAC, Secret, ConfigMap (seed), PVC, Deployment, Service, Ingress, cron-seed Job.
  • Runtime state (on the PVC, NOT reconciled): config.yaml, SOUL.md, .env, sessions/, memories/, skills/. The ConfigMap only seeds these on first boot; after that, edits made via the dashboard persist on the PVC and Argo will not revert them. For a hard reset, delete the PVC and re-apply.
    • Exception — cron jobs (cron/jobs.json): the cron-seed Sync hook re-runs on every ArgoCD sync and deletes + recreates each named job from cron-seed.yaml, so the cron schedule IS reconciled from Git. Live edits via hermes cron edit will be overwritten on the next sync — edit the prompts in cron-seed.yaml and commit instead.