Persist PageTree expand state via control-plane view-state and align chevron/DOM with restored expansion; keep Sidex-style shallow page-tree scan and drop the unused recursive scanner that only added cargo noise. Add password vault workbench routes/runtime/skill/CLI, split page_ai_pi into a module package, and retire Hermes/ACP/OpenHub recycle + root harness evidence from the index while gitignoring recycle and local diag dumps. Archive superseded design/bugs docs under old/, point architecture at ARCHITECTURE.md, and refresh smokes for Pi S1–S7, vault, and editor regressions so the working tree can stay clean.
12 KiB
[recycle] Rust Kernel / Web 实现偏差审查
执行状态:已归档到
design/10-review/done/。本文保留为历史审查快照,当前活跃口径以./06-execution-checklist-and-acceptance.md为准。
范围
本次只审查 Rust kernel / protocol / bridge-runtime / mnote-web / storage-convex-bridge 与当前设计主线的一致性。
重点对照设计:
ARCHITECTURE.mddesign/01-05-current-priority-overview.mddesign/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.mddesign/01-tree-first-graph-kernel/reference/1-1-tree-first-graph-kernel-checklist-v2.mddesign/02-convex-rust-long-term-architecture/process/2-tree-first-graph-convex-rust-long-term-architecture-v1.mddesign/03-rust-web/reference/3-rust-web-long-term-architecture-v1.mddesign/03-rust-web/reference/3-1-rust-web-long-term-checklist-v2.mddesign/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.mddesign/03-rust-web/process/3-15-runtime-fallback-retirement-checklist-v1.mddesign/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 主线没有落地”,而是当前仍存在几类收口缺口:
- 部分 Rust Web 主路径仍会静默合成 fallback / fixture 数据,和
Runtime Fallback 退场的激进口径不完全一致。 - Page Aggregate 对外标记为
KernelProjection,但 Rust Web 仍先取documents.meta/content再在 runtime 内拼成聚合;这是合理过渡实现,但“单一 kernel 真源”口径容易被写得过满。 - Tree realtime 已有正式 SSE 主链,但实现仍偏轮询 bridge overview,WS 仍是 snapshot/resync 骨架,尚未成为完整实时主链。
- 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 主路径仍存在静默 fallback:workspace shell 在 projection 加载失败时无条件合成最小 workspace/documents;sidebar/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/resync;WS 只发送初始 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到:80WebSocket 当前只发 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 smoke:Convex/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