docs: stop asserting DagView/NodeView after their deletion
The deletion PR removed the types but left ~10 sites still describing
them. Two are real breakage rather than staleness: rustdoc intra-doc
links to deleted items ([NodeView::kind] and [Self::snapshot] in
job_queue/mod.rs). Neither clippy --all-targets -D warnings nor cargo
test resolves intra-doc links, so the tree was green with both already
dangling.
The rest reassert facts the deletion made false: docs/coordinator.md
documented the event as RebuildQueueChanged { seq, queue: [DagView...] }
with a per-node field list, and three sites pointed at the removed
/api/state.rebuild_queue endpoint.
One is pointer rot rather than a rename, and no grep for a deleted name
finds it: SchedulesChanged justified itself as "same snapshot-shape
rationale as RebuildQueueChanged" -- which the deletion turned into the
one event that is not a snapshot. Repointed at TombstonesChanged /
MetaInputsChanged, in both the Rust doc and the dashboard doc.
Two are pre-existing and strictly out of scope, swept under the
pfadfinderregel because the same grep surfaced them: hive-sh4re/README
advertised a jobs module that crate has not had since the host-sock
split, and hive-host-sock/README claimed its own payload types live in
hive-sh4re.
Docs and comments only -- no behaviour, no API, no test changes.
This commit is contained in:
parent
f707c60f90
commit
730c923a97
10 changed files with 67 additions and 47 deletions
|
|
@ -441,8 +441,8 @@ the config PR, and for a spawn runs the post-spawn forge bookkeeping.
|
|||
Two visible consequences:
|
||||
|
||||
- **Operator dashboard**: after clicking APPR0VE the work-in-progress
|
||||
shows up on the *rebuild queue* card (`/api/state.rebuild_queue`
|
||||
+ live `rebuild_queue_changed` events), not on the approvals panel
|
||||
shows up on the *rebuild queue* card (`GET /api/jobq/graph`, refetched
|
||||
on every `rebuild_queue_changed` tick), not on the approvals panel
|
||||
(which already moved the row to "approved"). A long meta-update
|
||||
cascade renders as a parent DAG with one child rebuild per affected
|
||||
agent — see `docs/web-ui.md` for the layout.
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Cheap — no build slot:
|
|||
| `Drain` | await the harness clearing the fence, bounded by the 3-min graceful-stop timeout; resolves ok either way |
|
||||
| `WriteDropin` | `set_nspawn_flags` + `set_resource_limits` + daemon-reload |
|
||||
| `WritePermFile` | commit `tool-groups.json` / `capabilities.json` (single git commit under `META_LOCK`) + emit the P3RM1SS10NS snapshots |
|
||||
| `Reparent` | `set-parent` / `set-parent-bulk`: apply every `(child, new_parent)` move under one `META_LOCK` commit (`meta::bulk_commit_topology`), send the per-agent move notifications, rescan + diff-emit. Agentless like `MetaLock` — a bulk move can span multiple agents, and a reparent touches the meta repo, not any one container. `moves` is `(Ident, Option<Ident>)` pairs, not raw strings — mara: "use Ident type instead of string" (#2719, issuecomment 42691). Rides `Template::MetaUpdate` rather than a dedicated `Template` variant — that enum is on its way out (see `#2665`, still open/blocked on a scope question) and is already internal-only (not on `DagView`'s wire shape), so the stand-in only affects `terminal_hook` dispatch (resolves to no hook either way) and history-retention bucketing |
|
||||
| `Reparent` | `set-parent` / `set-parent-bulk`: apply every `(child, new_parent)` move under one `META_LOCK` commit (`meta::bulk_commit_topology`), send the per-agent move notifications, rescan + diff-emit. Agentless like `MetaLock` — a bulk move can span multiple agents, and a reparent touches the meta repo, not any one container. `moves` is `(Ident, Option<Ident>)` pairs, not raw strings — mara: "use Ident type instead of string" (#2719, issuecomment 42691). Rides `Template::MetaUpdate` rather than a dedicated `Template` variant — that enum is on its way out (see `#2665`, still open/blocked on a scope question) and is already internal-only (it never reaches the graph wire), so the stand-in only affects `terminal_hook` dispatch (resolves to no hook either way) and history-retention bucketing |
|
||||
|
||||
There is deliberately **no `GitCommit` node**: `meta.rs` fuses each mutation
|
||||
with its commit under its internal `META_LOCK` mutex, so a standalone commit
|
||||
|
|
@ -252,16 +252,26 @@ cancelled-while-queued, which fails the approval instead of dangling it).
|
|||
|
||||
### Wire shape
|
||||
|
||||
`RebuildQueueChanged { seq, queue: [DagView…] }` (event name kept). Each
|
||||
`DagView` carries the entry-level fields (`id`, `kind` = template string,
|
||||
roll-up `state`, `source`, `reason`, timestamps, `inputs`,
|
||||
`approval_id`) plus `nodes: [NodeView…]` — per-node `agent`, `kind`, `deps`,
|
||||
`state`, `build_log_id`, timestamps, `error`. There is **no
|
||||
DAG-level `agent`** (agent is per-node, so a DAG can span agents); consumers
|
||||
derive a DAG's agent(s) from its nodes. The node kind *is* the phase label —
|
||||
there is no separate sub-step string; build logs are **per-node**. The
|
||||
dashboard renders the node chain on each queue card and keys the live-log
|
||||
panel off the running node.
|
||||
`RebuildQueueChanged { seq }` (event name kept) — **a bare trigger, no
|
||||
payload.** It says *the queue changed*; a client that wants to know how
|
||||
re-fetches `GET /api/jobq/graph`.
|
||||
|
||||
That endpoint serves the graph generically (`hive-jobq-wire`): every node
|
||||
carries `id`, `parent`, `deps`, `state`, `label` (the node kind's own wire
|
||||
string — the kind *is* the phase label, there is no separate sub-step
|
||||
string) and free-form `data` for what only some kinds have (`agent`,
|
||||
`approval_id`, `inputs`, `build_log_id`). Group roots ride as ordinary
|
||||
nodes, so a group's state is just the root's own `state`.
|
||||
|
||||
There is **no group-level `agent`** — agent is per-node, so one group can
|
||||
span agents; consumers derive a group's agent(s) from its nodes. Build logs
|
||||
are likewise **per-node**: the dashboard renders the node tree and keys the
|
||||
live-log panel off the running node.
|
||||
|
||||
The event used to ship the whole queue as a typed `DagView`/`NodeView`
|
||||
projection. That was a second rendering of the same graph, kept in
|
||||
agreement by hand with the endpoint every consumer actually read; it is
|
||||
gone, and the event's whole job is now telling a client *when* to refetch.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -225,12 +225,10 @@ does not render the queue itself; it just mounts the element and
|
|||
listens for its `hive-jobq-graph-update` event to drive the two things
|
||||
below it that the generic view doesn't show. The component owns
|
||||
fetching, cold and live: `GET /api/jobq/graph` on mount, and
|
||||
`.refresh()` on every `rebuild_queue_changed` SSE tick (that event
|
||||
still carries its own `Vec<QueueEntry>` payload — `DagView`-shaped,
|
||||
also read by `hivectl`'s own wait/progress loop, a separate migration
|
||||
— on the wire, but neither dashboard page reads it anymore; both
|
||||
treat the tick as a pure refetch trigger against the generic
|
||||
endpoint).
|
||||
`.refresh()` on every `rebuild_queue_changed` SSE tick (that event is a
|
||||
bare `{ seq }` trigger — it carried a typed queue snapshot until every
|
||||
consumer had moved to the generic endpoint, and now carries none; both
|
||||
dashboard pages treat the tick as a pure refetch trigger).
|
||||
|
||||
Each row is one root graph node (`parent: null`); a multi-step op's
|
||||
per-agent subgraphs and sub-steps render as nodes within that one
|
||||
|
|
@ -900,7 +898,8 @@ fetch entirely.
|
|||
life). Two consequences for anything rendering it:
|
||||
|
||||
- The label vocabulary is **open** — it is the node's own wire tag
|
||||
(`NodeKind::as_str`, the same strings `NodeView.kind` carries),
|
||||
(`NodeKind::as_str`, the same strings the graph wire's node
|
||||
labels carry),
|
||||
not a fixed set. Treat it as an opaque display string; do not
|
||||
switch on specific values. `restarting` in particular no longer
|
||||
exists, because no node kind is unique to a restart.
|
||||
|
|
@ -1441,19 +1440,19 @@ payload):
|
|||
`crash_watch` poll. Client upserts/removes by name; the
|
||||
pending overlay is read from `transientsState` since the
|
||||
payload doesn't carry it.
|
||||
- `rebuild_queue_changed` (seq, queue: `Vec<QueueEntry>`) —
|
||||
full snapshot of the rebuild queue on every mutation (enqueue,
|
||||
state transition, dedup collapse, terminal-history trim).
|
||||
Same snapshot-over-diff rationale as `tombstones_changed` /
|
||||
`meta_inputs_changed`: the list is small and the client renders
|
||||
each DAG's multi-agent shape from its own `nodes` (no cross-DAG
|
||||
grouping). Cold-loaded from `/api/state.rebuild_queue`.
|
||||
- `rebuild_queue_changed` (seq) — **payload-free trigger**, fired on
|
||||
every queue mutation (enqueue, state transition, dedup collapse,
|
||||
terminal-history trim). Unlike the snapshot events below it ships
|
||||
no state at all: the client re-fetches `GET /api/jobq/graph`, which
|
||||
is where it reads the queue from cold too. There is no
|
||||
`/api/state.rebuild_queue` — it went with the typed projection.
|
||||
- `schedules_changed` (seq, schedules: `Vec<WireSchedule>`) —
|
||||
full snapshot of all scheduled prompts. Emitted after every
|
||||
operator mutation via the `/api/schedules` surface (new /
|
||||
edit / cancel / fire-now) and after the worker fires or
|
||||
rearms a row. Same snapshot-shape rationale as
|
||||
`rebuild_queue_changed`. The SCH3DUL3S tab subscribes and
|
||||
`tombstones_changed` / `meta_inputs_changed` (small list, no
|
||||
add/remove races). The SCH3DUL3S tab subscribes and
|
||||
re-renders `schedulesState` on receipt; tab activation still
|
||||
re-fetches as a safety net for approval-path inserts and
|
||||
disconnect windows.
|
||||
|
|
|
|||
|
|
@ -635,10 +635,14 @@ impl Coordinator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Emit a `RebuildQueueChanged` snapshot event. Called from the
|
||||
/// queue mutation helpers (`enqueue` / `finish` / `cancel`-adjacent
|
||||
/// wrappers below) and the worker so every state transition
|
||||
/// surfaces on the dashboard without extra plumbing.
|
||||
/// Emit a `RebuildQueueChanged` tick. Called from the queue mutation
|
||||
/// helpers (`enqueue` / `finish` / `cancel`-adjacent wrappers below) and
|
||||
/// the worker so every state transition surfaces on the dashboard without
|
||||
/// extra plumbing.
|
||||
///
|
||||
/// Carries no queue payload — clients refetch `/api/jobq/graph`. The name
|
||||
/// keeps `snapshot` because *that* is still what a client ends up with;
|
||||
/// what changed is who serves it.
|
||||
pub fn emit_rebuild_queue_snapshot(self: &Arc<Self>) {
|
||||
self.emit_dashboard_event(DashboardEvent::RebuildQueueChanged {
|
||||
seq: self.next_seq(),
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ pub(super) async fn get_build_log_full(
|
|||
///
|
||||
/// Same `BuildLogFull` JSON (`stdout` / `stderr` + header) as
|
||||
/// `get_build_log_full`; HTTP 404 when the node has no linked log (the
|
||||
/// client gates the request on `NodeView.build_log_id`, but a vacuum
|
||||
/// client gates the request on the wire node's `build_log_id`, but a vacuum
|
||||
/// race can still 404). This is the on-demand live-log-panel fetch,
|
||||
/// distinct from the `build_log_id` on the wire — that id is for
|
||||
/// deep-linking to the BUILD L0GS tab's full history view, not for
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@ pub enum DashboardEvent {
|
|||
/// Full snapshot of all scheduled prompts. Emitted after every
|
||||
/// operator mutation (new / edit / cancel / fire-now) and after the
|
||||
/// worker fires or rearms a row. Same snapshot-shape rationale as
|
||||
/// `RebuildQueueChanged` — the list is small and the client's
|
||||
/// `TombstonesChanged` / `MetaInputsChanged` — the list is small and the
|
||||
/// client's
|
||||
/// per-target `last_result` / `last_fired_at_unix` fields are most
|
||||
/// naturally re-derived from the full list.
|
||||
SchedulesChanged {
|
||||
|
|
|
|||
|
|
@ -308,9 +308,10 @@ impl JobQueue {
|
|||
/// so both are running and both name `a`. Anything keying this set by agent
|
||||
/// alone will silently drop one — see [`super::scheduler`].
|
||||
///
|
||||
/// `label` is the node's own wire tag ([`NodeKind::as_str`]), the vocabulary
|
||||
/// [`NodeView::kind`] already ships, so a pill and a DAG node name an
|
||||
/// operation identically. `takes_container_down` is the crash watcher's
|
||||
/// `label` is the node's own wire tag ([`NodeKind::as_str`]), the same
|
||||
/// vocabulary the graph wire ships as a node's label, so a pill and a
|
||||
/// graph node name an operation identically. `takes_container_down` is the
|
||||
/// crash watcher's
|
||||
/// input and does **not** ride the wire to the frontend — a `Start` pill and
|
||||
/// a `Stop` pill are both pills; only one means a vanished container is
|
||||
/// expected.
|
||||
|
|
@ -381,10 +382,10 @@ impl JobQueue {
|
|||
|
||||
/// One or more nodes plus their live subtrees, as generic wire nodes —
|
||||
/// the `QueueNodes` polling surface behind `hivectl`'s wait/progress
|
||||
/// loop. Sibling of [`Self::snapshot`] (which serves the same graph
|
||||
/// through the typed `DagView`/`NodeView` projection for the
|
||||
/// dashboard's `/api/state.rebuild_queue`), this one goes through
|
||||
/// [`GraphWire::wire_snapshot`] instead — no `Done`-node filtering, no
|
||||
/// loop. Goes through [`GraphWire::wire_snapshot`] — the same projection
|
||||
/// [`Self::graph_snapshot`] serves the dashboard with, differing only in
|
||||
/// *which* nodes it selects (caller-named ids and their subtrees, rather
|
||||
/// than every visible root). No `Done`-node filtering, no
|
||||
/// roll-up field (a node's own `state` answers that, see
|
||||
/// `hive_jobq_wire`'s doc comment). Looks each id up by identity
|
||||
/// alone — no assumption that it names a DAG container or a root;
|
||||
|
|
|
|||
|
|
@ -322,7 +322,8 @@ impl hive_jobq_wire::WireNode for NodeKind {
|
|||
}
|
||||
|
||||
impl NodeKind {
|
||||
/// Wire string for `NodeView.kind`.
|
||||
/// Wire string for the node's label on the graph wire
|
||||
/// ([`hive_jobq_wire::WireNode::label`]).
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
NodeKind::MetaSync { .. } => "meta_sync",
|
||||
|
|
|
|||
|
|
@ -15,9 +15,15 @@ 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.
|
||||
shared payload types some variants reference (`Approval`, `AgentStatusRow`)
|
||||
stay in `hive-sh4re` — this crate is only the protocol envelope, no server or
|
||||
client implementation.
|
||||
|
||||
Its own `jobs` module is the exception: the job-queue vocabulary `hivectl`
|
||||
needs (`Source`, `State`, `PermPayload`, `NodeId`) is protocol-local. The typed
|
||||
`DagView`/`NodeView` projection that used to live there is gone — the queue is
|
||||
served as a generic graph (`hive-jobq-wire`), not as a second hand-written
|
||||
view.
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ Those crates re-export or reference the payload types that still live here
|
|||
|
||||
## 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<Utc>` (serialized RFC 3339), while sqlite storage + input
|
||||
args stay unix-epoch `i64`; this module owns the two boundary conversions.
|
||||
|
|
|
|||
Loading…
Reference in a new issue