forked from roger/k3s-cluster
deploy both qwen3.6 versions
This commit is contained in:
139
home-manager/README.md
Normal file
139
home-manager/README.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user