docs: catch up post-#658/#604/#660 + add operator hivectl section (#124)

This commit is contained in:
damocles 2026-05-31 09:39:12 +02:00
commit fcb5fae345
6 changed files with 44 additions and 16 deletions

View file

@ -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

View file

@ -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/<name>/claude/` bind-mounts to
`/root/.claude` (RW). Sharing one dir across agents is NOT viable —
`/home/<name>/.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/<name>/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/<name>/state/` bind-mounts to
`/agents/<name>/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

View file

@ -136,11 +136,13 @@ Under `/var/lib/hyperhive/agents/<name>/`:
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/<name>/.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/<name>/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/<name>/` — the hive-c0re-only
applied repo. Tracks `flake.nix` (module-only boilerplate; never

View file

@ -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/<name>/.claude/` — mode `0700`, owned by the per-agent
user `<name>` (post-#658 — was `/root/.claude` owned by root
pre-#658). nixbld users cannot read it.
- `$HYPERHIVE_STATE_DIR/forge-token` (= `/agents/<name>/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

View file

@ -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.

View file

@ -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] <sender> in <room>: <first 100c>`)
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 <this> --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 <this> --token "$(cat $HYPERHIVE_STATE_DIR/forge-token)"`
(= `/agents/<name>/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).
'';
};