Persist PageTree expand state via control-plane view-state and align chevron/DOM with restored expansion; keep Sidex-style shallow page-tree scan and drop the unused recursive scanner that only added cargo noise. Add password vault workbench routes/runtime/skill/CLI, split page_ai_pi into a module package, and retire Hermes/ACP/OpenHub recycle + root harness evidence from the index while gitignoring recycle and local diag dumps. Archive superseded design/bugs docs under old/, point architecture at ARCHITECTURE.md, and refresh smokes for Pi S1–S7, vault, and editor regressions so the working tree can stay clean.
175 lines
9.5 KiB
Markdown
175 lines
9.5 KiB
Markdown
# [recycle] 4-18 [done] 树域 final DOM shell 切换硬门禁 v1
|
||
|
||
> 创建时间:2026-04-28
|
||
>
|
||
> 目的:纠正此前把 `Rust/WASM reducer runtime` 误当成 `final Rust renderer` 的完成口径,重新定义 page tree / file tree / picker 真正收口所需的不可绕过门禁。
|
||
>
|
||
> 收口更新(2026-05-16):旧 `TreeShellIframeHost` 与对应测试已退出 active source,并移动到 `recycle/`;`NEXT_PUBLIC_TREE_SHELL_LEGACY_IFRAME_HOST` 回退入口已删除。当前口径不再保留 iframe/srcDoc legacy/debug host,默认与唯一活跃 host 是 `rust_wasm_dom_shell_host + dom_wasm`。
|
||
>
|
||
> 前置文档:
|
||
> - `/mnt/Data1T/mnote/design/04-tree-domain/done/4-11-tree-rust-family-final-renderer-and-host-thinning-checklist-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/04-tree-domain/process/4-16-tree-rust-family-remaining-final-runtime-checklist-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/04-tree-domain/process/1.md`
|
||
|
||
## 1. 口径纠偏
|
||
|
||
### 2026-04-28 收口结果
|
||
|
||
本轮 `task-010` 至 `task-013` 已按本文硬门禁完成默认主路径切换:
|
||
|
||
- `TreeShellHost` 在 `rust_family + workspaceId` 下默认选择 `rust_wasm_dom_shell_host`。
|
||
- 历史 `TreeShellIframeHost` 不再保留 active 入口;相关源码与测试已进入 `recycle/`,不再作为可开启的 legacy/debug 排障 host。
|
||
- 默认 page tree / file tree / picker 主路径标注 `data-tree-browser-bridge="dom_wasm"`,负向测试禁止 `iframe_srcdoc` 被当成默认成功路径。
|
||
- 默认 DOM host 不再调用 `LOCAL_TREE_SHELL_TEMPLATE`、`buildInlinePageTreeHtml`、`buildInlineFileTreeHtml`、`buildInlinePickerHtml`。
|
||
- 默认 DOM host 的展开、选择、高亮、打开、右键、拖放、picker pick 由 `reduceTreeShellRuntime` WASM artifact 或同源 `/api/tree/runtime/reduce` Rust seam 返回的 `state / hostEvents / commandEvents` 驱动;不再保留 iframe/srcDoc JS fallback reducer 作为可用路径。
|
||
- `task112-tree-rust-family-regression-smoke.js` 与 `task113-picker-keyboard-regression-smoke.js` 已支持并验证默认 DOM host;后续不再验收 legacy iframe 路径。
|
||
|
||
`task-010` 之前,过去几轮已经完成的是:
|
||
|
||
- Rust renderer input / state family / runtime facade。
|
||
- `tree-shell-runtime-wasm` reducer artifact。
|
||
- 3000 主路径 wasm-first `reduceTreeShellRuntime`。
|
||
- page / filetree / picker 的若干 hostEvent / commandEvent / DOM patch 切片。
|
||
- `rust_runtime_artifact_host` 主路径标识。
|
||
|
||
这些都只是 `Rust/WASM reducer runtime-first`,不是 `final Rust DOM renderer`。
|
||
|
||
`task-010` 之前真正没有完成的是:
|
||
|
||
- 当时 `TreeShellIframeHost` 仍在 3000 主路径生成 `srcDoc`。
|
||
- 当时 `LOCAL_TREE_SHELL_TEMPLATE` 仍承载 DOM 壳、事件绑定、hydration、fallback renderer 与状态 patch。
|
||
- 当时 `data-tree-browser-bridge="iframe_srcdoc"` 仍是默认真实流量的浏览器执行层。
|
||
- 当时 page / filetree / picker 的 DOM shell 仍由 JS adapter 维护,Rust/WASM 只主导 reducer result。
|
||
|
||
因此,后续任何文档、harness、提交说明都不能再把 `task112/task113 通过`、`rust_runtime_artifact_host` 或 `wasmModuleUrl/jsGlueUrl 非空` 作为 final renderer 完成声明;必须同时检查默认 host implementation、浏览器 bridge 标记和 legacy flag 边界。
|
||
|
||
## 2. 不可绕过的完成定义
|
||
|
||
只有同时满足以下条件,才允许声明“页面树 / 文件树已切换为 Rust final renderer”:
|
||
|
||
- 3000 默认真实流量的 page tree / file tree / picker 不再通过 `TreeShellIframeHost` 的 `srcDoc` 内联模板承载 DOM shell。
|
||
- 默认主路径不再标注 `data-tree-browser-bridge="iframe_srcdoc"`。
|
||
- `LOCAL_TREE_SHELL_TEMPLATE`、`buildInlinePageTreeHtml`、`buildInlineFileTreeHtml`、`buildInlinePickerHtml` 不再参与默认 page / filetree / picker 渲染路径。
|
||
- `TreeShellIframeHost` 不得继续存在于 active source;历史源码只能位于 `recycle/` 且被 gitignore 排除。
|
||
- Rust/WASM 或等价 Rust family renderer 持有初始渲染、动态 DOM patch、事件绑定归一化、展开/选择/高亮/拖放反馈的运行时 DOM shell。
|
||
- 3000 host 只保留挂载、认证、transport、文件字节读取、postMessage / command bridge、artifact 资源发布等浏览器能力边界。
|
||
- page / filetree / picker 的主路径回归测试必须包含负向断言:默认路径不得出现 `iframe_srcdoc` DOM renderer。
|
||
- `task112/task113` 仍通过,并且 smoke 需要验证的是新 Rust DOM shell 主路径,而不是旧 inline iframe host。
|
||
|
||
## 3. 第一优先级:先加负向门禁
|
||
|
||
下一轮实现前必须先补负向测试,防止继续小步绕开最终目标。
|
||
|
||
### 前端门禁
|
||
|
||
- `tree-shell-host.test.tsx`、surface 测试或新测试必须断言默认主路径不再输出:
|
||
- `srcDoc={renderedInlineSrcDoc}`
|
||
- `data-tree-browser-bridge="iframe_srcdoc"`
|
||
- `LOCAL_TREE_SHELL_TEMPLATE`
|
||
- `buildInlineInitialTreeHtml`
|
||
- `buildInlinePageTreeHtml`
|
||
- `buildInlineFileTreeHtml`
|
||
- `buildInlinePickerHtml`
|
||
- 允许这些字符串只出现在 `recycle/` 下的历史文件中;active source 与默认 host implementation 测试不能再把它们作为成功条件。
|
||
|
||
### smoke 门禁
|
||
|
||
- `task112-tree-rust-family-regression-smoke.js` 需要确认 page/filetree 默认 renderer host 不是 inline srcdoc host。
|
||
- `task113-picker-keyboard-regression-smoke.js` 需要确认 picker 默认 renderer host 不是 inline srcdoc host。
|
||
- direct `/api/tree/shell -> 3104` debug disabled 仍应保留,但它不能替代 final DOM shell 验收。
|
||
|
||
### 文档门禁
|
||
|
||
- `harness` 任务完成条件必须包含“不依赖 iframe srcdoc DOM shell”。
|
||
- 任一阶段文档若只完成 reducer/state family,标题和完成记录必须写成 `runtime reducer/state-family stage`,不得写成 `final renderer completed`。
|
||
|
||
## 4. 实现路线
|
||
|
||
### Phase P:冻结旧 inline host 主路径
|
||
|
||
状态:已完成。
|
||
|
||
目标:把旧 `TreeShellIframeHost` 从 active source 中移出,彻底关闭 legacy/debug 候选入口。
|
||
|
||
执行项:
|
||
|
||
- 新增主路径 host 名称,例如 `rust_dom_shell_host` 或 `rust_wasm_dom_shell_host`。
|
||
- 旧 `TreeShellIframeHost` 与测试移动到 `recycle/`,不再提供 debug/legacy flag 入口。
|
||
- `TreeShellHost` 默认选择新 host;旧 host 不再作为 `rust_family` 默认实现。
|
||
- 所有旧 `srcDoc` 合同测试迁到 legacy/debug 测试组。
|
||
|
||
验收:
|
||
|
||
- 默认 `TreeShellHost` 测试不再匹配 `iframe_srcdoc`。
|
||
- active 测试不再证明旧 host 可用于回退排障,只保留默认 DOM/WASM host 的负向门禁。
|
||
|
||
### Phase Q:建立 Rust/WASM DOM shell host
|
||
|
||
状态:已完成默认主路径切换。
|
||
|
||
目标:给 page / filetree / picker 建立一个不依赖 inline JS template 的 DOM shell 承载。
|
||
|
||
执行项:
|
||
|
||
- 复用现有 `rendererInput` 与 `TreeShellRuntimeRequest/Result`。
|
||
- WASM artifact 输出或驱动 DOM shell 初始化,不再由 `buildInline*Html` 生成主路径 HTML。
|
||
- DOM patch、hostEvent、commandEvent 的应用入口统一放在新 host adapter,adapter 只负责浏览器边界,不维护树状态机。
|
||
- page tree 先切,再切 picker,最后切 filetree。
|
||
|
||
验收:
|
||
|
||
- page / picker / filetree 默认主路径首屏可见。
|
||
- 键盘、展开、选择、右键、打开、拖放反馈继续工作。
|
||
- `task112/task113` 使用新 host 通过。
|
||
|
||
### Phase R:删除默认路径 JS renderer 状态机
|
||
|
||
状态:已完成默认路径隔离;旧 JS renderer/state machine 已从 active source 移到 `recycle/`。
|
||
|
||
目标:移除默认主路径对旧 JS DOM renderer/state machine 的依赖。
|
||
|
||
执行项:
|
||
|
||
- 默认路径删除对 `renderTree()`、`renderFileTree()`、`hydrateInitialPageTree()`、`hydrateInitialPickerTree()` 等旧 DOM shell 的调用。
|
||
- 旧本地 fallback reducer 不再保留 active 入口。
|
||
- 删除或隔离 `buildInlinePageTreeHtml` / `buildInlineFileTreeHtml` / `buildInlinePickerHtml` 的默认路径调用。
|
||
|
||
验收:
|
||
|
||
- 默认 host implementation 中没有 `srcDoc` 主渲染链。
|
||
- 默认主路径没有第二套 JS 展开、选择、高亮、拖放接受规则。
|
||
- `TreeShellIframeHost` 已移动到 `recycle/`,不能再作为 debug 目录或 active 回退入口。
|
||
|
||
### Phase S:最终文档收口
|
||
|
||
状态:已更新 4-11、4-16、4-18 的真实代码状态。
|
||
|
||
目标:只在真实代码满足门禁后移动文档状态。
|
||
|
||
执行项:
|
||
|
||
- `4-11`、`4-16`、`4-18` 中所有 final DOM shell gate 勾选。
|
||
- 将真正完成后的最终清单移动到 `done/`。
|
||
- 若 `4-12` 到 `4-15` 的旧标题继续误导,则移动到 `design/old/done` 或在标题中明确标记 `state-family stage`。
|
||
|
||
验收:
|
||
|
||
- 文档状态与默认真实流量一致。
|
||
- 没有任何 `done` 文档暗示 `iframe_srcdoc` 主路径等于 final Rust renderer。
|
||
|
||
## 5. 非目标
|
||
|
||
- 不拆除 Convex substrate。
|
||
- 不恢复 `3104` 为默认浏览器入口。
|
||
- 不把文件字节读取、浏览器 DnD `File[]` 对象直接塞入 Rust/WASM。
|
||
- 不因为切 DOM shell 而重写 tree command / projection / artifact contract。
|
||
- 不把 `task112/task113` 的旧 inline host smoke 当作最终通过标准。
|
||
|
||
## 6. 当前下一步
|
||
|
||
本文定义的 final DOM shell 硬门禁已收口。后续继续推进时,不应再回到 `iframe_srcdoc` 默认路径,而应沿以下方向继续减少过渡面:
|
||
|
||
1. 继续把剩余 tree command、Page Aggregate、snapshot 独立事件等非 DOM shell 收口项按各自设计稿推进。
|
||
2. 若新增 page / filetree / picker 交互,默认必须接入 `TreeShellRuntimeRequest/Result`,不得在 DOM host 增加第二套 JS reducer。
|
||
3. 若需要排障,只能在 Rust DOM/WASM host 或 Rust Web debug route 上加临时观测,不得恢复 iframe/srcDoc host。
|