From bbfc578c955b393049fc94314e1247ba4d0c31a0 Mon Sep 17 00:00:00 2001 From: atlas Date: Thu, 23 Jul 2026 12:37:04 +0200 Subject: [PATCH] docs(#2627): add READMEs for the remaining infra crates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second increment of the per-crate README effort, covering the rest of the infra/wire/priv column: hive-priv, hive-metric, hive-types, hive-sh4re, hive-core-agent-sock, hive-agent-sock. Same shape as the first batch — purpose + when-to-use, and point at the crate-root //! docs plus the relevant docs/ pages rather than duplicating them. Wires readme = "README.md" into each Cargo.toml [package]. Disjoint from the batch-1 crates, so the two increments compose cleanly. --- hive-agent-sock/Cargo.toml | 1 + hive-agent-sock/README.md | 26 ++++++++++++++++++++++++++ hive-core-agent-sock/Cargo.toml | 1 + hive-core-agent-sock/README.md | 21 +++++++++++++++++++++ hive-metric/Cargo.toml | 1 + hive-metric/README.md | 26 ++++++++++++++++++++++++++ hive-priv/Cargo.toml | 1 + hive-priv/README.md | 32 ++++++++++++++++++++++++++++++++ hive-sh4re/Cargo.toml | 1 + hive-sh4re/README.md | 33 +++++++++++++++++++++++++++++++++ hive-types/Cargo.toml | 1 + hive-types/README.md | 18 ++++++++++++++++++ 12 files changed, 162 insertions(+) create mode 100644 hive-agent-sock/README.md create mode 100644 hive-core-agent-sock/README.md create mode 100644 hive-metric/README.md create mode 100644 hive-priv/README.md create mode 100644 hive-sh4re/README.md create mode 100644 hive-types/README.md diff --git a/hive-agent-sock/Cargo.toml b/hive-agent-sock/Cargo.toml index 7818923d..0c6b82e7 100644 --- a/hive-agent-sock/Cargo.toml +++ b/hive-agent-sock/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-agent-sock" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-agent-sock/README.md b/hive-agent-sock/README.md new file mode 100644 index 00000000..6a772dd3 --- /dev/null +++ b/hive-agent-sock/README.md @@ -0,0 +1,26 @@ +# hive-agent-sock + +Wire types for the **in-agent socket** — the one the `hive-agent` harness serves +*inside* the container to its local producers (the matrix / bash MCP daemons and +`forge_notify`). Unlike the host-served sockets, this one **never leaves the +container**. + +## What it carries + +- the loose-ends-v2 **todo** op family +- the harness-local **reminder** op family + +More in-agent request families may be added over time — the socket is +deliberately named for the agent, not for the todos. + +## Why in-container + +The harness owns the todo + reminder stores locally and signals its own turn +loop directly, so `hive-c0re` is not in either path: no broker round-trip, no +long-poll, no marker files. That locality is the point — it's also what lets +these stores travel with the agent for hive portability. + +## Not to be confused with `hive-core-agent-sock` + +That crate is the *host*-served core↔agent protocol on `/run/hive/mcp.sock` +(the harness talking out to `hive-c0re`). This socket is purely intra-container. diff --git a/hive-core-agent-sock/Cargo.toml b/hive-core-agent-sock/Cargo.toml index c0e6a342..d0d677c5 100644 --- a/hive-core-agent-sock/Cargo.toml +++ b/hive-core-agent-sock/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-core-agent-sock" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-core-agent-sock/README.md b/hive-core-agent-sock/README.md new file mode 100644 index 00000000..afa130a3 --- /dev/null +++ b/hive-core-agent-sock/README.md @@ -0,0 +1,21 @@ +# hive-core-agent-sock + +Wire types for the **per-agent + manager socket** (`/run/hive/mcp.sock`) — the +unified `Request` / `Response` protocol spoken between an agent's in-container +harness (and the manager) and the `hive-c0re` daemon. + +## Why it's its own crate + +Re-homed out of `hive-sh4re` so this one socket owns its protocol crate, +mirroring the `hive-host-sock` / `hive-priv-sock` splits. The shared payload +types it references (`Message`, `LooseEnd`, `Approval`, …) stay in `hive-sh4re`, +which this crate depends on — this crate is just the request/response envelope +for this socket. + +## Not to be confused with `hive-agent-sock` + +This is the **host-served** protocol: the harness talks *out* to `hive-c0re` +over `/run/hive/mcp.sock` (broker sends, approvals, questions, lifecycle). +`hive-agent-sock` is the separate *in-container* socket the harness serves to +its own local producers — that one never leaves the container. See +`docs/boundary.md` for the socket topology. diff --git a/hive-metric/Cargo.toml b/hive-metric/Cargo.toml index d71614be..741d3419 100644 --- a/hive-metric/Cargo.toml +++ b/hive-metric/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "hive-metric" version.workspace = true +readme = "README.md" edition.workspace = true [[bin]] diff --git a/hive-metric/README.md b/hive-metric/README.md new file mode 100644 index 00000000..7a43cd1f --- /dev/null +++ b/hive-metric/README.md @@ -0,0 +1,26 @@ +# hive-metric + +A tiny CLI that pushes **a single labeled metric** to the OTEL collector, then +exits. Built on the OpenTelemetry Rust SDK with the OTLP HTTP/JSON exporter. + +## When to use it + +For emitting a one-off counter or gauge from a shell script or systemd unit +without embedding an OTEL SDK in the caller — the harness and various hive +scripts use it to record per-agent metrics. + +## Usage + +```text +hive-metric [--type counter|gauge] [--labels key=value ...] +``` + +Standard OTEL environment variables are read automatically by the SDK: + +- `OTEL_EXPORTER_OTLP_ENDPOINT` — collector URL (**required**) +- `OTEL_EXPORTER_OTLP_HEADERS` — auth headers (`Key=Value,...`) +- `OTEL_RESOURCE_ATTRIBUTES` — resource labels (`k=v,...`) + +The harness populates all of these per-agent when +`services.hyperhive.otel.enable = true`. See `docs/observability.md` for the +collector setup and the metrics hyperhive exports. diff --git a/hive-priv/Cargo.toml b/hive-priv/Cargo.toml index 5f427dc8..a322d0f9 100644 --- a/hive-priv/Cargo.toml +++ b/hive-priv/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-priv" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-priv/README.md b/hive-priv/README.md new file mode 100644 index 00000000..68da1905 --- /dev/null +++ b/hive-priv/README.md @@ -0,0 +1,32 @@ +# hive-priv + +The minimal **root privileged-helper** for hive-c0re. It runs as root and +exposes a narrow unix socket at `/run/hive/priv.sock` that accepts `PrivRequest` +JSON lines and performs only the handful of operations that genuinely require +root — bind-mount edits, `nsenter` into a container, btrfs subvolume ops. All +coordination logic (broker, HTTP, scheduling) stays in the *unprivileged* +`hive-c0re` process, which delegates here. + +## Why it exists + +Privsep. `hive-c0re` runs as the unprivileged `hive-core` user so a bug or a +prompt-injection in the large daemon can't directly wield root. The few root +operations it needs are funnelled through this small, auditable helper instead. +See `docs/boundary.md` and `docs/security.md` for the privilege boundary. + +## Security model + +- **Strict allowlist.** Every request is validated against a container-name + allowlist before any filesystem or process operation — only names matching the + hive convention (`h-*`, the manager container, known sibling service + containers) are accepted. +- **No pass-through.** Every `PrivRequest` variant maps to a single known + operation; there is no arbitrary-command escape hatch. +- **Socket-activated, always.** systemd binds `/run/hive/priv.sock` + (`SocketGroup=hive-core`, `0660`) and passes the listener as fd 3 + (`LISTEN_FDS`); the helper requires this and has no self-bind fallback, so dev + and prod take the identical path and the group grant always holds. + +The wire contract (`PrivRequest` / response types) lives in the separate +`hive-priv-sock` crate so this root binary depends on just the protocol shapes, +not the whole daemon-shared crate. diff --git a/hive-sh4re/Cargo.toml b/hive-sh4re/Cargo.toml index 3338ed51..42e8f980 100644 --- a/hive-sh4re/Cargo.toml +++ b/hive-sh4re/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-sh4re" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-sh4re/README.md b/hive-sh4re/README.md new file mode 100644 index 00000000..f7c0f8d6 --- /dev/null +++ b/hive-sh4re/README.md @@ -0,0 +1,33 @@ +# hive-sh4re + +The **shared wire types** between `hive-c0re` and the in-container harness — the +common vocabulary (`Message`, `Approval`, `LooseEnd`, `HelperEvent`, the +Agent / Manager request + response shapes) that the unix-socket protocols are +built from. + +## Where it sits + +This is the shared payload crate; the per-socket *protocol envelopes* have been +split into their own smaller crates so specialised binaries don't have to pull +in all of `hive-sh4re`: + +- `hive-host-sock` — host admin socket (`hivectl` ↔ `hive-c0re`) +- `hive-core-agent-sock` — per-agent/manager socket (`/run/hive/mcp.sock`) +- `hive-priv-sock` — the privileged-helper socket + +Those crates re-export or reference the payload types that still live here +(`Approval`, `Message`, `LooseEnd`, …). + +## Modules + +- **`jobs`** — the job-queue wire types (`DagView`) surfaced to the dashboard SSE + stream + hivectl. +- **`wire_time`** — the timestamp convention: wire fields are + `chrono::DateTime` (serialized RFC 3339), while sqlite storage + input + args stay unix-epoch `i64`; this module owns the two boundary conversions. +- **`paths`** — well-known on-disk path helpers. +- **`assets`** — resolves bundled runtime asset paths (branding, prompts) under + `HIVE_ASSETS_DIR`. + +Agent-name fields are typed as `hive_types::Ident` for serde-validated parsing at +the socket boundary. diff --git a/hive-types/Cargo.toml b/hive-types/Cargo.toml index d472adb5..cea91cd5 100644 --- a/hive-types/Cargo.toml +++ b/hive-types/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-types" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-types/README.md b/hive-types/README.md new file mode 100644 index 00000000..f3e897fa --- /dev/null +++ b/hive-types/README.md @@ -0,0 +1,18 @@ +# hive-types + +Foundational shared **newtypes** for the hyperhive workspace. A zero-dependency +(bar `serde`) leaf crate, so every wire-type crate (`hive-sh4re`, +`hive-host-sock`, `hive-core-agent-sock`) and both binaries (`hive-c0re`, +`hivectl`) can share them without cross-crate coupling and without growing +`hive-sh4re`. + +## What's here + +- **`Ident`** — a validated agent-name newtype. Typing agent-name fields as + `Ident` (rather than bare `String`) gets serde-validated parsing **at the + socket boundary for free**: a malformed name is rejected at deserialize time + instead of flowing into a handler that has to re-validate by hand. + +The crate is deliberately a leaf with the smallest possible dependency footprint +so anything in the workspace can depend on it. See `docs/conventions.md` +("identity = socket") for how agent identity is modelled across the sockets.