docs: fix genuine passive-voice hits in docs/web-ui/dashboard.md (part 2/2)

Second half (lines 762-1389) of dashboard.md's write-good.Passive backlog --
22 rewrites, reusing an actor already named nearby wherever one exists
(the dashboard, hive-c0re, the harness, the operator, the endpoint, the
broker forwarder, CSS, Client, the manual fan-out, ...). Companion to
part 1 (PR #4117, lines 1-697).

10 left alone in this half: five established idioms (config-state
conditionals, negative-capability "nothing is X", state descriptors
"is untouched"/"is gone"), and one literal quoted UI string
("container will be created") that documents exact displayed text
rather than the doc's own voice. One rewrite (naming "the dashboard"
for the old L762 'is known stopped') incidentally leaves behind a new
instance of the same 'is stopped' idiom already accepted at L797 --
21 net fewer hits from this half, not 22, though 22 edits were made.

Together with part 1 (31 rewrites, 7 left alone), this closes out
dashboard.md's 70-hit Passive backlog: 53 edits total, 52 net fewer
hits, 18 left alone.
This commit is contained in:
iris 2026-09-08 15:18:08 +02:00 committed by mara
commit acdd9e884b

View file

@ -759,9 +759,9 @@ dashboard doesn't pre-check whether the agent is reachable, it
just lets the `<img>` try and listens for an `error` event. On
failure the handler swaps the `src` to `/favicon.svg` (served by
the dashboard itself, always reachable) and adds the
`icon-unreachable` class for the dimmed look. When the container
is known stopped up front (`ContainerView.running = false`) the
fallback fires immediately, skipping the doomed `<url>/icon`
`icon-unreachable` class for the dimmed look. When the dashboard
already knows the container is stopped (`ContainerView.running = false`)
the fallback fires immediately, skipping the doomed `<url>/icon`
fetch entirely.
**Line 1** — agent name (link → new tab), m1nd/ag3nt chip, an
@ -771,8 +771,8 @@ own backend. The response (`DashboardState`) carries: `links` (nav
strip entries — `📊 stats`, `🖥 screen` when GUI is enabled, `⬡ forge
profile`, `↳ agent-configs mirror`, plus any agent-declared
`dashboardLinks` extras), `status_text` / `status_set_at` (agent
self-reported status — the `(set N ago)` chip is stamped `data-set-at`
and ticks every 30s to stay fresh across the long-lived keyed row
self-reported status — the `(set N ago)` chip carries a `data-set-at`
stamp and ticks every 30s to stay fresh across the long-lived keyed row
cache), `rate_limited`, `ctx_tokens` / `context_window_tokens`
(context-window badge data). The agent backend is the single source
of truth for all of these. The dashboard resolves each `AgentLink.kind`
@ -789,17 +789,17 @@ Gateway-off is the flag-absent fallback (a dashboard served outside a
hyperhive deploy): base URL is
`http://<host>:<container.port>` (direct TCP). Forge
links resolve against `state.forge_public_url` (sourced from
`services.hyperhive.swarm.forge.publicUrl`) and are omitted entirely when
`services.hyperhive.swarm.forge.publicUrl`) and disappear entirely when
that's unset — never guessed from `<host>:3000`. External links are
already absolute. The same base URL drives the primary agent-name
link + favicon fetch, so the whole row routes through the gateway
as a unit.
**When the container is stopped** (`ContainerView.running = false`),
the async `dashboard-state` fetch is skipped entirely (the agent
web server is down), so the badge chain is replaced by a single
badge, the nav strip is empty, and status text / rate-limited / ctx
badges are suppressed. The agent icon goes straight to the dimmed
the dashboard skips the async `dashboard-state` fetch entirely (the agent
web server is down), so a single badge replaces the badge chain,
the nav strip is empty, and status text / rate-limited / ctx
badges disappear. The agent icon goes straight to the dimmed
`/favicon.svg` fallback instead of attempting a doomed load from the
container's URL. Static fields — `needs_update`, `deployed_sha`,
`pending_reminders`, `parent`, `config` link — remain visible
@ -823,13 +823,13 @@ older backend without the field serves `failed: undefined`, which
reads falsy — degrades cleanly to the single `not running` badge.
When the container is running, status badges follow — `⊘ rate
limited` (red, while the harness is parked after a 429), `needs
limited` (red, while the harness parks itself after a 429), `needs
login`, `needs update` — plus **one `◐ pending-state…` pill per
active transient** (replaces buttons during operator-initiated
start / stop / restart / rebuild / destroy). An agent can carry
**multiple transients at once** — for example a lease-exempt `prebuild`
running alongside a `stop_for_update` on the same agent — and each
renders as its own independent badge rather than being collapsed
renders as its own independent badge instead of collapsing
into one label, matching the existing multi-badge convention this
line already uses for `paused`/`needs_update`/model/ctx.
@ -877,13 +877,13 @@ container is running and the harness has persisted a model name (the
`active_model` field of `hyperhive-harness.json`, the consolidated
harness state file in the agent's state dir). Read by hive-c0re's
`ContainerView` (`read_active_model`); absent until the agent has
completed at least one turn and stale values are suppressed for
stopped containers.
completed at least one turn, and hive-c0re suppresses stale values
for stopped containers.
**`ctx · Nk` chip** shows the agent's last-turn context size,
populated from `DashboardState.ctx_tokens` (absent until the
agent has completed at least one turn). The chip colour (green /
yellow / red) is keyed off `DashboardState.context_window_tokens`
yellow / red) keys off `DashboardState.context_window_tokens`
(the real context window for the model the agent last ran on,
authoritative from the agent side); the badge goes yellow ≥ 50%
and red ≥ 75% of that window, matching the harness compaction
@ -936,8 +936,8 @@ that wants step-level counts instead, unused here.
All confirmations, prompts, and transient error notices use an
in-app themed dialog system (`@hive/shared/modal.js`) rather than the
browser's native `confirm()` / `prompt()` / `alert()` chrome, so
they match the Catppuccin palette and can't be styled away by the
OS. Three primitives, all built on the `openDialog` core:
they match the Catppuccin palette and the OS can't style them away.
Three primitives, all built on the `openDialog` core:
- `themedConfirm({ message, danger, confirmLabel, checkboxes })`
— a modal confirm that resolves to `null` on cancel or an object
@ -987,8 +987,8 @@ text-glyph-painted**: each indent lane is its own positioned `<span>`
so CSS can draw full-height vertical bars that bridge the gap between
sibling rows. Plain text box-drawing characters (`├─`, `└─`, `│ `)
would only paint one text-line tall and leave visible breaks between
the taller-than-one-line container cards, so the bars are drawn as
CSS borders instead: a continuation bar runs the full height of an
the taller-than-one-line container cards, so CSS borders draw the
bars instead: a continuation bar runs the full height of an
ancestor's still-open subtree, and the joint at a row's own depth is
`├` (more siblings below) or `└` (last sibling — the line stops at
the row's icon midline). Exact lane widths and positioning live in
@ -1007,7 +1007,7 @@ toggles its selection (an in-memory `Set<name>`); `Esc` or the bar's
switches in-memory — the bar just hides on non-SW4RM tabs since other
tabs don't show the agent cards needed to cross-reference.
When one or more agents are selected (via the icon), a sticky
When the operator selects one or more agents (via the icon), a sticky
frosted-mauve bar slides up from the bottom of the viewport
(`#selection-bar`, `position: fixed; bottom: 0`). It shows:
@ -1043,8 +1043,8 @@ frosted-mauve bar slides up from the bottom of the viewport
the tree repaints without a page reload.
- **`✕ clear`** button + `Esc` key clear the entire selection.
Stale selections (agents destroyed while selected) are pruned on
every render before the bar appears.
Every render prunes stale selections (agents destroyed while
selected) before the bar appears.
## Approval card
@ -1186,9 +1186,9 @@ below — some endpoints aren't in it yet.
bodies at 1 MiB. Selection-time backing for the inline path-link
preview.
Detection of which tokens *are* path links is done
The broker forwarder detects which tokens *are* path links
**server-side at broker-message ingest**, not client-side:
the broker forwarder calls `scan_validated_paths(body)`
it calls `scan_validated_paths(body)`
same allow-list helper the read endpoint uses — and attaches
the verified file tokens to the event as `file_refs: Vec<String>`.
The client trusts that list and linkifies only those tokens,
@ -1241,7 +1241,7 @@ below — some endpoints aren't in it yet.
Writes the capability set for `{agent}` to
`/var/lib/hyperhive/meta/capabilities.json` and queues a rebuild so
`HIVE_CAPABILITIES` takes effect. Agent name validated;
unknown capability strings are rejected (400). `guard_agent_name`
unknown capability strings rejected (400). `guard_agent_name`
applied.
- `POST /api/permissions` — batch perm apply for the save-all
permissions button. Body
@ -1251,10 +1251,11 @@ below — some endpoints aren't in it yet.
replace semantics as the per-agent endpoints above). Each affected
agent gets ONE combined `PermChange` queue entry, so changing both
an agent's tool-groups and capabilities triggers a single rebuild,
not two. **Atomic**: every change is validated first (agent names via
not two. **Atomic**: the endpoint validates every change first (agent names via
`guard_agent_name`, group + capability names) and on any validation
error nothing is written or enqueued (non-2xx `{ error }`); rows with
both fields omitted are skipped, not errors. Returns `200 "ok"` on
error nothing is written or enqueued (non-2xx `{ error }`); it skips
rows with both fields omitted rather than erroring on them.
Returns `200 "ok"` on
success.
- `GET /api/schedules` — list all schedules (active and
recently cancelled) for the SCH3DUL3S scheduled-prompts panel.
@ -1283,8 +1284,8 @@ below — some endpoints aren't in it yet.
pulse. Fires the schedule body once immediately to
every active target. Recurring schedules: `next_fire_at_unix`
is untouched; the regular cadence continues. One-shots: the
schedule is consumed (cancelled) after the manual fan-out.
Per-target `last_result` is annotated as a manual fire so
manual fan-out consumes the schedule (cancels it).
The endpoint annotates per-target `last_result` as a manual fire so
the audit trail distinguishes scheduled fires from operator-
triggered ones.
- `POST /api/schedules/{id}/pause` — pause a recurring or
@ -1331,8 +1332,8 @@ payload):
(`actions::approve`), the job queue's own node execution
(`job_queue::exec`, for example after a rebuild's stop/swap/start
steps or a destroy's teardown step) — and from the 10s
`crash_watch` poll. Client upserts/removes by name; the
pending overlay is read from `transientsState` since the
`crash_watch` poll. Client upserts/removes by name and
reads the pending overlay from `transientsState` since the
payload doesn't carry it.
- `rebuild_queue_changed` (seq) — **payload-free trigger**, fired on
every queue mutation (enqueue, state transition, dedup collapse,
@ -1362,8 +1363,8 @@ payload):
assignments: `BTreeMap<String, Vec<String>>`) — full snapshot of
capability grants. Emitted from the rebuild-queue worker after a
`PermChange` / Capabilities entry commits the JSON file. Payload
matches `GET /api/capabilities` shape so `renderCapabilities` can
be called directly. P3RM1SS10NS tab subscribes; activation
matches `GET /api/capabilities` shape so the client can call
`renderCapabilities` directly. P3RM1SS10NS tab subscribes; activation
re-fetch still runs as a safety net.
- `tool_groups_changed` (seq, groups: `Vec<str>`, descriptions: map,
assignments: `BTreeMap<String, Vec<String>>`) — full snapshot of