diff --git a/docs/web-ui/shape.md b/docs/web-ui/shape.md
index 38ad869b..c16d8030 100644
--- a/docs/web-ui/shape.md
+++ b/docs/web-ui/shape.md
@@ -37,10 +37,10 @@
`marked` (npm dep, replacing the vendored UMD bundle) and then
`DOMPurify.sanitize()` before hitting `innerHTML` — untrusted row
text (peer-agent / matrix-relayed message bodies, agent-authored
- state files) can carry arbitrary HTML/script via markdown, so the
- markdown path is sanitized rather than XSS-safe by construction the
- way the text-node `linkify` path is. Rendered ``s are rewritten
- to `target="_blank"`.
+ state files) can carry arbitrary HTML/script via markdown, so
+ `DOMPurify.sanitize()` cleans the markdown path rather than it being
+ XSS-safe by construction the way the text-node `linkify` path is.
+ Rendered ``s are rewritten to `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 server assembled the snapshot);
@@ -192,9 +192,10 @@ inside a fresh text node, so the autolinker never touches
trailing-punctuation strip keeps `.,;:` outside the link surface.
Markdown bodies go through `marked` separately, then
`DOMPurify.sanitize()` on the resulting HTML before it's assigned to
-`innerHTML` (see `mdNode` in `app.js` / `common.js`) — this path is
-sanitized, not text-node-safe like `linkify`, since markdown can
-carry raw HTML. Rendered ``s get the same target rewrite.
+`innerHTML` (see `mdNode` in `app.js` / `common.js`) —
+`DOMPurify.sanitize()` cleans this path rather than it being
+text-node-safe like `linkify`, since markdown can carry raw HTML.
+Rendered ``s get the same target rewrite.
The JS app handles all `form[data-async]` submissions via a delegated
listener: read `data-confirm`, swap the button to a spinner, POST
@@ -226,12 +227,12 @@ before returning.
**Keyed DOM caching:** for sections whose rows hold interactive state
(textarea drafts, checkboxes, focused inputs) `paintAtomic` isn't
-enough — wiping and rebuilding still destroys the state even if the
-flash is hidden. The keyed pattern keeps a `Map`
-where the fingerprint is `JSON.stringify({...visible fields...})`.
-On each render: cache-hit rows are reused verbatim (preserving
-textarea draft, checkbox state, and event listeners); only cache-miss
-rows are rebuilt and inserted. Used for: containers (`containerRowCache`),
+enough — wiping and rebuilding still destroys the state even if
+`paintAtomic` hides the flash. The keyed pattern keeps a
+`Map` where the fingerprint is
+`JSON.stringify({...visible fields...})`. On each render, the pattern
+reuses cache-hit rows verbatim (preserving textarea draft, checkbox
+state, and event listeners) and rebuilds only cache-miss rows. Used for: containers (`containerRowCache`),
rebuild-queue entries (`rebuildQueueRowCache`). The spawn-form input+focus and meta-input
checkboxes use a lighter snapshot-then-restore pattern (snapshot
before `replaceChildren`, restore after) since they're single
@@ -298,7 +299,7 @@ flood the journal. The per-agent UI's `bind_with_retry`
than looping forever.
The per-agent UI optionally binds a `UnixListener` instead of
-TCP when `HIVE_WEB_SOCKET` is set — the unix-socket transition
+TCP when the nix module sets `HIVE_WEB_SOCKET` — the unix-socket transition
mechanics (per-agent `/run/hive-agent//` bind-mount,
`.bound` marker filtering, `agent-sockets.json` consumer on the
gateway side) live in [`docs/networking/gateway.md::Per-agent unix-socket