# 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` | one-shot Job that creates the Hermes cron schedule | | `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 | `qwen3.6` 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 `script.goodnight`, etc.). 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. To re-seed after a wipe: `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 door-window-check` — and confirm the message lands in Discord (or `[SILENT]` if all clear). --- ## 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`, `cron/jobs.json`, `sessions/`, `memories/`, `skills/`. The ConfigMap only *seeds* these on first boot; after that, edits made via the dashboard or `hermes cron edit` persist on the PVC and Argo will not revert them. For a hard reset, delete the PVC and re-apply.