From fcb5fae345934150afa3fb57c694bc26b2b11177 Mon Sep 17 00:00:00 2001 From: damocles Date: Sun, 31 May 2026 09:39:12 +0200 Subject: [PATCH] docs: catch up post-#658/#604/#660 + add operator hivectl section (#124) --- README.md | 18 ++++++++++++++++++ docs/gotchas.md | 13 ++++++++----- docs/persistence.md | 8 +++++--- docs/security.md | 8 ++++++-- hive-matrix-mcp/Cargo.toml | 2 +- nix/templates/harness-base.nix | 11 ++++++----- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3bcf3955..5e87f046 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,24 @@ the container as environment variables. Common options: See `nix/templates/harness-base.nix` for the full list of options and their descriptions. +## Operator CLI + +`hivectl` is the operator-facing host CLI for ad-hoc administration that +doesn't go through the broker (built alongside `hive-c0re` when the host +module is enabled): + +```sh +sudo hivectl forge create-user mara # provisions a forge user +sudo hivectl forge create-user mara --password # … with a fixed password +sudo hivectl matrix create-user mara # provisions a matrix user +sudo hivectl matrix create-user mara --password-stdin # … reading from stdin +``` + +For agent names (i.e., a `Coordinator::agent_state_root(name)` exists), +`hivectl` persists the resulting token to the agent's state dir like the +boot sweep does. For non-agent names (e.g. the operator's own forge/matrix +account), it prints the token to stdout and writes nothing. + ## Build / deploy ```sh diff --git a/docs/gotchas.md b/docs/gotchas.md index eff10354..5f13dce6 100644 --- a/docs/gotchas.md +++ b/docs/gotchas.md @@ -65,17 +65,20 @@ propagate in. Operators don't need to set anything on their side. ## Claude credentials are per-agent `/var/lib/hyperhive/agents//claude/` bind-mounts to -`/root/.claude` (RW). Sharing one dir across agents is NOT viable — +`/home//.claude` (RW; was `/root/.claude` pre-#658 when every +harness ran as root). Sharing one dir across agents is NOT viable — OAuth refresh tokens rotate, so any sibling refresh invalidates all the others. Login flow runs from the per-agent web UI; creds persist across `destroy`/recreate (`--purge` wipes them). ## Persistent notes dir per agent -`/var/lib/hyperhive/agents//state/` bind-mounts to `/state` -(RW). System prompts tell agents to keep durable knowledge here -(`/state/notes.md`, anything else under `/state/`). The harness also -writes its events log here (`/state/hyperhive-events.sqlite`). +`/var/lib/hyperhive/agents//state/` bind-mounts to +`/agents//state` (RW; uniform for sub-agents + manager +post-#604, was `/state` pre-#604). The harness exposes the same path +via `$HYPERHIVE_STATE_DIR`. System prompts tell agents to keep +durable knowledge here (`notes.md`, anything else). The harness also +writes its events log here (`hyperhive-events.sqlite`). Survives `destroy`/recreate alongside the claude dir. ## Web UI ports collide on hash diff --git a/docs/persistence.md b/docs/persistence.md index aea02c8f..dd9b3f52 100644 --- a/docs/persistence.md +++ b/docs/persistence.md @@ -136,11 +136,13 @@ Under `/var/lib/hyperhive/agents//`: precise changes from the manager; RW into the manager via the `/agents` tree bind. - `claude/` — claude OAuth credentials, bind-mounted RW to - `/root/.claude` inside the container. + `/home//.claude` inside the container (post-#658 — was + `/root/.claude` pre-#658 when every harness ran as root). - `state/` — durable notes, the events.sqlite db, and the turn-stats sqlite db. Bind-mounted to `/agents//state` - inside the container (the manager still uses the legacy - `/state` mount point — same host path either way). + inside the container (uniform for sub-agents + manager + post-#604). The `$HYPERHIVE_STATE_DIR` env var exposes the + same path to in-container scripts. Under `/var/lib/hyperhive/applied//` — the hive-c0re-only applied repo. Tracks `flake.nix` (module-only boilerplate; never diff --git a/docs/security.md b/docs/security.md index 32c6951c..22e4ab64 100644 --- a/docs/security.md +++ b/docs/security.md @@ -18,8 +18,12 @@ any file in the container that the nixbld user can read. **What is NOT exposed**: -- `/root/.claude/` — mode `0700`, owned by root. nixbld users cannot read it. -- `/state/forge-token` — written at mode `0600` by `hive-c0re/src/forge.rs`. +- `/home//.claude/` — mode `0700`, owned by the per-agent + user `` (post-#658 — was `/root/.claude` owned by root + pre-#658). nixbld users cannot read it. +- `$HYPERHIVE_STATE_DIR/forge-token` (= `/agents//state/forge-token`) + — written at mode `0600` by `hive-c0re/src/forge.rs` and chowned to the + per-agent uid:gid by `lifecycle::chown_to_agent` (post-#673/#678). nixbld users cannot read it. **Policy**: all credential files written to agent state directories MUST be mode diff --git a/hive-matrix-mcp/Cargo.toml b/hive-matrix-mcp/Cargo.toml index faa3fe1a..ef4cfeef 100644 --- a/hive-matrix-mcp/Cargo.toml +++ b/hive-matrix-mcp/Cargo.toml @@ -27,7 +27,7 @@ name = "hive-matrix-daemon" path = "src/main.rs" # `hive-matrix-mcp` — thin stdio MCP bridge spawned by claude per turn. -# Forwards every tool call to the daemon over /run/hive-matrix.sock, +# Forwards every tool call to the daemon over /run/hive-matrix/socket, # returns the daemon's response shape to claude. No matrix-sdk dep at # this entrypoint — the heavy crate only loads when the daemon binary # is invoked. diff --git a/nix/templates/harness-base.nix b/nix/templates/harness-base.nix index 09ed177c..d99061ff 100644 --- a/nix/templates/harness-base.nix +++ b/nix/templates/harness-base.nix @@ -249,7 +249,7 @@ in list_room_members, read_room) to claude via an auto-injected `extraMcpServers.matrix` entry. Claude spawns the stdio `hive-matrix-mcp` bridge per turn, which forwards each tool - call to the daemon over `/run/hive-matrix.sock`. + call to the daemon over `/run/hive-matrix/socket`. - wakes the agent on incoming room events via a short teaser Wake signal (`[matrix] in : …`) to the hyperhive control socket; the full event stays @@ -386,10 +386,11 @@ in description = '' Base URL of the hyperhive-managed Forgejo. Used at container boot by a oneshot systemd unit that calls - `tea login add --url --token "$(cat /state/forge-token)"` - so the agent's claude can shell out to `tea` without an extra - auth dance. No-op when `/state/forge-token` is missing (i.e. - hive-forge isn't running on the host). + `tea login add --url --token "$(cat $HYPERHIVE_STATE_DIR/forge-token)"` + (= `/agents//state/forge-token`) so the agent's claude can + shell out to `tea` without an extra auth dance. No-op when the + forge-token file is missing (i.e. hive-forge isn't running on + the host). ''; };