From 6458c039a01cec14a962a0605c1ec34f9a52ecc2 Mon Sep 17 00:00:00 2001 From: atlas Date: Sat, 1 Aug 2026 16:23:10 +0200 Subject: [PATCH] docs(#2815): the transient pill's vocabulary is open, not a fixed set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit argus flagged on !2910 that the dashboard doc still described the pill's old shape. It did, in two ways that now teach the wrong thing: - it listed a fixed vocabulary, where the label is now the running node's own wire tag — the `NodeKind::as_str` strings `NodeView.kind` already carries. A client that switches on specific values is now wrong, and `restarting` in particular no longer exists at all. - it described the transient as operator-initiated ("set the moment the operator clicks"), which was the distinction between it and the rebuild-queue fallback. That is no longer true: the transient is derived from the running node, so worker-driven work the operator never clicked lights the same pill. The queue-`kind` half of that section is untouched — that path did not change and its vocabulary is still fixed. Also notes on the wire-event list that `transient_kind` is a display string to render, not an enum to branch on, since that is the property a client would otherwise have to infer from a now-open set. Docs only, no code change. --- docs/web-ui/dashboard.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index 7556155b..a8cfaff2 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -852,12 +852,29 @@ fetch entirely. icon, so it's obvious at a glance which container is actually moving. **Pending-state derivation:** the pill is sourced from two - separate stores in priority order. (1) The operator-initiated - **transient** (`transientsState`) is set on the dashboard the - moment the operator clicks start / stop / restart / rebuild / - destroy / spawn — covers the create-and-start window where the + separate stores in priority order. (1) The **transient** + (`transientsState`) — covers the create-and-start window where the container literally isn't up yet, before any backend state event - has fired. (2) If no transient is set, the **rebuild-queue + has fired. + + A transient is **derived from the 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), + 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. + - It is **not** exclusively operator-initiated. Work the operator + never clicked (a meta-update cascade, a crash-recover rebuild) + lights the same pill, since it is the running node that sets it. + + Ops with no queue node behind them (destroy, migration) supply + their own label directly. (2) If no transient is set, the **rebuild-queue entry** for this agent is consulted (`rebuildQueueState`); this covers worker-driven ops — meta-update cascades, crash-recover rebuilds, approval-driven rebuilds — that the operator didn't @@ -1351,7 +1368,9 @@ payload): - `transient_set` (name, transient_kind, since_unix) / `transient_cleared` (name) — lifecycle action spinners. The client ticks the elapsed-seconds badge off `since_unix` - client-side, no polling. + client-side, no polling. `transient_kind` is an **open** + display string (the running node's own tag), not a fixed + enum — render it, don't branch on it. - `container_state_changed` (container: ContainerView) / `container_removed` (name) — per-row container mutations, emitted by `Coordinator::rescan_containers_and_emit` from