Files
kandev/docs/decisions/2026-09-05-trusted-browser-html-preview.md
T
2026-09-07 13:45:28 +01:00

103 lines
5.0 KiB
Markdown

# ADR-2026-09-05-trusted-browser-html-preview: Treat HTML Preview as Trusted Workspace Code
**Status:** accepted
**Date:** 2026-09-05
**Area:** frontend, backend, agentctl, security
**Amended:** 2026-09-06 to make in-editor preview the primary desktop surface
## Context
Kandev needs a one-click preview for `.html` and `.htm` files. The desired
product behavior is normal browser fidelity: relative assets, native DOM and
browser APIs, links, forms, media, modules, and network behavior. The preview
must also use the current unsaved editor buffer.
The first design treated every workspace document as hostile. It used QuickJS
in a Web Worker, a virtual DOM, a controlled renderer, resource filtering, and
execution budgets. That design reduced ambient authority but did not provide a
normal browser. It also duplicated a large and permanently incomplete browser
compatibility surface.
Kandev already routes executor-local HTTP ports through a session-authorized
proxy and renders trusted workspace pages in iframes that permit scripts and
same-origin behavior. Reusing this path gives static HTML the same fidelity and
executor coverage as an explicitly started development server.
[ADR-2026-07-24-operator-owned-agent-launcher-settings](2026-07-24-operator-owned-agent-launcher-settings.md)
requires workspace-controlled web content to use a separate origin when it is
treated as untrusted. The product owner explicitly selected the existing
trusted native-browser model for HTML preview instead of a dedicated preview
origin.
## Decision
Treat native HTML preview as execution of trusted workspace code. Use the
existing Browser-panel iframe sandbox, origin behavior, and session port proxy.
Do not claim that preview isolates users from hostile HTML or JavaScript.
Agentctl will lazily start an ephemeral loopback static server for each selected
workspace or repository root. The current editor buffer is stored as a bounded
in-memory overlay for its workspace path. The server reads other relative assets
from that root. The backend authorizes the task session and forwards publish
requests to agentctl. Desktop and mobile replace the active file viewer body
with the returned session proxy URL. Desktop can open the same URL in the
Browser panel only through an explicit secondary action.
This decision narrows the untrusted-content rule in the 2026-07-24 ADR: native
HTML preview is an explicit trusted-content exception. That ADR continues to
govern operator-owned launcher settings and any future feature that promises to
render workspace-controlled content as untrusted. If Kandev later offers an
untrusted HTML preview mode, that mode must use a dedicated origin or a stronger
independently reviewed boundary.
The static server must contain filesystem reads to the selected root and listen
only on loopback. It must use the existing authenticated proxy and stop with
agentctl. Logs must not contain source content. These requirements control the
host and routing. They are not a browser-script sandbox.
## Consequences
- HTML, CSS, JavaScript, relative assets, and browser APIs behave like they do
in the existing Browser-panel iframe.
- Unsaved HTML can be previewed without writing it to the workspace.
- Local, Docker, SSH, and Kubernetes task sessions reuse one routing mechanism.
- Users must trust previewed documents. The UI and public documentation must
state that previewing executes workspace code with Browser-panel authority.
- Same-origin deployments can expose Kandev/browser authority to previewed code.
This risk is accepted for this feature and must not be described as isolated.
- Kandev owns a small static-server and in-memory-overlay lifecycle instead of
an ECMAScript engine, virtual DOM, browser emulation layer, and safe renderer.
- Applications that need builds, backend routes, HMR, or framework-specific
behavior continue to use their configured development server.
## Alternatives considered
### QuickJS with a virtual DOM and controlled renderer
Rejected because it is a browser reimplementation with limited compatibility.
Its complexity is not justified when browser fidelity is the product goal.
### Dedicated preview origin
Rejected for the current feature because it adds deployment, DNS, cookie,
desktop, and remote-executor routing work. It remains the preferred direction
if Kandev needs to claim hostile-content isolation later.
### Scriptless `srcDoc` iframe
Rejected because it does not support the required scripts, relative assets, or
normal browser APIs.
### Require users to configure a development-server command
Rejected as the only workflow because a static HTML document needs one action,
not project-specific command configuration. The explicit development server
remains available for non-static applications.
### Open a Browser panel as the primary desktop result
Rejected because a file-preview action should preserve the user's active file
context and match the existing source/preview mental model. The Browser panel
remains available as an explicit secondary action for broader browsing and
inspection workflows.