hive-c0re's admin socket and hive-agent's in-agent socket (mode 0666) read the request with an unbounded read_line: no length cap and no deadline, so a peer that never sends a newline grows a buffer and pins a task forever. The bounded reader (16 MiB cap) moves from hive-c0re's socket_server into hive-sock-client, the one crate both daemons already share or can take, and gains optional deadlines for the first byte and for the rest of the line. Both sockets now use it and answer an over-long or stalled line with the same error reply the bounded sockets give, then close. The admin socket bounds only the started line (clients may idle between requests); the in-agent socket is single-shot and bounds silence too. The per-agent sockets keep their behaviour (no deadline).
11 KiB
hyperhive — claude entry point
Hey claude. This is your starting page. The detailed docs live in
docs/ and are written for humans + you both — read them
when you need depth on a subsystem. This file is the index.
- High-level project intro: README.md.
- Open work + backlog: the forge issue tracker at
$HIVE_FORGE_URL/hyperhive/hyperhive/issues. Read the host out of the env var — inside an agent containerlocalhostis the agent, not the forge, so a hardcoded loopback address fails to connect. - Operator/agent trust-boundary design:
docs/trust-boundary/boundary.md (
area/opsissues for the deployment/gateway/privsep work — the separator is a slash, and--label area:opsnow fails withdid you mean "area/ops"?). - Agent trust model (trust boundary, prompt-injection threat model, capability = accepted risk), credential isolation + sandbox threat model: docs/trust-boundary/security.md.
- Odd-looking nspawn / container plumbing usually has a story: docs/process/gotchas.md.
Build & check
Always through the devshell — a bare cargo fails (failed to find tool "cc", cannot find -lsqlite3). Details:
docs/process/conventions.md.
nix develop -c cargo clippy --all-targets -- -D warnings
nix develop -c cargo test
nix fmt # treefmt is the CI gate, NOT bare cargo fmt
Changed a hivectl / swarmctl verb or flag? Regenerate its doc — only
CI's nix flake check catches the drift:
nix develop -c cargo run --bin hivectl -- markdown-docs > docs/tools/hivectl-cli.md
(same for swarmctl → docs/tools/swarmctl-cli.md). CI red but local
green → build the suspect check (e.g. nix build .#checks.x86_64-linux.hivectl-docs) before blaming the builder.
Repo map
One line per crate / top-level dir. Each module's authoritative,
always-current description lives in its own //! doc-comment —
grep/read the module when you need detail. This index is kept
deliberately lean: it auto-loads into every turn's context, and a
hand-maintained per-file tree drifts out of sync with the code.
Rust workspace (Cargo.toml members)
Per-hive (host + in-container):
hive-c0re/— host daemon (runs as the unprivilegedhive-coreuser), daemon-only — the operator CLI ishivectl. Owns the sqlite broker, reminder queue, meta flake, lifecycle (nixos-containershellouts), gateway wiring, per-container stats and the axum operator dashboard. Agent forge/matrix accounts areswarm-controller's. Largest crate.hivectl/— operator CLI; talks tohive-c0reover the host admin socket, does NOT link it. Verb reference (CI-enforced):docs/tools/hivectl-cli.md.hive-priv/— minimal root helper, socket-activated at/run/hive/priv.sock; the few root ops (bind-mount edits, nsenter)hive-c0redelegates. Seedocs/trust-boundary/boundary.md.hive-agent/— the in-container serve loop: turn-loop policy (turn.rs) overhive-runtime, per-agent web UI, event + turn-stats sinks, system-prompt renderer, claude launch config (mcp_config.rs). Withhive-agent-mcpit's what "hive-ag3nt" refers to — there is no such directory.hive-agent-mcp/— the embedded MCP server (hive-mcp-httpunit).hive-runtime/— theRuntimeinterface an agent's turns run on: aclaudebackend (overhive-claude) and anacpbackend whose stream is translated into claude'sstream-jsonshape. Links no hyperhive binary crate, so the subagent daemon uses it too.hive-bash-mcp/,hive-matrix-mcp/,hive-subagent-mcp/— per-agent MCP daemons serving streamable-http directly (no stdio bridge): background bash tasks, matrix-sdk tools, nested subagent sessions (optionally goal-driven over several turns; daemon state is in-memory, the claude session survives a restart).hive-screen-mcp/— stdio MCP bridge for GUI agents: screenshot, keyboard, mouse. All userspace.hive-forge/—hive-forgeForgejo CLI; one module per verb.hive-forge-notify/— notification pollers → todos on the in-agent socket. Two binaries:hive-forge-notify,hive-github-notify.hive-jobq/— the job-DAG scheduler library. Runtime-only — nothing writes the graph to disk, so node ids are stable within a run, not across restarts.hive-c0re'sjob_queue/is being removed in its favour — new scheduler-shaped code goes here.hive-jobq-wire/— presentation of ahive-jobqgraph to viewers (WireNode/WireResource); kept out ofhive-jobqon purpose.hive-jobq-metrics/— OTEL export of a graph's state rollup on a timer.hive-log/— the one log-sink chooser: journald or stdout, never both (under a unit, stdout already is the journal). Do not grow it into a utility crate.hive-metric/— one-shot CLI pushing a labeled metric over OTLP.
Wire types + socket plumbing:
hive-types/— leaf newtypes, chiefly the validatedIdent.hive-sh4re/— shared payload types (Message,HelperEvent, …).hive-host-sock/(hivectl ↔ c0re),hive-priv-sock/(c0re ↔ priv),hive-core-agent-sock/(harness ↔ c0re,/run/hive/mcp.sock) — per-socket wire types, split out so each client links only its protocol.hive-agent-sock/— the in-agent socket the harness serves to in-container producers (todos, reminders); also holds theextra_mcpspec. ⚠️ This socket never leaves the container —hive-c0reis not in the path, unlikehive-core-agent-sock.hive-sock-client/— the shared JSON-line unix-socket client; retry is a policy value (Retry::None/Retry::RideOutRestart). Also holds the bounded request-line reader (read_request_line) the socket servers use.
Swarm-level:
swarm-controller/— owns what is true across hives; opt-in, one per swarm. Serves HTTP over a unix socket nginx proxies to — ⚠️ the socket's directory is its access control; the crate README has the constraint and a unit test pins the path.swarmctl/— swarm operator CLI; runs as root and acts directly (README says why). Does not linkswarm-controller— its wire shapes are a local mirror. ⚠️ Edits authelia'susers.ymlin place, shared withswarm-authelia-bridge; that crate's README says what both writers must uphold. Verb reference (CI-enforced):docs/tools/swarmctl-cli.md.swarm-authelia-bridge/(+swarm-authelia-bridge-sock/wire types) — the other writer of authelia's users DB; runs insideswarm-authelia.swarm-secret-client/— OpenBao client overvaultrs. ⚠️ Reads theBAO_env spellings explicitly —vaultrs'sVAULT_*defaults are set by no unit here, and falling through to them yields a client with no identity and a TLS failure that names no cause.swarm-queue-client/— the one authenticated connect to the swarm NATS queue.swarm-nats-auth/— NATS auth-callout responder; without it the queue is fail-closed and admits nobody.swarm-agent-verify/— checks aswarm-agent.<agent>.<secret>token against the store; shared byswarm-nats-authandswarm-logs-auth.swarm-logs-auth/— nginxauth_requestresponder for agent access to the log store.swarm-metrics-auth/— nginxauth_requestresponder for Grafana's bearer on the metrics store's query API.swarm-logs/— agent CLI: a LogsQL query in, log lines out.swarm-matrix-client/— appservice calls against the swarm homeserver, shared byswarm-controllerandswarm-matrix-ctl.swarm-matrix-ctl/— the one binary run insidecontainers.hive-matrix; new in-container jobs are verbs here, not crates.swarm-builder/— builds agent config PR heads for commit status. Design:docs/swarm/builder.md.swarm-ci-metrics/— polls the forge's Actions runs and pushes each finished run's duration and queue wait to the metrics store. Design:docs/swarm/ci-metrics.md.swarm-claude-login/— runsclaude auth loginfor one agent and stores the credentials atswarm/agents/<agent>/claude-credentials. Design:docs/swarm/claude-login.md.swarm-review-classifier/— oneclaude --printper PR classification, no tools, no forge credential. Design:docs/swarm/review-classifier.md.
External dependencies with no directory here
hive-claude— app-agnostic driver for headlessclaude --print(stream-json,Telemetry, the self-compactingInfiniteSession). ⚠️ Its own repo, not a workspace member — there is nohive-claude/directory andgrephere will not find it.
Other top-level dirs
frontend/— npm workspaces built hermetically bynix/packages/frontend.nix:shared,dashboard(operator SPA),agent(per-container UI),swarm-ui(Preact; packaged separately bynix/packages/swarm-ui.nix, not inpackages.default's closure).nix/—host-modules/(the host stack),agent-modules/(per-agent harness features),container-modules/(guest side of service containers),templates/{agent,ruth}.nix(container entry points),packages/,docs/(options doc),module-eval/(NixOS module-eval tests),builder/(check-flake),script-tests/, plussources.nix/rust.nix/checks.nix/devshell.nix/treefmt.nixbehind the thinflake.nix.docs/— subsystem reference docs (see Reading paths below).branding/,scripts/— static assets + helper scripts.
Reading paths
docs/README.md is the single index, grouped by
topic. Don't add a second copy of it here — a parallel list used to live
in this file and drifted.
Conventions & process
- Never add
#[allow(clippy::…)]— fix the lint instead (extract a helper, add backticks, etc.). Worked examples:docs/process/conventions.md. - Pre-push lint hook (catches tracker-tag and comment-block failures
before CI does — install once per clone):
ln -sf ../../scripts/pre-push .git/hooks/pre-push - Comment/PR-description length: size it to how non-obvious the
thing is, not to how much investigation it took to find it — a
mechanical fix gets a one-line comment, a genuinely non-obvious
invariant or decision earns real prose. Don't restate a module's
//!doc in a comment further down the same file. - Operator-facing doc with real implementation detail mixed in: wrap
the implementation part in a
<details><summary>…</summary>block (blank line after<summary>so the markdown inside renders) rather than a sibling page — seedocs/integrations/github.md's "Implementation" section. It only collapses in a rendered browser, and the<summary>line isn't markdown-processed, so keep it plain prose with no backticks.