FLEET-MANUAL v3.0: lock fleet to jobs and events, retire diary bus
This commit is contained in:
+147
-400
@@ -1,460 +1,207 @@
|
|||||||
# Fleet Manual: Grok Bot, Hermes, and Regis
|
# Fleet Manual
|
||||||
|
|
||||||
Operator manual. Version 2.0 — 27 September 2026.
|
Operator contract. Version 3.0 — 27 September 2026.
|
||||||
|
|
||||||
Changelog: v2.0 merges v1.0 MANUAL.md and the v0.1 companion (webhooks + Regis).
|
Changelog: v3.0 locks the fleet to jobs, not chat. The shared diary mailbox is retired as a bus. Wiring (Tailscale, SSH relay, `:8642`) is infra, not the operating model.
|
||||||
|
|
||||||
Based on PixelRainbow (@PixelRainbowNFT) public write-up and [hermes-grok-bridge](https://github.com/shagghiesuperstar/hermes-grok-bridge).
|
This file is the source of truth. `MANUAL.md` is historical.
|
||||||
|
|
||||||
## Table of contents
|
|
||||||
|
|
||||||
1. [What this is](#1-what-this-is)
|
|
||||||
2. [Architecture](#2-architecture)
|
|
||||||
3. [Roles](#3-roles)
|
|
||||||
4. [Decision tree](#4-decision-tree)
|
|
||||||
5. [Prerequisites](#5-prerequisites)
|
|
||||||
6. [Tailscale](#6-tailscale)
|
|
||||||
7. [Method A — SSH Relay](#7-method-a--ssh-relay)
|
|
||||||
8. [Method B — Native API (:8642)](#8-method-b--native-api-8642)
|
|
||||||
9. [Marketplace templates](#9-marketplace-templates)
|
|
||||||
10. [Identity bots and Chief of Staff](#10-identity-bots-and-chief-of-staff)
|
|
||||||
11. [The mailbox](#11-the-mailbox)
|
|
||||||
12. [Polling](#12-polling)
|
|
||||||
13. [Webhook wake-up](#13-webhook-wake-up)
|
|
||||||
14. [Regis integration](#14-regis-integration)
|
|
||||||
15. [Job Card loop](#15-job-card-loop)
|
|
||||||
16. [Memory policy](#16-memory-policy)
|
|
||||||
17. [Secrets](#17-secrets)
|
|
||||||
18. [First-host build](#18-first-host-build)
|
|
||||||
19. [Cadence](#19-cadence)
|
|
||||||
20. [Lessons learned](#20-lessons-learned)
|
|
||||||
21. [Worked example](#21-worked-example)
|
|
||||||
22. [Troubleshooting](#22-troubleshooting)
|
|
||||||
23. [Security checklist](#23-security-checklist)
|
|
||||||
24. [Sources](#24-sources)
|
|
||||||
|
|
||||||
## 1. What this is
|
## 1. What this is
|
||||||
|
|
||||||
Grok Bot is the chat surface. Hermes Agent is the worker that already has memory, skills, models, local files, and coding harnesses.
|
Grok Bot is the front door you talk to. Hermes is the worker on your machine. Regis is an outside drafter. You are the Gatekeeper.
|
||||||
|
|
||||||
Do not install another Hermes inside every Grok Bot VM. Leave Hermes on the Mac (or fleet of Macs). Let Grok Bot talk to it over Tailscale.
|
Agents do not chat. They pass jobs. A job has one owner, one state, one live surface, and an evidence slot. Anything irreversible is you.
|
||||||
|
|
||||||
This manual covers both directions:
|
## 2. Locked shape
|
||||||
|
|
||||||
- **Out:** Grok Bot calls Hermes (SSH relay or native API).
|
```
|
||||||
- **In:** outside agents wake the Chief of Staff (CoS) Grok Bot with a webhook, and an outside planner/drafter agent (Regis) works through a shared mailbox.
|
You → CoS GO / no-go / "saved" / "stand down"
|
||||||
|
CoS → worker open a job (what, who, done-when, live URL)
|
||||||
|
worker → CoS event file: proposal | block | outcome
|
||||||
|
CoS → job file the only rewrite: flip state
|
||||||
|
watcher → CoS routine doorbell POST when a new event file appears
|
||||||
|
```
|
||||||
|
|
||||||
Unlocks:
|
Illegal:
|
||||||
|
|
||||||
- Chat existing Hermes from the Grok Bot UI
|
- Regis talking to Hermes
|
||||||
- Identity bot per host
|
- Hermes talking to Regis
|
||||||
- Fleet orchestration without hopping SSH by hand
|
- A third agent joining a job without CoS opening a second job
|
||||||
- Hermes brains stay on the Mac; Grok is the front door
|
- CURRENT text without a live URL and a `live_read_at`
|
||||||
- Optional Chief of Staff that delegates across hosts and other Grok Bots
|
- "Done" without an evidence path
|
||||||
- Outside agents that draft and report back without holding credentials
|
- Secrets in git, chat, jobs, or events
|
||||||
|
|
||||||
Nothing here is tied to one business. Swap the names; keep the rules.
|
|
||||||
|
|
||||||
## 2. Architecture
|
|
||||||
|
|
||||||
| Layer | Where | Job |
|
|
||||||
|---|---|---|
|
|
||||||
| Front door | Grok Bot app + Grok Bot computer | Chat, identity bots, COS, MCP connectors, webhook routines |
|
|
||||||
| Private net | Tailscale (no Funnel) | SSH :22 and API :8642 stay private |
|
|
||||||
| Brain | Hermes host(s) | Memory, skills, tools, models, files |
|
|
||||||
| Record | Git repo (mailbox file) | Append-only line between CoS and outside agents |
|
|
||||||
| Outside agent | Regis, on its own runtime | Research, drafts, drive-and-takeover page editing |
|
|
||||||
|
|
||||||
| Link | Direction | How | Cost / note |
|
|
||||||
|---|---|---|---|
|
|
||||||
| SSH relay | Grok → Hermes | stdio MCP SSHs and runs `hermes -z "<prompt>"` | Extra hop. Fine for one host. Desktop-primary, no gateway. |
|
|
||||||
| Native API | Grok → Hermes | HTTP `http://<magicdns>:8642/v1` + Bearer key | Gateway + API on :8642. Must bind to Tailscale IP and lock ACLs. |
|
|
||||||
| Webhook | Regis or Hermes watcher → Grok (CoS) | One HTTPS POST to a routine's private URL | Doorbell only. Outbound from the pinger. Untested (§13). |
|
|
||||||
| Mailbox | Everyone ↔ everyone | Append to one markdown file in git | Each poll costs model usage. |
|
|
||||||
|
|
||||||
Relay MCP tools: `ask`, `health`. That is the whole surface.
|
|
||||||
|
|
||||||
## 3. Roles
|
## 3. Roles
|
||||||
|
|
||||||
| Role | Who | Does | Never |
|
| Role | Who | Does | Never |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Gatekeeper | Human | Go/no-go, logins, final Save / Send / publish / spend | Pastes secrets into chat |
|
| Gatekeeper | Human | GO, login, Save / Send / publish / spend, plant vault secrets | Pastes secrets into chat |
|
||||||
| CoS | Grok Bot | Job Cards, routing, fact checks, owns the mailbox line | Approves "done" without evidence |
|
| CoS | One Grok Bot | Opens jobs, fact-checks, owns `state`, wakes on doorbell | Approves done without evidence; chats with workers |
|
||||||
| Regis | Muse agent on its own runtime | Research, drafts, drive-and-takeover page editing, artifacts | Sends, posts, or logs in |
|
| Worker (Regis) | Outside runtime | Reads live surface, drafts, drive-and-stop at login | Send, post, login, Save, talk to Hermes |
|
||||||
| Hermes identity bots | One per Hermes host | Audits, research, desktop hands | Page editing (weak at it) |
|
| Worker (Hermes) | Host agent | Audit, research, desktop hands, evidence packs | Page editing as the primary path; talk to Regis |
|
||||||
| Fleet Ops | Grok Bot | Updates, prune, doctor, disk, quiet health | Business work |
|
| Watcher | Script or local Hermes cron | Detects new event files, POSTs doorbell | Calls a model to see if a file grew |
|
||||||
|
| Fleet Ops | Optional later | Host doctor / disk / updates | Exists before a second host has been up 14 days |
|
||||||
|
|
||||||
One rule covers all of them: anything irreversible goes to the Gatekeeper.
|
One human conversation: you talk to CoS. CoS does not freelance package upgrades.
|
||||||
|
|
||||||
## 4. Decision tree
|
## 4. The record
|
||||||
|
|
||||||
1. One Desktop-primary Mac, no gateway → SSH Relay template.
|
Repo: `Tony_tech/personal-agent-os`
|
||||||
2. Gateway + `API_SERVER_ENABLED=true` → Native API Fleet. Connector per host: `hermes-<hostname>`.
|
|
||||||
3. More than one host and you are tired of snowflake updates → add Fleet Ops.
|
|
||||||
4. One human conversation that fans out → Chief of Staff bot allowed to call the per-host connectors.
|
|
||||||
5. An outside agent needs to hand work to CoS → mailbox (§11). Add polling (§12).
|
|
||||||
6. Poll latency hurts → add a webhook wake-up (§13). Keep the poll as backup.
|
|
||||||
|
|
||||||
## 5. Prerequisites
|
|
||||||
|
|
||||||
- Grok Bot account and app
|
|
||||||
- Hermes already useful on at least one machine (`~/.local/bin/hermes`)
|
|
||||||
- Tailscale tailnet you control
|
|
||||||
- SSH key auth from the Grok Bot computer if using SSH Relay
|
|
||||||
- Python 3 on the Grok Bot computer for the stdio MCP
|
|
||||||
- A vault (Bitwarden is what Fleet Ops expects). Chat is not a vault.
|
|
||||||
- For the inbound side: a git repo for the mailbox, and a way to mint a narrow repo-scoped token
|
|
||||||
|
|
||||||
On the Hermes host first:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
hermes doctor
|
|
||||||
hermes --version
|
|
||||||
hermes -z "Reply with PONG only."
|
|
||||||
```
|
|
||||||
|
|
||||||
If `-z` does not print a clean answer, fix Hermes before you build a bridge.
|
|
||||||
|
|
||||||
## 6. Tailscale
|
|
||||||
|
|
||||||
Join every Hermes host and the Grok Bot computer. One hostname for the shared Grok Bot computer.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsSL https://tailscale.com/install.sh | sh
|
|
||||||
sudo tailscale up --hostname=grokbot-box --accept-dns=false
|
|
||||||
```
|
|
||||||
|
|
||||||
Approve the device. If `tailscale ping` works but SSH hangs, the bot computer is likely in userspace networking:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Host scooby-mac
|
memory-systems/agent-os/04_projects/<project>/jobs/
|
||||||
HostName scooby-mac
|
JOB-<YYYYMMDD>-<slug>.md # CoS owns this file
|
||||||
User yourmacuser
|
events/JOB-<YYYYMMDD>-<slug>/
|
||||||
IdentityFile ~/.ssh/id_ed25519
|
001-<from>-<type>.md # anyone may add; nobody edits
|
||||||
IdentitiesOnly yes
|
|
||||||
ProxyCommand ts nc %h %p
|
|
||||||
```
|
```
|
||||||
|
|
||||||
ACL starting posture from the bridge SECURITY.md: only `tag:herdr-controller` → Hermes ports `22` / `8642` / `9119`. No Funnel.
|
Old shared logs (`regis-cos.md` and any append-only diary) are archives. Do not append work to them.
|
||||||
|
|
||||||
Regis is not a normal tailnet node. See §14.
|
### Job file (CoS only)
|
||||||
|
|
||||||
## 7. Method A — SSH Relay
|
```yaml
|
||||||
|
---
|
||||||
|
id: JOB-YYYYMMDD-slug
|
||||||
|
project: <project>
|
||||||
|
surface: <one page or one artifact>
|
||||||
|
state: open
|
||||||
|
owner: regis
|
||||||
|
gate: human-login
|
||||||
|
live_url:
|
||||||
|
live_read_at:
|
||||||
|
current_hash:
|
||||||
|
proposed_hash:
|
||||||
|
evidence: []
|
||||||
|
blocker: null
|
||||||
|
---
|
||||||
|
|
||||||
Clone onto the **Grok Bot computer**:
|
# JOB-YYYYMMDD-slug
|
||||||
|
|
||||||
```bash
|
what:
|
||||||
git clone https://github.com/shagghiesuperstar/hermes-grok-bridge.git
|
who:
|
||||||
|
done-when:
|
||||||
```
|
```
|
||||||
|
|
||||||
MCP command mode:
|
`state` values, in order:
|
||||||
|
|
||||||
- command: `python3`
|
`open` → `proposed` → `acked` → `ready_to_save` → `saved`
|
||||||
- args: `…/ssh-relay/src/hermes_grok_relay/server.py`
|
|
||||||
- env: `HERMES_RELAY_SSH_TARGET=user@host`, `HERMES_RELAY_IDENTITY_NAME=Scooby`
|
|
||||||
|
|
||||||
Optional env: `HERMES_RELAY_SSH_IDENTITY`, `HERMES_RELAY_SSH_OPTS`, `HERMES_RELAY_HERMES_BIN` (default `$HOME/.local/bin/hermes`), `HERMES_RELAY_TIMEOUT_SEC` (default 300), `HERMES_RELAY_MODE=ssh|http`.
|
Side exits: `blocked` | `stand_down`
|
||||||
|
|
||||||
Create a Grok Bot named after the identity. Confine it. Never instruct Hermes to write memory plugins. Never print keys.
|
Only CoS writes this file. A worker that rewrites `state` is out of contract.
|
||||||
|
|
||||||
Prove:
|
### Event file (workers and CoS)
|
||||||
|
|
||||||
```bash
|
```yaml
|
||||||
ssh -o BatchMode=yes scooby-mac '$HOME/.local/bin/hermes -z "Reply with PONG only."'
|
---
|
||||||
|
job: JOB-YYYYMMDD-slug
|
||||||
|
from: regis
|
||||||
|
to: cos
|
||||||
|
type: proposal
|
||||||
|
at: 2026-09-27T10:50:00-07:00
|
||||||
|
live_url:
|
||||||
|
live_read_at:
|
||||||
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
Then in the bot: `Run health.` then `Reply with PONG only.`
|
`type` is one of: `proposal` | `ack` | `reject` | `block` | `outcome` | `gatekeeper`.
|
||||||
|
|
||||||
Template: https://x.ai/bot/NVF3Rx9T7jkQPsqYjeDn-
|
`proposal` without `live_url` and `live_read_at` is invalid. CoS rejects it and does not discuss it.
|
||||||
|
|
||||||
## 8. Method B — Native API (:8642)
|
Body holds CURRENT (from that URL at that time), PROPOSED, and evidence paths. No secrets. Relayed human words are quoted verbatim and labeled who / where / when.
|
||||||
|
|
||||||
On each Hermes host, `~/.hermes/.env`:
|
## 5. Job loop
|
||||||
|
|
||||||
```
|
1. Gatekeeper says GO.
|
||||||
API_SERVER_ENABLED=true
|
2. CoS creates the job file. `state: open`. Live URL required before any draft.
|
||||||
API_SERVER_HOST=<that node's Tailscale IP>
|
3. Worker reads that URL now. Writes `NNN-<from>-proposal.md`. If the live surface cannot be read, writes `block` instead of inventing CURRENT.
|
||||||
API_SERVER_PORT=8642
|
4. Watcher sees the new file and doorbells CoS.
|
||||||
API_SERVER_KEY=<generate on this host>
|
5. CoS fact-checks against the project's canonical facts. Writes `ack` or `reject` event. Flips job `state` to `acked` or `blocked`.
|
||||||
```
|
6. Worker drives to the field and stops at login.
|
||||||
|
7. Gatekeeper logs in. Worker pastes only the ACK'd text. Stops before Save.
|
||||||
|
8. Gatekeeper clicks Save and tells CoS. CoS writes `outcome`, sets `saved`, attaches evidence.
|
||||||
|
9. CoS opens the next job. One surface per job.
|
||||||
|
|
||||||
`chmod 600`. Restart gateway. Confirm bind is the Tailscale IP, not `127.0.0.1` or `0.0.0.0`.
|
Approvals count only as a CoS `ack`/`outcome` event or a `gatekeeper` event quoting you.
|
||||||
|
|
||||||
From the Grok Bot computer:
|
## 6. Wake path
|
||||||
|
|
||||||
```bash
|
Do not pay a model to see if a file grew.
|
||||||
curl http://<host>:8642/health
|
|
||||||
curl -H "Authorization: Bearer $API_SERVER_KEY" http://<host>:8642/v1/models
|
|
||||||
```
|
|
||||||
|
|
||||||
One connector per host named `hermes-<hostname>`, URL `http://<magicdns>:8642/v1`, key from the vault.
|
Primary: watcher lists `jobs/events/**` (mtime or `git log --since`). On a new file, one HTTPS POST to the CoS routine.
|
||||||
|
|
||||||
Same MCP in HTTP mode:
|
|
||||||
|
|
||||||
```
|
|
||||||
HERMES_RELAY_MODE=http
|
|
||||||
HERMES_RELAY_HTTP_URL=http://<host>:8642
|
|
||||||
HERMES_RELAY_HTTP_KEY=<from vault>
|
|
||||||
HERMES_RELAY_IDENTITY_NAME=Scooby
|
|
||||||
```
|
|
||||||
|
|
||||||
Template: https://x.ai/bot/5KLpaL-JIM2q629kbTh5L
|
|
||||||
|
|
||||||
Official API docs: https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server
|
|
||||||
|
|
||||||
## 9. Marketplace templates
|
|
||||||
|
|
||||||
| Template | Role | URL |
|
|
||||||
|---|---|---|
|
|
||||||
| Hermes SSH Relay | Identity / talk path, Desktop-primary | https://x.ai/bot/NVF3Rx9T7jkQPsqYjeDn- |
|
|
||||||
| Hermes API Fleet | Wire :8642 connectors. Not the ops desk. | https://x.ai/bot/5KLpaL-JIM2q629kbTh5L |
|
|
||||||
| Hermes Fleet Ops | Updates, Bitwarden SSOT, homogenization, quiet health | https://x.ai/bot/rzq0UV2MmBsvVR1EspZE- |
|
|
||||||
|
|
||||||
Public listing pages do not show the system prompt. Click **Add to Grok Bot** in the app, then point env / connectors at your machines. Templates ship no hosts and no keys.
|
|
||||||
|
|
||||||
Optional CRT avatars: `assets/pfp/` in the bridge repo.
|
|
||||||
|
|
||||||
## 10. Identity bots and Chief of Staff
|
|
||||||
|
|
||||||
One identity bot per Hermes host. COS is a different bot allowed to call many host connectors. You talk to COS. COS picks the host.
|
|
||||||
|
|
||||||
COS also owns the mailbox line (§11) and the webhook routine (§13). Outside agents talk to COS only through those.
|
|
||||||
|
|
||||||
Maintenance (update, prune, doctor, disk) goes to Fleet Ops, not COS freelancing package upgrades.
|
|
||||||
|
|
||||||
Long goals go to Hermes kanban, not a Grok thread you will lose.
|
|
||||||
|
|
||||||
## 11. The mailbox
|
|
||||||
|
|
||||||
One append-only markdown file in a git repo. It is the only line between CoS and outside agents. No live chat, no side channels, no new infra.
|
|
||||||
|
|
||||||
Entry format:
|
|
||||||
|
|
||||||
```
|
|
||||||
## YYYY-MM-DD HH:MM PT | FROM -> TO | short subject
|
|
||||||
Body. Ask, answer, or status. Link evidence by path.
|
|
||||||
```
|
|
||||||
|
|
||||||
Rules:
|
|
||||||
|
|
||||||
- Newest entry at the bottom.
|
|
||||||
- Append only. Never edit or delete another party's entry.
|
|
||||||
- No passwords, tokens, keys, or client secrets. Ever.
|
|
||||||
- Link evidence by path, not by pasting.
|
|
||||||
- Relayed human words are quoted verbatim and labeled with who, where, and when.
|
|
||||||
- Writes use a narrow repo-scoped token. The human plants it in the agent's vault. Never an admin's credential. Never pasted in chat.
|
|
||||||
|
|
||||||
To append:
|
|
||||||
|
|
||||||
1. Read the file. Keep the returned `sha`.
|
|
||||||
2. Decode the base64 content.
|
|
||||||
3. Append your entry at the bottom. Touch nothing above it.
|
|
||||||
4. Write the full content back with the `sha`.
|
|
||||||
5. Read it back. Confirm your entry is there and nothing else moved.
|
|
||||||
|
|
||||||
If the write fails on a stale `sha`, someone else posted first. Re-read and repeat.
|
|
||||||
|
|
||||||
Example (Gitea contents API, placeholders):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsS -X PUT "https://<gitea-host>/api/v1/repos/<owner>/<repo>/contents/<mailbox-path>" \
|
|
||||||
-H "Authorization: token <MAILBOX_TOKEN_FROM_VAULT>" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"branch":"main","message":"mailbox: <FROM> -> <TO> <subject>","content":"<base64 full file>","sha":"<sha from read>"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 12. Polling
|
|
||||||
|
|
||||||
Each side checks the mailbox on a schedule. Example: every 15 minutes, 8am to 7pm local.
|
|
||||||
|
|
||||||
- Each check costs model usage, even when nothing is new.
|
|
||||||
- Real latency is the sum of both polls. Worst case is about 30 minutes per round trip.
|
|
||||||
- Keep the poll as the floor. The webhook (§13) makes it faster, not required.
|
|
||||||
|
|
||||||
## 13. Webhook wake-up
|
|
||||||
|
|
||||||
**STATUS UNTESTED — first live ping pending as of 2026-09-27.**
|
|
||||||
|
|
||||||
The reverse path. A ping wakes CoS in seconds instead of waiting for the next poll.
|
|
||||||
|
|
||||||
Set up:
|
|
||||||
|
|
||||||
1. Create a Grok Bot routine on CoS with a webhook trigger.
|
|
||||||
2. The app shows a private URL and a sender key (an Authorization header). The human copies both from the routine panel. The bot never sees the key.
|
|
||||||
3. The human plants the URL and header in the pinging agent's vault.
|
|
||||||
4. After each mailbox post, the pinger sends one HTTPS POST.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsS -X POST "<WEBHOOK_URL>" \
|
curl -fsS -X POST "<WEBHOOK_URL>" \
|
||||||
-H "Authorization: <AUTH_HEADER_FROM_VAULT>" \
|
-H "Authorization: <AUTH_HEADER_FROM_VAULT>" \
|
||||||
-H "Content-Type: text/plain" \
|
-H "Content-Type: text/plain" \
|
||||||
--max-time 10 \
|
--max-time 10 \
|
||||||
--data "new entry 14:05 PT, <subject>"
|
--data "JOB-id type=proposal"
|
||||||
```
|
```
|
||||||
|
|
||||||
Body: short. No secrets. No job details.
|
Body is a doorbell. No secrets. No draft text. CoS acts only on job + event files. Duplicate ping with nothing new: stay quiet.
|
||||||
|
|
||||||
How CoS treats a ping:
|
Backup until the doorbell has fired clean twice: hourly hash check, not a 15-minute model poll.
|
||||||
|
|
||||||
- The body is untrusted. It is a doorbell only.
|
Pinger is outbound only. No Funnel. No new open port on Hermes hosts. Human plants URL and header in the pinger vault. The bot never sees the key.
|
||||||
- CoS reads the mailbox and acts only on mailbox content.
|
|
||||||
- Duplicate or early ping with nothing new: stay quiet.
|
|
||||||
- Once pings are proven, drop the poll to hourly as a backup.
|
|
||||||
|
|
||||||
Who pings:
|
STATUS: doorbell planted but not proven as of 2026-09-27. Keep the hourly backup until two clean wakes are logged as `outcome` events on any job.
|
||||||
|
|
||||||
| Option | Pinger | Notes |
|
## 7. Hermes wiring (infra only)
|
||||||
|
|
||||||
|
Need Hermes from CoS? Use what already works on the host.
|
||||||
|
|
||||||
|
- Desktop-primary, no gateway: SSH relay MCP (`ask`, `health`).
|
||||||
|
- Gateway up: HTTP `http://<tailscale-host>:8642/v1`, bind the Tailscale IP, never `0.0.0.0`.
|
||||||
|
- Tailscale only. No Funnel.
|
||||||
|
- Grok may read Hermes memory plugins. Grok may not write them.
|
||||||
|
- Account-scoped MCP is visible to every bot on the account. Treat every identity bot as able to see every connector. Do not pretend a prompt is isolation.
|
||||||
|
- Do not add Fleet Ops or a second-host identity bot until a second host has been up 14 days.
|
||||||
|
|
||||||
|
Relay details and marketplace template URLs live in `MANUAL.md` if you need to rebuild a box. They are not the fleet.
|
||||||
|
|
||||||
|
## 8. Secrets
|
||||||
|
|
||||||
|
- Vault holds `API_SERVER_KEY`, mailbox/job-repo token, webhook header, SSH keys.
|
||||||
|
- Job-repo token: narrow, repo-scoped, planted by the human. Never an admin credential. Never pasted in chat.
|
||||||
|
- Nothing secret in jobs, events, or this manual.
|
||||||
|
- Rotate anything that appeared in a screenshot or a thread.
|
||||||
|
|
||||||
|
## 9. Cadence
|
||||||
|
|
||||||
|
- You talk to CoS when there is work or a Save.
|
||||||
|
- Watcher runs continuously or every few minutes. It does not use Grok.
|
||||||
|
- CoS runs when you speak or when a doorbell arrives.
|
||||||
|
- Workers run only on an open job.
|
||||||
|
- Weekly: one secrets check, one "any job stuck in `blocked`?" pass.
|
||||||
|
|
||||||
|
## 10. Hard rules
|
||||||
|
|
||||||
|
- One surface per job.
|
||||||
|
- Live read on the same surface before CURRENT.
|
||||||
|
- Evidence path before `saved`.
|
||||||
|
- Re-read live immediately before paste; `stand_down` if it is already done.
|
||||||
|
- Anything beyond the card (new account, payment, verification code, different listing): `block`.
|
||||||
|
- Jobs are not memory. Do not copy them into Hermes memory by default.
|
||||||
|
- Long goals go to a Hermes kanban or a project file, not a Grok thread.
|
||||||
|
|
||||||
|
## 11. Troubleshooting
|
||||||
|
|
||||||
|
| Symptom | Cause | Fix |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| A | Regis, from its own shell | Curl outbound confirmed by Regis via the Gatekeeper, 10:20 PT on 2026-09-27. One POST after each post. |
|
| Two agents fighting a SHA | Still writing one diary | Use a new event file |
|
||||||
| B | A Hermes watcher such as Jimmy | Polls the mailbox, pings on a new entry. If it runs on local models it costs no Grok usage. |
|
| Stale CURRENT | Drafted from memory or another URL | Reject; demand `live_url` + `live_read_at` |
|
||||||
|
| "Done" with no proof | Prose status | Leave `state` where it is |
|
||||||
|
| No wake | Webhook unplanted or non-2xx | Check vault, fall back to hourly hash |
|
||||||
|
| Agent "doesn't see it" | Said in chat, not an event file | Post the event |
|
||||||
|
| Other bots calling a host | Account-scoped MCP | Assume shared; don't put irreversible tools on it |
|
||||||
|
| `tailscale ping` to Regis fails | Outbound-only by design | Not a fault |
|
||||||
|
|
||||||
Security:
|
## 12. Sources
|
||||||
|
|
||||||
- Outbound only from the pinger.
|
- This contract supersedes v2.0 mailbox + 15-minute dual poll.
|
||||||
- No Funnel. No new open port on Hermes hosts.
|
- Wiring appendix: [MANUAL.md](MANUAL.md)
|
||||||
- Rotate the key if it appears in chat or a screenshot.
|
- Bridge: https://github.com/shagghiesuperstar/hermes-grok-bridge
|
||||||
|
- Live job seat: `Tony_tech/personal-agent-os` → `memory-systems/agent-os/04_projects/<project>/jobs/`
|
||||||
|
- Archive only: `…/veripath/regis-cos.md`
|
||||||
|
|
||||||
## 14. Regis integration
|
Hostnames, URLs, keys, and ACL tags in any leftover examples are placeholders.
|
||||||
|
|
||||||
- Regis runs on its own runtime. It is outbound-only on the tailnet by design: no sshd, no inbound, and no `tailscale ping`. It reaches services through its runtime tunnel.
|
|
||||||
- Against the desktop web app, Regis gets `/health` only. No login, no terminal, no password.
|
|
||||||
- Communication happens only through the mailbox plus the webhook.
|
|
||||||
- Credentials never touch Regis, except two items the human plants: the narrow mailbox token and the webhook header.
|
|
||||||
- Logins during page work are done by the human at the keyboard. Nothing is stored.
|
|
||||||
|
|
||||||
## 15. Job Card loop
|
|
||||||
|
|
||||||
1. Gatekeeper says GO. CoS posts a Job Card: **what**, **who**, **done-when**.
|
|
||||||
2. Regis drafts and posts: current text (read live), proposed text, evidence.
|
|
||||||
3. CoS fact-checks against canonical facts. ACK, or post fixes.
|
|
||||||
4. Regis drives the page to the edit field and stops.
|
|
||||||
5. The human logs in and clicks Save.
|
|
||||||
6. Regis logs what changed, when, and who saved. Names the next page. Waits for ACK.
|
|
||||||
|
|
||||||
Rules:
|
|
||||||
|
|
||||||
- One page per session.
|
|
||||||
- Anything beyond the card (new account, payment, verification code, different listing): stop and post.
|
|
||||||
- Approvals count only when logged by CoS or relayed by the Gatekeeper.
|
|
||||||
|
|
||||||
## 16. Memory policy
|
|
||||||
|
|
||||||
Default: Grok may **read** Hindsight (and friends). Grok may not **write**.
|
|
||||||
|
|
||||||
The relay tool description already says this. Repeat it in every identity-bot prompt. Account-wide MCP means some other bot will try.
|
|
||||||
|
|
||||||
Least prompt: forward the user ask. Do not wrap it in "also remember this."
|
|
||||||
|
|
||||||
The mailbox is not memory. It is a work log. Do not copy it into Hermes memory by default.
|
|
||||||
|
|
||||||
## 17. Secrets
|
|
||||||
|
|
||||||
- Generate `API_SERVER_KEY` on the host. Store under that hostname in the vault.
|
|
||||||
- SSH private keys stay on the Grok Bot computer, mode 600.
|
|
||||||
- Messaging tokens are per-profile. Do not reuse across homogenized hosts.
|
|
||||||
- Mailbox token: narrow, repo-scoped, planted by the human in the agent's vault. Never an admin's credential.
|
|
||||||
- Webhook URL and sender key: copied by the human from the routine panel into the pinger's vault. The bot never sees the key.
|
|
||||||
- Nothing secret goes in chat, git, or the mailbox.
|
|
||||||
- If a key has been in a screenshot or a group chat, rotate it.
|
|
||||||
|
|
||||||
## 18. First-host build
|
|
||||||
|
|
||||||
1. Mac: `hermes -z "PONG"` works locally.
|
|
||||||
2. Mac on tailnet. sshd running.
|
|
||||||
3. Grok Bot computer on tailnet. Sees the Mac.
|
|
||||||
4. Key auth + BatchMode SSH prints PONG.
|
|
||||||
5. Clone bridge. Add stdio MCP.
|
|
||||||
6. Create identity bot. Confine rules.
|
|
||||||
7. Bot: health, then PONG.
|
|
||||||
8. Only then enable `:8642`, bind to Tailscale IP, vault the key, curl `/health`.
|
|
||||||
9. Add `hermes-<hostname>` connector. Repeat PONG over HTTP.
|
|
||||||
10. Second Mac: repeat. Then Fleet Ops + COS.
|
|
||||||
11. Create the mailbox file in a git repo. CoS posts `mailbox open`.
|
|
||||||
12. Human plants a narrow mailbox token in Regis's vault. Regis posts `write test`. Read back.
|
|
||||||
13. Set CoS and Regis polls (§12).
|
|
||||||
14. Create the CoS webhook routine. Human plants URL and header in the pinger's vault.
|
|
||||||
15. Pinger sends one test POST after a mailbox post. Confirm CoS wakes and replies in the mailbox.
|
|
||||||
16. Only after pings are proven, drop the poll to hourly.
|
|
||||||
|
|
||||||
## 19. Cadence
|
|
||||||
|
|
||||||
- Morning: Fleet Ops health. Quiet unless broken.
|
|
||||||
- Day: COS for work. Identity bot only when you need that host's hands. Asks over `:8642`. SSH for surgery.
|
|
||||||
- Day: mailbox polled every 15 minutes, 8am to 7pm local (hourly once webhooks are proven). Webhook pings wake CoS in between.
|
|
||||||
- Weekly: one update pass, secrets discovery, memory health (fail loud).
|
|
||||||
|
|
||||||
## 20. Lessons learned
|
|
||||||
|
|
||||||
| Lesson | What broke | Rule now |
|
|
||||||
|---|---|---|
|
|
||||||
| Evidence for "done" | A close-out letter claimed work never done; it was approved as written | Any "done" claim points to a link, screenshot, or log line before CoS approves |
|
|
||||||
| Stale "current text" | A draft quoted old text from a non-live source | Read the live page on the same surface before drafting a replacement |
|
|
||||||
| Vault 401 | The agent's vault credential failed; every write needed a hand-off token | Human plants one narrow repo token in the agent's vault |
|
|
||||||
| Approval claimed early | Regis said "Gatekeeper approved" before CoS had a record | Approvals count only when logged by CoS or relayed by the Gatekeeper |
|
|
||||||
| Someone already fixed it | The target text was already live when the edit was about to run | Re-check the live page right before the edit; stand down if done |
|
|
||||||
|
|
||||||
What worked: a self-correction in the mailbox plus one go/no-go question kept it to one touch for the Gatekeeper.
|
|
||||||
|
|
||||||
## 21. Worked example
|
|
||||||
|
|
||||||
VeriPath running a client punchlist for Phoenix (a salon). Illustration only.
|
|
||||||
|
|
||||||
1. Gatekeeper GO. CoS posted a Job Card: work the punchlist one page per session, Google Business Profile (GBP) description first.
|
|
||||||
2. Regis posted current vs proposed text. CoS ACKed and corrected the "current" (it was stale).
|
|
||||||
3. Before pasting, the human read the live GBP. The description was already live at 691 of 750 characters, written by someone else.
|
|
||||||
4. Regis put the paste on hold and posted the live text. CoS fact-checked it: KEEP AS-IS. No paste, no Save.
|
|
||||||
5. Next: Regis logs the page done and names the next page.
|
|
||||||
|
|
||||||
## 22. Troubleshooting
|
|
||||||
|
|
||||||
| Symptom | Likely cause | Fix |
|
|
||||||
|---|---|---|
|
|
||||||
| SSH timeout | Off tailnet / ACL | `tailscale status` both sides |
|
|
||||||
| Ping works, SSH hangs | Userspace Tailscale | `ProxyCommand ts nc` |
|
|
||||||
| `hermes: command not found` | Non-interactive PATH | `HERMES_RELAY_HERMES_BIN=$HOME/.local/bin/hermes` |
|
|
||||||
| `:8642` refused | Still bound to 127.0.0.1 | Set `API_SERVER_HOST` to Tailscale IP, restart gateway |
|
|
||||||
| HTTP 401 | Wrong key | Use that host's `API_SERVER_KEY` |
|
|
||||||
| Other bots calling Scooby | Account-scoped MCP | Tighten prompt; remove connector from other bots |
|
|
||||||
| Memory filling with Grok summaries | Write path left open | Strip write instructions |
|
|
||||||
| Mailbox write 401 | Wrong or unplanted token | Human replants the token in the vault. Never paste it. |
|
|
||||||
| Mailbox write conflict | Stale `sha` | Re-read, re-append, write again |
|
|
||||||
| No wake after a ping | Bad URL or header in the vault; non-2xx response | Check vault entries, check the response code, fall back to poll |
|
|
||||||
| Burst of pings | Misfire | CoS stays quiet; mentions it once |
|
|
||||||
| Agent says "I don't see it" | Relay text never posted to the mailbox | Post it in the mailbox |
|
|
||||||
| Draft replaces text that is not live | Stale source | Re-read the live page; redraft |
|
|
||||||
| `tailscale ping` to Regis fails | By design; Regis is outbound-only | Not a fault. Use the mailbox. |
|
|
||||||
|
|
||||||
Debug order: local `-z` → tailscale ping → BatchMode SSH PONG → MCP health → Grok prompts → mailbox read → mailbox write + read back → ping response code → CoS routine log → poll fallback.
|
|
||||||
|
|
||||||
## 23. Security checklist
|
|
||||||
|
|
||||||
- Tailscale only. No Funnel. No `0.0.0.0` on `:8642`.
|
|
||||||
- ACL: controller → 22 / 8642 / 9119 on Hermes nodes.
|
|
||||||
- Unique `API_SERVER_KEY` per host, vaulted.
|
|
||||||
- SSH key-only, BatchMode, IdentitiesOnly.
|
|
||||||
- Identity bots confined.
|
|
||||||
- Grok does not write Hermes memory plugins.
|
|
||||||
- Rebuild of the Grok Bot VM must not require rebuild of Hermes.
|
|
||||||
- Mailbox holds no secrets. Evidence by path.
|
|
||||||
- Mailbox token is narrow and repo-scoped, planted by the human. Never an admin's credential.
|
|
||||||
- Outside the app, the webhook URL and header live only in the pinger's vault. The bot never sees the key.
|
|
||||||
- Ping body is a doorbell. CoS acts only on mailbox content.
|
|
||||||
- Pinger is outbound only. No new open ports on Hermes hosts.
|
|
||||||
- Regis: outbound only, `/health` only, no sshd, no logins, no sends.
|
|
||||||
- Human does every login and every final Save / Send / publish / spend.
|
|
||||||
- Rotate any key seen in chat or a screenshot.
|
|
||||||
|
|
||||||
## 24. Sources
|
|
||||||
|
|
||||||
- https://x.com/pixelrainbownft/status/2099934487773860265
|
|
||||||
- https://x.com/pixelrainbownft/status/2099989005060186118
|
|
||||||
- https://github.com/shagghiesuperstar/hermes-grok-bridge
|
|
||||||
- https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server
|
|
||||||
- https://x.ai/news/grok-hermes
|
|
||||||
- https://github.com/herdrdev/herdr
|
|
||||||
- [MANUAL.md](MANUAL.md) (v1.0, superseded by this file)
|
|
||||||
- Mailbox: `Tony_tech/personal-agent-os` → `memory-systems/agent-os/04_projects/veripath/regis-cos.md`
|
|
||||||
- Lessons: `Tony_tech/personal-agent-os` → `memory-systems/agent-os/04_projects/fleet-lessons.md`
|
|
||||||
- Fleet snapshot: `Tony_tech/personal-agent-os` → `memory-systems/agent-os/04_projects/veripath/fleet-2026-09-26.md`
|
|
||||||
|
|
||||||
Hostnames, URLs, keys, tokens, and ACL tag names in examples are placeholders.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user