Architecture decisions

August 21, 2026 · View on GitHub

D001 — Exact DSH rc.7 compatibility

Build, test and publish against DeepSeek Harness 0.1.0-rc.7 with matching Host/Client peers. DSH release-candidate APIs are not widened by semver assumption. Node is ^22.19.0 || >=24.

D002 — Public conversation.view instead of replacing details

rc.7 exposes an additive, session-scoped conversation.view, keyed tool.call.toolview, and settings.section. Its assembled details surfaces are single-owner/keyed UI internals rather than a published generic additive list for this out-of-tree bundle. Live Preview therefore contributes a conversation view and never replaces DSH's details owner or Core layout.

D003 — Generic loopback Connection RPC

Host operations use effect-owned ctx.connection.rpc.handle('/live-loop', ..., { authority: 'loopback' }). The lazy client calls the matching public RPC service. Generated Typert Remote is not used because its generated client contribution pipeline is not an exported out-of-tree package seam in rc.7.

D004 — Shared process lease, isolated Preview Session

Identical Target starts converge on one Runtime Session to avoid duplicate servers. Each DSH subject receives its own random Preview Session and BrowserContext. Process reuse never implies cookie/storage/navigation reuse.

D005 — DSH subprocess for applications; Playwright ownership for browser

Application servers use ctx.subprocess so executable resolution, credential scrubbing, collection, cancellation and process-tree teardown stay inside DSH's public lifecycle. Playwright must own the Chromium process protocol itself; the service explicitly closes pages, contexts and browser on idle/dispose/crash.

D006 — Independent rc.7 Browser Provider

Three choices were evaluated:

  1. reuse ChenyuHeee/dsh-browser-playwright directly;
  2. adapt it as an optional provider;
  3. implement an independent provider informed by its public design.

Choice 3 is selected. dsh-browser-playwright is MIT-licensed and its per-session BrowserContext, accessibility refs, DSH attachments, LRU cleanup and disabled-by-default evaluate are sound patterns. Its published peer range excludes 0.1.0-rc.7, and it does not own Live Loop's target/process/verification/UI report contract. xu1132/dsh-plugin-browser is MIT-licensed but targets older DSH seams and a simpler CSS-selector operation model. No source was copied. Optional-provider complexity would weaken one authoritative state model without producing an rc.7-compatible lifecycle/evidence contract.

D007 — Four model tools

Expose one detection tool, one lifecycle tool with operations, one browser tool with operations, and one high-level verify tool. This keeps names discoverable, schemas bounded, KV-cache shape stable, permissions coherent, and the verification entry more prominent than low-level actions.

D008 — Bounded explicit stability

Require DOMContentLoaded/main completion plus a configurable quiet window before a hard deadline. WebSocket and EventSource do not count as ordinary in-flight work. Infinite Playwright networkidle is not used. Explicit text/URL waits can extend only within their bounded maximum.

D009 — Strict ordered verdicts

The only report states are VERIFIED, VERIFIED_WITH_WARNINGS, FAILED, and UNVERIFIED. Infrastructure/evidence absence is UNVERIFIED; observed product failure is FAILED; task criteria absent yields a warning rather than a full pass. Error/noise classification occurs before success.

D010 — Attachment evidence is required

A verification screenshot must be saved through DSH Attachments. Local paths alone do not satisfy a passing report. Text-only model routes keep attachment identity and textual diagnostics but omit native image blocks that would break the next model request.

D011 — Direct iframe plus screenshot fallback; no preview proxy

The UI frames the direct managed loopback URL only when topology and response policy permit it. CSP/XFO and remote-localhost failures are preserved and surfaced. A plugin proxy was rejected after inspecting rc.7 HTTP/Upgrade routing because a transparent arbitrary Vite/Next/HMR proxy would require broad path ownership, cookie/header rewriting, and an SSRF/open-proxy surface. Screenshot stream and external-open meet preview needs without modifying the verified page.

D012 — CDP request-stage security gate

Playwright route.continue() does not re-run policy for the rest of one redirect chain; route.fetch() can inspect hops but buffers and breaks streaming/SSE and can alter Chrome address-space classification. Chromium CDP Fetch.requestPaused is therefore used at Request stage. It pauses every redirect request separately, preserves direct response streaming, and applies the allowlist before send. Cross-origin WebSockets use Playwright's separate WebSocket route and are blocked; same-origin HMR passes directly.

D013 — No arbitrary page evaluate

Internal fixed evaluate callbacks implement DOM summary and image normalization. The Agent/client API cannot provide JavaScript source or arbitrary selectors. This limits page-driven prompt injection and privilege expansion.

D014 — Soft Agent guidance, accurately described

Use ctx.systemPrompt.section, tool descriptions and next-action fields to encourage edit→verify→diagnose→fix→reverify. rc.7 provides no public hard completion gate that an out-of-tree plugin can insert without modifying Agent Loop Core, so documentation never claims one.

D015 — Bounded evidence and explicit retention

All process logs, diagnostics, DOM text/nodes, screenshots, JSON output and retained runs have limits. Evidence remains sensitive developer data despite best-effort redaction. Uninstall does not silently delete evidence.