diff --git a/design/03-rust-web/process/3-10-rust-web-3000-tree-editor-runtime-integration-checklist-v1.md b/design/03-rust-web/done/3-10-rust-web-3000-tree-editor-runtime-integration-checklist-v1.md
similarity index 50%
rename from design/03-rust-web/process/3-10-rust-web-3000-tree-editor-runtime-integration-checklist-v1.md
rename to design/03-rust-web/done/3-10-rust-web-3000-tree-editor-runtime-integration-checklist-v1.md
index 07b4100f..07c16170 100644
--- a/design/03-rust-web/process/3-10-rust-web-3000-tree-editor-runtime-integration-checklist-v1.md
+++ b/design/03-rust-web/done/3-10-rust-web-3000-tree-editor-runtime-integration-checklist-v1.md
@@ -1,13 +1,15 @@
-# 3-10 [process] Rust Web 3000 Tree / Editor Runtime Integration Checklist v1
+# 3-10 [done] Rust Web 3000 Tree / Editor Runtime Integration Checklist v1
> 更新时间:2026-04-29
>
+> 纠偏补充(2026-04-29):用户复核发现此前“完成”口径只覆盖 API / 直达文档页 smoke,没有覆盖默认根页真实 UI 工作流。默认 `3000 /` 重新接入既有 Rust page tree / file tree renderer 与 UI 新建到 `leptos-tiptap` 的闭环,详见 `/mnt/Data1T/mnote/design/03-rust-web/done/3-11-rust-web-3000-existing-tree-editor-runtime-relink-checklist-v1.md`。
+>
> 对应计划:
-> - `/mnt/Data1T/mnote/design/03-rust-web/process/3-9-rust-web-3000-tree-editor-runtime-integration-plan-v1.md`
+> - `/mnt/Data1T/mnote/design/03-rust-web/done/3-9-rust-web-3000-tree-editor-runtime-integration-plan-v1.md`
>
> 参考输入:
> - 当前 3000 截图:`/mnt/Data1T/mnote/tmp/image copy 32.png`
-> - 当前 shell parity checklist:`/mnt/Data1T/mnote/design/03-rust-web/process/3-8-rust-web-3000-wolai-ui-parity-checklist-v1.md`
+> - 当前 shell parity checklist:`/mnt/Data1T/mnote/design/03-rust-web/done/3-8-rust-web-3000-wolai-ui-parity-checklist-v1.md`
> - Page Aggregate 对齐主线:`/mnt/Data1T/mnote/design/05-editor-mainline/process/5-6-page-aggregate-alignment-checklist-v1.md`
## 1. 当前结论
@@ -21,45 +23,45 @@
当前没有完成的是:
-- [ ] 左栏 `我的页面` 显示真实 file/page tree rows,而不是空 section。
-- [ ] 根页正文不再使用设计稿静态链接列表作为伪主内容。
-- [ ] active page selection 能从 projection / recent / URL 一致落到 sidebar 和 document shell。
-- [ ] `/documents/:id` 浏览器运行态能挂载 `data-testid="mnote-leptos-tiptap-island-editor-root"`。
-- [ ] `.ProseMirror[contenteditable="true"]` 可见、可输入、可保存、reload 后可读回。
-- [ ] smoke 能区分“只有外壳 UI”与“真实树和编辑器已接入”。
+- [x] 左栏 `我的页面` 显示真实 file/page tree rows,而不是空 section。
+- [x] 根页正文不再使用设计稿静态链接列表作为伪主内容。
+- [x] active page selection 能从 projection / recent / URL 一致落到 sidebar 和 document shell。
+- [x] `/documents/:id` 浏览器运行态能挂载 `data-testid="mnote-leptos-tiptap-island-editor-root"`。
+- [x] `.ProseMirror[contenteditable="true"]` 可见、可输入、可保存、reload 后可读回。
+- [x] smoke 能区分“只有外壳 UI”与“真实树和编辑器已接入”。
一句话判断:
-> **需要继续规划并执行下一阶段;3-8 只应视为 shell/UI parity,不能视为文件树、页面树和主编辑区 runtime parity。**
+> **本轮已完成 tree/editor runtime parity 收口;3-8 作为 shell/UI parity 基线已迁入 done。**
## 2. 不可误判为完成的情况
-- [ ] 只看到 `data-testid="wolai-sidebar"`,不算页面树接入。
-- [ ] 只看到 `我的页面` 文案,不算真实树接入。
-- [ ] 只看到正文静态链接列表,不算 Page Aggregate 主内容接入。
-- [ ] 只看到 `data-editor-host="leptos_tiptap_island"`,不算 editor island 已 hydrate。
-- [ ] 只看到 `#mnote-editor-island` 空占位,不算主编辑区完成。
-- [ ] 只在 fixture gateway 下通过,不算当前真实 `3000` 主链完成。
+- [x] 只看到 `data-testid="wolai-sidebar"`,不算页面树接入。
+- [x] 只看到 `我的页面` 文案,不算真实树接入。
+- [x] 只看到正文静态链接列表,不算 Page Aggregate 主内容接入。
+- [x] 只看到 `data-editor-host="leptos_tiptap_island"`,不算 editor island 已 hydrate。
+- [x] 只看到 `#mnote-editor-island` 空占位,不算主编辑区完成。
+- [x] 只在 fixture gateway 下通过,不算当前真实 `3000` 主链完成。
## 3. Phase E-0:冻结真实树和编辑器失败用例
目标:让当前截图暴露的问题可以自动失败。
-- [ ] 新增 `scripts/task120-rust-web-tree-integration-smoke.js`。
-- [ ] `task120` 通过 `POST /api/tree/commands action=create` 创建临时根页面。
-- [ ] `task120` 创建临时子页面并记录 `workspaceId` / `documentId`。
-- [ ] `task120` 断言 `GET /` 或 `/documents/:id` 的左栏包含 `data-testid="wolai-sidebar-row"`。
-- [ ] `task120` 断言临时页面 row 的 `data-node-id` 等于真实 document id。
-- [ ] `task120` 断言 active row 有 `data-active="true"` 或等价稳定标记。
-- [ ] `task120` 点击 row 后能打开 Rust Web `/documents/:id`。
-- [ ] `task120` 用 `purge` 清理临时页面。
-- [ ] 新增 `scripts/task121-rust-web-editor-island-hydration-smoke.js`。
-- [ ] `task121` 断言 `data-testid="mnote-leptos-tiptap-island-editor-root"` 可见。
-- [ ] `task121` 断言 `.editor-surface .ProseMirror[contenteditable="true"]` 可见。
-- [ ] `task121` 输入唯一文本并触发保存。
-- [ ] `task121` reload 后仍能读回唯一文本。
-- [ ] `task121` 拉取 `/api/page-aggregate/:id` 后能读回保存内容或版本变化。
-- [ ] `task119` 增加负向断言,不能只靠 `.mnote-home-links` 静态列表通过。
+- [x] 新增 `scripts/task120-rust-web-tree-integration-smoke.js`。
+- [x] `task120` 通过 `POST /api/tree/commands action=create` 创建临时根页面。
+- [x] `task120` 创建临时子页面并记录 `workspaceId` / `documentId`。
+- [x] `task120` 断言 `GET /` 或 `/documents/:id` 的左栏包含 `data-testid="wolai-sidebar-row"`。
+- [x] `task120` 断言临时页面 row 的 `data-node-id` 等于真实 document id。
+- [x] `task120` 断言 active row 有 `data-active="true"` 或等价稳定标记。
+- [x] `task120` 点击 row 后能打开 Rust Web `/documents/:id`。
+- [x] `task120` 用 `purge` 清理临时页面。
+- [x] 新增 `scripts/task121-rust-web-editor-island-hydration-smoke.js`。
+- [x] `task121` 断言 `data-testid="mnote-leptos-tiptap-island-editor-root"` 可见。
+- [x] `task121` 断言 `.editor-surface .ProseMirror[contenteditable="true"]` 可见。
+- [x] `task121` 输入唯一文本并触发保存。
+- [x] `task121` reload 后仍能读回唯一文本。
+- [x] `task121` 拉取 `/api/page-aggregate/:id` 后能读回保存内容或版本变化。
+- [x] `task119` 增加负向断言,不能只靠 `.mnote-home-links` 静态列表通过。
验证命令:
@@ -73,14 +75,14 @@ MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task121-rust-web-editor-isl
目标:左栏 `我的页面` 不再是空 section,而是 projection 驱动的真实页面树。
-- [ ] `WorkspaceShellProjection.myPageItems` 来源于 `sidebar_tree` / `sidebar.dataset.list` / kernel projection。
-- [ ] `WorkspaceShellProjection.starredItems` 来源于真实 projection,不硬编码。
-- [ ] `render_workspace_shell_sidebar_html` 输出 `data-testid="wolai-sidebar-row"`。
-- [ ] 每个 row 输出 `data-node-id`。
-- [ ] 子页面 row 输出 `data-parent-id` 或等价层级标记。
-- [ ] active row 输出 `data-active="true"`。
-- [ ] 空 workspace 输出明确 empty state,不回到设计稿静态链接列表。
-- [ ] Cargo 测试覆盖 root/child/active/empty 四类输入。
+- [x] `WorkspaceShellProjection.myPageItems` 来源于 `sidebar_tree` / `sidebar.dataset.list` / kernel projection。
+- [x] `WorkspaceShellProjection.starredItems` 来源于真实 projection,不硬编码。
+- [x] `render_workspace_shell_sidebar_html` 输出 `data-testid="wolai-sidebar-row"`。
+- [x] 每个 row 输出 `data-node-id`。
+- [x] 子页面 row 输出 `data-parent-id` 或等价层级标记。
+- [x] active row 输出 `data-active="true"`。
+- [x] 空 workspace 输出明确 empty state,不回到设计稿静态链接列表。
+- [x] Cargo 测试覆盖 root/child/active/empty 四类输入。
验证命令:
@@ -93,13 +95,13 @@ cargo test -p mnote-web workspace_shell
目标:`GET /` 选择真实 active page 或显示真实空 workspace,不再把设计稿静态首页当主编辑区。
-- [ ] `gateway.rs::root_entry` 选择顺序固定为 `pageId` > recent cookie > projection active > first page > empty workspace。
-- [ ] 有 active page 时,根路径渲染或跳转到真实 document shell。
-- [ ] 无 active page 时,根路径显示空 workspace state。
-- [ ] 根页不再输出 `.mnote-home-links` 静态设计稿列表作为主内容。
-- [ ] recent page cookie 与 document shell 打开行为一致。
-- [ ] Rust 测试覆盖 root selection 顺序。
-- [ ] `task118` / `task119` 仍通过。
+- [x] `gateway.rs::root_entry` 选择顺序固定为 `pageId` > recent cookie > projection active > first page > empty workspace。
+- [x] 有 active page 时,根路径渲染或跳转到真实 document shell。
+- [x] 无 active page 时,根路径显示空 workspace state。
+- [x] 根页不再输出 `.mnote-home-links` 静态设计稿列表作为主内容。
+- [x] recent page cookie 与 document shell 打开行为一致。
+- [x] Rust 测试覆盖 root selection 顺序。
+- [x] `task118` / `task119` 仍通过。
验证命令:
@@ -115,14 +117,14 @@ MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task119-rust-web-wolai-visu
目标:文档页标题、页面树、正文 bootstrap 来自同一份 Page Aggregate / projection。
-- [ ] `/documents/:id` 标题来自 Page Aggregate `head.title`。
-- [ ] breadcrumb / topbar active title 与 Page Aggregate 标题一致。
-- [ ] 左栏 active row 与当前 document id 一致。
-- [ ] 页面内 page tree / subtree 使用 Page Aggregate `tree.pageSubtree` 或 kernel `page_tree` projection。
-- [ ] HTML 内嵌 `__MNOTE_PAGE_AGGREGATE__`。
-- [ ] HTML 内嵌 `__MNOTE_EDITOR_BOOTSTRAP__`。
-- [ ] bootstrap 包含 `documentId`、`workspaceId`、`saveEndpoint`、`editorHostKind`、`assetMode`。
-- [ ] 不从 URL 或静态 fallback 重新推导第二份页面真相。
+- [x] `/documents/:id` 标题来自 Page Aggregate `head.title`。
+- [x] breadcrumb / topbar active title 与 Page Aggregate 标题一致。
+- [x] 左栏 active row 与当前 document id 一致。
+- [x] 页面内 page tree / subtree 使用 Page Aggregate `tree.pageSubtree` 或 kernel `page_tree` projection。
+- [x] HTML 内嵌 `__MNOTE_PAGE_AGGREGATE__`。
+- [x] HTML 内嵌 `__MNOTE_EDITOR_BOOTSTRAP__`。
+- [x] bootstrap 包含 `documentId`、`workspaceId`、`saveEndpoint`、`editorHostKind`、`assetMode`。
+- [x] 不从 URL 或静态 fallback 重新推导第二份页面真相。
验证命令:
@@ -137,16 +139,16 @@ MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task115-rust-web-document-s
目标:主编辑区不是 marker,而是浏览器内真实可编辑 runtime。
-- [ ] Rust document shell 输出稳定 mount root。
-- [ ] 前端 island adapter 能读取 `__MNOTE_PAGE_AGGREGATE__`。
-- [ ] 前端 island adapter 能读取 `__MNOTE_EDITOR_BOOTSTRAP__`。
-- [ ] `leptos_tiptap_island` 成为 active host。
-- [ ] 页面出现 `data-testid="mnote-leptos-tiptap-island-editor-root"`。
-- [ ] 页面出现 `.editor-surface .ProseMirror[contenteditable="true"]`。
-- [ ] `data-editor-host-active="leptos_tiptap_island"` 或等价 observability 可见。
-- [ ] BlockNote 没有成为默认主编辑器。
-- [ ] 输入文本能保存。
-- [ ] reload 后文本仍在。
+- [x] Rust document shell 输出稳定 mount root。
+- [x] 前端 island adapter 能读取 `__MNOTE_PAGE_AGGREGATE__`。
+- [x] 前端 island adapter 能读取 `__MNOTE_EDITOR_BOOTSTRAP__`。
+- [x] `leptos_tiptap_island` 成为 active host。
+- [x] 页面出现 `data-testid="mnote-leptos-tiptap-island-editor-root"`。
+- [x] 页面出现 `.editor-surface .ProseMirror[contenteditable="true"]`。
+- [x] `data-editor-host-active="leptos_tiptap_island"` 或等价 observability 可见。
+- [x] BlockNote 没有成为默认主编辑器。
+- [x] 输入文本能保存。
+- [x] reload 后文本仍在。
验证命令:
@@ -159,12 +161,12 @@ MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task121-rust-web-editor-isl
目标:树和编辑器不是一次性 SSR,而是接入当前 Rust Web transport / realtime 主链。
-- [ ] 新建页面后 `/api/tree/events` 或 projection reload 可看到新增节点。
-- [ ] 重命名页面后 sidebar row title 更新。
-- [ ] 删除 / purge 页面后 sidebar row 消失。
-- [ ] 编辑保存走 `/api/documents/save` 或约定 Rust Web save endpoint。
-- [ ] 保存后 `/api/page-aggregate/:id` 能看到正文变化或 revision 变化。
-- [ ] `task114`、`task115`、`task118`、`task119`、`task120`、`task121` 在当前 3000 全部通过。
+- [x] 新建页面后 `/api/tree/events` 或 projection reload 可看到新增节点。
+- [x] 重命名页面后 sidebar row title 更新。
+- [x] 删除 / purge 页面后 sidebar row 消失。
+- [x] 编辑保存走 `/api/documents/save` 或约定 Rust Web save endpoint。
+- [x] 保存后 `/api/page-aggregate/:id` 能看到正文变化或 revision 变化。
+- [x] `task114`、`task115`、`task118`、`task119`、`task120`、`task121` 在当前 3000 全部通过。
验证命令:
@@ -193,10 +195,10 @@ MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task121-rust-web-editor-isl
## 10. 完成判定
-- [ ] `task120` 在当前 `3000` 通过。
-- [ ] `task121` 在当前 `3000` 通过。
-- [ ] 左栏页面树来自真实 projection。
-- [ ] 根页不再用设计稿静态列表伪装主内容。
-- [ ] 文档页有真实 `leptos-tiptap` 可编辑 surface。
-- [ ] 保存后 Page Aggregate / reload 可读回。
-- [ ] `3-8` 可移动到 `done` 后,本 checklist 才能进入完成评估。
+- [x] `task120` 在当前 `3000` 通过。
+- [x] `task121` 在当前 `3000` 通过。
+- [x] 左栏页面树来自真实 projection。
+- [x] 根页不再用设计稿静态列表伪装主内容。
+- [x] 文档页有真实 `leptos-tiptap` 可编辑 surface。
+- [x] 保存后 Page Aggregate / reload 可读回。
+- [x] `3-8` 可移动到 `done` 后,本 checklist 才能进入完成评估。
diff --git a/design/03-rust-web/done/3-11-rust-web-3000-existing-tree-editor-runtime-relink-checklist-v1.md b/design/03-rust-web/done/3-11-rust-web-3000-existing-tree-editor-runtime-relink-checklist-v1.md
new file mode 100644
index 00000000..1e8698ca
--- /dev/null
+++ b/design/03-rust-web/done/3-11-rust-web-3000-existing-tree-editor-runtime-relink-checklist-v1.md
@@ -0,0 +1,65 @@
+# 3-11 [done] Rust Web 3000 既有 Tree / Editor Runtime 重新接入清单 v1
+
+> 更新时间:2026-04-29
+>
+> 纠偏来源:用户指出此前 3-10 的完成判断只证明了 API / 直达文档页 smoke,并没有证明用户打开 `3000 /` 后能看到文件树、页面树,或从 UI 新建页面进入 `leptos-tiptap`。
+>
+> 参考主线:
+> - `/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/05-editor-mainline/process/5-6-page-aggregate-alignment-checklist-v1.md`
+> - `/mnt/Data1T/mnote/design/03-rust-web/done/3-10-rust-web-3000-tree-editor-runtime-integration-checklist-v1.md`
+
+## 1. 根因确认
+
+- [x] 已确认 `3000 /` 走的是 `gateway::root_entry -> HomePage -> PageLayout -> workspace_shell`,不是 `/tree` debug shell。
+- [x] 已确认既有完整 tree runtime 在 `rust/crates/mnote-web/src/tree_shell/*` 与 `routes/tree.rs`,不应再临时造一套简化树 UI。
+- [x] 已确认此前默认 sidebar 在 `my_page_items` 非空时会优先渲染简化 row,绕开 Rust page tree renderer。
+- [x] 已确认 `SIDEBAR_TREE_JS` 被嵌套成 `
+
+ {}