Files
mnote/design/10-review/done/01-rust-kernel-web-review.md
T

122 lines
12 KiB
Markdown
Raw Normal View History

2026-05-13 22:43:16 +08:00
# Rust Kernel / Web 实现偏差审查
2026-05-14 16:30:13 +08:00
> 执行状态:已归档到 `design/10-review/done/`。本文保留为历史审查快照,当前活跃口径以 `./06-execution-checklist-and-acceptance.md` 为准。
2026-05-13 22:43:16 +08:00
## 范围
本次只审查 Rust kernel / protocol / bridge-runtime / mnote-web / storage-convex-bridge 与当前设计主线的一致性。
重点对照设计:
- `ARCHITECTURE.md`
- `design/01-05-current-priority-overview.md`
- `design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md`
- `design/01-tree-first-graph-kernel/reference/1-1-tree-first-graph-kernel-checklist-v2.md`
2026-05-13 22:43:16 +08:00
- `design/02-convex-rust-long-term-architecture/process/2-tree-first-graph-convex-rust-long-term-architecture-v1.md`
- `design/03-rust-web/reference/3-rust-web-long-term-architecture-v1.md`
- `design/03-rust-web/reference/3-1-rust-web-long-term-checklist-v2.md`
2026-05-13 22:43:16 +08:00
- `design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md`
- `design/03-rust-web/process/3-15-runtime-fallback-retirement-checklist-v1.md`
- `design/04-tree-domain/done/4-6-tree-command-protocol-cutover-stage2-v1.md`
重点代码:
- `rust/crates/core-protocol/`
- `rust/crates/core-domain/`
- `rust/crates/bridge-runtime/`
- `rust/crates/mnote-web/`
- `rust/crates/storage-convex-bridge/`
## 结论
Rust kernel / protocol / bridge-runtime / mnote-web 的主干方向与当前设计基本一致:`core-protocol` 已有统一 kernel node / edge / projection / page aggregate 协议;`bridge-runtime` 已能执行 kernel query / command / projection`mnote-web` 已持有 3000 主入口、文档页 shell、`/api/page-aggregate/:id`、tree command、`/api/tree/events`、Search shell 等关键接缝;`storage-convex-bridge` 明确把 `tree.*` / `page.*` 等语义命令映射到底层 Convex mutation。
主要偏差不是“Rust 主线没有落地”,而是当前仍存在几类收口缺口:
1. 部分 Rust Web 主路径仍会静默合成 fallback / fixture 数据,和 `Runtime Fallback 退场` 的激进口径不完全一致。
2. Page Aggregate 对外标记为 `KernelProjection`,但 Rust Web 仍先取 `documents.meta/content` 再在 runtime 内拼成聚合;这是合理过渡实现,但“单一 kernel 真源”口径容易被写得过满。
3. Tree realtime 已有正式 SSE 主链,但实现仍偏轮询 bridge overviewWS 仍是 snapshot/resync 骨架,尚未成为完整实时主链。
4. Legacy / compat 能力默认大多关闭,但配置位、proxy 辅助函数和兼容源枚举仍在,设计文档中“全部退场”的勾选状态可能偏乐观。
## 关键发现表格
| 编号 | 分类 | 严重度 | 发现 | 证据 |
| --- | --- | --- | --- | --- |
| RK-01 | 未完成 | 中 | Kernel projection 仍主要从 `sidebar.dataset.list` 这一份 Convex 数据集构建,广义 node pool / reference edge / summary/index 真相层尚未完全独立。 | `rust/crates/mnote-web/src/routes/snapshot_support.rs:27` 定义 `sidebar.dataset.list``:93` 先加载 sidebar dataset 再执行 `kernel.project_view``rust/crates/bridge-runtime/src/lib.rs:8010` 后续由 sidebar 数据构建 subtree`:8111` 再转为 projection。 |
| RK-02 | 实现偏差 / 风险 | 高 | Rust Web 主路径仍存在静默 fallbackworkspace shell 在 projection 加载失败时无条件合成最小 workspace/documentssidebar/filetree 在 `allow_dev_fixtures` 时合成开发数据;Search 在 Convex query 失败时返回内置搜索数据。这与 `3-15-runtime-fallback-retirement` 的“默认不再 fallback”口径冲突。 | `rust/crates/mnote-web/src/routes/web_shell.rs:2379``:2401` 无条件 fallback 最小 dataset`:2432``:2461` 合成 sidebar dev dataset`:2493``:2519` 合成 filetree dev dataset`rust/crates/mnote-web/src/routes/search.rs:233``:247` 搜索失败后走 `fallback_search_dataset`。 |
| RK-03 | 方向变化 / 文档滞后 | 中 | Page Aggregate 已由 Rust Web 暴露正式 route,但实现仍是先读 `documents.meta/content`,再把 joined data 交给 `page.aggregate.get` 生成 projection。代码对外 source 标成 `KernelProjection`,但底层仍是 meta/content join 的迁移形态;需要文档明确这是 Rust runtime adapter,而非完整 kernel storage 真源。 | `rust/crates/mnote-web/src/routes/web_shell.rs:2282``:2315` 先读 meta/content 再执行 `page.aggregate.get``rust/crates/bridge-runtime/src/lib.rs:8246``:8253` 将 source 传为 `PageAggregateSource::KernelProjection``:5303``:5324` 从 meta/content 中抽取 title/content/revision。 |
| RK-04 | 未完成 | 中 | Tree realtime 正式 route 已存在,但当前 SSE 仍通过 polling `bridge.workspace.overview` 生成 snapshot/delta/resyncWS 只发送初始 snapshot,并只支持客户端请求 resync,不是完整主实时链路。 | `rust/crates/mnote-web/src/routes/sse.rs:51``:91` 循环 sleep/poll overview 后生成 delta`rust/crates/mnote-web/src/routes/ws.rs:32` 发送 snapshot`:40``:80` 只处理 resync 或 unsupported ack。 |
| RK-05 | 风险 / 文档滞后 | 低 | Legacy Next compat 默认关闭,但代码仍保留 env-gated proxy 能力、Next proxy 辅助函数和 compat 配置位。若文档继续写“legacy compat 已删除”,会与代码事实不一致;若保留,应写成显式调试/迁移边界。 | `rust/crates/mnote-web/src/app.rs:42``:54` 仍读取 `MNOTE_WEB_LEGACY_NEXT_BASE_URL` / `MNOTE_WEB_ENABLE_LEGACY_NEXT_COMPAT``rust/crates/mnote-web/src/routes/gateway.rs:86``:87` auth API 可转 legacy proxy`:402``:499` legacy proxy 实现仍在;`rust/crates/mnote-web/src/routes/documents.rs:153` 当前 `should_proxy_via_next` 返回 false,但 Next proxy helper 仍保留。 |
| RK-06 | 实现一致 | 低 | Tree command cutover Stage 2 的长期命名面已在 Rust route / bridge / storage mapping 中落地,`documents.*` 仍作为 alias/底层 Convex mutation 名称存在,和 Stage 2A/2B 过渡口径基本一致。 | `rust/crates/storage-convex-bridge/src/mapping.rs:37``:43` 映射 `tree.*``:52``:68` 保留 `documents.*` / `page.*` alias`rust/crates/mnote-web/src/tree_shell/dispatcher.rs:16``:23` 使用 `tree.*``rust/crates/mnote-web/src/routes/tree.rs:7634` 附近测试确认 documents alias 映射仍存在。 |
| RK-07 | 实现一致 | 低 | Debug shell 默认关闭,符合 `3104`/debug 壳默认退场口径。 | `rust/crates/mnote-web/src/routes/mod.rs:120``:124` 仅在 `enable_debug_shell_routes` 时挂 `/tree``/document-debug`;同文件测试 `:142``:184` 验证默认 404。 |
## 证据
### 1. Kernel / projection 已落地,但底层仍主要基于 sidebar dataset
- `rust/crates/core-protocol/src/kernel.rs:7``:42` 定义 `KernelNodeType``KernelEdgeType``KernelProjectionKind`
- `rust/crates/mnote-web/src/routes/kernel.rs:62``:85` 暴露 projection route,并经 `load_projection_snapshot` 获取投影。
- `rust/crates/mnote-web/src/routes/snapshot_support.rs:27``:47` 固定 `sidebar.dataset.list` 为数据获取入口。
- `rust/crates/bridge-runtime/src/lib.rs:8119``:8137` 在没有 root 时由当前数据构建 subtree,再生成 projection`file_tree` 另走 `build_file_tree_projection_result`
判断:这符合 `1-1` 中“真实主线已落地,但更广义 node pool/reference edge 仍后续”的口径,不应被写成“尚未开始”;也不应被写成“完整 kernel 真源已闭环”。
### 2. Runtime fallback 仍在主路径附近
- `rust/crates/mnote-web/src/routes/web_shell.rs:2379``:2401`workspace shell projection 加载失败时合成 `active_workspace_id``workspaces``documents`
- `rust/crates/mnote-web/src/routes/web_shell.rs:2432``:2461``allow_dev_fixtures` 时合成 sidebar dev dataset。
- `rust/crates/mnote-web/src/routes/web_shell.rs:2493``:2519``allow_dev_fixtures` 时合成 filetree dev dataset。
- `rust/crates/mnote-web/src/routes/search.rs:233``:247`:搜索 Convex 查询失败后执行 `fallback_search_dataset(workspace_id)`
判断:这与 `design/03-rust-web/process/3-15-runtime-fallback-retirement-checklist-v1.md` 的“默认运行时不再 fallback / 不静默降级”存在偏差。尤其 Search fallback 会产生看似真实的固定结果,风险高于空状态降级。
### 3. Page Aggregate 是 Rust route,但仍是迁移期 adapter
- `rust/crates/mnote-web/src/routes/mod.rs:53``:56` 挂载 `/api/page-aggregate/{document_id}`
- `rust/crates/mnote-web/src/routes/web_shell.rs:2264``:2319` 构建 aggregate。
- `rust/crates/bridge-runtime/src/lib.rs:5291``:5442` 从 meta/content 形状构建 `PageAggregateProjection`
- `rust/crates/core-protocol/src/page_aggregate.rs:4``:10` 协议层仍保留 `KernelProjection``CompatMetaContentJoin``Fixture` 三种 source。
- `rust/crates/mnote-web/src/page_aggregate/builder.rs:66` 默认 source 仍是 `CompatMetaContentJoin`,但当前检索未发现该 builder 进入主要 route 主路径。
判断:当前代码已摆脱 TS builder runtime 主链,但还不是“页面域全部直接来自独立 kernel storage 真源”。文档应保留“Rust-first Page Aggregate 过渡态”的精确口径。
### 4. Tree realtime 主链已成立,但不是完整实时闭环
- `rust/crates/mnote-web/src/routes/mod.rs:113` 挂载 `/api/tree/events``:114` 挂载 `/api/stream/events``:115` 挂载 `/api/realtime/ws`
- `rust/crates/mnote-web/src/routes/sse.rs:127``:146``/api/tree/events``x-mnote-web-owner: mnote-web``x-mnote-tree-stream-owner: rust-web`
- `rust/crates/mnote-web/src/routes/sse.rs:51``:91` 通过 sleep/poll bridge overview 发现变化。
- `rust/crates/mnote-web/src/routes/ws.rs:32``:80` WebSocket 当前只发 snapshot,并响应 resync 请求。
判断:这与 `3-3` 中“已完成 route / snapshot / delta / resync 基础,WS 尚未成为主链,live cache 未完全统一”一致;若 `3-15` 写成 tree realtime 补偿链已完全删除,则偏乐观。
### 5. Compat / legacy 未成为默认主链,但未完全删除
- `rust/crates/mnote-web/src/app.rs:42``:54` 仍读取 legacy Next 相关环境变量,默认 `enable_legacy_next_compat` 为 false。
- `rust/crates/mnote-web/src/routes/gateway.rs:86``:87` 在 compat 开启且配置 legacy base URL 时,`/api/auth` 可走 legacy proxy。
- `rust/crates/mnote-web/src/routes/documents.rs:153` 当前 `should_proxy_via_next` 返回 false,说明文档 API 默认不走 Next proxy。
判断:代码实际状态更像“默认关闭、残留显式迁移/调试能力”,不是“所有 legacy proxy 代码已删除”。
## 建议优先级
### P0
- 移除或显式隔离 Search 的 `fallback_search_dataset`。失败时应返回明确错误或空 projection,并带可观测错误头;不要返回固定假结果。
-`load_workspace_shell_projection` 的无条件合成 dataset 做决策:若用于首屏容错,应在响应或 contract 中显式标记 degraded;若严格执行 fallback 退场,应改为失败或空树,不再伪装成真实 workspace projection。
### P1
-`allow_dev_fixtures` 相关 fallback 全部加上更明确的 debug/dev 标识,并确认 `desktop:hot` / 3000 默认启动链不会误开。
- 补一条 Rust Web smokeConvex/query 不可用时,搜索、Sidebar、filetree 不应返回假业务数据。
- Page Aggregate 文档补一句:当前 Rust route 已是主读链,但底层仍通过 Rust runtime adapter 消费 meta/content substrate;完整页面域单一真源仍在推进。
### P2
- Tree realtime 后续应把 SSE polling overview 与真正 domain event stream 的边界写清楚,并继续推进 page subtree / filetree / preferred snapshot 同一 live cache。
- Legacy Next proxy 若仍需保留,建议统一命名为 explicit migration/debug boundary;若不再需要,后续单独删除 proxy helper、配置位和测试样例,避免和 `3-15` 的退场状态长期冲突。
- `PageAggregateSource::CompatMetaContentJoin` / `Fixture` 是否继续保留在 `core-protocol` 需要架构决策:保留则标记为迁移态 source;删除则需先确认没有测试、local folder、fixture 依赖。
## 修改的文件路径
2026-05-14 16:30:13 +08:00
- `/mnt/Data1T/mnote/design/10-review/done/01-rust-kernel-web-review.md`