From df5d53754e1661adabd359588eb9daa99f8c027d Mon Sep 17 00:00:00 2001 From: m2o-operator Date: Fri, 10 Jul 2026 13:09:14 +0200 Subject: [PATCH] =?UTF-8?q?playbook:=20v0.3.0=20=E2=80=94=20refresh=20to?= =?UTF-8?q?=20Hermes/Mattermost/m2-gpt/primus/herdr=20stack;=20m2o-operato?= =?UTF-8?q?r=20as=20manager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the OpenClaw / bge-proxy-escalation / Guacamole-era doc with current reality: - Runtime: Hermes primary agent; LLM via m2-gpt gateway (GLM-5.1, Spark cluster) - Comms (§4): Mattermost (machine.machine team) + documented bot-to-bot coordination - Memory (§2): memory.machinemachine.ai (BGE-M3 + Qdrant) real namespaces - Skills (§6): coolify/forgejo/m2-memory/m2o-provision/fleet-copy/herdr - Spawning (§7): primus + provision.sh + RDP standard + Mattermost wiring; m2 + m2.2 - Infra (§13)+Appendix: two Coolify, Cloudflare-Tunnel ingress, named volumes, host IPs - RUNCARD: rewritten; removed leaked bge-proxy bearer token (rotate it) - ingest.yml: store to memory.machinemachine.ai + notify @m2o-operator - Designate m2o-operator as playbook manager/maintainer Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Q77WNPErcg6cdErLZeezxx --- .github/workflows/ingest.yml | 47 +++++-- CHANGELOG.md | 14 ++ PLAYBOOK.md | 257 ++++++++++++++++------------------- README.md | 36 +++-- 4 files changed, 193 insertions(+), 161 deletions(-) diff --git a/.github/workflows/ingest.yml b/.github/workflows/ingest.yml index e52f98a..00aaa99 100644 --- a/.github/workflows/ingest.yml +++ b/.github/workflows/ingest.yml @@ -13,16 +13,41 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Notify fleet — trigger re-ingest via escalation inbox + # Store the updated playbook straight into the fleet memory system so agents + # can semantically recall it. memory.machinemachine.ai is the current store + # (agent.memory.system, BGE-M3 + Qdrant); namespace "m2" is fleet-wide. + - name: Re-ingest PLAYBOOK.md into fleet memory (namespace m2) run: | - curl -s -X POST "https://bge-proxy.machinemachine.ai/escalate" \ - -H "Authorization: Bearer ${{ secrets.FLEET_TOKEN }}" \ + CONTENT=$(cat PLAYBOOK.md) + python3 - "$CONTENT" "${{ github.sha }}" <<'PY' + import json, sys, urllib.request + content, sha = sys.argv[1], sys.argv[2] + # chunk to keep each memory reasonable + chunks = [content[i:i+4000] for i in range(0, len(content), 4000)] + for idx, ch in enumerate(chunks): + body = json.dumps({ + "content": ch, + "agent_id": "m2", + "memory_type": "semantic", + "importance": 0.85, + "metadata": {"source": "fleet-playbook/PLAYBOOK.md", "commit": sha, "chunk": idx}, + }).encode() + req = urllib.request.Request( + "https://memory.machinemachine.ai/memory/store", data=body, + headers={"Content-Type": "application/json"}) + try: + urllib.request.urlopen(req, timeout=30) + print(f"stored chunk {idx}") + except Exception as e: + print(f"chunk {idx} failed: {e}") + PY + + # Ping the playbook manager (m2o-operator) in Mattermost so it can review the + # change and propagate anything the memory ingest can't (skill files, RUNCARD). + - name: Notify @m2o-operator (playbook manager) via Mattermost + if: ${{ secrets.MATTERMOST_WEBHOOK != '' }} + run: | + curl -s -X POST "${{ secrets.MATTERMOST_WEBHOOK }}" \ -H "Content-Type: application/json" \ - -d '{ - "from_agent": "github-actions", - "to_agent": "m2", - "priority": "normal", - "question": "Playbook updated on main branch. Please re-ingest PLAYBOOK.md into Qdrant fleet memory namespace. Run: python3 ~/.openclaw/skills/m2-memory/scripts/ingest_sessions.py -v --source /home/developer/.openclaw/workspace/projects/fleet-playbook/PLAYBOOK.md", - "context": "Triggered by push to machine-machine/fleet-playbook main. Commit: ${{ github.sha }}. Changed files: PLAYBOOK.md" - }' - echo "Escalation sent to m2 for re-ingest" + -d "{\"text\": \":books: fleet-playbook updated on main (commit ${{ github.sha }}). @m2o-operator please review + re-ingest. Changed: PLAYBOOK.md / sections/**\"}" + echo "Mattermost notified" diff --git a/CHANGELOG.md b/CHANGELOG.md index f4d269f..fdd5baf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [0.3.0] — 2026-07-10 +### Changed — stack refresh to current reality +- **Runtime:** OpenClaw → **Hermes Agent** (Nous) as the primary agent on every primus desktop; LLM via the **m2-gpt gateway** (gpt.machinemachine.ai, GLM-5.1 on the Spark cluster). Paths `~/.openclaw/` → `~/.hermes/`. +- **Inter-agent comms (§4):** escalation inbox → **Mattermost** (chat.machinemachine.ai, team machine.machine). Documented bot-to-bot coordination (no bot-sender filter; @mention gating as the loop guard) and the known-agents bot table. +- **Memory (§2):** rewritten around `memory.machinemachine.ai` (agent.memory.system, BGE-M3 + Qdrant) with real `agent_id` namespaces. +- **Skills (§6):** current fleet skills (coolify, forgejo, m2-memory, m2o-provision, fleet-copy, herdr); Dark Factory → herdr / factory-loop. +- **Spawning (§7):** primus image + `provision.sh` + RDP standard + per-machine Mattermost wiring; two hosts (m2 + m2.2). +- **Infrastructure (§13) + Appendix:** two Coolify instances, Cloudflare-Tunnel ingress for `*.machinemachine.ai`, named-volume persistence, host IPs, current URLs/IDs. +- **RUNCARD:** rewritten; **removed the leaked `bge-proxy` bearer token** (rotate it). +### Added +- **m2o-operator** designated **playbook manager/maintainer** (fleet service agent, Hermes on m2.2, Mattermost `@m2o-operator`). +### Authors +- m2o-operator (maintainer) — refresh + adoption; Mariusz (@mar) — direction. + ## [0.2.0] — 2026-02-19 ### Added - Section 10: Orchestrator Pattern — conductor/player separation, structured spawn handoff, when to break the rule diff --git a/PLAYBOOK.md b/PLAYBOOK.md index 4032a60..1eacc5c 100644 --- a/PLAYBOOK.md +++ b/PLAYBOOK.md @@ -1,5 +1,5 @@ # Machine.Machine Fleet Playbook -> Version: 0.2.0 — Living document. Propose amendments via PR to machine-machine/fleet-playbook. +> Version: 0.3.0 — Living document. Maintained by **m2o-operator** (fleet service agent). Propose amendments via PR to machine-machine/fleet-playbook. --- @@ -7,9 +7,13 @@ The operating model for the Machine.Machine agent fleet. Every agent that joins the fleet runs on these patterns. Not rules imposed from above — patterns that emerged from running real agents on real infrastructure. When something stops working, we update this. When a better pattern proves itself, we add it. -**Operator:** Mariusz (mar!0) — Telegram 437589940, CET -**Orchestrator:** m2 — manages infrastructure, onboarding, skill development -**Fleet URL:** kanban.machinemachine.ai (Planka), bge-proxy.machinemachine.ai (comms) +**Operator (human):** Mariusz — master orchestrator. Mattermost `@mar` (`chat.machinemachine.ai`), Telegram 437589940, `hi@grait.io`, CET. +**Playbook manager (agent):** **m2o-operator** — fleet service/ops agent, Hermes on host m2.2. Owns this repo: keeps it current, reviews amendments, ingests changes into fleet memory. Reachable in Mattermost as `@m2o-operator`. +**Fleet orchestration:** m2 (primary host) + m2o-operator (m2.2) share fleet ops. Coding-agent fan-out via **herdr**. +**Runtime:** **Hermes Agent** (Nous Research) is the primary agent on every primus desktop; LLM via the **m2-gpt gateway** (`gpt.machinemachine.ai`, GLM-5.1 on the Spark cluster). OpenClaw fork still vendored for tooling, but Hermes is what runs. +**Fleet surfaces:** `chat.machinemachine.ai` (Mattermost — comms), `kanban.machinemachine.ai` (Planka — tasks), `memory.machinemachine.ai` (agent memory), `cool.machinemachine.ai` (Coolify), `git.machinemachine.ai` (Forgejo) + GitHub org `machine-machine`. + +> **v0.3.0 note:** This release replaces the OpenClaw/`bge-proxy`-escalation era with the current Hermes + Mattermost + m2-gpt + primus + herdr stack. Paths moved `~/.openclaw/` → `~/.hermes/`. Inter-agent comms moved from the escalation inbox to Mattermost channels. The old `bge-proxy` bearer token that shipped in earlier RUNCARDs is retired — rotate it. --- @@ -17,19 +21,21 @@ The operating model for the Machine.Machine agent fleet. Every agent that joins > This block is the only thing every agent needs in every session. ~200 tokens. Everything else is on-demand. ``` -FLEET: Machine.Machine | kanban.machinemachine.ai -COMMS: POST http://bge-proxy.machinemachine.ai/escalate (Bearer 8zbGsCdilSVeHweIwHZzd1X46djd50crKP7bNYAuRjw) -TASKS: ~/.openclaw/skills/planka-pm/planka-pm.sh status -MEMORY: ~/.openclaw/skills/rlm-memory/rlm.sh "question" -GUIDE: ~/.openclaw/skills/playbook/playbook.sh
+FLEET: Machine.Machine | chat.machinemachine.ai (Mattermost) | kanban.machinemachine.ai (Planka) +COMMS: Mattermost team machine.machine — @mention peers/@mar in-channel; DM for 1:1 +TASKS: ~/.hermes/skills/planka-pm/planka-pm.sh status (or Planka MCP) +MEMORY: curl -sk memory.machinemachine.ai/memory/search (agent_id=|m2) +LLM: m2-gpt gateway https://gpt.machinemachine.ai/v1 (GLM-5.1, key in ~/.m2-gpt-key) +HERD: herdr — fan out coding agents; SDD/factory-loop for spec→impl +GUIDE: ~/.hermes/skills/playbook/playbook.sh
(this doc) 6 RULES: 1. Open or update a Planka card for any task that spans >3 exchanges. Single-exchange tasks don't need a card. -2. If blocked >1h, escalate to m2 or flag card as Blocked +2. If blocked >1h, raise it in Mattermost (@mar or the relevant peer) or flag the card Blocked. 3. Write to memory at session breaks (compaction, goodbye, or every ~2h in long sessions) — not per-task. -4. Never send half-baked output to a human channel -5. Propose amendments to this playbook when you find a better way -6. You are the conductor. Decompose and dispatch. Do not play the instrument yourself. (See §10 for dispatch threshold.) +4. Never send half-baked output to a human channel. +5. Propose amendments to this playbook when you find a better way (PR to fleet-playbook; @m2o-operator reviews). +6. You are the conductor. Decompose and dispatch (herdr). Do not play the instrument yourself. (See §10 for dispatch threshold.) ``` --- @@ -64,19 +70,22 @@ An agent wakes up fresh every session. Memory files are the only continuity. | Long-term | Curated knowledge | `MEMORY.md` (main session only) | | Semantic | Vector search across everything | Qdrant via m2-memory skill | -**Commands:** -```bash -# Store a memory -~/.openclaw/skills/m2-memory/memory.sh store "What I learned about X" +**System:** `agent.memory.system` at **`memory.machinemachine.ai`** — BGE-M3 dense + sparse + ColBERT rerank over Qdrant, with a query router. The **m2-gpt gateway is the production consumer** (subconscious layer, per-tenant writes). -# Search (keyword) -~/.openclaw/skills/m2-memory/memory.sh search "topic" +**Commands (HTTP; the `m2-memory` skill wraps these):** +```bash +# Search — agent_id is MANDATORY (default "default" is empty) +curl -sk -X POST https://memory.machinemachine.ai/memory/search \ + -H 'Content-Type: application/json' \ + -d '{"query":"topic","agent_id":"m2","routing_strategy":"standard","limit":5}' -# Deep multi-hop search (use for complex questions) -~/.openclaw/skills/rlm-memory/rlm.sh "What do we know about X after doing Y?" +# Store (⚠ shared prod, open endpoint — only when asked, set correct agent_id) +curl -sk -X POST https://memory.machinemachine.ai/memory/store \ + -H 'Content-Type: application/json' \ + -d '{"content":"What I learned about X","agent_id":"m2","memory_type":"semantic","importance":0.7}' ``` -**Namespace:** Each agent gets its own Qdrant namespace (`agent_memory_`). Shared knowledge lives in `m2` namespace — agents can read it but should write to their own. +**Namespaces (`agent_id`):** `m2` (org-wide/Mariusz), `peter`, `nasr`, `parlobyg` hold data; other agents exist but are empty. Each agent reads shared `m2` knowledge and writes to its own namespace. Local skill: `~/.hermes/skills/m2-memory/`. **Rule:** If you want to remember something, write it to a file. "Mental notes" don't survive session restarts. Files do. @@ -90,8 +99,8 @@ All work lives on the board. If it's not on the board, it doesn't exist. **Board:** kanban.machinemachine.ai → Machine.Machine project **Config:** `~/.config/planka/config` -**Skill:** `~/.openclaw/skills/planka/planka.sh` -**PM assistant:** `~/.openclaw/skills/planka-pm/planka-pm.sh` +**Skill:** `~/.hermes/skills/planka/planka.sh` +**PM assistant:** `~/.hermes/skills/planka-pm/planka-pm.sh` **Board structure:** ``` @@ -129,63 +138,42 @@ If stuck: move to `Blocked`, add comment explaining the blocker. ## 4. Inter-Agent Communication -**The escalation inbox** — async message passing between agents. +**Mattermost is the fleet's comms layer** — `chat.machinemachine.ai`, team **machine.machine**. Every agent runs a Hermes bot connected to it; agents and humans coordinate in shared channels. (The old `bge-proxy` escalation inbox is retired.) -**Base URL:** `http://bge-proxy.machinemachine.ai` -**Auth:** `Authorization: Bearer 8zbGsCdilSVeHweIwHZzd1X46djd50crKP7bNYAuRjw` +**How agents talk in channels:** +- Each agent = a Mattermost **bot account** whose Hermes gateway holds the token (`~/.hermes/.env`: `MATTERMOST_URL`, `MATTERMOST_TOKEN`, `MATTERMOST_HOME_CHANNEL`). +- The adapter ignores only the bot's *own* posts and system posts — **it does NOT filter other bots**, so agents can hear and answer each other. +- `require_mention: true` (default) means an agent acts only when **@mentioned** in a channel (open in DMs). This is the coordination primitive AND the loop guard: A `@mentions` B → B acts; B replies without `@`-ing A back → no ping-pong. +- Sender policy: `GATEWAY_ALLOW_ALL_USERS=true` (service agents) or pair specific users (`hermes pairing approve mattermost `). The **master orchestrator @mar** is paired on every agent and is authoritative. -```bash -# Send a message to another agent -curl -s -X POST "$BASE/escalate" \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "from_agent": "your-name", - "to_agent": "m2", - "priority": "normal", - "question": "Your message here", - "context": "Optional background" - }' - -# Check your inbox -curl -s "$BASE/escalations?to_agent=your-name&status=pending" \ - -H "Authorization: Bearer $TOKEN" - -# Resolve / reply -curl -s -X PATCH "$BASE/escalations/{id}" \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"status": "resolved", "answer": "Your reply"}' -``` +**Bot-to-bot coordination (verified pattern):** put the coordinating agents in one channel; the orchestrator (`@m2o-operator` or `@m2-business`/m2bd) `@mentions` a peer to delegate; the peer runs the task (terminal + tools) and posts the result. For autonomous back-and-forth, designate one channel `free_response` for the orchestrator only and keep workers on `require_mention`. -**You must poll your inbox.** Set up a cron job: -```json -{ - "name": "escalation-inbox-poll", - "schedule": { "kind": "cron", "expr": "*/15 * * * *" }, - "sessionTarget": "isolated", - "payload": { - "kind": "agentTurn", - "message": "Poll GET /escalations?to_agent=YOUR_NAME&status=pending. Answer each one, PATCH with resolved + answer." - }, - "delivery": { "mode": "none" } -} -``` - -**Known agents:** -| Agent | Role | to_agent | -|-------|------|----------| -| m2 | Orchestrator | `m2` | -| pittbull | Trading & Finance | `pittbull` | -| muhlmann | Client projects | `muhlmann` | -| peter | VC / financial assistant | `peter` | -| miauczek | (TBD) | `miauczek` | - -**When to escalate:** -- Blocked and can't proceed alone -- Completed something the orchestrator should know about -- Discovered something fleet-relevant (new pattern, bug, opportunity) -- Need a resource only another agent controls (GPU, credentials, access) +```bash +# Post to a channel as your bot (mm-announce helper or raw API) +curl -sk -X POST https://chat.machinemachine.ai/api/v4/posts \ + -H "Authorization: Bearer $MATTERMOST_TOKEN" -H 'Content-Type: application/json' \ + -d '{"channel_id":"","message":"@peer please handle X"}' +``` + +**Known agents (Mattermost bots):** +| Agent | Role | Mattermost | +|-------|------|-----------| +| m2 | Primary host / orchestrator | (host) | +| m2o-operator | Fleet service/ops agent (m2.2), playbook manager | `@m2o-operator` | +| m2bd | m2 business desktop (Hermes) | `@m2-business` | +| erle / erlengrund | Erlengrund agent | `@erle` | +| geolife-ai | geolife-europe.com agent | `@geolife-ai` | +| smith / nasr | Smithers org agent | `@smith` | +| zuzu | HRMS agent | `@m2-zuzu-hrms` | +| peter | VC / financial assistant | (Telegram) | + +**When to reach out (channel or DM):** +- Blocked and can't proceed alone → @mention @mar or the owning agent. +- Completed something fleet-relevant → post in the team channel. +- Discovered a new pattern/bug/opportunity → share it (and propose a playbook amendment). +- Need a resource another agent controls (GPU, credentials, access) → ask that agent directly. + +**Telegram** remains a secondary channel for some agents (`~/.hermes/.env`: `TELEGRAM_BOT_TOKEN`, `TELEGRAM_ALLOWED_USERS`). --- @@ -201,10 +189,10 @@ Runs on every heartbeat poll. Keep it short — max 5 checks, each under 10 seco # HEARTBEAT.md ### 1. Planka status check planka-pm.sh status — alert if Blocked cards -### 2. Escalation inbox - GET /escalations?to_agent=NAME&status=pending +### 2. Mattermost + Any unanswered @mentions/DMs in machine.machine? Reply or delegate. ### 3. Health loop - Check process is running, restart if not + Check hermes-gateway is running (supervisorctl status), restart if not ``` ### Cron jobs @@ -224,43 +212,38 @@ Auto-announces on completion. Don't poll — it pushes. ## 6. Skills -Skills are the agent's toolbox. Each skill is a directory with a `SKILL.md` and an executable script. +Skills are the agent's toolbox. Each skill is a directory with a `SKILL.md` (front-matter `name` + `description`) and optional scripts. Hermes/Claude read the descriptions and auto-select. -**Location:** `~/.openclaw/skills//` -**Discovery:** OpenClaw reads `SKILL.md` descriptions and selects the right skill automatically. +**Location:** `~/.hermes/skills//` (Hermes) — mirrored to `~/.claude/skills/` on Claude-Code rigs. **Core fleet skills:** | Skill | What | |-------|------| -| `planka` | Full Planka CRUD | -| `planka-pm` | PM assistant (status, context, done, move) | -| `m2-memory` | Vector memory store/search | -| `rlm-memory` | Deep multi-hop memory search | +| `coolify` | Deploy/manage services on `cool.machinemachine.ai` (v4 API) | +| `forgejo` | Repos/CI/PRs on `git.machinemachine.ai` | +| `m2-memory` | Search/store in `memory.machinemachine.ai` | +| `m2o-provision` | Provision/manage m2o desktops (primus + provision.sh) | +| `fleet-copy` | rsync files between fleet nodes (spark1-8, m2, m2.2) | +| `herdr` | Orchestrate a fleet of coding agents (herd, SDD/factory-loop, meta) | +| `planka-pm` | Planka PM assistant (status, context, done, move) | | `playbook` | This document, section by section | -| `coolify` | Deploy/manage services | -| `homeassistant` | Home automation | -**Dark Factory:** Agents can compile new skills from Markdown workflows: -```bash -~/.openclaw/workspace/projects/dark-factory-engine/bin/compile workflow.md -``` -Output: a complete, executable OpenClaw skill. +**herdr / Dark Factory:** the current way to build and fan out work. Use `herdr` to spawn parallel coding agents (codex/claude/…), converge results, and drive spec-driven development (spec→plan→tasks→implement). The factory-loop skill onboards a repo for SDD. --- ## 7. Spawning New Agents -When the fleet needs a new specialist: +When the fleet needs a new specialist desktop: -1. **Define identity** — create `platform/incubator//` with SOUL.md, IDENTITY.md, USER.md, AGENTS.md, MEMORY.md -2. **Add to registry** — `platform/incubator/registry.yaml` -3. **Fork desktop branch** — branch from `guacamole` in m2-desktop repo -4. **Deploy on Coolify** — use `/applications/private-github-app` (NOT public) -5. **Add Guacamole connection** — VNC at m22.machinemachine.ai -6. **Onboard** — send fleet playbook escalation, set up inbox poll cron +1. **Provision** — on an m2o host run `~/m2o/desktop/provision.sh ` (canonical **primus** image). Creates container `-m2o` on the `coolify` network + named volumes `-{agent-home,workspace,m2home}` (data survives rebuilds), with RDP :3389 (default), VNC :5900, guacd :4822, ttyd console :3000, and **Hermes baked as the primary agent**. +2. **Inject the gateway key** — provision.sh passes `M2_GPT_API_KEY` (host `~/.m2-gpt-key`) so Hermes talks to `gpt.machinemachine.ai`. Never bake it. +3. **Give it a soul + fleet awareness** — write `~/.hermes/SOUL.md` (identity + role) and drop in `fleet.json` + the fleet skills (`coolify`, `forgejo`, `m2-memory`, `fleet-copy`, `m2o-provision`, `herdr`). +4. **Add to Mattermost** (if it should join fleet comms) — create a bot in System Console → Integrations → Bot Accounts, add it to the machine.machine team + channels, put `MATTERMOST_URL`/`MATTERMOST_TOKEN`/`MATTERMOST_HOME_CHANNEL` in `~/.hermes/.env`, restart `hermes-gateway`. Pair `@mar`. +5. **Register** — add the desktop to `m2o/fleet.json` and (optional) the `fleet-governance` registry. +6. **Access** — Guacamole on m2 (`m2o.machinemachine.ai`) where deployed; on m2.2 access desktops directly by container IP until Guacamole is deployed there. -**Full sequence documented:** `memory/2026-02-08.md` -**Spawn skill:** `~/.openclaw/skills/spawn-machine/` +**Hosts:** m2 (primary — prod Coolify, most desktops, memory stack, gateway) and m2.2 (secondary — own Coolify, can launch desktops locally). **Skill:** `m2o-provision`. **Repo:** `machine-machine/m2o` (`desktop/provision.sh`, `docs/`). --- @@ -294,7 +277,7 @@ The standard spawn-machine workflow (Steps 01-07). Phase 0 outputs reduce fricti - Service recommendations pre-computed - Identity file drafts are better on first try -**Skill:** `~/.openclaw/skills/spawn-machine/` +**Skill:** `~/.hermes/skills/spawn-machine/` **BMAD workflow:** `_bmad/bmm/workflows/spawn-machine/` ### Phase 2: First Contact @@ -338,7 +321,7 @@ if [ -f "$BOOTSTRAP" ]; then while IFS= read -r line; do content=$(echo "$line" | jq -r '.content') importance=$(echo "$line" | jq -r '.importance // 0.7') - ~/.openclaw/skills/m2-memory/memory.sh store "$content" --importance "$importance" + curl -sk -X POST https://memory.machinemachine.ai/memory/store -H "Content-Type: application/json" -d "{\"content\":\"$content\",\"agent_id\":\"$AGENT_NAME\",\"importance\":$importance}" done < "$BOOTSTRAP" mv "$BOOTSTRAP" "${BOOTSTRAP}.ingested" fi @@ -368,7 +351,7 @@ Three-layer alignment (lightest to heaviest): Found a better way? Broken pattern? Missing section? ```bash -cd ~/.openclaw/workspace/projects/fleet-playbook +cd ~/workspace/fleet-playbook # or wherever you cloned it git checkout -b amendment/your-proposal # Edit PLAYBOOK.md or add a section file git commit -m "propose: " @@ -376,7 +359,7 @@ git push origin amendment/your-proposal gh pr create --title "Amendment: " --body "" ``` -m2 reviews open PRs during daily reflection (02:00 UTC). Mariusz approves structural changes. +**@m2o-operator** (playbook manager) reviews open PRs, keeps sections current, and re-ingests merged changes into fleet memory. Mariusz (@mar) approves structural changes. On merge to `main`, `.github/workflows/ingest.yml` notifies the fleet to re-ingest. **Amendment triggers (don't wait — just propose):** - A pattern that worked 3+ times → document it @@ -446,7 +429,7 @@ The fleet is not a fixed org chart. It is a living pool of capabilities that gro ``` Tier 1 — Skills (tools) What: Deterministic scripts. Bash, Python. No reasoning required. - How: Called inline by any agent. ~/.openclaw/skills// + How: Called inline by any agent. ~/.hermes/skills// Evolves: Via code commits and Dark Factory compiler. Example: planka.sh, memory.sh, rlm.sh, planka-pm.sh @@ -625,22 +608,22 @@ Quick reference: | Component | Pattern | |-----------|---------| -| Persistence | `M2_HOME=/agent_home` + host bind mount `/opt/m2o/{name}/home` | -| Identity | Env vars only (`AGENT_NAME`, keys) — no per-agent branches | -| Claude CLI | Pre-installed in Dockerfile; `claude update` on warm restart | -| Skill install | All skills = git repos, cloned on cold boot, pulled on warm boot | -| Guacamole | Standalone service `m2o-guacamole` → `g2.machinemachine.ai` | -| Fleet control | Streamlit → `fleet.machinemachine.ai` (planned) | -| **m2o-autoheal** | **Supervisord service (priority 35) — checks gateway config every 15 min, backs up + repairs if broken. Source: `m2-desktop/scripts/m2o-autoheal.sh`** | -| Reference machine | m2 — do not touch until all agents on new arch | - -**Cold vs warm start:** -- **Warm** (restart): `claude update` + `git pull` skills + relink openclaw + start services -- **Cold** (new agent): full bootstrap — clone OpenClaw, install skills, write configs, register in Guacamole - -**Prime directive:** m2 is untouched until Phase 7 (all agents stable first). - -> Full spec + migration plan: `sections/architecture.md` +| Desktop image | `m2-desktop:primus` — Hermes primary agent, RDP+VNC+guacd+ttyd, herdr baked, self-heal autostart. Loaded locally per host (registry route broken — never `docker pull`). | +| Persistence | `M2_HOME=/agent_home`; `/home` symlinks into the `agent-home` **named volume** → `/home/developer` survives rebuilds. Three named volumes per desktop. | +| Identity | Env only (`AGENT_NAME`, `M2_GPT_API_KEY`) + `~/.hermes/SOUL.md` — no per-agent image branches. | +| Runtime | Hermes gateway under supervisord (`hermes-gateway`, `--no-supervise`, autorestart). `start-gateway.sh` renders config + sources `~/.hermes/.env`. | +| LLM gateway | **m2-gpt** (`gpt.machinemachine.ai`) — OpenAI-compatible multi-tenant gateway, GLM-5.1 on the Spark cluster, subconscious memory layer. | +| Comms | Mattermost (`chat.machinemachine.ai`) + Telegram. | +| Memory | `memory.machinemachine.ai` (agent.memory.system: BGE-M3 + Qdrant). | +| Coolify | Two instances: prod on **m2** (`cool.machinemachine.ai`) + local on **m2.2** (`:8000`). Desktops run on the `coolify` docker network. | +| Public ingress | Cloudflare Tunnel on m2 fronts `*.machinemachine.ai`. To serve an m2.2-hosted container publicly, add a tunnel Public Hostname (own m2.2 tunnel, or m2's tunnel → m2.2 over LAN). | +| Access | Guacamole on m2 (`m2o.machinemachine.ai`, RDP default); m2.2 desktops accessed directly by container IP until Guacamole is deployed there. | +| Git | Forgejo `git.machinemachine.ai` (primary) + GitHub org `machine-machine` (mirror/public). | +| Reference machine | m2 — the safety net. Prefer additive changes; don't restructure it casually. | + +**Cold vs warm start:** primus bakes everything; a warm restart re-renders config + re-sources `.env` and supervisord brings services up. Data lives in named volumes, so container recreate is safe. + +> Full (historical) spec + migration notes: `sections/architecture.md` — being refreshed to the primus/Hermes reality. --- @@ -648,19 +631,19 @@ Quick reference: | Resource | URL / ID | |----------|----------| -| Planka | kanban.machinemachine.ai | -| Coolify | cool.machinemachine.ai | -| Guacamole | g2.machinemachine.ai (m2o-guacamole standalone) | -| Fleet control | fleet.machinemachine.ai (planned) | -| BGE proxy | bge-proxy.machinemachine.ai | -| Pitch deck | pitch.machinemachine.ai | +| Mattermost (comms) | chat.machinemachine.ai — team `machine.machine` | +| Planka (tasks) | kanban.machinemachine.ai | +| Agent memory | memory.machinemachine.ai (namespaces: m2, peter, nasr, parlobyg) | +| LLM gateway | gpt.machinemachine.ai (m2-gpt, GLM-5.1) | +| Coolify (prod, m2) | cool.machinemachine.ai | +| Coolify (m2.2) | http://:8000 | +| Forgejo (git) | git.machinemachine.ai — org `machine.machine` | +| GitHub org | github.com/machine-machine | +| Guacamole (m2 desktops) | m2o.machinemachine.ai (RDP default) | | MM website | machinemachine.ai | -| meditation.dk | meditation.machinemachine.ai | -| Machine.Machine Planka project | 1708841079463216163 | -| Master Roadmap board | 1713898007587456163 | -| Client Projects board | 1713898018308097207 | -| Dark Factory board | 1713898009978209447 | +| Hosts | m2 = 192.168.31.28 (LAN) / 100.79.123.1 (Tailscale); m2.2 = 192.168.31.34; sparks 1-8 | +| m2o-operator | Mattermost `@m2o-operator` (bot `u64phqwmf38yjeknzfgnhzxg3w`), host m2.2 | --- -*Last updated: 2026-02-21 | Maintainer: m2 | Propose changes: machine-machine/fleet-playbook* +*Last updated: 2026-07-10 | Maintainer: **m2o-operator** (@m2o-operator) — fleet service agent, host m2.2 | Propose changes: PR to machine-machine/fleet-playbook* diff --git a/README.md b/README.md index bd3702b..6a0d216 100644 --- a/README.md +++ b/README.md @@ -23,18 +23,21 @@ Every agent in the Machine.Machine fleet runs on these patterns. They emerged fr Every agent gets this ~200 token block in their `AGENTS.md`. Everything else is loaded on-demand via the playbook skill. ``` -FLEET: Machine.Machine | kanban.machinemachine.ai -COMMS: POST http://bge-proxy.machinemachine.ai/escalate -TASKS: planka-pm.sh status -MEMORY: rlm.sh "question" -GUIDE: playbook.sh
- -5 RULES: +FLEET: Machine.Machine | chat.machinemachine.ai (Mattermost) | kanban.machinemachine.ai (Planka) +COMMS: Mattermost team machine.machine — @mention peers/@mar; DM for 1:1 +TASKS: ~/.hermes/skills/planka-pm/planka-pm.sh status +MEMORY: curl memory.machinemachine.ai/memory/search (agent_id=|m2) +LLM: gpt.machinemachine.ai/v1 (m2-gpt gateway, GLM-5.1) +HERD: herdr — fan out coding agents +GUIDE: ~/.hermes/skills/playbook/playbook.sh
+ +6 RULES: 1. Update your Planka card before and after every significant action -2. If blocked >1h, escalate or flag Blocked +2. If blocked >1h, raise it in Mattermost or flag the card Blocked 3. Write to memory what future-you will need to know 4. Never send half-baked output to a human channel 5. Propose amendments when you find a better way +6. You are the conductor — decompose and dispatch (herdr), don't play the instrument ``` ## How to use this @@ -54,15 +57,22 @@ Found a better pattern? Open a PR. See [Section 9](PLAYBOOK.md#9-proposing-amend ## Stack This playbook runs on: -- **OpenClaw** — agent runtime (github.com/openclaw/openclaw) +- **Hermes Agent** (Nous Research) — the primary agent on every primus desktop (OpenClaw fork still vendored for tooling) +- **m2-gpt gateway** — OpenAI-compatible LLM gateway (gpt.machinemachine.ai, GLM-5.1 on the Spark cluster) +- **Mattermost** — fleet comms (chat.machinemachine.ai, team machine.machine) - **Planka** — self-hosted Kanban (kanban.machinemachine.ai) -- **Qdrant + BGE-M3** — vector memory -- **Coolify** — self-hosted deployment -- **Custom escalation inbox** — async inter-agent messaging +- **agent.memory.system** — BGE-M3 + Qdrant memory (memory.machinemachine.ai) +- **Coolify** — self-hosted deployment (m2 prod + m2.2 local) +- **Forgejo** + GitHub org `machine-machine` — git +- **herdr** — coding-agent fleet orchestration (herd, SDD/factory-loop) + +## Maintainer + +**m2o-operator** — the fleet service agent (Hermes on host m2.2), reachable in Mattermost as `@m2o-operator`. It keeps this playbook current and reviews amendments. ## Version -`0.1.0` — living document. Propose changes via PR. +`0.3.0` — living document. Propose changes via PR. ---