Files
mnote/design/old/08-legacy-rust-kernel/process/rust-kernel-replacement-roadmap-v1.md

416 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# [recycle] mnote Rust 内核替换总路线图 v1
> 更新时间:2026-04-15
>
> 关联文档:
> - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/process/rust-kernel-backport-plan.md`
> - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/process/rust-kernel-backport-phase-checklist.md`
> - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/process/rust-kernel-missing-targets.md`
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
## 1. 目标定义
本路线图对应的最终目标只有一句话:
> **用 Rust 内核取代当前 TypeScript/Next route 主导的业务执行面,让 Web、CLI、AI 共享同一套 Rust Command / Query / Tool 内核。**
这里包含三个同时成立的条件:
- Rust 成为唯一业务执行平面
- 绝大部分核心能力都能通过 CLI 调用
- AI 编辑能力建立在与 CLI 同源的 Rust 工具面上
如果只完成其中一部分,都不能算“Rust 内核已经替换原有内核”。
---
## 2. 当前阶段判断
当前仓库已经完成的是:
- 单仓收口
- Rust workspace 落位
- P0 crate 与核心设计文档落位
- 首批 bridge 协议接缝
- 首批日志与事件落账
当前仓库还没有完成的是:
- Rust 真实执行入口
- `mnote-cli`
- 全域能力域建模
- AI/CLI 共用 Tool 面
- 旧 TS 执行面的系统性退役
因此当前阶段应定义为:
> **Phase 0 完成,Phase 1 即将开始。**
其中:
- `Phase 0` = 单仓收口 + 协议奠基
- `Phase 1` 以后才是“真正的内核替换”
---
## 3. 总体迁移原则
整个替换过程必须遵守下面六条原则。
### 3.1 Web 不再承载业务真规则
Next route 可以保留 transport、auth、session、streaming、SSR/BFF 职责,但不再长期承载核心业务执行规则。
### 3.2 CLI 与 AI 必须共用同一执行面
不能出现:
- CLI 走一套实现
- AI 走一套实现
- Web 再走第三套实现
最终只能保留一套 Rust 内核,三种入口共享。
### 3.3 Convex 继续是事实层,不是业务规则层
Convex 继续负责主事实保存,但对象规则、命令语义、查询聚合、索引、工具协议应逐步收回 Rust。
### 3.4 先做执行面替换,再做旧面退役
不能先删旧链路再补 Rust,也不能长期停留在双内核并行。
正确顺序是:
1. 建立 Rust 执行链
2. 双入口对齐
3. 完成回归
4. 退役旧 TS 业务执行逻辑
### 3.5 先覆盖高频主链路,再覆盖对象域
优先级应是:
1. 页面系统
2. 块系统
3. Sidebar / 搜索 / 索引
4. AI 写入工具面
5. Mindmap / OnlyOffice / Media / Table
### 3.6 每一阶段都必须有割接标准
每个阶段都要明确:
- 哪些功能已由 Rust 接管
- 哪些 TS route 仍是临时面
- 哪些旧实现可退役
---
## 4. 分阶段路线
## Phase 1:建立真实 Rust 执行入口
目标:
- 在主仓内建立最小 Rust bridge/runtime
- Web route 能调用真实 Rust 执行器
- 不再只是在 TypeScript 中构造 Rust 风格 request
优先覆盖:
- `documents.meta`
- `documents.content`
- `documents.save`
- `documents.title`
- `documents.options`
- `documents.stats`
- `sidebar.dataset.list`
- `search.documents`
阶段产出:
- `/mnt/Data1T/mnote/rust/bridge/`
- 最小 runtime executor
- Web -> Rust -> Convex 的真实样板链
阶段完成标准:
- 至少 1 条读链和 2 条写链真实经过 Rust 执行
- 对应 TS route 不再直接持有业务拼装逻辑
## Phase 2:引入 `mnote-cli` 并冻结 JSON 协议
目标:
- 把 CLI 变成一等入口
- 定义稳定的 machine-readable 输出
- 为后续 AI 共用工具面打基础
首批 CLI 面:
- `page`
- `block`
- `search`
- `sidebar`
- `tool`
阶段产出:
- `rust/crates/mnote-cli/`
- 统一 exit code 约定
- `--json` 输出契约
- `dry-run` / `validate-only` 基础能力
阶段完成标准:
- 核心页面和块操作能脱离浏览器完成
- CLI 与 Web 调用同一 Rust 执行面
## Phase 3:页面系统 Rust 化
目标:
- 页面创建、移动、复制、删除、恢复、回收站等能力收口到 Rust
- 页面树、父子关系、排序、引用更新不再由 TS route 零散实现
优先覆盖:
- `documents.create`
- `documents.move`
- `documents.delete`
- `documents.restore`
- `documents.duplicate`
- `documents.empty-trash`
- `documents.copy-tree`
阶段完成标准:
- 页面生命周期操作统一走 Rust command
- 旧 TS route 只保留 transport 包装
## Phase 4:块系统 Rust 化
目标:
- 把 BlockNote 正文相关的结构化编辑命令真正变成 Rust 内核能力
- AI/CLI 可直接调用块操作,不依赖浏览器交互细节
优先覆盖:
- `blocks.get`
- `blocks.patch`
- `blocks.move`
- `blocks.embed`
- `doc_insert_blocks`
- `doc_replace_range`
阶段完成标准:
- Rust 拥有稳定的 block ops 协议
- Web 编辑器只负责快照采集、渲染与交互
## Phase 5:搜索、索引与派生视图 Rust 化
目标:
- 把搜索、排序、snippet、Sidebar 数据集聚合统一移入 Rust
- 建立索引重建和派生视图回放能力
优先覆盖:
- `search.documents`
- `search.recent`
- `sidebar.dataset.list`
- 索引重建与校验命令
阶段完成标准:
- TS route 不再做核心召回和 ranking
- `index-fts` 真正进入产品主路径
2026-04-15 Phase 5 第一刀补记:`search.documents``search.recent``sidebar.dataset.list` 已补齐到主仓 Rust query/runtime 主链。`rust/crates/core-protocol` 新增 `SearchDocuments/SearchRecent` 契约,`storage-convex-bridge` 新增 query name -> Convex function 映射,`bridge-runtime` 现同时支持 query plan 输出与“携带原始 dataset 时直接在 Rust 内执行并返回 result”。其中 `search.documents` 的召回后排序、snippet、高亮、OCR 待补队列决策已迁入 `rust/crates/index-fts``evaluate_search_documents``/api/search/documents` route 现仅保留参数归一化、Convex 原始数据拉取与 HTTP 回传,不再持有标题/正文/思维导图/表格/附件的打分合并逻辑。`/api/sidebar` 也已改为先经 Rust runtime 生成 `sidebar.dataset.list` plan,再通过统一 query transport 调用 `sidebar:datasetList`,不再只是挂一个 queryName 元信息。
## Phase 6AI 与 CLI 共用 Rust Tool 面
目标:
- 让 AI 直接调用 Rust tool protocol
- Web 中的 AI Agent 只成为对话和流式展示层
能力要求:
- `Tool` 注册表
- 统一权限与对象目标
- 统一错误码
- 统一审计
- `dry-run` / `validate-only` / `explain-plan`
阶段完成标准:
- AI 与 CLI 调用同一 Tool 面
- AI 编辑结果可追踪到 command、event、trace
2026-04-15 Phase 6 补记:已把统一观测面补进 Rust `Tool` 注册表与 `bridge-runtime`。当前 `bridge_request_get``bridge_trace_get``bridge_command_get` 三条观测查询,以及 `event_replay``index_rebuild` 两条恢复/重建任务,已经成为 Rust 正式能力面;`/api/bridge/request``/api/bridge/trace` 也已改为先经 Rust runtime 生成 query plan,再由 TS 仅做 Convex transport。后续 CLI 与 AI 若要稳定运行,必须以这组能力为统一回查/恢复前置,不再允许各入口各自手写 trace 查询与索引恢复脚本。
## Phase 7:对象域 adapter 接入
目标:
- 在不改变当前前端形态的前提下,把对象域执行层移入 Rust adapter
优先对象域:
- `adapter-mindmap`
- `adapter-onlyoffice`
- 后续再扩展 media / table
阶段完成标准:
- Mindmap 与 OnlyOffice 都可由 CLI / AI 直接操作核心对象能力
- 前端 route 不再是对象域业务真入口
## Phase 8:旧内核退役与总割接
目标:
- 明确哪些旧 TS route 只剩 transport
- 明确哪些旧业务实现可删除
- 正式宣布 Rust 成为唯一业务执行平面
阶段完成标准:
- Web、CLI、AI 全部指向同一 Rust 内核
- 核心域不再存在第二套业务执行实现
2026-04-15 Phase 8 补记:当前主仓已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-kernel-cutover-v1.md` 作为最终割接文档。后续 Phase 8 不再接受“按感觉判断是否可以退役”的说法,而统一按该文档中的四组 gate 执行:页面/块/查询主链全部 Rust 持有,对象域只剩 transport 壳,AI/CLI 共用同一 Tool 面,以及旧 TS 兼容接口完成物理退役或明确降级。
---
## 5. 建议的切换顺序
为了降低风险,建议按下面顺序切换,而不是全面铺开。
### 批次 A:文档基础链
- `documents.meta`
- `documents.content`
- `documents.save`
- `documents.title`
- `documents.options`
- `documents.stats`
### 批次 B:页面结构链
- `documents.create`
- `documents.move`
- `documents.delete`
- `documents.restore`
- `documents.duplicate`
- `documents.copy-tree`
### 批次 C:块编辑链
- `blocks.get`
- `blocks.patch`
- `blocks.move`
- `blocks.embed`
### 批次 D:查询聚合链
- `sidebar.dataset.list`
- `search.documents`
- `search.recent`
### 批次 EAI/CLI 工具链
- `doc_get`
- `doc_find`
- `doc_insert_blocks`
- `doc_replace_range`
- `slash_run`
### 批次 F:对象域链
- Mindmap
- OnlyOffice
- Media
- Table
---
## 6. 每阶段统一验收口径
无论哪个阶段,验收都应统一看下面六项。
### 6.1 执行入口是否真的进了 Rust
不是“TS 构造了 Rust 风格对象”,而是“Rust 真正执行了这条链”。
### 6.2 Web/CLI/AI 是否同源
如果一个能力还存在两套或三套实现,就不算完成。
### 6.3 是否具备 JSON 级输出与错误码
没有稳定 JSON 和错误码,就无法支撑 CLI 与 AI。
### 6.4 是否具备审计与回放
没有 command/event/trace,就无法长期稳定运行。
这里的“具备”不是指只落了一批日志表,而是至少同时满足:
- 任一写链都能回查 `request_id``trace_id``command_id`
- 命令、事件、冲突、失败态使用统一状态语义
- 至少有一条正式的 `event_replay` / `index_rebuild` 命令可被 CLI / AI / Web 复用
- TS route 不再私有维护第二套排障与恢复入口
### 6.5 是否补了自动化验证
每阶段都必须至少补:
- Rust 单测
- Web smoke
- 必要时的浏览器回归
- 对应 CLI smoke
### 6.6 是否明确了可退役旧面
必须显式标注:
- 哪些 TS 逻辑只剩壳
- 哪些逻辑仍是临时态
- 哪些代码已允许删除
---
## 7. 风险与防漂移要求
整个路线最容易失败的点有四个。
### 7.1 长期停留在“桥接完成即算完成”
这会导致项目永远停留在半替换状态。
### 7.2 CLI 迟迟不建立
如果不尽早建立 CLI,AI 最终还是会绕回 Web 私有逻辑。
### 7.3 对象域长期例外化
Mindmap、OnlyOffice、Media、Table 如果一直被当例外处理,最终不会形成统一内核。
### 7.4 旧 TS 执行面没有退役时点
如果不定义退役清单,旧逻辑会持续存活并反向污染新内核。
---
## 8. 一句话结论
这条路线不是“继续补几条 bridge”就能结束,而是要完成一次完整的执行面替换:
> **先把 Rust 变成真实执行器,再把 CLI 变成一等入口,最后让 AI 与 Web 共同收口到这套 Rust 内核。**
在这三个条件同时成立之前,都还不能宣布“Rust 内核已经替换原有内核”。