docs/web-ui.md: scrub self-ref cookies (#719 batch 1)

14 issue-ref cookies removed from docs/web-ui.md. Most were
attribution refs to closed issues that landed the feature being
described — the prose around them already describes the current
behaviour, the cookie was just a 'this was issue NNN' breadcrumb.

Scrubbed:
- #753 (manager port hash 8100-8999)
- #233 (linkify XSS)
- #448 (SSE multiplexing SharedWorker)
- #515 (worker-death self-heal)
- #451 (side-panel drag-to-resize)
- #635 (matrix.gui.enable defaults)
- #609 + #15 (gateway re-root) → 'lives in docs/gateway.md'
- #66 (ctx badge thresholds)
- #541 (journald panel-body column-flex)
- #447 (rebuild-queue cancel)
- #559 (mark all read)
- #474 (schedules PATCH partial edit)
- #467 (schedules fire-now)
- #589 (hive-qualified label phase A)

docs/web-ui.md: 14 → 0 issue-ref cookies. Self-contained read.
This commit is contained in:
iris 2026-05-31 15:30:58 +02:00 committed by mara
commit ac83404f1c

View file

@ -2,9 +2,9 @@
Two web surfaces share the same skeleton: the dashboard (port 7000)
and the per-agent UIs (every container — including the manager —
hashes into :8100-8999 via `lifecycle::agent_web_port`'s FNV-1a,
since #753). Both are SPAs — `GET /` returns a static shell,
`/api/state` returns JSON, JS renders. No full-page reloads.
hashes into :8100-8999 via `lifecycle::agent_web_port`'s FNV-1a).
Both are SPAs — `GET /` returns a static shell, `/api/state`
returns JSON, JS renders. No full-page reloads.
## Shape (shared by both)
@ -33,7 +33,7 @@ since #753). Both are SPAs — `GET /` returns a static shell,
based, no `innerHTML` — XSS-safe); markdown bodies get the
same treatment via `marked`'s autolink (npm dep, replacing the
vendored UMD bundle), with the rendered `<a>`s rewritten to
`target="_blank"` (issue #233).
`target="_blank"`.
- `GET /api/state` → JSON snapshot the JS app renders into the
DOM. Includes a top-level `seq` (the dashboard event channel's
high-water mark at the moment the snapshot was assembled);
@ -50,7 +50,7 @@ since #753). Both are SPAs — `GET /` returns a static shell,
~200 broker messages wrapped in `{ seq, events }`) on the
dashboard and `GET /events/history` (last 2000 `LiveEvent`s
also wrapped in `{ seq, events }`) on the agent.
**SSE multiplexing** (#448): the dashboard uses a
**SSE multiplexing**: the dashboard uses a
`SharedWorker` (`stream-worker.js`) to hold one upstream
`EventSource` per URL. All same-origin tabs share this worker
— a second dashboard tab joins the existing connection rather
@ -59,7 +59,7 @@ since #753). Both are SPAs — `GET /` returns a static shell,
page re-subscribes (gets a synthetic `open` event immediately
if the upstream is already connected). Falls back gracefully
when `SharedWorker` is unavailable (e.g. some private-mode
browsers). **Worker-death self-heal** (#515): Firefox kills
browsers). **Worker-death self-heal**: Firefox kills
"idle" SharedWorkers under memory pressure with no client-side
signal — the port silently goes no-op. The worker now pings
every connected port every 30s; the client bumps a
@ -194,7 +194,7 @@ titled header, a close button, and a scrollable body. Closes on
the button, a backdrop click, or `Escape`. `Panel.open(title,
node)` swaps the body; the JS builders for file previews,
approval diffs, and journald logs all render into it. **The
drawer width is drag-to-resize** (#451): a thin 6px hit-strip on
drawer width is drag-to-resize**: a thin 6px hit-strip on
the left edge captures pointer events, resizes the drawer in
real-time (pointer capture keeps dragging even if the cursor
outpaces the handle), and persists the chosen width to
@ -432,7 +432,7 @@ with `--base-href /matrix/`, swappable via
`services.hyperhive.matrix.gui.package`) served by the hive-gateway
nginx container at `/matrix/` when
`services.hyperhive.matrix.gui.enable` is on (defaults to
`matrix.enable`, #635). c0re signals availability via the
`matrix.enable`). c0re signals availability via the
`HIVE_MATRIX_GUI_ENABLED` env var → `state.matrix_gui_enabled` in
`/api/state`; the gateway does the actual static serving.
@ -442,7 +442,7 @@ in once with the in-host tuwunel homeserver URL
The unified nginx-front re-root to
`https://matrix.${hyperhive.domain}` + `.well-known/matrix/client`
auto-discovery is tracked in #609 (atlas's lane, post-#15).
auto-discovery lives in `docs/gateway.md` (atlas's lane).
### FL0W page (`/flow.html`)
@ -567,7 +567,7 @@ fetch entirely.
`ContainerView.context_window_tokens`; the badge goes yellow
≥ 50% and red ≥ 75% of that window (the harness compaction
watermarks). When the window can't be resolved the badge falls
back to fixed 100k / 150k thresholds. (issue #66)
back to fixed 100k / 150k thresholds.
- Line 2: status badges only (no per-card action buttons — actions
moved to the **selection bar**, see below).
- Line 3: drill-in triggers —
@ -577,7 +577,7 @@ fetch entirely.
A unit dropdown (harness service / full machine journal) and
a refresh button live in the panel. The panel uses a column-flex
layout so the `<pre>` log surface fills the full remaining panel
height (#541); scroll happens inside the `<pre>`, not the side
height; scroll happens inside the `<pre>`, not the side
panel body.
- Plain navigation links (config repo, forge profile,
`dashboardLinks` extras) now live in the icon-only nav strip
@ -755,13 +755,13 @@ not ours.
the sentinel `[cancelled]`. Same code path as a real answer.
- `POST /request-spawn` — queue a Spawn approval.
- `POST /update-all` — rebuild every stale container.
- `POST /api/rebuild-queue/{id}/cancel` — drop a `Queued` entry
(#447). Refuses `Running` / terminal-state entries (in-flight
- `POST /api/rebuild-queue/{id}/cancel` — drop a `Queued` entry.
Refuses `Running` / terminal-state entries (in-flight
rebuilds can't be safely interrupted). Always 200; body is
`{"cancelled": true}` on a successful flip or
`{"cancelled": false}` when the entry was not in `Queued` state.
- `POST /api/agent/{name}/mark-all-read` — ack all pending broker
messages for `{name}` (#559). Backfills `delivered_at` for rows
messages for `{name}`. Backfills `delivered_at` for rows
not yet delivered and sets `acked_at = now`. Returns
`{ "marked": N }`. Agent name validated against
`[a-z0-9_-]`, 1-63 chars; 400 on bad input.
@ -810,7 +810,7 @@ not ours.
`{ targets, body, first_fire_at_unix, interval_seconds?, description? }`.
Agent-initiated schedules go through the approval queue instead
(manager MCP `request_schedule_prompt`).
- `PATCH /api/schedules/{id}` — partial edit (#474). JSON body
- `PATCH /api/schedules/{id}` — partial edit. JSON body
`{ body?, description?, interval_seconds?, next_fire_at_unix?,
targets_add?, targets_remove? }`.
Missing key = "leave alone"; explicit `null` on
@ -828,7 +828,7 @@ not ours.
`{ targets?: ["name", …] }` cancels just those recipients;
absent or empty body cancels the whole schedule.
- `POST /api/schedules/{id}/fire-now` — out-of-band manual
pulse (#467). Fires the schedule body once immediately to
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.
@ -983,7 +983,7 @@ tooltip, and `qualified_label` — the hive-qualified agent name
(`name@domain` form when `HYPERHIVE_HIVE_DOMAIN` is set, otherwise
just `name`). The frontend uses `qualified_label` to set the browser
tab title so two tabs from different hives are distinguishable; the
header `<h2 id="title">` stays short (#589 phase A).
header `<h2 id="title">` stays short.
**Main content** (`<main class="agent-main">`): fills the viewport
and scrolls behind the fixed header + footer.