Files
mnote/design/04-tree-domain/process/4-16-tree-rust-family-remaining-final-runtime-checklist-v1.md
T
lix-2026 4ab36a9386 feat(tree): complete rust family runtime checklist
- add tree shell runtime artifact contracts and page/filetree/picker runtime reducers
- sink tree.subtree.move write operation through Rust and formalize command event plans
- harden file tree search projection contract and route thin-proxy boundaries
- record completed harness tasks and move design docs into process/done
2026-04-27 10:27:15 +08:00

12 KiB
Raw Blame History

4-16 [process] 树域 Rust 家族剩余 final runtime checklist v1

创建时间:2026-04-27

来源:4-9 / 4-10 / 4-11 中仍未完成的后续目标,以及 4-124-15 完成后的剩余边界。

本文只规划后续目标,不回滚已完成的 3000 inline host、Rust initial DOM、rendererInput/state family 与现有 smoke 覆盖。

0. 当前执行状态(2026-04-27

harness 本轮从本文拆出的 task-001task-009 已全部执行完成,harness-progress.txt 记录为 completed=9 / pending=0 / in_progress=0 / failed=0

已完成

  • Phase K 已完成 rust_tree_shell_runtime_artifact_v1 artifact 边界,以及 page / filetree / picker 的 Rust-side runtime reducer contract。
  • Phase K 已固定 3000 inline host 与 mnote-web /tree debug shell 都输出同名 runtime artifact3000 主路径继续使用 same-origin inline host/api/tree/shell -> mnote-web:3104 debug 直连默认关闭。
  • Phase L 已引入 Rust treeWriteOperationConvex documents.move 优先执行 Rust write operation,并保留 normalizedMove 作为兼容 fallback。
  • Phase M 已将 page.body.savedblock.patchedblock.movedblock.embedded 切到 formal domainEventPlan payload schema,复合命令 stream delta 使用 resync_required 保守策略。
  • Phase N 已新增 route thinning manifest 与 boundary 测试,明确 /api/tree/commands/api/tree/stream/api/tree/shell 的 thin proxy / debug / compat 边界。
  • Phase O 已完成 file_tree 搜索 hardeningmaxResults=80、祖先补全/排序/异步可见性元数据、空结果文案,以及 index / asset-folder / asset / mindmap child / book / pdf fixture 覆盖。

仍剩余

  • TreeShellIframeHost 内联模板中的运行时执行层仍是 compat JS 镜像;已完成的是 Rust artifact/reducer contract,不是完整 wasm/Rust DOM runtime 替换。
  • normalizedMove fallback 仍保留;后续可在确认所有调用方都稳定传入 treeWriteOperation 后删除兼容 fallback。
  • document.snapshot.saved 仍未作为独立 event type 固定;当前 snapshot 信息随 page.body.saved payload 进入 formal schema。
  • tree.node.embedpageReference block 组装仍在 3000 route compat 边界内,后续应进入 Page Aggregate / Rust artifact。
  • Phase O 的异步索引可见性目前是 projection request meta / move-embed picker 搜索路径契约,不是完整索引指标平台。

1. 当前基线

  • harness task-001 至 task-009 已完成。
  • page tree / file tree / picker 默认主路径已使用 3000 same-origin inline host,不再请求 /api/tree/shell -> mnote-web:3104
  • 首屏 DOM 已由 Rust initial renderer 输出:
    • data-rust-page-renderer="initial_v1"
    • data-rust-filetree-renderer="initial_v1"
    • data-rust-picker-renderer="initial_v1"
  • 主路径已统一为 state.items + rendererInput,不再通过 __MNOTE_TREE_SHELL_OVERRIDE__ 注入第二份 items。
  • page focus、filetree selection、picker state 已暴露并消费 reducer contract;运行时执行仍主要是 compat JS 镜像。
  • 3000 inline host 与 mnote-web /tree debug shell 已同步输出 rust_tree_shell_runtime_artifact_v1,供后续真正 Rust runtime / wasm 替换执行层。
  • tree command move 写路径已优先使用 Rust treeWriteOperationConvex 继续作为 substrate 与一致性校验层。
  • block/save 复合命令已具备 formal domainEventPlanresync_required 保守 delta 合同。

2. 后续总目标

把树域从“Rust 持有语义 + compat JS 持有运行时 DOM/state machine”的过渡态,推进到:

  • Rust family 持有 renderer runtime / state machine contract。
  • Rust family 真正持有 renderer runtime / DOM 执行层,不再依赖 TreeShellIframeHost compat JS 镜像。
  • 3000 host 收薄为挂载、认证、transport bridge、artifact writer 与浏览器能力边界。
  • Convex compat mutation 不再优先承担 tree command 的核心 legality / normalize / write truth。
  • block/save 复合命令进入正式 Rust artifact / domain-event contract。
  • snapshot 独立事件与 Page Aggregate 深层收口继续后续推进。

3. Phase K:正式 Rust runtime / wasm 承接 tree shell 运行时

目标

完整替换 TreeShellIframeHost 内联模板中的主要 compat JS runtime,至少先把 page/filetree/picker 的核心状态机从字符串模板 JS 迁到 Rust runtime/wasm 或等价正式 Rust family runtime。

checklist

  • 定义 runtime artifact 边界:
    • 输入:rendererInput、projection items、expanded ids、selected row ids、active picker item、focused id。
    • 输出:DOM patch / intent event / command dispatch event。
    • 事件:focus、keyboard、expand/collapse、selection、context menu、drag/drop、pick。
  • 为 page tree runtime 建立 Rust-side 状态机:
    • focus normalize / next / previous / home / end。
    • expand / collapse / open / context-menu intent。
    • drag move intent 与 drop feedback state。
  • 为 file tree runtime 建立 Rust-side 状态机:
    • selection / range / context selection / normalize visible rows。
    • drag row ids / copy-move effect / drop target feedback。
    • asset-folder / asset / index / doc 的打开与菜单 intent。
  • 为 picker runtime 建立 Rust-side 状态机:
    • next / previous / home / end / focus / pick。
    • excluded ids 与 root pick。
    • 搜索态输入框焦点不被 iframe/runtime 抢走。
  • 3000 inline host 与 mnote-web /tree debug shell 输出并消费正式 runtime artifact contract。
  • 3000 host 不再维护主路径 JS 镜像状态机;仍需把 TreeShellIframeHost 内联模板 compat JS 执行层迁到 Rust wasm/runtime 或等价正式 runtime。
  • mnote-web /tree debug shell 只保留 debug/internal runtime 验证入口。

验收

  • pnpm vitest run src/components/sidebar/tree-shell-iframe-host.test.tsx src/components/sidebar/tree-shell-surface.test.tsx
  • cargo test -p mnote-web page_renderer filetree_renderer picker_renderer
  • node scripts/task112-tree-rust-family-regression-smoke.js
  • node scripts/task113-picker-keyboard-regression-smoke.js
  • smoke 中 direct_tree_shell_debug_disabled 仍成立,3000 主路径不请求 3104。

当前保留边界

  • 这里的完成口径是 artifact / reducer contract / debug 边界完成,不代表 TreeShellIframeHost 的 DOM runtime 已完全从 JS template 替换为 Rust wasm。

4. Phase Ltree.subtree.move 最终写路径下沉 Rust kernel

目标

tree.subtree.move 的 legality、target parent、position normalize、canonical sort plan 与最终写入从 Convex compat mutation 继续回收到 Rust kernel / Rust write path。

checklist

  • 梳理当前 normalizedMove 写入链:
    • /api/tree/commands preflightData。
    • bridge-runtime canonical order plan。
    • Convex documents.move optional validation。
  • Rust kernel 输出最终 write operation
    • parent_id。
    • sort_order patch set。
    • workspace_id / updated_at。
    • self / descendant / missing-parent legality error。
  • Convex mutation 优先执行 Rust treeWriteOperation,退为 substrate 写入执行器与一致性断言层。
  • 前端 Rust runtime / command adapter 已透传 treeWriteOperation,不再以 documents move compat 语义作为主路径。
  • domain event 与 streamDelta 使用 Rust move result,而不是 TS/Convex 再拼。
  • 删除 normalizedMove fallback,并把无 treeWriteOperation 的旧 compat move 降级为显式 legacy/debug 路径。

验收

  • cd rust && cargo test -p bridge-runtime tree_subtree_move_command
  • cd wolai-frontend && pnpm vitest run src/app/api/tree/commands/route.test.ts src/lib/documents/tree-command-client.test.ts src/lib/tree-stream/tree-delta.test.ts
  • 增加或复用 Convex 层测试,证明 Convex 优先接受 Rust treeWriteOperation 并校验当前排序状态。

当前保留边界

  • normalizedMove 仍作为旧调用链 fallback 保留;这不是第二份主排序真相,但仍是后续可删除的 compat 面。

5. Phase Mblock/save-snapshot 复合命令 formal artifact 与 domain-event contract

目标

page.body.save / documents.save / blocks.patch|move|embed / snapshot save 等复合命令补齐最终 formal Rust artifact / domain-event contract,避免停留在 noop 或过渡 hint。

checklist

  • 固定复合命令 event type
    • page.body.saved
    • document.snapshot.saved
    • block.patched
    • block.moved
    • block.embedded
  • 固定 payload schema
    • document id / page id。
    • block ids / patch summary / move source-target。
    • snapshot version / content hash / updated_at 作为 page.body.saved payload 的一部分。
  • Rust command plan 输出正式 domainEventPlanstreamDeltaHint,不再只用 noop 占位。
  • 3000 adapters 与 Rust artifact writer 按同一 schema 落 command_logs / domain_events
  • SSE reducer 对这些事件有明确 delta 或保守 resync 策略。
  • 将 snapshot save 是否需要独立 document.snapshot.saved 事件定稿,并避免与 page.body.saved payload 重叠。

验收

  • cd rust && cargo test -p bridge-runtime documents_save_command_plans_include_formal_domain_event_contract block_commands_include_formal_domain_event_contract
  • cd wolai-frontend && pnpm vitest run src/lib/documents/rust-runtime.test.ts src/lib/documents/page-write-command-adapter.test.ts src/lib/blocks/block-command-adapter.test.ts
  • 至少一个非 noop 复合命令事件可在 command log 与 domain event 中稳定关联同一 command_id

当前保留边界

  • document.snapshot.saved 未独立落地;当前完成的是 page.body.saved formal payload 中包含 snapshot 摘要。

6. Phase N3000 Next route 过渡职责继续收薄

目标

3000 保持唯一浏览器公开入口,但 Next route 只做薄代理、认证/浏览器能力桥和兼容边界,不继续承担树域主语义、主 delta 或主 renderer runtime。

checklist

  • 盘点 3000 route 中仍在拼树域主语义的入口。
  • 将 route 内 action switch 收敛到 Rust command result / artifact writer。
  • 对 polling / SSE / snapshot route 标注 Rust 主体与 Next 薄代理边界。
  • 隔离只服务旧 compat host 的 runtime 分支,/api/tree/shell 默认关闭 debug 直连。
  • 保留文件字节读取、upload URL、cookie/auth 等浏览器入口必须职责。
  • tree.node.embedpageReference block 组装从 3000 compat 边界迁到 Page Aggregate / Rust artifact。

验收

  • cd wolai-frontend && pnpm vitest run src/app/api/tree/commands/route.test.ts src/lib/tree-stream/tree-delta.test.ts
  • node scripts/task112-tree-rust-family-regression-smoke.js
  • 新增文档说明哪些 route 是 thin proxy,哪些仍是待迁移 compatdesign/04-tree-domain/process/4-17-tree-3000-route-thin-proxy-boundary-v1.md

当前保留边界

  • 3000 仍是唯一浏览器公开入口;thin proxy 不等于删除浏览器能力桥。
  • tree.node.embed 的目标读取与 pageReference block 组装仍是明确标注的 compat 待迁移项。

7. Phase O:搜索语义 hardening

目标

file_tree 搜索过滤主链已在 Rust projection query;后续只补更丰富搜索语义和稳定性,不作为当前 renderer/runtime gate。

checklist

  • index.md / asset / asset-folder / mindmap child / book / pdf 搜索命中补更多 fixture。
  • 明确 maxResults 与祖先补全的排序/截断规则。
  • 增加异步索引可见性元数据,特别是 move/embed picker 搜索结果路径。
  • 空结果与 fallback 文案保持稳定。
  • 如后续需要完整索引平台,再补真实异步索引延迟、刷新和可见性指标,而不是只依赖 projection request meta。

验收

  • cd wolai-frontend && pnpm vitest run src/lib/tree-stream/tree-delta.test.ts
  • 搜索 route / projection fixture 覆盖新增资源类型与边界。

当前保留边界

  • 本阶段完成的是 file tree projection 搜索契约 hardening,不是独立搜索服务或完整索引指标平台。

8. 非目标

  • 不拆除 Convex substrate。
  • 不把 OnlyOffice 嵌入 BlockNote 画布。
  • 不恢复旧 React PageTree/FileTree 作为 rust_family 主路径 fallback。
  • 不把 3104 重新暴露为默认前端入口。
  • 不在前端新增第二套树结构真相或排序真相。