简明目的
常见文件能快速、安全地预览;文件太大、损坏或格式不支持时明确降级,不白屏、不把任意路径交给 renderer。
Outcome(专业定义)
基于规范 descriptor 的 renderer registry 为 Markdown、text/code、JSON、CSV、raster image 与 PDF 提供确定的 format/trust/size/capability 路由、流式读取、资源预算、隔离与显式 fallback。registry 基础已交付;剩余范围聚焦边界、性能和负向安全证据,不再承担通用 plugin renderer、audio/video 或 rich SVG。
Complexity
L — 处理不可信文件、流式大数据、解码预算与 PDF 隔离,属于安全和性能高风险面。
Context
#187 已交付 registry 基础,但 subtype/trust/size 决策、100MiB 级文本虚拟化、cancellable range、PDF worker、image decode budget 和 crash fallback 尚未完成。原子票 #295 /#298 扩展到 audio/video 与 rich SVG,超出当前首发结果。
Scope
按 MIME/subtype、trust、size 与 runtime capability 确定 renderer/fallback。
支持 Markdown Preview/Source、text/code、JSON、CSV 的流式/虚拟化预览。
支持 raster image 的像素、帧数、解码内存与取消预算。
在隔离 PDF worker 中预览 PDF,并限制链接、附件、脚本和外部动作。
renderer crash/timeout 时提供 Source、Metadata、retry、external-open/save-copy 等诚实动作。
所有内容通过 descriptor/range stream 获取,不传任意本地路径。
Non-goals
不实现 audio/video renderer;首发显示 metadata/source/external-open fallback。
不实现 rich SVG 渲染;SVG 首发按 source/metadata 或安全外部打开处理。
不提供通用第三方 renderer/plugin platform。
不读取旧 savedPath、旧 extension renderer fallback、任意 file URL 或来源特判。
不实现 HTML 和 Office;分别归 [REQ-096] HTML 产物在零桥接隔离宿主中静态预览 #208 与 alpha-work#3。
Acceptance criteria
AC1. 相同 descriptor 在不同入口得到相同 renderer/fallback 决策,且决策显式考虑 subtype、trust、size 与 capability。
AC2. Markdown、text/code、JSON、CSV 在预算内完整预览;超出预算时只读取并显示开头节选并明确告知,内容经 main 侧分段通道读取,不整包进入界面。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC3. 本机文件预览经分段通道读取,关闭或切换后读取立即停止;云端产物的二进制预览有 20 MiB 上限,超限提供外部打开。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC4. PDF 在隔离的独立预览视图中显示,该视图无应用能力、网络、导航与下载默认拒绝。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC5. 超过 20 MiB 的图片不内联解码,显示说明并提供外部打开;损坏图片显示可理解的失败。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC6. renderer crash、timeout 或 unsupported format 不导致空白 Workbench;Source、Metadata、retry 与 external-open/save-copy 动作可达。
AC7. audio/video 与 rich SVG 明确显示“当前不内置渲染”,不会通过 extension fallback 或通用 plugin 静默执行。
AC8. renderer 只能经受控通道按工作区相对路径或 descriptor 请求内容,不能读取未授权路径、网络资源或其它会话内容。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
Evidence map
AC
Evidence surface
AC1
#291 registry decision table tests
AC2
packages/ui-mac/src/shared/file-viewer.ts:11/:13 + session-rail/files/file-viewer-state.ts:4-6;#294 不做
AC3
file-viewer-state.ts:4-6 + packages/ui-mac/src/main/artifact-service.ts:1425;#293 不做
AC4
packages/ui-mac/src/main/rail-preview-host.ts:6/:27;#296 not planned
AC5
shared/file-viewer.ts:15 + session-rail/files/file-viewer-view.tsx:249;#297 不做
AC6
#292 crash/fallback tests
AC7
unsupported-format contract test;#295 /#298 不属于完成条件
AC8
packages/ui-mac/src/main/workspace-file-service.test.ts:104/:122
Acceptance owner
@jinjunnn — 按 AC 逐条验收并手工关闭;PR 不得关闭父需求。
设计要点
registry 输入只包含已验证 descriptor facts,不依赖 filename 猜测或 saved path。
预览预算贯穿 main→IPC→worker→renderer,不只限制 UI 最后一层。
fallback 是显式产品状态,不能用 generic extension handler 隐式扩大权限。
PDF/image 解码与主 renderer 隔离;取消信号贯穿数据源。
潜在问题与风险
过时性与兼容性结论
需求核心有效且基础已交付。旧 savedPath、extension fallback、generic plugin renderer、audio/video 与 rich SVG 首发承诺已过时/超范围,直接移出。保留流式取消、资源预算、崩溃恢复和未知格式 fail-closed。
关联与职责边界
Delivery plan / 建议子票
Dependencies
简明目的
常见文件能快速、安全地预览;文件太大、损坏或格式不支持时明确降级,不白屏、不把任意路径交给 renderer。
Outcome(专业定义)
基于规范 descriptor 的 renderer registry 为 Markdown、text/code、JSON、CSV、raster image 与 PDF 提供确定的 format/trust/size/capability 路由、流式读取、资源预算、隔离与显式 fallback。registry 基础已交付;剩余范围聚焦边界、性能和负向安全证据,不再承担通用 plugin renderer、audio/video 或 rich SVG。
Complexity
L — 处理不可信文件、流式大数据、解码预算与 PDF 隔离,属于安全和性能高风险面。
Context
#187 已交付 registry 基础,但 subtype/trust/size 决策、100MiB 级文本虚拟化、cancellable range、PDF worker、image decode budget 和 crash fallback 尚未完成。原子票 #295/#298 扩展到 audio/video 与 rich SVG,超出当前首发结果。
Scope
Non-goals
savedPath、旧 extension renderer fallback、任意 file URL 或来源特判。alpha-work#3。Acceptance criteria
AC1. 相同 descriptor 在不同入口得到相同 renderer/fallback 决策,且决策显式考虑 subtype、trust、size 与 capability。
AC2. Markdown、text/code、JSON、CSV 在预算内完整预览;超出预算时只读取并显示开头节选并明确告知,内容经 main 侧分段通道读取,不整包进入界面。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC3. 本机文件预览经分段通道读取,关闭或切换后读取立即停止;云端产物的二进制预览有 20 MiB 上限,超限提供外部打开。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC4. PDF 在隔离的独立预览视图中显示,该视图无应用能力、网络、导航与下载默认拒绝。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC5. 超过 20 MiB 的图片不内联解码,显示说明并提供外部打开;损坏图片显示可理解的失败。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC6. renderer crash、timeout 或 unsupported format 不导致空白 Workbench;Source、Metadata、retry 与 external-open/save-copy 动作可达。
AC7. audio/video 与 rich SVG 明确显示“当前不内置渲染”,不会通过 extension fallback 或通用 plugin 静默执行。
AC8. renderer 只能经受控通道按工作区相对路径或 descriptor 请求内容,不能读取未授权路径、网络资源或其它会话内容。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
Evidence map
packages/ui-mac/src/shared/file-viewer.ts:11/:13+session-rail/files/file-viewer-state.ts:4-6;#294 不做file-viewer-state.ts:4-6+packages/ui-mac/src/main/artifact-service.ts:1425;#293 不做packages/ui-mac/src/main/rail-preview-host.ts:6/:27;#296 not plannedshared/file-viewer.ts:15+session-rail/files/file-viewer-view.tsx:249;#297 不做packages/ui-mac/src/main/workspace-file-service.test.ts:104/:122Acceptance owner
@jinjunnn — 按 AC 逐条验收并手工关闭;PR 不得关闭父需求。
设计要点
潜在问题与风险
过时性与兼容性结论
需求核心有效且基础已交付。旧
savedPath、extension fallback、generic plugin renderer、audio/video 与 rich SVG 首发承诺已过时/超范围,直接移出。保留流式取消、资源预算、崩溃恢复和未知格式 fail-closed。关联与职责边界
alpha-work#1/#2:artifact transport/registry;本票只消费 descriptor。alpha-work#3:Office;[REQ-108] 工作区本地文件可在 Session 右栏安全预览 #244:普通工作区本地 source adapter。Delivery plan / 建议子票
[REQ-095][CODE] Expose cancellable artifact range streams without full IPC buffers #293 — cancellable descriptor range stream。2026-09-17 按 owner 裁决不做关闭(AC3 已改写)。[REQ-095][CODE] Virtualize 100 MiB text, CSV, and long JSON previews #294 — 100 MiB 文本/CSV/JSON 虚拟化。2026-09-17 按 owner 裁决不做关闭(AC2 已改写)。[REQ-095][CODE] Render PDF in an isolated PDF.js worker with action and link policy #296 — 隔离 PDF worker 与动作策略。2026-08-28 not planned(改用 Electron 自带 Chromium PDF viewer 隔离视图)。[REQ-095][CODE] Enforce image pixel, frame, and decode-memory budgets #297 — raster image decode budgets。2026-09-17 按 owner 裁决不做关闭(AC5 已改写)。建议 VERIFY:恶意文件、慢消费者、取消与 packaged 边界。从未建票;2026-09-17 AC8 改写后不再需要。Dependencies
alpha-work#1/#2,但不复刻其 transport/registry 实现。