From ec16b80415612c2d99ae409132722fee7066516d Mon Sep 17 00:00:00 2001 From: atlas Date: Sun, 2 Aug 2026 13:06:01 +0200 Subject: [PATCH] docs(coordinator): a DAG is declared, not described MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The submit-time petgraph `toposort` this described is gone — a cycle needs an edge pointing at a node declared later, and a handle only exists for a node already declared. Say why the validation pass is absent rather than leaving a description of one that isn't there. `templates.rs`'s module doc was 35 lines and over the comment-block lint's max; it now points here for the reasoning instead of restating it, and drops the power-op paragraph that `submit.rs` already owns. --- docs/coordinator.md | 12 +++++++--- hive-c0re/src/job_queue/templates.rs | 33 +++++++++------------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/docs/coordinator.md b/docs/coordinator.md index af66f329..dc87418d 100644 --- a/docs/coordinator.md +++ b/docs/coordinator.md @@ -23,9 +23,15 @@ dashboard group; the **node** is the unit of scheduling / execution / build-log. Deps are intra-DAG edges only (`AfterOk` by default: the dep must succeed, a failed/cancelled dep cancels the dependent — cancel-downstream). Cross-DAG ordering comes from the per-agent lease, -never from edges between DAGs. Submit-time validation (petgraph `toposort`) -rejects cyclic specs outright, fixing the old queue's "circular dep silently -deadlocks" caveat. +never from edges between DAGs. + +A DAG is **declared, not described**: a template builds it through +`hive_jobq::JobBuilder`, naming each node it depends on via the handle +`b.node(kind)` handed back, and the builder inserts the nodes itself. A handle +only exists for a node already declared, so every edge points backwards and a +cycle cannot be written down — there is no submit-time validation pass, because +there is no malformed spec to reject. (The old queue had a petgraph `toposort` +here, guarding against the positional indices that used to express edges.) ### Node inventory (primitives) diff --git a/hive-c0re/src/job_queue/templates.rs b/hive-c0re/src/job_queue/templates.rs index 78f6550b..5ea6c886 100644 --- a/hive-c0re/src/job_queue/templates.rs +++ b/hive-c0re/src/job_queue/templates.rs @@ -1,19 +1,7 @@ //! DAG shape builders — every operation as a template over the shared -//! node primitives. -//! -//! Every node carries its own `agent` (there is no DAG-level agent) — the -//! [`node`] helper stamps each node's agent and declares the resources that -//! node's kind needs. This module holds the *pure* shape builders (no I/O). -//! The hive-wide **power ops** (`stop` / `start` / `restart`) are NOT here: -//! their per-agent shape depends on each agent's live running state (an async -//! `lifecycle::is_running` read), so they are assembled dynamically in -//! `submit.rs` out of the shared pure primitives this module exports -//! ([`node`], [`rebuild_nodes`]) — one independent per-agent subgraph each, -//! concurrent on its own lease, ONE DAG for the whole hive-wide op. -//! `stop`/`start` write the durable `wanted` intent via a head `SetWanted(w)` -//! node (holding the agent lease, so intent+reconcile is atomic per-agent); -//! `restart` writes no intent — it bounces the container and lets the tail -//! `Reconcile` converge to the agent's existing `wanted`. +//! node primitives. Pure (no I/O); each node carries its own `agent` (there is +//! no DAG-level agent), stamped by the [`node`] helper along with the +//! resources that node's kind needs. //! //! ```text //! rebuild(a): MetaSync(a) → Prebuild(a) → StopForUpdate(a) → Swap(a) →(ok) PostSwap(a) →(any) Reconcile(a) @@ -24,15 +12,14 @@ //! reparent(moves): Reparent(moves) [no rebuild — topology.json is read live] //! ``` //! -//! Nodes are **named, not counted**: a template declares a node and holds the -//! handle it gets back, so an edge says which node it waits on instead of -//! computing where that node landed. There is no submit-time cycle validation -//! left to do — `hive_jobq`'s builder inserts in declaration order and rejects -//! a reference to a node declared later, so every edge points backwards and a -//! cycle is unrepresentable rather than merely rejected. +//! Nodes are **named, not counted** — a template holds the handle +//! [`Job::node`] hands back, so an edge says which node it waits on. Why that +//! removes submit-time cycle validation: `docs/coordinator.md`. //! -//! For the dynamic power-op shapes (`stop` / `start` / `restart`, built from -//! live online/offline state), see `submit.rs`. +//! The hive-wide **power ops** (`stop` / `start` / `restart`) are NOT here: +//! their per-agent shape depends on live running state (an async +//! `lifecycle::is_running` read), so `submit.rs` assembles them out of the +//! primitives this module exports ([`node`], [`rebuild_nodes`]). use hive_jobq::TerminalState;