140 lines
6.7 KiB
Markdown
140 lines
6.7 KiB
Markdown
# 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.
|