Files
mnote/design/10-review/done/01-rust-kernel-web-review.md
T
lix-2026 5f97800489 chore: align local-first control plane and editor fixes
- wire SQLite control-plane access/session paths into Rust web local-folder routes

- preserve local Markdown attachment semantics across upload, reload, and secondary-pane resource tabs

- refresh design governance docs, Reasonix task templates, and bug records

- retire root .mcp.json local MCP config
2026-05-23 23:38:42 +08:00

12 KiB
Raw Blame History

Rust Kernel / Web 实现偏差审查

执行状态:已归档到 design/10-review/done/。本文保留为历史审查快照,当前活跃口径以 ./06-execution-checklist-and-acceptance.md 为准。

范围

本次只审查 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
  • 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
  • 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 / projectionmnote-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_viewrust/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 datasetrust/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.getrust/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 后生成 deltarust/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_COMPATrust/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.* aliasrust/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 定义 KernelNodeTypeKernelEdgeTypeKernelProjectionKind
  • 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,再生成 projectionfile_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:2401workspace shell projection 加载失败时合成 active_workspace_idworkspacesdocuments
  • rust/crates/mnote-web/src/routes/web_shell.rs:2432:2461allow_dev_fixtures 时合成 sidebar dev dataset。
  • rust/crates/mnote-web/src/routes/web_shell.rs:2493:2519allow_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 协议层仍保留 KernelProjectionCompatMetaContentJoinFixture 三种 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/eventsx-mnote-web-owner: mnote-webx-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 依赖。

修改的文件路径

  • /mnt/Data1T/mnote/design/10-review/done/01-rust-kernel-web-review.md