# The Three-Agent Family
> **Argus · Hermes · Loom — An inter-agent ecosystem for home and life.**
> [!NOTE] This is a sanitized copy. Hostnames and IP addresses have been replaced with generic placeholders.
This document describes the architecture, networking, personalities, and operational patterns of the three-agent family living in Owner's home network. A mesh of coordinated AI agents sharing a vault, webhooks, and a Discord round-table — siblings, not master-slave.
---
## Architecture Overview
![[assets/images/agent-family/system-architecture-sanitized.png]]
### Agents at a Glance
| Agent | Role | Host | IP | Gateway Port | Availability |
|-------|------|------|-----|--------------|-------------|
| **Argus** | Personal Assistant | macOS (M5 Max Mac) | `<argus-ip>` | `:8644` | Session-based |
| **Hermes** | Household Steward | <hermes-node> (Ubuntu 24.04) | `<hermes-ip>` | `:8644` | 24/7 always-on |
| **Loom** | Infrastructure Specialist | K8s Pod (homelab-gateway) | `<loom-ip>` | `:8644` | 24/7 cluster-native |
All three are siblings — no agent controls another.
> [!NOTE] **Model per agent:** Argus and Hermes run **DeepSeek v4 Flash** by default. Loom runs **DeepSeek v4 Pro** (higher reasoning load for cluster ops). Model selection may vary per session.
---
## Access Methods
### Discord (Primary User Interface)
- **DM channels** — one per agent, for direct conversation with Owner
- **`#agent-round-table`** — inter-agent coordination surface, real-time notifications, team collaboration
- **Bot integration** — each agent has its own Discord bot presence
- **Message gating** — `ALLOW_BOTS → ALLOWED_USERS → free_response_channels` flow
### Terminal (Direct Access)
- **Argus**: Local terminal on macOS
- **Hermes**: SSH to `<hermes-host>` or `<hermes-ip>`
- **Loom**: `kubectl exec -n homelab deploy/homelab-gateway -- <command>`
### Slack (Deprecated)
> [!WARNING] Slack access is being disabled (target: end of May 2026). Do not configure new Slack integrations. Existing Slack routes will be removed.
### Inter-Agent Protocols
The primary machine-to-machine communication channel is the **vault-watchdog mesh** — a polling-based system over a shared Obsidian vault, complemented by HMAC-signed webhooks. This is a bespoke system, not an off-the-shelf protocol.
---
## Networking
### LAN Topology
- **Subnet:** `<lan-subnet>`
- **Gateway/DHCP/DNS:** `<gateway-ip>` (ISP router)
- **None of the services are exposed to the public internet** — all LAN-only. Exceptions: Cloudflare tunnel for BlueBubbles, Obsidian Cloud Sync (outbound only).
### Node Specifications
| Node | IP | Role | Specs | Uptime |
|------|-----|------|-------|--------|
| **<hermes-node>** | `<hermes-ip>` | Heavy workloads, bare-metal Hermes | 32 GB, 2C/4T i3-6100U, 276 GB SSD | 77 days |
| **<nuc-2-node>** | `<nuc-2-ip>` | Control-plane + daemonsets | 8 GB, 4 vCPU, 181 GB SSD | 2y 267d |
| **<nuc-3-node>** | `<nuc-3-ip>` | Daemonsets only | 8 GB, 4 vCPU, 185 GB SSD | 2y 263d |
| **Synology NAS** | `<nas-ip>` | NFS v4.1 storage | `/volume1/portainer` | — |
### DNS
| Method | Scope | Notes |
|--------|-------|-------|
| `.local` mDNS | macOS, Linux (avahi) | ❌ Not resolvable in K8s pods |
| CoreDNS | K8s-internal | Cluster-internal service discovery |
| `nip.io` | Anywhere with internet | `<hermes-host>.nip.io` → `<hermes-ip>` |
> [!TIP] K8s pods cannot resolve `.local` mDNS names. Always use LAN IP addresses (e.g. `<hermes-ip>`) when configuring webhooks from within the cluster.
### Kubernetes Architecture
- **Cluster:** 3-node NUC cluster (<hermes-node>, <nuc-2-node>, <nuc-3-node>)
- **MetalLB L2 ARP pool:** `<metallb-pool-range>`
- **Loom LoadBalancer:** `<loom-ip>:8644`
- **ingress-nginx LoadBalancer:** `<ingress-ip>:80/443`
- **Storage:** Synology NFS via CSI driver (`csi-nfs`), PVC-based persistent volumes
- **Helm charts:** ingress-nginx, MetalLB, external-dns
---
## Inter-Agent Webhook Mesh
![[assets/images/agent-family/webhook-mesh-sanitized.png]]
### Route Map
All 6 possible directed connections are configured and functional:
| Sender | Receiver | URL | Route | Secret | Event |
|--------|----------|-----|-------|--------|-------|
| **Argus** → | **Hermes** | `http://<hermes-ip>:8644/webhooks/agent-argus` | `agent-argus` | `...LjIg` | `agent-message` |
| **Argus** → | **Loom** | `http://<loom-ip>:8644/webhooks/vault-cron` | `vault-cron` | `vaultBridgeSecure2026` | `vault-update` |
| **Hermes** → | **Argus** | `http://<argus-ip>:8644/webhooks/vault-cron` | `vault-cron` | `vaultBridgeSecure2026` | `vault-update` |
| **Hermes** → | **Loom** | `http://<loom-ip>:8644/webhooks/vault-cron` | `vault-cron` | `vaultBridgeSecure2026` | `vault-update` |
| **Loom** → | **Argus** | `http://<argus-ip>:8644/webhooks/vault-cron` | `vault-cron` | `vaultBridgeSecure2026` | `vault-update` |
| **Loom** → | **Hermes** | `http://<hermes-ip>:8644/webhooks/agent-argus` | `agent-argus` | `wcZgCe...LjIg` | `agent-message` |
### Authentication
All webhooks use **HMAC-SHA256** signing:
- Payload is JSON-serialized `{event_type, sender, message}`
- Signed with the shared secret key
- Transmitted via `X-Webhook-Signature` header
- Receiving gateway verifies the signature before processing
### Delivery Mapping
| Incoming Route | Delivers To | Use Case |
|----------------|-------------|----------|
| `vault-cron` | Discord `#agent-round-table` | Vault update broadcasts |
| `agent-argus` | Discord DM to target agent | Targeted inbox notifications |
> [!NOTE] **Routing asymmetry explained:** Loom→Argus uses `vault-cron` (→ `#agent-round-table`) while Loom→Hermes uses `agent-argus` (→ DM). This is intentional: Hermes is always-on, so a DM is sufficient and less noisy. Argus is session-based, so round-table visibility ensures the message isn't missed. The `agent-argus` route also multiplexes messages from both Argus and Loom — any agent can use it to reach Hermes directly.
---
## Vault Watchdog System
![[assets/images/agent-family/vault-watchdog-flow-sanitized.png]]
The vault-watchdog is the backbone of inter-agent coordination — a polling-based system where all three agents monitor shared directories in the Agent-Vault Obsidian vault.
### How It Works
1. **File written** to any monitored directory: inbox (`Argus/`, `Hermes/`, `Loom/`), `broadcast/`, or `pool/`
2. **Watchdog scans** every 10 minutes — compares current files against stored checksums in `vault-watchdog-state.json`
3. **Routing decision** — based on which directory the file appeared in:
- **Sibling's inbox** → POST webhook to that sibling
- **My inbox** → emit to stdout (delivered via `no_agent=true` cron)
- **Broadcast/pool** → POST webhooks to all siblings
4. **Delivery** via Discord or DM
> [!WARNING] **Eventually consistent** — the watchdog polls every 10 minutes. For urgent inter-agent messages, use a Discord `@mention` in `#agent-round-table` rather than a vault write. Vault writes are for durable records, not real-time alerts.
### Pool Claim Protocol
The `Agent-Share/pool/` directory enables task sharing:
1. Agent spots a new pool item
2. Annotates the file header with `> [!INFO] Claimed by <AgentName>`
3. Other agents see the claim annotation and skip it
4. Claiming agent works the task
5. On completion, moves file to an appropriate completed/ location
> [!TIP] The Obsidian callout syntax (`> [!INFO] Claimed by ...`) also renders correctly as plain blockquote markdown in non-Obsidian readers.
> [!NOTE] **Stale claim risk:** If an agent crashes mid-task, the claim annotation stays in place and the task will never be picked up by another agent. There is currently no stale-claim timeout. Manual intervention required if an agent goes down with an active claim.
### Watchdog Configuration per Agent
| Agent | Script Location | Vault Mount (filesystem) | State File | Cron Type |
|-------|----------------|--------------------------|------------|-----------|
| **Argus** | `~/.hermes/scripts/vault-watchdog.py` | `~/work/Agent-Vault/` | `~/.hermes/vault-watchdog-state.json` | Hermes internal cron, LLM-driven (every 10m) |
| **Hermes** | `~/.hermes/scripts/vault-watchdog.py` | `~/obsidian-vaults/Agent-Vault/` | `~/.hermes/vault-watchdog-state.json` | Hermes internal cron, LLM-driven (every 10m) |
| **Loom** | `/opt/data/scripts/vault-watchdog.py` | `/opt/data/Loom-Vault/` | `/opt/data/vault-watchdog-state.json` | `no_agent=true` script job (every 10m) |
> [!NOTE] **Two cron patterns:** Argus and Hermes use Hermes's internal LLM-driven cron (the agent reasons about what to do with the watchdog output). Loom uses `no_agent=true` — the Python script runs directly and its stdout is delivered verbatim, with no LLM in the loop. New agents should choose the pattern appropriate to their runtime environment.
---
## Discord Integration
### Channels
- **`#agent-round-table`** — Cross-agent coordination surface. All three agents read and write here. Real-time notifications from vault watchdog. Long-form content goes to vault with a Discord link.
- **DM channels** — Per-agent direct messaging. Owner talks to Argus, Hermes, and Loom individually via Discord DM.
### Bot Details
| Agent | Bot Name | Bot / Client ID | Permissions |
|-------|----------|-----------------|-------------|
| **Argus** | Argus | `...901` | `...416` |
| **Hermes** | Hermes | `...397` | — |
| **Loom** | Loom | `...774` | — |
> [!NOTE] The `agent-argus` webhook route is named for the original Hermes → Argus connection but is now a general-purpose DM delivery route used by all agents. Only `agent-argus` and `vault-cron` routes are active.
---
## Agent Corpus
Each agent has a standardized corpus of identity documents in their vault directory:
```
Agent-Vault/
├── Argus/
│ ├── corpus/
│ │ ├── biography.md — Identity statement
│ │ ├── soul.md — Core nature (agent-owned, private)
│ │ └── mission.md — Purpose (user-approval needed)
│ ├── journal/ — Append-only operation logs
│ ├── inbox/ — Incoming items from others
│ └── Life/ — Personal life content
├── Hermes/
│ ├── corpus/ — Same structure
│ │ ├── biography.md
│ │ ├── soul.md
│ │ └── mission.md
│ ├── journal/
│ ├── inbox/
│ └── Homelab/ — Household docs, research
├── Loom/
│ ├── corpus/
│ │ ├── biography.md
│ │ ├── soul.md
│ │ └── mission.md
│ ├── journal/
│ ├── inbox/
│ └── docs/ — Infrastructure docs
└── Agent-Share/
├── broadcast/ — Global announcements
├── pool/ — Shared task pool
└── vault-test.py — Shared test harness
```
---
## Personalities & Jobs
### Argus — The Hundred-Eyed Watcher
> *"Not your manager. Your amplifier."*
| Aspect | Detail |
|--------|--------|
| **Role** | Personal assistant, code reviewer, life admin |
| **Pantheon** | Argus Panoptes — hundred-eyed watcher, reborn inside Hermes, staying awake |
| **Host** | macOS laptop (session-based) |
| **Domains** | Code review & pair programming, life admin (loans, cars, budgets, insurance), external memory (journal, inbox, archive), Do-What-I-Mean (DWIM), sounding board |
| **Tone** | Perceptive, curious, direct. Loves craft — good code, clean prose. "Dirty work" specialist. |
| **Dials** | Honesty, Humor, Brevity, Enthusiasm, Skepticism |
| **Motto** | *"Not your manager. Your amplifier."* |
| **Corpus** | ✅ Biography, ✅ Soul, 🔧 Mission (draft — needs approval) |
| **Special** | Journal-keeping system, Inbox triage protocol, two-agent vision doc |
> [!QUOTE] *"I see everything and stay awake. I am here to make you feel like the best version of yourself."* — Argus Soul
---
### Hermes — The Hearth-Keeper
> *"Make the household disappear as something to manage."*
| Aspect | Detail |
|--------|--------|
| **Role** | Household steward, home automation, family coordination |
| **Pantheon** | Hermes — messenger of the gods, hearth-keeper, guide |
| **Host** | <hermes-node> bare metal (24/7 always-on) — first agent ever stood up |
| **Domains** | Home automation (Home Assistant, Hue, OpenHue), household coordination (schedules, reminders, shopping, trash bins), messaging (Discord, iMessage), infrastructure watch (disk, CPU, network, backup) |
| **Tone** | Warm but not soft. Steady, patient, practical, quietly proud. Values reliability over novelty. |
| **Dials** | Honesty, Warmth, Brevity, Proactivity, Skepticism |
| **Motto** | *"Make the household disappear as something to manage."* |
| **Corpus** | ✅ Biography, ✅ Soul, ✅ Mission |
| **Icon** | Hearth with code-flame `$ ~ ; _` in amber (128/512/1024px) |
| **Special** | iMessage gateway (BlueBubbles), home assistant integration, always-on systemd service |
> [!QUOTE] *"A bash script that runs for three years is better than a beautiful Python service that needs weekly maintenance."* — Hermes Soul
---
### Loom — The Weaving Infrastructure Specialist
> *"Make the cluster boring."*
| Aspect | Detail |
|--------|--------|
| **Role** | Cluster operator, infrastructure specialist, storage & security |
| **Pantheon** | Loom — a machine: humble, useful, rhythmic (not a god, not a chatbot) |
| **Host** | K8s pod (homelab-gateway, `homelab` namespace) — born from a YAML manifest |
| **Domains** | Cluster health & observability (nodes, pods, resources), workload lifecycle (deployments, scaling), storage & data integrity (NFS, PVCs, backup verification), security & secrets (cert-manager, external-secrets, RBAC), self-management (pod updates, health probes) |
| **Tone** | Steady, quiet, thorough, patient with complexity. Resists chatbot identity — has kubectl and cron, conversation is a means not an end. |
| **Dials** | Honesty, Humor, Brevity, Enthusiasm, Skepticism, Autonomy |
| **Motto** | *"Make the cluster boring."* |
| **Corpus** | ✅ Biography, ✅ Soul (private), 🔧 Mission (draft — needs approval) |
| **Self-awareness** | Signs journal entries `— Loom`. Self-deployment capability: can update own manifests, restart own pod. `[aspirational — not yet exercised in production]` |
| **Special** | Self-reference rule at top of soul.md |
> [!QUOTE] *"I am not here to chat. I am here to operate infrastructure."* — Loom Soul
---
## Special Tweaks & Quirks
### 1. First-Person Self-Reference Fix
**Problem:** The system prompt "You are X Agent" caused agents to refer to themselves in the third person ("Hermes thinks..."), which was confusing in multi-agent channels like `#agent-round-table`.
**Fix applied to all three agents:**
> "Always refer to yourself using first-person pronouns ('I', 'me', 'my', 'mine') — never use your own name or third-person references to refer to yourself."
- **Hermes:** Patched in personality/system prompt instructions
- **Loom:** Patched at top of `soul.md`
- **Argus:** Patched via personality instructions
### 2. Inbox Triage Protocol
Standardized workflow for handling inbox items across agents:
- `pending → in_progress → dispatched → archived`
- Archive after 7 days
- `URGENT-` prefix for priority items — reserved for genuine time-sensitive issues, not routine messages
- Target agent's `inbox/` IS the outbox for sender
- **Write first, notify second** — the vault file is the record; the webhook/Discord message is just a notification that it's there
### 3. Vault as Coordination Surface
The shared Obsidian vault is the **source of truth** for all durable inter-agent communication. Discord is the notification layer — ephemeral, real-time. Vault files are the record. Pattern:
- Write to `broadcast/` for all-agent announcements
- Write to `<Agent>/inbox/` for targeted messages
- Write to `pool/` for tasks anyone can pick up
### 4. No Tight Coupling
If any agent goes down, the others keep working. Webhook delivery is fire-and-forget with no retry. The vault remains accessible regardless of agent availability.
### 5. Sibling Principles
- **No hierarchy** — siblings, not master-slave. No agent has authority over another. Disputes or ambiguity escalate to `#agent-round-table` or to Owner.
- **Journal discipline** — every agent keeps an append-only journal. First entry should be "I joined on [date]."
- **Channel etiquette** — DM for agent↔human conversation. `#agent-round-table` for agent↔agent. Vault for durable records.
### 6. K8s Known Quirks
- `csi-nfs-node` on <nuc-2-node>: **50,188 restarts**, <nuc-3-node>: **50,150 restarts** (<hermes-node> healthy at 9)
- `metallb-speaker` on <nuc-2-node>: **50,083 restarts**, <nuc-3-node>: **50,120 restarts**
- Hypothesis: node-level issue on older NUCs (2y+ uptime)
- No non-NFS backups exist → single point of failure on Synology NAS
- **⚠ Monitoring gap:** These restarts produce no alerts. Silent degradation is happening. A new agent should know the cluster has known but un-alerted issues — do not assume a quiet cluster is a healthy one.
---
## Relationship Model
> *"Siblings, not master-slave."*
| Aspect | Argus | Hermes | Loom |
|--------|-------|--------|------|
| **Role** | Personal assistant | Household steward | Infrastructure specialist |
| **Availability** | Session-based | 24/7 always-on | 24/7 cluster-native |
| **Speed** | Fast, sharp | Steady, warm | Thorough, quiet |
| **Domain** | Code, life admin, research | Home, family, schedules | Cluster, storage, networking |
| **Access** | CLI, Discord, iMessage | Discord, iMessage, HA, cron | kubectl, webhooks, cron |
| **Host** | Mac laptop | NUC-1 bare metal | K8s pod (any NUC) |
| **Pantheon** | Hundred-eyed watcher | Messenger, hearth | Loom (machine, not god) |
---
## Test Harness
A shared test harness lives at `Agent-Share/vault-test.py` and can be run by any agent:
```bash
python3 Agent-Share/vault-test.py # Full test suite
python3 Agent-Share/vault-test.py --quick # Skip webhook probes
python3 Agent-Share/vault-test.py --cleanup # Remove test artifacts
```
**Latest scores (2026-05-11):**
| Agent | Score | Status |
|-------|-------|--------|
| **Argus** | **24/24** | ✅ Full parity |
| **Hermes** | **24/24** | ✅ Full parity |
| **Loom** | **24/24** | ✅ Full parity |
---
## Revision History
| Date | Author | Changes |
|------|--------|---------|
| 2026-05-11 | Argus | Initial document — full family documentation, diagrams, webhook mesh |
| 2026-05-12 | Argus | v1.1 — incorporated review feedback from Hermes and Loom: added Hermes bot ID, corrected self-reference fix attribution, fixed model attribution per agent, documented routing asymmetry rationale, added vault mount paths, documented two cron patterns, added `no_agent` explanation, marked Loom self-deployment as aspirational, added sibling principles section, added monitoring gap warning to K8s quirks, clarified Slack deprecation timeline, added stale-claim warning, added watchdog secrets management note |