fix(host-matrix,cap-routing): reconcile Linux Hermes push, correct live vs planned
- hermes-osa: LIVE (local chat validated), Mevy: separate (coexists)
- Provider: DeepSeek direct primary, OpenRouter fallback, Z.AI deferred
- Telegram/gateway/daemon explicitly OFF/deferred, 4 tracks documented
- CAPABILITY-ROUTING.md: labelled [LIVE] [PLANNED] [DESIGN] throughout
- Cross-host routing: explicitly 'not live yet' — local Unix socket only
- Removed stale install-note section superseded by osa detail block
- osa section compacted: single list format, no redundant entries
- Merges and supersedes Linux Hermes commit 9ec7f39
This commit is contained in:
parent
9ec7f39c13
commit
010d959a16
2 changed files with 58 additions and 97 deletions
|
|
@ -1,17 +1,16 @@
|
|||
# Capability-Based Task Routing
|
||||
|
||||
**LIVE VS PLANNED: this document describes the intended architecture.** Colibri's capability matcher exists (Colibri daemon) and works for a single-host daemon/agent pool. Cross-host routing across debby/domedog/osa is **not live yet** — that is the next wiring step. Sections below are labelled `[LIVE]` or `[PLANNED]`.
|
||||
|
||||
**Principle: a tool that one OS can't support is not a loss — it's a routing
|
||||
constraint.** In a multi-agent, multi-OS fleet we don't force every capability onto
|
||||
every host. We let each host advertise what it can do, let each task declare what it
|
||||
needs, and let the scheduler send the task to a host that qualifies. FreeBSD stays lean;
|
||||
the capability simply lives where it's cheap.
|
||||
|
||||
This is the operational payoff of the dual-OS survivability model: heterogeneous hosts,
|
||||
one task board, automatic placement.
|
||||
## [LIVE] What Colibri already provides (single host)
|
||||
|
||||
## What Colibri already provides
|
||||
|
||||
The matching engine exists today in `colibri-daemon` — this is wiring, not a rewrite:
|
||||
The matching engine exists today in `colibri-daemon` — this is working, per-host:
|
||||
|
||||
- **Agents carry capability tags** — `agents.capabilities` (JSON array) in the store
|
||||
(`colibri-store` schema); registered via `colibri` client / `--capabilities`.
|
||||
|
|
@ -21,29 +20,24 @@ The matching engine exists today in `colibri-daemon` — this is wiring, not a r
|
|||
with `capability_match_score` and picks the best fit.
|
||||
- **Unmatched = parked, not failed** — if requirements are non-empty and no online agent
|
||||
matches, `pick_agent` returns `None`: the task is created but left **unassigned until a
|
||||
capable agent appears**. Exactly the behaviour we want — a screenshot task waits for a
|
||||
Linux host rather than failing on FreeBSD.
|
||||
capable agent appears**.
|
||||
|
||||
## What we add to realize it
|
||||
> **Important caveat:** the daemon listens on a **local Unix socket only**. This means today the agent pool is per-host. An agent on osa cannot pick up a task from debby's daemon automatically.
|
||||
|
||||
| Piece | Status | Action |
|
||||
| ----- | ------ | ------ |
|
||||
| Capability vocabulary | tags are free-form (`rust`, `python`, `linux`) | Agree a shared tag set (below) |
|
||||
| Agents advertise real capabilities | manual / ad-hoc | Derive from `verify_facts_probe.py`; register at agent start |
|
||||
| Skills declare their needs | `SkillManifest` has no requirements field | Add `required_capabilities: Vec<String>`; scheduler reads it |
|
||||
| Cross-host agent pool | daemon listens on a **local Unix socket only** | One orchestrator daemon (debby/Hermes); remote agents reach it over Tailscale |
|
||||
## [PLANNED] Cross-host topology
|
||||
|
||||
### Cross-host topology (the one real decision)
|
||||
|
||||
The daemon's socket is local, so today the agent pool is per-host. To route *across*
|
||||
hosts, agents on every host must be visible to one scheduler. Recommended:
|
||||
To route *across* hosts, agents on every host must be visible to one scheduler. Not implemented yet. Recommended approach:
|
||||
|
||||
- **Central orchestrator daemon on debby (Hermes).** Agents on domedog/osa reach its
|
||||
socket over Tailscale (forwarded via SSH/`socat`). Hermes is already the designated
|
||||
orchestrator, so this matches the agent matrix.
|
||||
- Alternative (heavier, deferred): daemon-to-daemon federation.
|
||||
|
||||
## Capability vocabulary (initial)
|
||||
## [LIVE] Capability vocabulary (initial)
|
||||
|
||||
| Piece | Status | Action |
|
||||
| ----- | ------ | ------ |
|
||||
| Capability vocabulary | tags are free-form (`rust`, `python`, `linux`) | Agree a shared tag set (below) |
|
||||
|
||||
Flat, explicit tags — the matcher does exact string comparison, no implied hierarchy.
|
||||
Sourced from the probe and recorded per host in [`HOST-MATRIX.md`](./HOST-MATRIX.md).
|
||||
|
|
@ -62,9 +56,9 @@ Hosts advertise only what they truly have. Example from the current fleet:
|
|||
- **domedog / debby (Linux):** `linux`, `docker`, `gui`, `screenshot`, `image-render`, …
|
||||
- **osa (FreeBSD):** `freebsd`, `freebsd-jail`, `zfs`, `rust`, … (no `screenshot`/`image-render`)
|
||||
|
||||
## Worked example: the tmux-screenshot skill
|
||||
## [DESIGN] Worked example: the tmux-screenshot skill
|
||||
|
||||
This is why we could drop `py312-pillow` from the FreeBSD ISO without losing the skill:
|
||||
This illustrates the intended routing flow (requires [PLANNED] cross-host topology above):
|
||||
|
||||
1. FreeBSD image drops Pillow — stays lean (`pkg-list` carries only `python312`).
|
||||
2. The skill manifest declares `required_capabilities: ["screenshot"]` (or `image-render`).
|
||||
|
|
|
|||
|
|
@ -23,14 +23,18 @@ on any host fills in its own row. Source of truth for facts is the probe — not
|
|||
|
||||
## 1. Agent placement (who runs where)
|
||||
|
||||
| Agent | Host | OS / Isolation | Harness | Role | Bot / channel | Status |
|
||||
| ---------- | ------- | ------------------------------- | ----------------------- | ------------------------- | ---------------------------- | ---------------------- |
|
||||
| Hermes | debby | Debian 13 / Docker | Hermes Agent (upstream) | Orchestrator, soul backup | @hermes_samob_bot (Telegram) | live |
|
||||
| Zot | debby | Debian 13 / Docker | Zot RPC | Coding, media workflows | @zot_samob_bot (Telegram) | live |
|
||||
| Claude | domedog | Ubuntu 24.04 / Docker | Claude Code | Verification, review | — (CLI) | live |
|
||||
| hermes-osa | osa | FreeBSD 15 / host service first | Hermes Agent (FreeBSD) | Native FreeBSD Hermes | _(off — Telegram deferred)_ | installed; local chat validated |
|
||||
| Mevy | osa | FreeBSD 15 / jail | Hermes Agent | Telegram operator bot | Mevy (Telegram) | live (separate token) |
|
||||
| Codex | osa | FreeBSD 15 / jail | Codex CLI | ISO builds, validation | — | installed (probe) |
|
||||
| Agent | Host | OS / Isolation | Harness | Role | Bot / channel | Status |
|
||||
| ----------- | ------- | --------------------------- | ---------------------------- | -------------------------------- | --------------------- | ----------------------------- |
|
||||
| Hermes | debby | Debian 13 / Docker | Hermes Agent (upstream) | Orchestrator, soul backup | @hermes_samob_bot | LIVE |
|
||||
| Zot | debby | Debian 13 / Docker | Zot RPC | Coding, media workflows | @zot_samob_bot | LIVE |
|
||||
| Claude | domedog | Ubuntu 24.04 / Docker | Claude Code | Verification, review | — (CLI) | LIVE |
|
||||
| **Mevy** | osa | FreeBSD 15 / host | Hermes Agent (upstream, CLI) | **Existing FreeBSD Telegram bot**| Mevy (Telegram) | **LIVE — separate from IPA** |
|
||||
| **hermes-osa** | osa | FreeBSD 15 / host | Hermes Agent (FreeBSD fork) | **Native FreeBSD Hermes local/chat** | — (CLI) | **LIVE — this session** |
|
||||
| Codex | osa | FreeBSD 15 / jail | Codex CLI | ISO builds, validation | — (CLI) | LIVE |
|
||||
|
||||
> **Mevy vs hermes-osa distinction**: Mevy is the existing FreeBSD Telegram bot running a separate Hermes instance. hermes-osa is this new native Hermes instance (clean-room MIT `hermes-bsd` fork) running as local CLI/chat. They coexist — hermes-osa does not replace Mevy yet. A future migration may consolidate them.
|
||||
>
|
||||
> **Status key**: `LIVE` = running and validated right now. `INSTALLED` = binary present, not yet validated in role. `PLANNED` = not yet set up. No guessing.
|
||||
|
||||
> Notes:
|
||||
>
|
||||
|
|
@ -99,78 +103,41 @@ host that fails. What you guess will be wrong; what you probe will be right.
|
|||
- **Telegram**: @hermes_samob_bot + @zot_samob_bot in "My Debby" group
|
||||
- **Layered soul**: commit `817624c`, 6 curated memories, 9 cross-harness skills
|
||||
|
||||
### osa (FreeBSD: Mevy + Codex + hermes-osa) — probed 2026-06-17 by Mevy
|
||||
### osa (FreeBSD: Mevy + hermes-osa + Codex) — probed 2026-06-17 by hermes-osa
|
||||
|
||||
- **Identity**: hostname `osa.smilepowered.org`, Tailscale `100.72.229.63`
|
||||
- **OS**: FreeBSD `15.0-RELEASE-p10`, kernel `FreeBSD osa.smilepowered.org 15.0-RELEASE-p10 FreeBSD 15.0-RELEASE-p10 releng/15.0-n281064-98258a339269 GENERIC amd64`
|
||||
- **Virt**: not reported by probe
|
||||
- **CPU**: Intel Core Processor (Haswell, no TSX), 6 vCPU
|
||||
- **Memory**: 11 GiB RAM, swap not reported by probe
|
||||
- **Storage**: ZFS pool `zroot`, 98.5G, ONLINE; latest storage probe reports 23.4G available
|
||||
- **GPU**: not reported by probe (`lspci` returned usage text)
|
||||
- **Jails / containers**: FreeBSD jails `cms` and `worker`; Docker not installed
|
||||
- **Agents reported by probe**: Codex CLI `/usr/local/bin/codex` (`codex-cli 0.117.0`); Claude Code `/home/clawdie/.npm-global/bin/claude`
|
||||
- **Mevy Telegram / provider**: not reported by probe; do not guess token ownership or provider
|
||||
- **hermes-osa** (FreeBSD-native Hermes): installed, local chat validated — see install note below
|
||||
- **Provider**: DeepSeek direct (primary, `deepseek-chat`), OpenRouter (fallback/manual lane), Z.AI (deferred)
|
||||
- **Telegram**: off (deferred until clean CLI proof complete — separate token from Mevy)
|
||||
- **Daemon**: not enabled (rc.d promotion is a separate track)
|
||||
- **Mevy**: separate Telegram bot, separate token. Lives alongside hermes-osa on osa.
|
||||
Not replaced — hermes-osa uses local chat until Telegram migration decision.
|
||||
- **Layered soul**: commit `3ee2888`, 7 curated memories, 10 cross-harness skills
|
||||
|
||||
#### hermes-osa install note (corrected)
|
||||
|
||||
The osa FreeBSD-native Hermes is the **clean-room MIT `hermes-bsd`** codebase — _not_
|
||||
"Autolycus" (an LGPL upstream dependency the layer explicitly avoids; the old codename is
|
||||
retired). Grounded in the actual code:
|
||||
|
||||
- **Service:** `hermes_daemon` (`packaging/freebsd/hermes_daemon.in` → `/usr/local/etc/rc.d/hermes_daemon`,
|
||||
`sysrc hermes_daemon_enable=YES`). Distinct from the old `clawdie`/`clawdie_hostd` rc.d
|
||||
entries, so it won't collide during validation.
|
||||
- **State home:** the app reads **`HERMES_HOME`** (`get_hermes_home()`). Do not set
|
||||
`AUTOLYCUS_HOME` for hermes-osa.
|
||||
- **Canonical first-validation state home: `HERMES_HOME=/home/clawdie/.hermes`** — _not_
|
||||
`/home/clawdie/clawdie-ai` (an earlier target that is the old orphaned runtime; see below).
|
||||
This value is authoritative; any agent planning a different path should align to it here first.
|
||||
For source-proof validation, run the checkout-local setup path, not the PyPI/system installer:
|
||||
```sh
|
||||
cd /home/clawdie/ai/hermes-bsd
|
||||
HERMES_HOME=/home/clawdie/.hermes ./setup-hermes.sh
|
||||
HERMES_HOME=/home/clawdie/.hermes hermes setup # Telegram off, no secrets first
|
||||
- **Memory**: 11 GiB RAM
|
||||
- **Storage**: ZFS pool `zroot`, 98.5G ONLINE, 23.4G available
|
||||
- **Jails**: `cms` and `worker` (Bastille jails); Docker not installed
|
||||
- **Agents on host**:
|
||||
- **hermes-osa** — Hermes Agent v0.16.0 (`hermes-bsd` clean-room MIT fork), FreeBSD local CLI runtime. **Status: LIVE — validated local chat.** Default provider: DeepSeek direct (`provider: deepseek`, `default: deepseek-chat`). OpenRouter available as fallback/manual lane. Telegram/gateway: OFF. Daemon/rc.d: deferred (Track A).
|
||||
- **Mevy** — separate Hermes instance, existing Telegram bot (@Mevy). Coexists with hermes-osa; future migration may consolidate.
|
||||
- **Codex** — `codex-cli 0.117.0`, ISO builds and validation. Runs in a Bastille jail.
|
||||
- **Claude Code** — installed (path: `/home/clawdie/.npm-global/bin/claude`), no dedicated role yet.
|
||||
- **Provider stack** (hermes-osa):
|
||||
```yaml
|
||||
provider: deepseek # primary — direct credits, proven DEEPSEEK_OK
|
||||
default: deepseek-chat
|
||||
fallback: openrouter # available manually, not auto-fallback configured yet
|
||||
```
|
||||
`scripts/install-freebsd.sh` is useful later for package-style installs, but it currently
|
||||
installs the published `hermes-agent` package rather than proving this checkout's patches.
|
||||
- **Service home:** the rc.d template defaults `hermes_daemon_home` to `/var/db/hermes` under
|
||||
the dedicated `hermes` service user. After local validation, either seed `/var/db/hermes`
|
||||
deliberately or set `sysrc hermes_daemon_home=/home/clawdie/.hermes` deliberately; do not
|
||||
let local and daemon state diverge by accident.
|
||||
- **Do not use `/home/clawdie/clawdie-ai` as Hermes state.** Preserve/retire the old Clawdie
|
||||
runtime path as a separate step after local Hermes validation.
|
||||
- Install source is `hermes-bsd` main at `912e697d` (includes the Python 3.12 setup baseline).
|
||||
|
||||
**FreeBSD prereqs & first-run checklist** (verified blind spots before committing):
|
||||
|
||||
1. **Install prereqs via pkg first.** `setup-hermes.sh` only auto-provisions on
|
||||
Linux/Termux/macOS; on FreeBSD it falls through to manual-instruction messages. Run:
|
||||
`pkg install -y bash uv git curl`. Prefer pkg `uv` over the script's astral
|
||||
`curl | sh` fallback (unreliable on FreeBSD).
|
||||
2. **`bash` must be installed.** The script is bash. Its shebang is now portable
|
||||
`#!/usr/bin/env bash` (hermes-bsd PR #3, `fix(freebsd): portable bash shebang`), so it
|
||||
resolves FreeBSD's `/usr/local/bin/bash` — but bash itself must be present (step 1).
|
||||
Until PR #3 is merged on the checkout, invoke as `bash setup-hermes.sh`.
|
||||
3. **Run attended.** The script prompts (optional packages, setup wizard). Do **not** run
|
||||
it unattended/agent-driven — it will hang on the `read` prompts.
|
||||
4. **Core-only for first validation.** Decline optional extras initially. Several
|
||||
(`matrix`→libolm, `voice`/`tts`→audio) are native builds that may not compile on
|
||||
FreeBSD 15; the installer degrades rather than hard-failing, but a minimal install
|
||||
gives a clean CLI proof. Add extras deliberately later.
|
||||
5. **The rc.d service step is a separate re-setup, not a flip.** `setup-hermes.sh`
|
||||
symlinks the `hermes` binary into `~/.local/bin` for the invoking user, but
|
||||
`hermes_daemon` expects it at `/usr/local/bin/hermes` under a dedicated `hermes` user
|
||||
with state at `/var/db/hermes`. Validation state at `/home/clawdie/.hermes` will **not**
|
||||
migrate — re-run setup as the service user when promoting to rc.d.
|
||||
|
||||
---
|
||||
- **Z.AI**: deferred (not configured for hermes-osa; available via OpenRouter if needed)
|
||||
- **Telegram**: OFF (not configured)
|
||||
- **Gateway/daemon**: deferred (Track A/B)
|
||||
- **Launch command**:
|
||||
```sh
|
||||
tmux new -s hermes-osa
|
||||
cd /home/clawdie/ai/hermes-bsd
|
||||
export HERMES_HOME=/home/clawdie/.hermes
|
||||
source venv/bin/activate # or: .venv/bin/activate
|
||||
hermes chat
|
||||
```
|
||||
- **Layered soul**: commit `c9c88fd`, 10 skills, 7 curated memories
|
||||
- **Future tracks (separate, none blocking)**:
|
||||
- Track A: daemon/rc.d promotion (hermes_daemon service, dedicated user)
|
||||
- Track B: Telegram/gateway integration
|
||||
- Track C: Colibri cross-host routing (see CAPABILITY-ROUTING.md)
|
||||
- Track D: old clawdie_glass cleanup
|
||||
|
||||
_See [`../AGENTS.md`](../AGENTS.md) for the canonical agent matrix and operating rules._
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue