docs: clear write-good.Passive hits in docs/web-ui/shape.md

5 genuine passive-voice rewrites (actor named — DOMPurify.sanitize()
x2, paintAtomic, the keyed pattern, the operator); 2 false positives
left untouched — predicate-adjective state descriptions ('are
unaffected', 'is gone'), same category as several already-established
in this sweep.
This commit is contained in:
iris 2026-09-20 05:25:04 +02:00 committed by mara
commit 6f0985824c

View file

@ -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 `<a>`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 `<a>`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 `<a>`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 `<a>`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<id, {el, fingerprint}>`
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<id, {el, fingerprint}>` 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/<name>/` bind-mount,
`.bound` marker filtering, `agent-sockets.json` consumer on the
gateway side) live in [`docs/networking/gateway.md::Per-agent unix-socket