diff --git a/hive-host-sock/Cargo.toml b/hive-host-sock/Cargo.toml index b39f0f9e..cdb83f53 100644 --- a/hive-host-sock/Cargo.toml +++ b/hive-host-sock/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-host-sock" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-host-sock/README.md b/hive-host-sock/README.md new file mode 100644 index 00000000..d9f427cc --- /dev/null +++ b/hive-host-sock/README.md @@ -0,0 +1,24 @@ +# hive-host-sock + +Wire types for the **host admin socket** (`/run/hyperhive/host.sock`) — the +host-control protocol spoken between the `hivectl` operator CLI and the +`hive-c0re` daemon. + +## Why it's its own crate + +Re-homed out of `hive-sh4re` so a standalone `hivectl` depends on **just this +protocol crate** instead of the whole daemon-shared crate. `hivectl` drives the +full hive (spawn / kill / destroy / rebuild / deploy) over this socket without +linking `hive-c0re`; keeping the request/response shapes here is what makes that +thin dependency possible. + +## Shape + +Serde-derived request/response enums for the host admin protocol. The larger +shared payload types some variants reference (`Approval`, `AgentStatusRow`, +`jobs::DagView`) stay in `hive-sh4re` — this crate is only the protocol +envelope, no server or client implementation. + +See `docs/boundary.md` (host admin socket access) for the trust model around who +may connect to the socket, and `hive-priv-sock` for the sibling split on the +privileged-helper socket. diff --git a/hive-jobq/Cargo.toml b/hive-jobq/Cargo.toml index 13059fa1..aa5370f7 100644 --- a/hive-jobq/Cargo.toml +++ b/hive-jobq/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-jobq" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-jobq/README.md b/hive-jobq/README.md new file mode 100644 index 00000000..46bcad53 --- /dev/null +++ b/hive-jobq/README.md @@ -0,0 +1,58 @@ +# hive-jobq + +A persistent job-DAG scheduler, extracted from hive-c0re's in-tree `job_queue` +as a **domain-agnostic** library. It schedules a single persistent graph of +nodes over named resources; it knows nothing about containers, rebuilds, or any +hyperhive type — the node payload `N` and resource name `R` are both generic, so +the caller supplies its own domain. + +## When to use it + +Reach for this crate whenever you need to run a DAG of interdependent work items +under bounded, named concurrency — the hive-c0re rebuild/lifecycle queue is the +first consumer, but nothing here is specific to it. The caller defines the node +kinds, wires deps, and supplies a runner; the scheduler decides what can start. + +## Model + +One **persistent graph** for the whole system, not a DAG per job. Enqueuing +inserts a self-contained sub-DAG and returns the new node ids; the scheduler +runs a continuous loop, starting every node whose deps are satisfied: + +- **Resource deps** are named counting semaphores over a caller-chosen type `R` + — e.g. `build-slot` (capacity N), `agent/` (capacity 1), or any + unconfigured name (capacity 1, created on use). A node acquires *all* its + resource deps atomically at start (all-or-nothing) — no hold-and-wait, so no + deadlock. +- **Node deps** wait on another node per `DepWhen`: `AfterOk` needs success (a + failed dep cancels the dependent), `AfterAny` only needs terminal. + +A node carries two independent axes: its `Dep`s (ordering + resource needs) and +its `parent` (structural grouping). The **parent chain**, not the node edges, is +what the scheduler consults for resource re-entrancy: a resource unit is held +for the acquiring node *plus its whole parent subtree*, and a descendant needing +a resource an ancestor already holds re-uses that grant (a re-entrant borrow, +one branch at a time) rather than taking a fresh unit. + +A `NodeId` is opaque, stable, and monotonic (safe to persist). The scheduler is +single-threaded — it owns the resource table and mutates it directly. + +## Shape + +- **`Graph`** — the persistent node store. `insert` mints ids and + validates dep/parent references; `set_state` is the single state-transition + choke point (and where each node's lifecycle timestamps — + `started_at` / `finished_at`, `DateTime` — are stamped). +- **`Node`** — `{ id, parent, payload, deps, state, started_at, + finished_at, error }`. All fields public; derives serde for persistence + the + wire. +- **`Scheduler`** — drives the graph: `settle()` starts every ready node + (acquiring resources atomically), `complete(id, outcome)` reports a finished + node's result and rolls terminality up the parent chain, releasing grants once + a subtree is done. `Outcome::{Done, Failed(String)}` — the failure reason + rides `Failed` onto the node's `error`. +- **`ResourceTable`** — per-name capacities; unconfigured names default to + capacity 1. + +See the crate-root and `scheduler` module `//!` docs for the full borrow/release +model. diff --git a/hive-priv-sock/Cargo.toml b/hive-priv-sock/Cargo.toml index e2902d84..d147d12e 100644 --- a/hive-priv-sock/Cargo.toml +++ b/hive-priv-sock/Cargo.toml @@ -2,6 +2,7 @@ name = "hive-priv-sock" edition.workspace = true version.workspace = true +readme = "README.md" [lints] workspace = true diff --git a/hive-priv-sock/README.md b/hive-priv-sock/README.md new file mode 100644 index 00000000..bbfdfbba --- /dev/null +++ b/hive-priv-sock/README.md @@ -0,0 +1,21 @@ +# hive-priv-sock + +Wire types for the **`hive-priv` privileged-helper socket** +(`/run/hive/priv.sock`) — the contract between `hive-priv` (the root helper, +server) and `hive-c0re` (client, via its `priv_client`). + +## Why it's its own crate + +Split out of `hive-sh4re` so `hive-priv` — a **root-privileged** binary — +depends on just this narrow protocol crate instead of the much larger +daemon-shared crate. Two wins: fewer dependencies in a root process's supply +chain, and a small, self-contained interface makes the privilege boundary this +crate encodes easier to audit. Mirrors `hive-host-sock`'s split for the host +admin socket. + +## Shape + +Serde-derived request/response types only — no server or client logic. Both +sides import them so the shapes stay in sync. See `docs/boundary.md` + +`docs/security.md` for the privilege boundary these types sit on, and +`hive-priv/README` for the helper itself.