Entity: Hermes Agent (AI Agent Service)
This page is the repository hub for the Hermes Agent Proxmox KVM deployment.
Overview
Hermes Agent is deployed as a dedicated KVM VM (VM 501 hermes) on the Proxmox node tazlab, migrated from the old LXC container (CT 105) on 2026-08-12 via the CRISP project hermes-agent-redesign. The deployment lives in a standalone repository (github.com/tazzo/hermes-agent) with Terraform + Ansible + shell orchestrators — no longer part of ephemeral-castle.
Data persistence follows the same pet/cattle principle as the old LXC deployment, adapted to VM semantics: the root disk is ephemeral (destroyed with the VM), while a dedicated 20G data disk survives destroy/create cycles via an lvrename out-of-convention trick.
Architecture
Proxmox node "tazlab" (192.168.1.200)
└── VM 501 "hermes" (KVM, Ubuntu 26.04 LTS "resolute")
├── 4 vCPU, 8 GB RAM, static IP 192.168.1.205/24 (gw 192.168.1.1)
├── virtio0: root disk 30 GB (local-lvm) — EPHEMERAL, destroyed with VM
├── virtio1: data disk 20 GB (local-lvm:vm-501-disk-2) — PERSISTENT pet
│ └── /home/hermes (whole home = Hermes state + code, option A)
├── Hermes v0.20.0 (bare-metal via install.sh)
│ ├── hermes-gateway.service
│ └── hermes-dashboard.service (port 9119, bind 0.0.0.0 + basic auth)
└── Users: bootstrap (admin, sudo NOPASSWD), hermes (UID 10000, no sudo)
Repository Structure
hermes-agent/ # github.com/tazzo/hermes-agent
├── create.sh # 8-phase orchestrator (enterprise logging)
├── destroy.sh # unlink data disk → lvrename → qm destroy
├── terraform/ # VM 501 resource (root disk ONLY — data disk outside state)
├── ansible/ # 4 playbooks + roles (baseline, agent, configure, verify)
├── configs/
│ └── runtime.env # VM_ID, IP, CORES, MEMORY, DISK sizes
└── logs/ # Timestamped, rotated (keep 20)
Quick Facts
| Property | Value |
|---|---|
| VM ID | 501 (KVM) |
| Hostname | hermes |
| IP | 192.168.1.205 |
| OS | Ubuntu 26.04 LTS (resolute) |
| Resources | 4 vCPU, 8 GB RAM |
| Root disk | 30 GB local-lvm (ephemeral) |
| Data disk | 20 GB local-lvm:vm-501-disk-2 (persistent pet, mounted at /home/hermes) |
| Dashboard | http://192.168.1.205:9119 (basic auth: user hermes, password in gopass infra/hermes-vm/dashboard-password) |
| LLM Backend | Configurato dall’utente via dashboard al primo accesso (30+ provider) |
| Hermes version | v0.20.0 (2026.8.3) |
| User | hermes (UID 10000, non-root, no sudo) |
| Bootstrap user | bootstrap (sudo NOPASSWD, maintenance) |
| Repo | github.com/tazzo/hermes-agent (default branch main) |
| Old deployment | CT 105 LXC — destroyed 2026-08-12 |
Canonical Starting Pages for Agents
Deployment & Lifecycle
- VM Deployment Architecture — KVM architecture, persistence model, lifecycle, key discoveries
LXC Deployment Architecture— SUPERSEDED (seehermes-lxc-deployment.mdbanner, historical only)
CRISP Project (source of truth)
- Project:
skills/crisp/projects/hermes-agent-redesign/(RESEARCH/DESIGN/PLAN/tasks/retrospective) - Report:
skills/memory/reports/2026-08-12_hermes-agent-vm-redesign.md
Secrets (gopass)
infra/hermes-vm/dashboard-password— dashboard basic authinfra/hermes-vm/bootstrap-password+infra/hermes-vm/hermes-password— SSH passwordsinfra/ssh-host-keys/hermes-agent/ed25519— SSH host key (injected post-boot via Ansible)bootstrap/proxmox/token-id+bootstrap/proxmox/token-secret— Proxmox API for create/destroy
Key Discoveries (2026-08-12, destructive tests)
qm destroydeletes by naming convention: removes ALLvm-501-*volumes even unused, even with--destroy-unreferenced-disks 0. Fix:lvrenamethe data volume tovm-501-data-orphanbefore destroy, rename back on create.- Data disk OUTSIDE Terraform state: if declared in
.tf,terraform destroydeletes it. Managed viapvesm alloc+qm set/qm unlink. - gopass multi-line:
gopass show -oreturns only first line (35B vs 411B for SSH keys) — usegopass cat. - Ansible 2.21 become non-root bug:
sudo -u hermespattern instead ofbecome_method: su. - Dashboard auth: scrypt hash must be STANDARD base64 with padding +
maxmem=0(urlsafe fails). Hash computed locally where gopass exists. agent.wait_for_ip.disabled = true: skips IP wait (static via cloud-init) → apply drops from ~15 min to <1 min.
Known Issues / Technical Debt
| TD | Area | Summary |
|---|---|---|
| TD-056 | gopass cache | GPG cache expires ~45 min — long builds fail with “gopass locked”; show -o truncates multi-line secrets (use cat) |
Relationships
- Infrastructure: ephemeral-castle — former home;
ephemeral-castle/hermes/removed (commit 504f353); now standalone repo - GitOps cluster: tazlab-k8s — talks to the cluster via LLM provider
- Semantic memory: mnemosyne-mcp-server
- Context governance: AGENTS.ctx — operational memory and rules