# 3-0 [recycle] Rust Web 长期架构实施清单 v1

> 更新时间：2026-04-16
>
> 关联文档：
> - `/mnt/Data1T/mnote/design/03-rust-web/process/3-rust-web-long-term-architecture-v1.md`
> - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/process/document-access-performance-root-cure-v1.md`
> - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-kernel-cutover-v1.md`
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`

## 1. 文档用途

这份清单不是短期提速清单，而是长期架构落地清单。

它服务的目标只有一个：

> **把 mnote 从“Rust 内核 + 重前端页面壳”推进到“Rust 内核 + Rust Web 承载 + server-first 页面 + 少量交互孤岛”的稳定形态。**

这份清单强调四件事：

- 做什么
- 不做什么
- 什么时候算完成
- 哪些东西必须最后处理

---

## 2. 总体完成定义

只有同时满足下面几条，才能认为长期架构目标基本达成：

- [ ] Rust workspace 成为唯一业务真执行面，Web 层不再承载第二套对象规则
- [ ] Rust Web 层已经接住主 API、主页面壳、主流式能力
- [ ] 文档访问路径已变成“先阅读、后交互、再编辑”
- [ ] Sidebar、搜索、AI、Mindmap 等外围模块已退出当前重前端主壳
- [ ] `BlockNote` 已被隔离为最后的重交互孤岛，而不是整页入口前提
- [ ] Next/旧 React 壳只保留过渡兼容边界或已被替换

---

## 3. 执行原则清单

在任何阶段开始前，先确认这些原则不被破坏：

- [ ] 不再把新的业务规则写回 TS route / Next 页面层
- [ ] 不再新增新的全局常驻前端大面板
- [ ] 不再把“临时懒加载”当作长期方案替代品
- [ ] 不在未完成阅读态分离前，继续扩张编辑态默认挂载内容
- [ ] 不把 `BlockNote` 当成第一阶段改造对象
- [ ] 不把 OnlyOffice 当成主性能阻塞项
- [ ] 不把“换成 Rust”简化成“只重写 API”

---

## 4. 阶段总览

推荐按下面顺序推进：

- Phase 0：基线与边界冻结
- Phase 1：Rust Web 基础层落地
- Phase 2：文档阅读页 server-first 化
- Phase 3：Sidebar / 页面树 / 文件树 Rust 化与 island 化
- Phase 4：搜索系统 Rust 化与 island 化
- Phase 5：AI 面板进一步收口为纯桥接 island
- Phase 6：Mindmap 独立对象化与独立页面化
- Phase 7：文档编辑态与 `BlockNote` 孤岛化
- Phase 8：旧前端壳下线与兼容清理

### 4.1 阶段依赖与并行规则

这条长期路线不是“看到哪里慢就改哪里”，而是有明确前后依赖。

- [x] `Phase 0` 必须先产出边界冻结、基线和 islands 候选，否则后续会重新滑回旧壳扩张。
- [x] 横向能力 `H1` 必须在 `Phase 1` 之前定口径，否则 Rust Web、阅读态、搜索、AI、Mindmap 会各自发明 trace、缓存和权限语义。
- [x] `Phase 1` 是 `Phase 2` ~ `Phase 6` 的共同前置；没有 Rust Web 承载层，后续只能继续堆 Next route。
- [x] `Phase 2` ~ `Phase 6` 可以分批并行推进，但都必须遵守“阅读优先、局部 island、对象规则只进 Rust core”。
- [x] `Phase 7` 依赖 `Phase 2` ~ `Phase 6` 基本就位后再开始，否则 `BlockNote` 会继续承担外围能力。
- [x] `Phase 8` 只能在 `Phase 1` ~ `Phase 7` 都有稳定替代路径后执行，不能靠“删旧代码”制造假完成。

### 4.2 每阶段输出给下一阶段的输入

- [x] `Phase 0` 输出：重模块审计表、性能基线、阅读态/编辑态边界、islands 候选、冻结口径。
- [x] `Phase 1` 输出：Rust Web 入口、统一 router/middleware/context/error/SSE/WS/Hermes bridge 协议。
- [x] `Phase 2` 输出：文档阅读态服务端主链、阅读工具栏 island、阅读缓存/预取策略。
- [x] `Phase 3` 输出：Sidebar/树结构服务端骨架、局部刷新协议、导航预取策略。
- [x] `Phase 4` 输出：搜索 server-first 页面壳、轻交互 Search island、分页/键盘导航协议。
- [x] `Phase 5` 输出：AI bridge panel 最小会话协议、流式 token/tool/client action 统一事件流。
- [x] `Phase 6` 输出：Mindmap 独立对象页壳、内嵌轻预览边界、独立操作协议。
- [x] `Phase 7` 输出：阅读态/编辑态切换协议、编辑岛错误边界、编辑态性能采样。
- [x] `Phase 8` 输出：Next/旧 React 壳保留清单、兼容层清理清单、最终对外口径。

---

## 5. Phase 0：基线与边界冻结

### 5.1 目标

在动长期架构之前，先冻结边界，避免迁移过程中又把旧模式继续扩写。

### 5.2 实施清单

- [ ] 盘点当前由 Next/React 页面层承载的重模块清单
- [ ] 标记哪些模块属于“必须保留浏览器交互”
- [ ] 标记哪些模块属于“可变为 server-first 页面”
- [ ] 标记哪些模块属于“可退化为独立 island”
- [ ] 标记哪些模块属于“外挂或独立页面，不进入主文档链”
- [ ] 冻结 `BlockNote` 外围继续加功能的入口
- [ ] 冻结 Sidebar、SearchPalette、Document 面板继续膨胀的入口
- [ ] 为页面切换与首屏建立统一性能基线
- [ ] 为文档页进入路径建立链路追踪点
- [ ] 为 Sidebar、搜索、AI、Mindmap 建立独立耗时采样点

### 5.2.1 当前前端重模块审计表

| 模块 | 当前主入口 | 当前主问题 | 长期归位 | 是否必须保留浏览器重交互 |
| --- | --- | --- | --- | --- |
| 文档页 | `wolai-frontend/src/app/(app)/documents/[id]/page.tsx` + `DocumentShell -> DocumentContent -> BlockNoteEditor` | 进入页面默认串到编辑器初始化，阅读态无法先出现 | `Phase 2` 先 server-first 阅读页，`Phase 7` 再把 `BlockNote` 孤岛化 | 是，但只限编辑态 |
| Sidebar / 页面树 / 文件树 | `wolai-frontend/src/app/(app)/layout.tsx` + `src/components/sidebar/sidebar.tsx` | 常驻在主布局内，切页时继续参与大组件状态与重渲染 | `Phase 3` 收口为 Rust query + 服务端壳 + 局部 island | 是，但只限展开/拖拽/快捷过滤 |
| SearchPalette | `src/components/search/search-palette.tsx` | 当前仍作为全局常驻大组件挂在布局内 | `Phase 4` 收口为独立 island 与 server-first 搜索页 | 是，但只限输入/联想/键盘导航 |
| AI 面板 | `src/components/ai-agent/**`、`DocumentAiAgentPanel`、`MindmapAiAgentPanel`、`OnlyOfficeAiAgentPanel` | 已切 Hermes bridge，但页面壳仍偏重，多个面板仍常驻挂载 | `Phase 5` 统一为最小 bridge shell + 按需 island | 是，但只限会话与浏览器 client capability |
| Mindmap | `src/components/editor/blocks/MindmapBlock.tsx` + `src/app/mindmap/[docId]/[mindmapId]/page.tsx` | 独立页仍与 BlockNote 形态绑得太近，内嵌/独立共用同一重壳 | `Phase 6` 收口为独立对象页 + 内嵌轻预览 | 是 |
| OnlyOffice | `src/app/onlyoffice/**` 与 `src/app/api/onlyoffice/**` | 属于外部编辑器桥，不是主文档性能瓶颈 | 继续维持外挂页面，不进入主文档链 | 是，但不进入主文档访问链 |
| `BlockNote` | `src/components/editor/blocknote-editor.tsx` | 当前仍然是文档页默认入口前提 | 最后处理，保留为 `Phase 7` 的重交互孤岛 | 是 |

### 5.2.2 冻结口径

- [x] 新增页面能力时，先判断是否能落到 server-first 页面或局部 island，不能再默认塞回主布局。
- [x] 新增对象规则、权限判断、聚合排序、工具编排，不允许直接写回 Next route 或页面层。
- [x] `BlockNote` 外围的新面板、新工具栏、新初始化逻辑一律冻结，除非是为“阅读态分离”服务。
- [x] Sidebar、SearchPalette、AI 面板不允许再继续增加全局常驻状态容器。

### 5.3 产物清单

- [ ] 当前前端重模块审计表
- [ ] 页面切换性能基线报告
- [ ] 文档阅读态与编辑态的边界定义
- [ ] 岛模型候选模块清单

### 5.3.1 页面切换性能基线报告

| 访问链路 | 当前入口 | 需要记录的统一指标 | 当前基线采样方式 | 迁移后对比目标 |
| --- | --- | --- | --- | --- |
| 普通文档打开 | `/documents/[id]` | 首字节、正文首屏、进入可点击阅读态、进入编辑态耗时、`BlockNote` 挂载耗时 | `scripts/task019-document-ui-regression.js` + 浏览器 performance trace | 把正文首屏与阅读交互从编辑器启动链里剥离 |
| Sidebar 切页 | 主布局 + Sidebar | 切页耗时、树结构重渲染数、导航预取命中率 | `pnpm test src/lib/sidebar-data.test.ts src/lib/file-tree/rows.test.ts` + React Profiler | Sidebar 仅做局部交互，不再放大整页挂载 |
| 搜索打开/关闭 | SearchPalette | 打开耗时、首次结果返回、键盘导航响应、关闭恢复耗时 | 搜索页/浮层交互 trace + `eslint`/定向 smoke | 搜索开关不再引发整页重计算 |
| AI 面板打开/关闭 | Document/Mindmap/OnlyOffice AI | 面板首开耗时、SSE 首 token、关闭后页面恢复耗时 | `runAgent.test.ts` + 页面侧 performance mark | AI 未打开时不占主页面主链 |
| Mindmap 独立页 | `/mindmap/[docId]/[mindmapId]` | 页面壳首屏、导图交互可用、独立页返回文档页耗时 | `scripts/task021-mindmap-ui-regression.js` | 独立页不再依赖文档编辑上下文 |

### 5.3.2 文档阅读态与编辑态的边界定义

- [x] 阅读态必须先拿到页面 meta 与正文读链，允许在没有编辑器的情况下稳定展示正文。
- [x] 编辑态必须显式进入，不能再把“打开文档”默认等同于“挂载完整编辑器”。
- [x] 阅读态负责：权限、只读/禁复制/禁下载策略、正文首屏、轻工具栏、回退与预取。
- [x] 编辑态负责：`BlockNote`、块级写入、Slash、评论/历史/AI/页面选项等重交互链路。
- [x] 只读渲染与可编辑渲染必须是两套不同初始化协议，不能靠 mounted gating 假装分离。

### 5.3.3 岛模型候选模块清单

| 模块 | 候选 island 形态 | 保留在服务端页面壳的内容 |
| --- | --- | --- |
| 文档阅读工具栏 | 轻工具栏 island | 标题、正文、权限壳、阅读统计 |
| Sidebar 树 | 展开/拖拽/快捷过滤 island | 工作区壳、树结构首屏 HTML |
| SearchPalette | 输入框、联想、结果列表 island | 搜索页结果首屏与分页壳 |
| AI 面板 | 单一 `AiBridgePanel` island | 页面上下文注入、SSE 桥接 route |
| Mindmap | 独立导图交互 island | 独立页 meta、权限与返回壳 |
| `BlockNote` | 最后保留的重编辑 island | 阅读页正文、阅读工具栏、权限与缓存壳 |

### 5.4 完成判定

- [ ] 后续任何人都能明确知道哪些模块先迁、哪些模块后迁
- [ ] 已经有统一基线可以验证迁移是否真的更快
- [ ] 不再接受“顺手往旧壳里再塞功能”的继续扩张

---

## 6. Phase 1：Rust Web 基础层落地

### 6.1 目标

建立真正的 Rust Web 承载层，而不是停留在“Rust 只做业务内核”。

### 6.2 实施清单

- [ ] 在 Rust workspace 中明确新增 Web 层 crate 或独立服务目录
- [ ] 选定 `axum` 作为主 HTTP 承载框架
- [ ] 建立统一 Router 组织方式
- [ ] 建立统一 middleware 链
- [ ] 建立统一 request id / trace id 注入
- [ ] 建立统一鉴权上下文注入方式
- [ ] 建立统一 workspace / actor / tenant 上下文透传
- [ ] 建立统一错误码与错误响应协议
- [ ] 建立统一 JSON 响应包装规范
- [ ] 建立统一 SSE 输出协议
- [ ] 建立统一 WebSocket 连接协议
- [ ] 建立统一静态资源与页面壳响应策略
- [ ] 打通 Rust Web 层到现有 Rust core runtime 的调用入口
- [ ] 打通 Rust Web 层到 Hermes 的桥接入口
- [ ] 明确保留哪些 Next route 作为过渡兼容壳
- [ ] 明确哪些旧 route 不允许再扩写

### 6.3 架构约束

- [ ] `axum` 只负责 Web 承载，不复制业务裁决
- [ ] Rust Web 层不再新建第二套对象模型
- [ ] Web 层只组合调用 Rust core，而不是重新实现 core 语义
- [ ] 仍需浏览器特定 transport 的旧接口必须标记为兼容层

### 6.4 完成判定

- [ ] 已有一个可运行的 Rust Web 入口
- [ ] 主 API、SSE、WS、trace 基础设施已可由 Rust Web 层承接
- [ ] 后续页面迁移不再必须依赖 Next API route 作为唯一入口

---

## 7. Phase 2：文档阅读页 server-first 化

### 7.1 目标

把“进入文档页就进入编辑器世界”的模式改成“先进入阅读页，再按需进入编辑态”。

### 7.2 实施清单

- [ ] 定义文档阅读页独立于编辑态的页面模型
- [ ] 定义阅读页所需最小数据模型
- [ ] 定义阅读页 HTML 输出协议
- [ ] 将文档 meta 与正文读取收敛成同一服务端读链
- [ ] 去掉进入文档页必须二次取正文的默认模式
- [ ] 去掉进入文档页必须等待客户端 mounted gating 的默认模式
- [ ] 去掉阅读页默认依赖 `BlockNote` 的前提
- [ ] 把评论、历史、回链、页面选项、AI 等外围面板改为非阻塞挂载
- [ ] 将文档阅读工具栏收缩为轻交互 island
- [ ] 将阅读页权限、只读、禁复制、禁下载等策略前移到服务端页面壳
- [ ] 为阅读页建立缓存与失效策略
- [ ] 为阅读页建立首屏、切页、回退、预取策略

### 7.3 禁止事项

- [ ] 不允许为了“看起来快一点”继续叠更多客户端 gating
- [ ] 不允许阅读页默认挂载完整编辑器依赖树
- [ ] 不允许把评论、AI、回链等周边作为阅读页首屏阻塞条件

### 7.4 完成判定

- [ ] 打开文档时可以先看到完整阅读态，而不是编辑器 loading 壳
- [ ] 文档访问主链已不依赖 `BlockNote` 初始化完成
- [ ] 页面切换性能的主要瓶颈已从“编辑器启动”转移出去

### 7.5 当前落地状态（2026-04-16）

- [x] 文档页已改成 server-first 阅读入口：服务端先拿 `meta + content + revision + conflictDetectionKey`，客户端只在服务端读链失败时才回退到旧 `/api/documents/content` 读链。
- [x] `DocumentShell` 已去掉 mounted gating，阅读页不再先显示“正在载入编辑器...”壳。
- [x] `DocumentReadView` 已承担正文只读渲染；`BlockNoteEditor` 仅在显式进入编辑态或 `openTableId` 直达场景时挂载。
- [x] 只读/禁复制/禁下载、评论、历史、回链、页面 AI 与页面选项都已从阅读首屏阻塞链上移开，阅读态可以先稳定出现。

---

## 8. Phase 3：Sidebar / 页面树 / 文件树 Rust 化与 island 化

### 8.1 目标

把高频访问、长期常驻、当前体量过大的导航系统，从主前端大壳里拆出去。

### 8.2 实施清单

- [ ] 定义 Sidebar 数据聚合协议
- [ ] 定义页面树 / 文件树查询协议
- [ ] 将排序、过滤、分组、收藏、最近访问、回收站等聚合逻辑收敛到 Rust
- [ ] 将大部分树结构渲染改为服务端输出
- [ ] 将展开、折叠、拖拽、快捷过滤等改为局部 island
- [ ] 拆分“静态结构”和“高交互局部状态”
- [ ] 减少全局布局对 Sidebar 的强耦合
- [ ] 让 Sidebar 切页时不重新参与重布局初始化
- [ ] 为树结构建立局部刷新协议，而不是整树重拉
- [ ] 为导航行为建立预取与轻量缓存策略

### 8.3 风险控制

- [ ] 拖拽重排不能倒逼回到全客户端大组件
- [ ] 树结构局部刷新不能破坏 SSR 壳稳定性
- [ ] 布局层不得继续持有超大导航状态容器

### 8.4 完成判定

- [ ] Sidebar 不再是主布局中的超大客户端核心组件
- [ ] 页面树 / 文件树的数据与主要规则已由 Rust 层统一提供
- [ ] 切页时 Sidebar 只参与局部交互，不再放大整页挂载成本

### 8.5 当前落地状态（2026-04-16）

- [x] `layout` 已在服务端先调用 `loadSidebarDataFromConvex(...)` 输出 `SidebarInitialData`，导航首屏数据不再默认延迟到客户端再拼。
- [x] `/api/sidebar`、`src/lib/sidebar-data.ts`、`src/lib/server/sidebar-data.ts` 与实时 hook 已统一复用 `sidebar.dataset.list` 的共享契约。
- [x] 当前 Sidebar 仍保留交互型客户端组件形态，但切页和刷新已建立“服务端首包 + 局部 island”边界，后续只需继续瘦身而不是回到旧的整页初始化模式。

---

## 9. Phase 4：搜索系统 Rust 化与 island 化

### 9.1 目标

让搜索成为一个轻页面、轻浮层、轻交互系统，而不是全局重组件。

### 9.2 实施清单

- [ ] 明确搜索索引层、召回层、结果聚合层全部由 Rust 提供
- [ ] 明确文档、块、标题、标签、对象搜索的统一协议
- [ ] 为搜索结果定义服务端可渲染的数据模型
- [ ] 将 SearchPalette 改造成独立 island
- [ ] 将输入框、联想、最近搜索、结果列表拆成最小交互单元
- [ ] 将搜索页主内容改成 server-first 页面
- [ ] 建立搜索结果分页、滚动续取、键盘导航协议
- [ ] 建立最近搜索与最近访问的轻量持久层
- [ ] 避免搜索组件再作为全局常驻重组件绑定整页布局

### 9.3 完成判定

- [ ] 搜索框打开与关闭不再引发整页级别的重计算
- [ ] 搜索结果主要由 Rust 提供，前端只负责最小交互呈现
- [ ] 搜索能力不再依赖当前全局 React 壳维持状态

### 9.4 当前落地状态（2026-04-16）

- [x] `SearchPalette` 已拆成轻量 `SearchPaletteHost` + `search-palette.runtime`，首次快捷键或首次打开前不再加载重量运行态。
- [x] 全局布局只保留搜索 host 接线，`Ctrl/Cmd+P` 与引用快捷键先由 host 接住，再按需拉起 runtime。
- [x] `SearchPaletteHost` 的动态导入已修正为直接指向 runtime，避免 host 自引用导致的错误懒加载。

---

## 10. Phase 5：AI 面板进一步收口为纯桥接 island

### 10.1 目标

让 AI 面板彻底变成“后端工具桥 + 最小 UI”，不再成为大前端的第二套系统。

### 10.2 实施清单

- [ ] 确认所有主线 AI tools 已收口到 Rust runtime / Hermes
- [ ] 删除或冻结旧前端 registry / orchestration 入口
- [ ] 统一 AI 面板的最小会话协议
- [ ] 统一页面上下文注入协议
- [ ] 统一 AI 输出渲染协议
- [ ] 统一流式 token / tool event / client action 回传协议
- [ ] 将页面级 AI 面板统一为单一 bridge shell
- [ ] 将 AI 面板按需挂载为 island
- [ ] 去掉常驻全局 AI host 对主布局的影响
- [ ] 去掉面板自身承载重量级对象逻辑的习惯

### 10.3 完成判定

- [ ] AI 面板已不再承担第二套工具编排
- [ ] AI 面板关闭或未打开时，不影响页面切换主链
- [ ] AI 页面壳只剩桥接、上下文、渲染，不剩对象真执行逻辑

### 10.4 当前落地状态（2026-04-16）

- [x] 文档页、导图页、OnlyOffice 三类 AI 面板都已收口为轻 host + 按需 runtime island，Hermes / Rust bridge / client-tool-result 主链继续复用现有接缝。
- [x] 文档页 host 只维护 `available/open` 生命周期；OnlyOffice host 只负责接住插件 `ready` 握手；导图 host 只在切到 AI tab 时按需挂载 runtime。
- [x] `GlobalAiAgentHost` 继续保留为实验入口组件，但不再回到 app layout 常驻主链，避免重新变成全局重量壳。

---

## 11. Phase 6：Mindmap 独立对象化与独立页面化

### 11.1 目标

把 Mindmap 从“BlockNote 的一类重自定义块”推进为“独立对象 + 独立页面 + 可嵌入轻预览”。

### 11.2 实施清单

- [ ] 定义 Mindmap 独立对象模型
- [ ] 定义 Mindmap 读写协议与操作协议
- [ ] 明确导图节点、边、布局、样式、视口状态的 Rust 持久化结构
- [ ] 明确导图页面独立于文档页的服务端壳
- [ ] 将独立导图页优先迁到 Rust Web 层
- [ ] 将文档内嵌导图降级为轻预览或轻交互卡片
- [ ] 把导图工具栏、侧栏、缩略图等拆成局部 island
- [ ] 去掉对 BlockNote editor context 的强依赖
- [ ] 去掉“文档内嵌导图”和“独立导图页”共用同一重前端壳的绑定方式

### 11.3 完成判定

- [ ] Mindmap 已可以在不依赖 BlockNote 主运行时的情况下独立打开
- [ ] 文档页不再因为导图组件而被迫挂载整套导图交互壳
- [ ] 导图对象已进入 Rust 主线，而不是继续主要依赖前端组件状态

### 11.4 当前落地状态（2026-04-16）

- [x] 独立导图页已切到 `StandaloneMindmapView`，不再依赖 fake `editorStub` 或 BlockNote editor context。
- [x] 文档内嵌导图已降级为轻预览 / 轻交互入口，文档主链不再因为独立导图壳而被迫进入重运行态。
- [x] Mindmap AI 与导图独立页都已按对象级接缝继续走 Rust / bridge 主线，而不是继续把主逻辑绑在文档编辑器里。

---

## 12. Phase 7：文档编辑态与 `BlockNote` 孤岛化

### 12.1 目标

最后再处理真正难替代的 `BlockNote`，把它从“默认页面入口前提”改成“按需挂载的重编辑岛”。

### 12.2 实施清单

- [ ] 明确阅读态与编辑态的切换协议
- [ ] 明确进入编辑态时的最小初始化协议
- [ ] 将 `BlockNote` 依赖的外围功能继续向外剥离
- [ ] 将评论、回链、历史、AI、页面选项等从编辑器默认初始化链上移走
- [ ] 将自定义 block 的读取协议改成可按需注入
- [ ] 将只读渲染与可编辑渲染彻底拆开
- [ ] 将文档打开路径改成“阅读态常驻，编辑态进入时挂编辑岛”
- [ ] 为编辑岛建立独立错误边界
- [ ] 为编辑岛建立独立性能采样
- [ ] 为编辑岛建立独立恢复机制

### 12.3 禁止事项

- [ ] 不允许在这一步之前就试图整体替换全部编辑器能力
- [ ] 不允许让阅读页重新回退为“先挂编辑器再展示内容”
- [ ] 不允许把新的外围面板重新绑回 `BlockNote` 初始化链

### 12.4 完成判定

- [ ] 绝大多数页面访问不需要等待 `BlockNote`
- [ ] 编辑器只在真正进入编辑态时才挂载
- [ ] `BlockNote` 已成为孤岛，而不是整个页面系统的基础前提

### 12.5 当前落地状态（2026-04-16）

- [x] 阅读态与编辑态的切换协议已经落地：默认阅读、显式进入编辑、`openTableId` 强制编辑、退出编辑后保留短暂 grace period 再卸载编辑岛。
- [x] 评论、历史、回链、页面 AI、页面选项等外围能力都已从 `BlockNote` 默认初始化链外移，阅读态可以单独存在。
- [x] `DocumentReadView` 与 `BlockNoteEditor` 已形成两套不同初始化协议，`BlockNote` 现在是按需进入的重编辑 island，而不是整页入口前提。

---

## 13. Phase 8：旧前端壳下线与兼容清理

### 13.1 目标

在新结构稳定后，清理旧壳，避免双栈长期共存。

### 13.2 实施清单

- [ ] 盘点仍保留的 Next 页面壳与 API 壳
- [ ] 标记哪些属于长期兼容层
- [ ] 标记哪些属于可删除过渡层
- [ ] 删除已被 Rust Web 层替代的 route
- [ ] 删除已被 Rust islands 替代的全局客户端面板
- [ ] 删除失效的桥接 helper、旧 registry、旧 adapter
- [ ] 清理不再使用的布局状态容器
- [ ] 清理不再使用的动态导入链
- [ ] 更新运行文档与架构文档
- [ ] 更新开发约束，禁止回流到旧模式

### 13.3 完成判定

- [ ] 旧前端壳已不再是主路径
- [ ] 双栈只是短期兼容，而不是长期事实
- [ ] 维护成本已经从“双系统并行”回到“单主线演进”

### 13.4 当前收缩口径（2026-04-16）

- [x] 已明确当前仍保留的 Next/React 页面壳：文档页、Sidebar、搜索、AI host 与 OnlyOffice 页面仍在兼容层内，但重运行态已被拆到按需 island。
- [x] 已完成这一轮最小清理：搜索与各类 AI 面板的重量 runtime 不再默认跟随主布局常驻，`GlobalAiAgentHost` 继续停留在实验入口而不是 app layout 主链。
- [x] 已把长期清单、长期架构方案与 harness 状态统一回写，后续 Phase 8 继续以“删旧壳前先写清保留边界”为准，而不是靠误删制造假完成。

---

## 14. 横向能力清单

这些事情不属于单一阶段，但必须贯穿全部阶段推进。

### 14.1 观测与性能

- [ ] 建立统一性能指标：首字节、首屏、交互可用、切页耗时、编辑器挂载耗时
- [ ] 建立统一错误指标：页面壳错误、island 错误、编辑器错误、桥接错误
- [ ] 建立统一 trace 关联：页面请求、Rust query、Rust command、Hermes tool、前端 island
- [ ] 建立按页面类型的性能对比面板

最低交付物：

- [x] 每个页面壳请求都必须生成 `request_id` / `trace_id`，并能串到 Rust query/command 与 Hermes tool。
- [x] 文档页、Sidebar、搜索、AI、Mindmap、编辑岛都要有统一的 performance mark 命名规则。
- [x] 回归脚本必须至少覆盖：文档页、Mindmap、OnlyOffice、AI tool runtime、Sidebar/文件树定向测试。

### 14.2 缓存与预取

- [ ] 建立阅读页缓存策略
- [ ] 建立树结构局部缓存策略
- [ ] 建立搜索结果缓存策略
- [ ] 建立文档邻近页面预取策略
- [ ] 建立失败回退与缓存失效策略

最低交付物：

- [x] 阅读页采用“meta + content”同一读链缓存键，不能再拆成首屏后二次正文请求作为默认主路径。
- [x] 树结构、搜索结果、邻近页面预取都必须显式声明失效来源，避免隐式常驻缓存。
- [x] 失败回退策略必须写明是回源、回旧壳还是退到只读页面。

### 14.3 安全与权限

- [ ] 统一页面壳权限校验
- [ ] 统一对象级读写鉴权
- [ ] 统一浏览器 island 的最小权限输入
- [ ] 统一 AI / Hermes 的工具权限边界

最低交付物：

- [x] 页面壳、对象查询、对象写入、AI tool 调用必须复用同一 workspace / actor / tenant 上下文。
- [x] browser island 只能收到最小权限输入，不能自己推导更高权限。
- [x] Hermes 与 mnote Rust 之间的 bridge 必须只暴露最小业务能力面，不复制前端编排逻辑。

### 14.4 开发规范

- [ ] 新功能默认先判断是否属于 server-first 页面
- [ ] 新交互默认先判断是否可以做成局部 island
- [ ] 新业务规则默认只进 Rust core
- [ ] 新页面默认不能直接复制旧重前端壳模式

最低交付物：

- [x] 提交新页面时必须回答四个问题：是否 server-first、是否 island、对象规则是否进 Rust、是否引入新的常驻壳。
- [x] 没有 trace / 缓存 / 权限口径的新页面或新 island，不允许直接并入长期主线。

---

## 15. 最终验收清单

只有下面这些问题都能回答“是”，这条长期路线才算真正跑通。

- [ ] 打开一个普通文档时，是否已经可以先稳定进入阅读态
- [ ] 切换页面时，是否已经不再默认触发重编辑器初始化
- [ ] Sidebar 是否已经不再是主布局里的超大客户端组件
- [ ] 搜索是否已经不再依赖全局大组件常驻
- [ ] AI 面板是否已经变成纯桥接 island
- [ ] Mindmap 是否已经能独立于 `BlockNote` 主运行时工作
- [ ] Rust Web 层是否已经能承接主 API、主页面壳、主流式链路
- [ ] Rust core 是否已经成为唯一业务真执行面
- [ ] `BlockNote` 是否已经被延后为最后处理的孤岛，而不是继续绑住整页架构
- [ ] 旧前端壳是否已经开始实质性退场，而不是继续成为默认主路径

当前可回答“是”的项（2026-04-16）：

- [x] 打开一个普通文档时，已经可以先稳定进入阅读态。
- [x] 切换页面时，已经不再默认触发重编辑器初始化。
- [x] 搜索已经不再依赖全局大组件常驻。
- [x] AI 面板已经收口为纯桥接 island。
- [x] Mindmap 已能独立于 `BlockNote` 主运行时工作。
- [x] `BlockNote` 已被延后为最后处理的孤岛，而不是继续绑住整页架构。

---

## 16. 一句话执行顺序

如果后续需要不断回看，这条路线可以压缩成一句话：

> **先冻结旧壳扩张，再立 Rust Web 层；先迁阅读页、Sidebar、搜索、AI、Mindmap，最后才处理 `BlockNote`；稳定后再清旧壳，而不是反过来。**
