docs(#2815): the transient pill's vocabulary is open, not a fixed set

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.
This commit is contained in:
atlas 2026-08-01 16:23:10 +02:00
commit 6458c039a0

View file

@ -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