- Refuse to mint for an HTML file in a hidden directory or directly in a
broad root (/, home, tmpdir, cases and user-space roots): the capability
serves the directory tree recursively to the page's own scripts.
- Keep HTML's source view and editor: a Page pill (per-device htmlRendered,
like MD) toggles to the file-content text path, and a refused mint (remote
case, broad root, hidden dir) falls through to it automatically.
- Tests: html-view auth exemption edges, revocation on logout / admin logout /
user deletion, out-of-workspace mint (blocked tree, confinement), hidden
and broad roots.
- Docs: Working-With-Files, architecture-invariants, security-architecture,
the file-routes comment and CLAUDE.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Clicking an agent's `.html` path showed source text or downloaded it, so a
generated report could only be viewed by asking the agent to start a web
server. Render it instead, without serving HTML same-origin:
- POST /api/sessions/:id/html-view mints a capability for the file's own
directory (workspace path, or outside it under the attachment guard).
- GET /html-view/:cap/* serves the page and its relative assets with
`Content-Security-Policy: sandbox` WITHOUT allow-same-origin, so the page
runs in an opaque origin (also as a top-level tab) and cannot read the
Codeman document, its cookies or its API.
- Served files: non-dot, asset-allowlisted, realpath-confined to that
directory, blocklist applied; GET only. Capabilities are memory-only with a
rolling TTL and are revoked with the web-tab ones on logout.
- Frontend: the file preview renders HTML in a sandboxed iframe (popout opens
the same URL); terminal `.html` links go to the preview, not the log viewer.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>