swarm.js: drop per-agent pending-badge fallback, transients-only now

mara, on review: "swarm.js should not need to pull in the jobq to do
its job" followed by "remove the per agent pending stuff - only show
what is running."

Deletes queuedOpsByAgent() entirely — no more per-agent badge derived
from Pending-state job-queue nodes. A card's pending badges are now
driven exclusively by transientsState (i.e. actually-running work);
queued-but-not-started work shows nothing on the card until a node
starts. jobqNodesState + refreshJobqGraph() stay, now feeding only
the queue-summary banner (a separate, still-open question — mara
separately asked for a dedicated rollup endpoint for that, tracked
apart from this PR).

Collapses the now-always-coincident `pending`/`pending-running` row
classes into one (`pending-running`) — there's no more queued-only
row state to visually distinguish it from.

docs/web-ui/dashboard.md's Container-row section rewritten to match:
the two-store priority-fallback description is gone, replaced with
"transients only."
This commit is contained in:
iris 2026-08-03 19:18:52 +02:00 committed by mara
commit 17f61d1da6
4 changed files with 66 additions and 106 deletions

View file

@ -883,22 +883,19 @@ fetch entirely.
independent badge rather than being collapsed into one label,
matching the existing multi-badge convention this line already uses
for `paused`/`needs_update`/model/ctx.
The row visual splits queued vs running: a **queued** entry (no
transient yet, see below) shows only the pending-state pill (no row
tint, so a long queue doesn't paint half the tab amber); a
**running** entry (at least one transient) keeps the amber row tint
AND draws a **rotating amber ring** around the agent icon, so it's
obvious at a glance which container is actually moving.
Any pending badge means the row is actually **running** something
right now — there is no separate queued-but-not-started row state
to visually distinguish it from (see **Pending-badge derivation**
below), so every row carrying ≥1 badge keeps the amber row tint AND
draws a **rotating amber ring** around the agent icon.
**Pending-badge derivation:** two separate stores, but no longer a
priority *order* between them — the second only ever applies when
the first has nothing to say. (1) **Transients**
(`transientsState`, keyed `agent -> Map<kind, since_unix>`) — a
transient is **derived from a job-queue node currently `Running`**
against that agent, not declared per request, so its label follows
the operation as it progresses (a rebuild reads `stop_for_update`,
then `swap`, then `reconcile` rather than one constant `rebuilding`
for its whole life). Two consequences for anything rendering it:
**Pending-badge derivation:** transients only (`transientsState`,
keyed `agent -> Map<kind, since_unix>`) — a transient is **derived
from a job-queue node currently `Running`** against that agent, not
declared per request, so its label follows the operation as it
progresses (a rebuild reads `stop_for_update`, then `swap`, then
`reconcile` rather than one constant `rebuilding` for its whole
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),
@ -916,24 +913,14 @@ fetch entirely.
their own label directly via `TransientSet`/`TransientCleared`
events carrying no backing node at all.
(2) The **job-queue fallback** (`jobqNodesState`, the flat
`GraphNode[]` from `GET /api/jobq/graph``swarm.js`'s
`refreshJobqGraph`, same generic endpoint the BU1LDS page's
`<hive-jobq-graph>` self-fetches, see above) only fires when an
agent has **zero** transients — since (1) now covers every
`Running` node unconditionally, a `Running` job-queue node can
never usefully reach this fallback by the time it's consulted; the
fallback exists purely for the **`Pending` (queued, not yet
started)** case, which `running_transients()`'s Running-only test
cannot represent. `queuedOpsByAgent()` (swarm.js) reflects this: it
only ever looks at `Pending`-state nodes carrying a non-empty
`payload.data.agent`, and (mara, on review) the badge shows the
node's raw `payload.label` string as-is — no English-phrase lookup
translating it first, same opaque-string treatment a transient's
own label already gets.
`opRunning` (driving the `pending-running` row class + spinner) is
simply "does this agent have at least one transient" — a queued-only
entry (no transient yet) leaves it false.
**Queued (not-yet-started) work shows nothing on the card.** An
earlier version of this page had a job-queue-backed fallback badge
for the `Pending` case (`queuedOpsByAgent()` in swarm.js, reading
`jobqNodesState`); removed per mara, on review of hyperhive#3028's
PR: *"swarm.js should not need to pull in the jobq to do its job"*,
followed by *"remove the per agent pending stuff - only show what
is running."* `jobqNodesState` still exists in swarm.js, but now
feeds only the queue-summary banner below, not per-card badges.
An **active model badge** (`model · <name>`, blue) appears when the
container is running and the harness has persisted a model name
(`harness/hyperhive-model`). Read by hive-c0re's `ContainerView`