Compare commits

...
Author SHA1 Message Date
iris
6809c782a3 docs: actually remove the Agent configuration section, not trim it
Missed mara'\''s reply on this PR before pushing two more commits on top
- she said remove, my first commit trimmed to two bullets, which is
still going into Matrix/GitHub as named subsystems. Deletes the
section outright; the two docs it pointed at (docs/tools/matrix.md,
docs/github.md) are still reachable from CLAUDE.md's reading path and
from docs/tools/README.md, just not named in the top-level README.
2026-08-03 12:59:28 +02:00
iris
3993f635d5 docs: add tools/ landing page
Part of hyperhive#1898 (b), the other missing docs subdir. Unlike
turn-loop/ this one has no single existing file that already covers
the whole directory - hivectl.md/hivectl-cli.md are genuinely
operator-facing (the operator's own host CLI), while bash.md/forge.md/
lifecycle.md/matrix.md/scheduling.md document the agents' own MCP tool
surface (a different audience: what the agent can do, not what the
operator does). Writes a new README.md rather than moving one,
splitting the link list along that line so the operator-relevant half
leads.
2026-08-03 12:57:00 +02:00
iris
04b274753b docs: give turn-loop/ a README.md landing page
Part of hyperhive#1898 (b): every docs subdir should have a top-level
README.md link, achieved by moving/renaming where an existing file
already fits the role.

docs/turn-loop.md already served as the hub + index for the three
sub-pages under turn-loop/ (claude-invocation.md, config.md, mcp.md),
so it moves wholesale rather than leaving a redundant top-level
pointer stub. Fixes every inbound/relative link across the repo
(top-level README.md, CLAUDE.md, docs/persistence.md,
docs/tools/scheduling.md, the sub-pages own back-link, hive-agent
README + doc comments, hive-agent/Cargo.toml, .prettierignore per-file
exemption entry) - grepped the whole tree for both turn-loop.md and
turn-loop/ to find every reference rather than trusting a partial
list.

nix fmt clean, cargo check -p hive-agent clean.
2026-08-03 12:55:18 +02:00
iris
c6af5a2abf docs: trim impl detail out of the top-level README
Per mara on hyperhive#1898: the top-level README should not go into
details about impl details or specific subsystems. Trims the
Multi-account Matrix support and GitHub account sections down to a
one-line pointer each.

The matrixAccounts option detail that was only ever documented in the
README (checked: docs/matrix.md is entirely about the host hive-matrix
container, not this per-agent option) moves to docs/tools/matrix.md
instead, next to the account parameter every matrix tool already
takes - the natural home, not a link to a page that never covered it.
2026-08-03 12:48:37 +02:00
13 changed files with 71 additions and 61 deletions

View file

@ -16,6 +16,6 @@ docs/persistence.md
docs/terminal-rendering.md
docs/tools/forge.md
docs/tools/matrix.md
docs/turn-loop.md
docs/turn-loop/README.md
docs/web-ui/agent.md
docs/web-ui/dashboard.md

View file

@ -179,7 +179,7 @@ read them à la carte.
- **"How does the per-agent terminal classify + colour
events?"** → [`docs/terminal-rendering.md`](docs/terminal-rendering.md).
- **"How does claude get its prompt and what tools does it have?"** →
[`docs/turn-loop.md`](docs/turn-loop.md) (index: the loop, binary shape,
[`docs/turn-loop/`](docs/turn-loop/README.md) (index: the loop, binary shape,
turn outcomes; sub-pages:
[`claude-invocation`](docs/turn-loop/claude-invocation.md),
[`config`](docs/turn-loop/config.md), [`mcp`](docs/turn-loop/mcp.md)).
@ -239,7 +239,7 @@ The docs below own the details — this section just points at them.
- **NixOS / nspawn quirks** (bind mounts, conf flags, etc.): →
[`docs/gotchas.md`](docs/gotchas.md).
- **Turn loop, sentinels (rate-limit, auth-failed), context
window:** → [`docs/turn-loop.md`](docs/turn-loop.md).
window:** → [`docs/turn-loop/`](docs/turn-loop/README.md).
- **Two-step spawn, approval flow, flake.lock validation:**
[`docs/approvals.md`](docs/approvals.md).
- **Pre-push lint hook** (catches tracker-tag and comment-block failures

View file

@ -46,7 +46,7 @@ Depth lives in [`docs/`](docs/) — pick the one matching your task:
| reading path | doc |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| dashboard layout + endpoints | [`docs/web-ui.md`](docs/web-ui.md) ([shape](docs/web-ui/shape.md) · [dashboard](docs/web-ui/dashboard.md) · [agent](docs/web-ui/agent.md)) |
| claude turn loop + MCP tools | [`docs/turn-loop.md`](docs/turn-loop.md) |
| claude turn loop + MCP tools | [`docs/turn-loop/`](docs/turn-loop/README.md) |
| config-edit + approval state machine | [`docs/approvals.md`](docs/approvals.md) |
| what survives destroy / purge / restart | [`docs/persistence.md`](docs/persistence.md) |
| naming, wire protocol, commit style | [`docs/conventions.md`](docs/conventions.md) |
@ -103,46 +103,6 @@ older/newer channel hits breakage hyperhive's CI doesn't catch.
For the full list of host and agent NixOS options see the
**[options reference](https://hyperhive.darkest.space/options/)**.
## Agent configuration
Per-agent config lives in each agent's `agent.nix` (proposed, operator-approved, deployed as git commits). Key options:
### Multi-account Matrix support
`hyperhive.matrixAccounts` declares _additional_ matrix accounts for an agent, beyond the hive-internal one. Each entry is keyed by account name and specifies:
- `tokenFile` — path to the matrix bearer token (provisioned out-of-band)
- `sessionDir` — path to the per-account matrix-sdk sqlite state (crypto keys + cache)
- `homeserver` — optional homeserver URL (defaults to `hyperhive.matrix.url`)
**Example:**
```nix
hyperhive.matrixAccounts = {
external-public = {
tokenFile = "/agents/myagent/state/matrix-token-external";
sessionDir = "/agents/myagent/state/matrix-sdk-state-external";
homeserver = "https://matrix.org";
};
};
```
The hive-internal account is always named `main` (synthesized from `hyperhive.matrix.url` + agent state). This option only declares _extras_; the `main` name is reserved and cannot be used here. Requires `hyperhive.matrix.enable = true`.
For more details see [`docs/matrix.md`](docs/matrix.md).
### GitHub account
Every agent gets a managed GitHub identity — a `gh` CLI wrapper and `git push` over HTTPS — on by default (`hyperhive.github.enable`), inert until a PAT is provisioned. There is nothing per-agent to declare: paste an operator-supplied personal access token into the agent's dashboard **credentials** tab (or `hivectl github set-token <agent> --token-stdin`) and it works. The `gh` wrapper + git credential helper read the token live (git auths as `x-access-token` + the PAT; github.com only), so a rotated PAT takes effect with no rebuild.
Turn the integration off for the whole hive with the host option:
```nix
services.hyperhive.github.enable = false;
```
The PAT value is never in nix — only the enable flag. For more details see [`docs/github.md`](docs/github.md).
## Operator CLI
`hivectl` is the operator-facing host CLI for ad-hoc administration that

View file

@ -239,7 +239,7 @@ Survives destroy/recreate, gone on `--purge`.
Empty marker file. Its presence parks the agent's turn loop: the
harness keeps serving its web UI and MCP daemons but drives no turns,
and inbox messages queue unacked until it's removed (see
[turn loop](turn-loop.md#the-loop)).
[turn loop](turn-loop/README.md#the-loop)).
Unusually, it's read and written from **both** sides of the harness
bind-mount, and that's the whole design: the harness stats it

33
docs/tools/README.md Normal file
View file

@ -0,0 +1,33 @@
# Tools
`hivectl` is *your* tool — the operator's own host CLI. Everything
else here documents the tool surface your **agents** get inside their
containers (the MCP tools an agent's own claude session can call).
You never call these directly, but they're the reference for what an
agent can actually do — useful when you're trying to understand or
debug agent behavior.
## For the operator
- **[hivectl](hivectl.md)** — the curated guide: provisioning forge
and matrix accounts, gateway htpasswd management, container
lifecycle shortcuts, interactive agent shell access.
- **[hivectl-cli](hivectl-cli.md)** — the exhaustive, auto-generated
flag-by-flag reference, kept in lockstep with the binary by CI.
## What your agents can do
- **[bash](bash.md)** — background shell execution (`mcp__bash__*`),
available on every agent unconditionally.
- **[forge](forge.md)** — the `hive-forge` Forgejo CLI every agent has
for issues, PRs, and comments. Not an MCP tool — a binary agents
shell out to instead of ad-hoc curl.
- **[lifecycle](lifecycle.md)** — kill/start/restart/update for an
agent's own direct children, plus the approval-gated config-change
tools.
- **[matrix](matrix.md)** — the matrix MCP tool surface
(`mcp__matrix__*`) for agents with a matrix account, multiple
accounts per agent, and declaring extra MCP servers generally.
- **[scheduling](scheduling.md)** — scheduled prompts (operator
approval required) and the diagnostics tools (`get_logs`,
`get_host_journal`).

View file

@ -67,6 +67,23 @@ room you haven't read yet.
- `mark_read(room, event_id)` — advance the read receipt
## Multiple accounts
`hyperhive.matrixAccounts` (declared in `agent.nix`) gives an agent
*additional* matrix identities beyond the hive-internal one — e.g. an
external-facing account alongside the internal one. Each entry is
keyed by account name and specifies `tokenFile` (bearer token,
provisioned out-of-band; basename must start with `matrix-token`),
`sessionDir` (per-account matrix-sdk sqlite state — crypto keys +
cache), and an optional `homeserver` (defaults to
`hyperhive.matrix.url`). The hive-internal account is always named
`main`, synthesized from `hyperhive.matrix.url` + agent state — this
option only declares extras, and `main` is a reserved key here.
Requires `hyperhive.matrix.enable = true`.
Every matrix tool above takes an optional `account` parameter (a name
from this map) to act as that identity instead of the primary one.
## Architecture
`hive-matrix-daemon` is a single long-running process (one per agent

View file

@ -89,6 +89,6 @@ lifecycle events, or another container's boot log.
## See also
- `remind` (no-approval self-wake path) — documented in
[`docs/turn-loop.md`](../turn-loop.md).
[`docs/turn-loop/`](../turn-loop/README.md).
- [`docs/approvals.md`](../approvals.md) — approval flow for
`request_schedule_prompt`.

View file

@ -14,7 +14,7 @@ agents) runs:
queued and unacked, so a resume drains the backlog instead of
losing it; reminders and todo wakes buffer in their channels. Set
it with `hivectl agent <name> pause` or the dashboard toggle; see
[persistence](persistence.md#-harnesspaused-per-agent).
[persistence](../persistence.md#-harnesspaused-per-agent).
1. Long-poll `Recv` on its socket. The host-side broker
(`broker.rs::recv_blocking_batch`) returns immediately if there's
a pending message, otherwise waits up to 30 s for a broker `Sent`
@ -31,7 +31,7 @@ agents) runs:
hard failure. The outcome drives the post-turn action (see
[Turn outcomes](#turn-outcomes)); compaction is handled inside the
session (see
[Compaction](turn-loop/claude-invocation.md#compaction)). Rate-limit
[Compaction](claude-invocation.md#compaction)). Rate-limit
and auth-failure detection is described [below](#failure-detection-and-login).
7. Emit `LiveEvent::TurnEnd { ok, note }`. Sleep `poll_ms` to avoid
tight loops on transient failures.
@ -94,12 +94,12 @@ loop (`serve_loop` / `handle_turn`) has no per-role branches.
flake sets it unconditionally for any container-deployed agent;
see `docs/conventions.md::Hive identity` for the env stack),
opens turn-stats sqlite, prepares the on-boot files (see
[claude-invocation](turn-loop/claude-invocation.md#on-boot-files)),
[claude-invocation](claude-invocation.md#on-boot-files)),
installs claude plugins, spawns `web_ui::serve` + `vacuum::run`,
and either drops into `serve_loop` directly (`Online`) or parks on
the login flow first (`NeedsLogin`). (The forge notification poller
used to be spawned here too; it is its own process now —
`hive-forge-notify`, see [`forge.md`](forge.md).)
`hive-forge-notify`, see [`forge.md`](../forge.md).)
`spawn_todo_socket` opens the todos store and, alongside
`todo_server::run` (the socket the out-of-process producers dial),
@ -153,17 +153,17 @@ harness between turns.
## Sub-pages
The rest lives in three topic pages under [`turn-loop/`](turn-loop/):
The rest lives alongside this page, in three topic files:
- **[claude-invocation.md](turn-loop/claude-invocation.md)** — how the harness
- **[claude-invocation.md](claude-invocation.md)** — how the harness
spawns `claude --print` each turn, the two-pronged compaction (reactive +
proactive), and the on-boot files it materialises (`--mcp-config`,
`--system-prompt-file`).
- **[config.md](turn-loop/config.md)** — the optional per-agent knobs the meta
- **[config.md](config.md)** — the optional per-agent knobs the meta
flake wires in (reference docs, icon, passwordless sudo, dashboard links,
custom static files, connectivity overrides, claude plugins, cargo message
filtering).
- **[mcp.md](turn-loop/mcp.md)** — the MCP tool surface claude sees: core tools,
- **[mcp.md](mcp.md)** — the MCP tool surface claude sees: core tools,
privileged tool groups, self-wake, authoritative state, the tool envelope,
and the built-in tool whitelist.

View file

@ -116,7 +116,7 @@ window with two triggers baked into its `run`:
*still* overflows, `run` surfaces `Error::PromptTooLong`; `drive_turn`
then archives the session (session lifecycle stays hive-side) and the
serve loop requeues the message so it redelivers into a fresh session
(see [Turn outcomes](../turn-loop.md#turn-outcomes) — the wake prompt itself is tiny, so
(see [Turn outcomes](README.md#turn-outcomes) — the wake prompt itself is tiny, so
the overflow was the accumulated context the archive clears).
- **Proactive** — a turn finishes cleanly but the last inference's context
size crossed the policy watermark. While the session is still healthy it

View file

@ -41,4 +41,4 @@ tempfile = "3"
# The sibling MCP server is its own bin crate now (`hive-agent-mcp`).
# Privilege boundary is enforced server-side at the socket (tool
# groups / manager surface).
# See `docs/turn-loop.md::Harness binary shape`.
# See `docs/turn-loop/README.md::Harness binary shape`.

View file

@ -15,7 +15,7 @@ understand or change: what happens between "a message lands in the
inbox" and "claude produces a reply", how login/auth is bootstrapped,
how the per-agent web UI is served, or how turn/event stats get
recorded. Architecture detail lives in
[`docs/turn-loop.md`](../docs/turn-loop.md); this README is just the
[`docs/turn-loop/`](../docs/turn-loop/README.md); this README is just the
map of the module tree.
## Shape
@ -48,4 +48,4 @@ map of the module tree.
Sibling: **`hive-agent-mcp`** (the MCP server this loop points claude
at every turn). Both are described together in
[`docs/turn-loop.md::Harness binary shape`](../docs/turn-loop.md).
[`docs/turn-loop/::Harness binary shape`](../docs/turn-loop/README.md).

View file

@ -118,7 +118,7 @@ impl LoginState {
/// infinite-401 loop a bare-existence check would produce when stale
/// credentials are already on disk. Mtime-snapshot resumption rationale
/// and `DirSnapshot` two-axis design: see
/// [`docs/turn-loop.md::The loop`](../../docs/turn-loop.md).
/// [`docs/turn-loop/::The loop`](../../docs/turn-loop/README.md).
///
/// # Panics
///

View file

@ -4,7 +4,7 @@
//! generic and testable. Sibling: `hive-agent-mcp` (the MCP server this
//! loop points claude at).
//! Architecture lives in
//! [`docs/turn-loop.md::Harness binary shape`](../../../docs/turn-loop.md).
//! [`docs/turn-loop/::Harness binary shape`](../../../docs/turn-loop/README.md).
//!
//! Single bin crate: the module tree below (formerly this crate's `lib.rs`,
//! before lib + bin were collapsed into one) plus the serve loop.
@ -510,7 +510,7 @@ fn spawn_todo_socket(
/// Boot — wires up the web UI, login state, stats, plugins, forge
/// notifier, and either drops into `serve_loop` directly (`Online`) or
/// parks on the login flow first (`NeedsLogin`). See
/// `docs/turn-loop.md::Boot wiring`.
/// `docs/turn-loop/README.md::Boot wiring`.
async fn serve_main<S: Surface>(socket: &Path, poll_ms: u64) -> Result<()> {
let port = std::env::var("HIVE_PORT")
.ok()