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.
282 lines
23 KiB
Markdown
282 lines
23 KiB
Markdown
# [recycle] 4-16 [done] 树域 Rust 家族剩余 final runtime checklist v1
|
||
|
||
> 创建时间:2026-04-27
|
||
>
|
||
> 来源:`4-9 / 4-10 / 4-11` 中仍未完成的后续目标,以及 `4-12` 到 `4-15` 完成后的剩余边界。
|
||
>
|
||
> 本文只规划后续目标,不回滚已完成的 3000 legacy inline host、Rust initial DOM、rendererInput/state family 与现有 smoke 覆盖。
|
||
>
|
||
> 口径修正(2026-04-28):本文记录的 `harness task-001` 至 `task-009` 完成,只代表 Rust/WASM reducer runtime、artifact、route thinning、projection hardening 等阶段性目标完成;不代表 page tree / file tree / picker 已完成 final Rust DOM shell 切换。真正 final DOM shell 的硬门禁以 `../done/4-18-tree-final-dom-shell-cutover-hard-gate-v1.md` 为准。
|
||
>
|
||
> 收口更新(2026-04-28):`harness task-010` 至 `task-013` 已完成 final DOM shell 默认路径切换。`rust_family` 默认 host 已改为 `rust_wasm_dom_shell_host`,默认 bridge 为 `dom_wasm`。
|
||
>
|
||
> 最终清理更新(2026-05-16):`TreeShellIframeHost` 与对应测试已移动到 `recycle/`,`NEXT_PUBLIC_TREE_SHELL_LEGACY_IFRAME_HOST` 入口已删除;active source 不再保留 iframe/srcDoc legacy/debug host。
|
||
>
|
||
> 最终 runtime 剩余项收口(2026-04-28):`harness task-014` 至 `task-018` 已完成。`normalizedMove` fallback 已删除;`page.body.saved` 与 `document.snapshot.saved` 已拆分为双 domain event plan;`tree.node.embed` 的 `pageReference` 结构与插入位置已迁入 Rust `pageAggregateEmbedPlan`;`file_tree` 搜索索引可见性已成为 projection result `meta.search.indexingVisibility`。
|
||
|
||
## 0. 当前执行状态(2026-04-27)
|
||
|
||
`harness` 本轮从本文拆出的 `task-001` 至 `task-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 artifact;当前默认主路径已继续收口为 `rust_wasm_dom_shell_host`,`/api/tree/shell -> mnote-web:3104` debug 直连默认关闭。
|
||
- Phase K 历史阶段曾把 3000 host implementation 从 `rust_inline_compat_host` 收口为 `rust_runtime_artifact_host`,并在 legacy runtime artifact manifest 中显式标注 `family=rust_family / version=1 / executionStrategy=browser_bridge / browserBridge=iframe_srcdoc`;当前该 active host 已删除,历史源码只在 `recycle/` 中保留。
|
||
- Phase K 已新增 Rust `TreeShellRuntimeRequest / TreeShellRuntimeResult` wire-safe facade:page / filetree / picker 三类 request 可 `serde_json` roundtrip,输出统一分为 `TreeShellDomPatch`、`TreeShellHostEvent`、`TreeShellCommandEvent`,并已在 runtime artifact manifest 中暴露 request/result contract、state snapshot、patch/event kind。
|
||
- Phase K 已新增 `mnote-web POST /api/tree/runtime/reduce`,并新增 3000 同源 `POST /api/tree/runtime/reduce` thin proxy;这是当前 browser bridge 调用 Rust runtime facade 的首个正式 HTTP seam。
|
||
- Phase K 已把 3000 `TreeShellIframeHost` 的 filetree selection / normalize visible rows / drag row ids 路径接到 runtime reduce seam,保留本地 reducer fallback,避免 Rust runtime endpoint 不可用时破坏现有真实交互。
|
||
- Phase K 已把 3000 `TreeShellIframeHost` 的 page focus / keyboard / expand / collapse / toggle / open / context menu 路径接到 runtime reduce seam,保留本地即时 fallback 与 runtime 对账。
|
||
- Phase K 已把 3000 `TreeShellIframeHost` 的 picker focus / keyboard / pick 路径接到 runtime reduce seam,保留本地即时 fallback 与 runtime 对账。
|
||
- Phase K 已把 3000 `TreeShellIframeHost` 的 page / filetree open-context 与 picker pick 路径接到 runtime hostEvent 回放器:主路径优先消费 `TreeShellRuntimeResult.hostEvents`,endpoint 不可用或无 hostEvent 时才回退本地宿主事件。
|
||
- Phase K 已把 3000 `TreeShellIframeHost` 的 filetree open / context menu 路径接到 runtime reduce seam,并已改为优先消费 runtime hostEvent。
|
||
- Phase K 已把 3000 `TreeShellIframeHost` 的 filetree drop-target highlight 路径接到 runtime reduce seam:hydrated 与 fallback 两条 dragover/dragleave 链都会构造 `updateDropTarget` 请求,并把 runtime snapshot 回填到 `data-drop-target` DOM patch。
|
||
- Phase K 已落地正式 Rust/WASM reducer runtime artifact:新增 `rust/crates/tree-shell-runtime-wasm`,通过 wasm-bindgen 导出 `reduceTreeShellRuntime`,固定产物为 `mnote-tree-shell-runtime.js` 与 `mnote-tree-shell-runtime_bg.wasm`。
|
||
- Phase K 已新增 3000 同源 `/api/tree-shell-runtime/*` 资源路由与 `build-tree-shell-runtime.js` 构建脚本,`dev-server` 启动前会生成正式 tree shell wasm artifact。
|
||
- Phase K 已将 3000 `TreeShellIframeHost` 的 page / filetree / picker reduce 执行器切为 wasm-first:默认优先调用 wasm artifact,HTTP `/api/tree/runtime/reduce` 只作为 fallback/debug seam。
|
||
- Phase L 已引入 Rust `treeWriteOperation`,Convex `documents.move` 只接受 Rust write operation;`normalizedMove` fallback 已删除。
|
||
- Phase M 已将 `page.body.saved`、`document.snapshot.saved`、`block.patched`、`block.moved`、`block.embedded` 切到 formal `domainEventPlan/domainEventPlans` 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` 搜索 hardening:`maxResults=80`、祖先补全/排序、projection result `meta.search.indexingVisibility`、空结果文案,以及 `index / asset-folder / asset / mindmap child / book / pdf` fixture 覆盖。
|
||
|
||
### 后续阶段已收口
|
||
|
||
- final DOM shell 默认路径已切到 `rust_wasm_dom_shell_host`:page / file tree / picker 不再通过 `TreeShellIframeHost` 的 `srcDoc` 内联模板承载默认 DOM shell。
|
||
- 默认 DOM host 通过 `reduceTreeShellRuntime` WASM artifact 或同源 `/api/tree/runtime/reduce` Rust seam 消费 `state / hostEvents / commandEvents`;旧本地 JS fallback reducer 不再保留 active 入口。
|
||
- 默认真实流量已禁止 `iframe_srcdoc` 作为 tree DOM shell 成功路径;对应负向门禁与 smoke 已覆盖。
|
||
- `normalizedMove` fallback 已删除,无 `treeWriteOperation` 的 move 不再进入主写路径。
|
||
- `document.snapshot.saved` 已作为独立 event type 固定;`page.body.saved` payload 只保留 page 与 blocks,snapshot 版本/hash/updatedAt 进入独立事件。
|
||
- `tree.node.embed` 的 `pageReference` block 组装已迁入 Rust `pageAggregateEmbedPlan`;3000 route 只负责读取源/目标 substrate 快照并作为 preflight 传入。
|
||
- Phase O 的索引可见性已从客户端 request meta 提升为 file_tree projection result meta;完整外部索引平台仍不是本树域 runtime 收口阶段目标。
|
||
|
||
## 1. 当前基线
|
||
|
||
- `harness` task-001 至 task-009 已完成。
|
||
- `page tree / file tree / picker` 默认主路径已使用 3000 same-origin `rust_wasm_dom_shell_host`,不再请求 `/api/tree/shell -> mnote-web:3104`,也不再依赖 `iframe_srcdoc` inline DOM shell。
|
||
- 首屏 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;默认 DOM host 已通过 Rust/WASM runtime facade 驱动 page / picker / filetree 的 focus、expand、selection、open/context、drop 与 picker pick,HTTP reduce seam 保留为同源 Rust fallback/debug。
|
||
- 3000 legacy inline host 与 `mnote-web /tree` debug shell 已同步输出 `rust_tree_shell_runtime_artifact_v1` manifest;默认 DOM host 已使用同源 tree-shell-runtime WASM artifact 或 HTTP reduce seam 执行 runtime。
|
||
- tree command move 写路径已优先使用 Rust `treeWriteOperation`;Convex 继续作为 substrate 与一致性校验层。
|
||
- block/save 复合命令已具备 formal `domainEventPlan` 与 `resync_required` 保守 delta 合同。
|
||
|
||
## 2. 后续总目标
|
||
|
||
把树域从“Rust 持有语义 + compat JS 持有运行时 DOM/state machine”的过渡态,推进到:
|
||
|
||
- [x] Rust family 持有 renderer runtime / state machine contract。
|
||
- [x] 3000 主路径 host implementation 已从 compat 命名收口为 `rust_wasm_dom_shell_host`。
|
||
- [x] Rust family 暴露可序列化的 runtime request/result facade,供后续 wasm/browser bridge 调用。
|
||
- [x] Rust family 已通过 wasm artifact 持有默认 reducer runtime 执行层,不再默认依赖 HTTP bridge 执行 reduce。
|
||
- [x] Rust family 默认持有 renderer DOM 执行层,不再依赖 `TreeShellIframeHost` browser bridge JS adapter 维护默认 DOM/state shell。
|
||
- [x] 3000 host 收薄为挂载、认证、transport bridge、artifact writer 与浏览器能力边界。
|
||
- [x] Convex compat mutation 不再优先承担 tree command 的核心 legality / normalize / write truth。
|
||
- [x] block/save 复合命令进入正式 Rust artifact / domain-event contract。
|
||
- [x] snapshot 独立事件与 Page Aggregate 深层收口继续后续推进。
|
||
|
||
### 最高优先级硬门禁
|
||
|
||
- [x] 默认 page tree / file tree / picker 主路径不得再依赖 `TreeShellIframeHost` 的 `srcDoc` inline DOM shell。
|
||
- [x] 默认主路径不得再标注 `data-tree-browser-bridge="iframe_srcdoc"`。
|
||
- [x] `TreeShellIframeHost` 必须降级为显式 legacy/debug host,不能作为 `rust_family` 默认执行面。
|
||
- [x] `task112/task113` 必须改为验证新 Rust/WASM DOM shell 主路径,而不是验证旧 inline iframe host 继续可用。
|
||
|
||
## 3. Phase K:正式 Rust runtime / wasm 承接 tree shell 运行时
|
||
|
||
### 目标
|
||
|
||
完整替换 `TreeShellIframeHost` 内联模板中的主要 compat JS runtime,至少先把 page/filetree/picker 的核心状态机从字符串模板 JS 迁到 Rust runtime/wasm 或等价正式 Rust family runtime。
|
||
|
||
### checklist
|
||
|
||
- [x] 定义 runtime artifact 边界:
|
||
- [x] 输入:`rendererInput`、projection items、expanded ids、selected row ids、active picker item、focused id。
|
||
- [x] 输出:DOM patch / intent event / command dispatch event。
|
||
- [x] 事件:focus、keyboard、expand/collapse、selection、context menu、drag/drop、pick。
|
||
- [x] 为 page tree runtime 建立 Rust-side 状态机:
|
||
- [x] focus normalize / next / previous / home / end。
|
||
- [x] expand / collapse / open / context-menu intent。
|
||
- [x] drag move intent 与 drop feedback state。
|
||
- [x] 为 file tree runtime 建立 Rust-side 状态机:
|
||
- [x] selection / range / context selection / normalize visible rows。
|
||
- [x] drag row ids / copy-move effect / drop target feedback。
|
||
- [x] asset-folder / asset / index / doc 的打开与菜单 intent。
|
||
- [x] 为 picker runtime 建立 Rust-side 状态机:
|
||
- [x] next / previous / home / end / focus / pick。
|
||
- [x] excluded ids 与 root pick。
|
||
- [x] 搜索态输入框焦点不被 iframe/runtime 抢走。
|
||
- [x] 3000 legacy inline host 与 `mnote-web /tree` debug shell 输出并消费正式 runtime artifact contract。
|
||
- [x] 历史 Phase K 主路径标识曾切到 `rust_runtime_artifact_host`,iframe 上显式标注 `data-tree-runtime-artifact-host=rust_tree_shell_runtime_artifact_v1` 与 `data-tree-browser-bridge=iframe_srcdoc`;当前默认主路径已继续切到 `rust_wasm_dom_shell_host` 与 `data-tree-browser-bridge=dom_wasm`。
|
||
- [x] 定义 wire-safe runtime facade:
|
||
- [x] `TreeShellRuntimeRequest` 统一承载 page / filetree / picker 的 environment、state、action。
|
||
- [x] `TreeShellRuntimeResult` 统一输出 state snapshot、`domPatches`、`hostEvents`、`commandEvents`。
|
||
- [x] `TreeShellDomPatch` 固定 `pageState / fileTreeState / pickerState`。
|
||
- [x] `TreeShellHostEvent` 固定 page open/context menu、filetree open/context menu、picker pick root/document。
|
||
- [x] `TreeShellCommandEvent` 固定 `createNode / renameNode / moveSubtree / copyResource / moveResource / uploadResource`。
|
||
- [x] runtime artifact manifest 暴露 `runtimeApi`,让 3000 host 可识别 request/result 与 patch/event kind。
|
||
- [x] `mnote-web` 暴露 `POST /api/tree/runtime/reduce`,让 browser bridge 可调用 Rust `reduce_tree_shell_runtime`。
|
||
- [x] 3000 暴露同源 `POST /api/tree/runtime/reduce` thin proxy,保留 cookie/auth/header 转发与 `no-store` 边界。
|
||
- [x] 3000 `TreeShellIframeHost` 的 filetree selection / visible row normalize / drag row ids 先接入 runtime reduce seam,并保留本地 fallback。
|
||
- [x] 3000 `TreeShellIframeHost` 的 page focus / keyboard / expand / collapse / toggle / open / context menu 已接入 runtime reduce seam,并保留本地 fallback。
|
||
- [x] 3000 `TreeShellIframeHost` 的 picker focus / keyboard / pick 已接入 runtime reduce seam,并保留本地 fallback。
|
||
- [x] 3000 `TreeShellIframeHost` 的 page / filetree open-context 与 picker pick 已开始消费 runtime hostEvent,并保留本地 fallback。
|
||
- [x] 3000 `TreeShellIframeHost` 的 filetree open / context menu 已接入 runtime reduce seam,并优先消费 runtime hostEvent。
|
||
- [x] 3000 `TreeShellIframeHost` 的 filetree drop-target highlight 已接入 runtime reduce seam,并保留本地 DOM fallback。
|
||
- [x] 新增正式 wasm artifact:
|
||
- [x] `rust/crates/tree-shell-runtime-wasm` 复用 `mnote-web/src/tree_shell/*` runtime API 与 reducer。
|
||
- [x] `reduceTreeShellRuntime(request)` wasm-bindgen API 已可在浏览器/Node 中执行 `TreeShellRuntimeRequest -> TreeShellRuntimeResult`。
|
||
- [x] `build-tree-shell-runtime.js` 生成固定 `mnote-tree-shell-runtime.js` 与 `mnote-tree-shell-runtime_bg.wasm`。
|
||
- [x] 3000 同源 `/api/tree-shell-runtime/manifest.json`、`/api/tree-shell-runtime/mnote-tree-shell-runtime.js`、`/api/tree-shell-runtime/mnote-tree-shell-runtime_bg.wasm` 已覆盖。
|
||
- [x] `TreeShellIframeHost` 已通过 `loadTreeShellWasmRuntime / reduceTreeShellRuntimeViaWasm / reduceTreeShellRuntimeWithArtifact` 默认优先使用 wasm artifact。
|
||
- [x] 3000 默认 host 不再维护主路径 JS adapter 状态机;`TreeShellIframeHost` 内联模板 browser bridge JS DOM shell 已移入 `recycle/`。
|
||
- [x] `mnote-web /tree` debug shell 只保留 debug/internal runtime 验证入口。
|
||
|
||
### 验收
|
||
|
||
- [x] 历史验收曾覆盖 `tree-shell-iframe-host.test.tsx`;2026-05-16 后该测试已随旧 host 移入 `recycle/`,active 验收改为 `tree-shell-host.test.tsx` / `tree-shell-surface.test.tsx` 的负向门禁。
|
||
- [x] `pnpm vitest run src/app/api/tree/runtime/reduce/route.test.ts src/app/api/tree/shell/route.test.ts src/components/sidebar/tree-shell-host.test.tsx src/components/sidebar/tree-shell-surface.test.tsx src/components/documents/move-embed-picker-dialog.test.tsx`
|
||
- [x] `pnpm vitest run src/components/documents/move-embed-picker-dialog.test.tsx`
|
||
- [x] `cargo test -p mnote-web page_renderer filetree_renderer picker_renderer`
|
||
- [x] `cargo test -p mnote-web tree_runtime_reduce_endpoint_returns_filetree_runtime_result`
|
||
- [x] `cargo test -p mnote-web tree_runtime_reduce_endpoint_returns_page_and_picker_runtime_results`
|
||
- [x] `cargo test -p mnote-web tree_shell_embeds_renderer_input_contract`
|
||
- [x] `cargo test -p mnote-web tree_shell_renderer_input_exposes_runtime_artifact_boundary`
|
||
- [x] `cargo test -p tree-shell-runtime-wasm -- --nocapture`
|
||
- [x] `node scripts/build-tree-shell-runtime.js`
|
||
- [x] `pnpm vitest run src/app/api/tree-shell-runtime/[...asset]/route.test.ts src/components/sidebar/tree-shell-host.test.tsx`
|
||
- [x] Node smoke:加载 `generated/mnote-tree-shell-runtime.js` + `.wasm` 后调用 `reduceTreeShellRuntime(mode=page, action=moveNext)`,返回 `focusedId=doc:child`。
|
||
- [x] `node scripts/task112-tree-rust-family-regression-smoke.js`
|
||
- [x] `node scripts/task113-picker-keyboard-regression-smoke.js`
|
||
- [x] smoke 中 `direct_tree_shell_debug_disabled` 仍成立,3000 主路径不请求 3104。
|
||
|
||
### 当前保留边界
|
||
|
||
- 这里的历史完成口径包含正式 Rust/WASM reducer runtime artifact 与默认 wasm-first reduce 执行;真正 final DOM shell 完成以 `task-010` 至 `task-013` 和 `4-18` 硬门禁为准。
|
||
- 当前 DOM runtime 阶段已把 page/picker/filetree 默认 host 切到 `TreeShellRustDomShellHost`;后续已继续删除 `normalizedMove` fallback、补 `document.snapshot.saved` 独立事件,并把 `tree.node.embed` 的 Page Aggregate / Rust artifact 边界收口。
|
||
- 后续阶段不得继续把“新增 runtime reducer action”或 legacy iframe 能力增强误写成 final renderer 主任务;默认路径必须保持 `rust_wasm_dom_shell_host + dom_wasm`。
|
||
|
||
## 4. Phase L:tree.subtree.move 最终写路径下沉 Rust kernel
|
||
|
||
### 目标
|
||
|
||
把 `tree.subtree.move` 的 legality、target parent、position normalize、canonical sort plan 与最终写入从 Convex compat mutation 继续回收到 Rust kernel / Rust write path。
|
||
|
||
### checklist
|
||
|
||
- [x] 梳理当前 `normalizedMove` 写入链:
|
||
- [x] `/api/tree/commands` preflightData。
|
||
- [x] `bridge-runtime` canonical order plan。
|
||
- [x] Convex `documents.move` optional validation。
|
||
- [x] Rust kernel 输出最终 write operation:
|
||
- [x] parent_id。
|
||
- [x] sort_order patch set。
|
||
- [x] workspace_id / updated_at。
|
||
- [x] self / descendant / missing-parent legality error。
|
||
- [x] Convex mutation 优先执行 Rust `treeWriteOperation`,退为 substrate 写入执行器与一致性断言层。
|
||
- [x] 前端 Rust runtime / command adapter 已透传 `treeWriteOperation`,不再以 documents move compat 语义作为主路径。
|
||
- [x] domain event 与 streamDelta 使用 Rust move result,而不是 TS/Convex 再拼。
|
||
- [x] 删除 `normalizedMove` fallback,并把无 `treeWriteOperation` 的旧 compat move 降级为显式 legacy/debug 路径。
|
||
|
||
### 验收
|
||
|
||
- [x] `cd rust && cargo test -p bridge-runtime tree_subtree_move_command`
|
||
- [x] `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`
|
||
- [x] 增加或复用 Convex 层测试,证明 Convex 优先接受 Rust `treeWriteOperation` 并校验当前排序状态。
|
||
|
||
### 当前保留边界
|
||
|
||
- `normalizedMove` 不再作为旧调用链 fallback 保留;move 主写路径强制使用 Rust `treeWriteOperation`。
|
||
|
||
## 5. Phase M:block/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
|
||
|
||
- [x] 固定复合命令 event type:
|
||
- [x] `page.body.saved`
|
||
- [x] `document.snapshot.saved`
|
||
- [x] `block.patched`
|
||
- [x] `block.moved`
|
||
- [x] `block.embedded`
|
||
- [x] 固定 payload schema:
|
||
- [x] document id / page id。
|
||
- [x] block ids / patch summary / move source-target。
|
||
- [x] snapshot version / content hash / updated_at 作为 `document.snapshot.saved` payload 的一部分。
|
||
- [x] Rust command plan 输出正式 `domainEventPlan` 与 `streamDeltaHint`,不再只用 noop 占位。
|
||
- [x] 3000 adapters 与 Rust artifact writer 按同一 schema 落 `command_logs / domain_events`。
|
||
- [x] SSE reducer 对这些事件有明确 delta 或保守 resync 策略。
|
||
- [x] 将 snapshot save 是否需要独立 `document.snapshot.saved` 事件定稿,并避免与 `page.body.saved` payload 重叠。
|
||
|
||
### 验收
|
||
|
||
- [x] `cd rust && cargo test -p bridge-runtime documents_save_command_plans_include_formal_domain_event_contract block_commands_include_formal_domain_event_contract`
|
||
- [x] `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`
|
||
- [x] 至少一个非 noop 复合命令事件可在 command log 与 domain event 中稳定关联同一 `command_id`。
|
||
|
||
### 当前保留边界
|
||
|
||
- `document.snapshot.saved` 已独立落地;`page.body.saved` formal payload 不再包含 snapshot 摘要。
|
||
|
||
## 6. Phase N:3000 Next route 过渡职责继续收薄
|
||
|
||
### 目标
|
||
|
||
`3000` 保持唯一浏览器公开入口,但 Next route 只做薄代理、认证/浏览器能力桥和兼容边界,不继续承担树域主语义、主 delta 或主 renderer runtime。
|
||
|
||
### checklist
|
||
|
||
- [x] 盘点 3000 route 中仍在拼树域主语义的入口。
|
||
- [x] 将 route 内 action switch 收敛到 Rust command result / artifact writer。
|
||
- [x] 对 polling / SSE / snapshot route 标注 Rust 主体与 Next 薄代理边界。
|
||
- [x] 隔离只服务旧 compat host 的 runtime 分支,`/api/tree/shell` 默认关闭 debug 直连。
|
||
- [x] 保留文件字节读取、upload URL、cookie/auth 等浏览器入口必须职责。
|
||
- [x] 将 `tree.node.embed` 的 `pageReference` block 组装从 3000 compat 边界迁到 Page Aggregate / Rust artifact。
|
||
|
||
### 验收
|
||
|
||
- [x] `cd wolai-frontend && pnpm vitest run src/app/api/tree/commands/route.test.ts src/lib/tree-stream/tree-delta.test.ts`
|
||
- [x] `node scripts/task112-tree-rust-family-regression-smoke.js`
|
||
- [x] 新增文档说明哪些 route 是 thin proxy,哪些仍是待迁移 compat:`design/04-tree-domain/done/4-17-tree-3000-route-thin-proxy-boundary-v1.md`。
|
||
|
||
### 当前保留边界
|
||
|
||
- 3000 仍是唯一浏览器公开入口;thin proxy 不等于删除浏览器能力桥。
|
||
- `tree.node.embed` 的目标读取仍是 3000 浏览器公开入口的 substrate 职责;`pageReference` block 结构与插入位置语义已由 Rust `pageAggregateEmbedPlan` 产出。
|
||
|
||
## 7. Phase O:搜索语义 hardening
|
||
|
||
### 目标
|
||
|
||
`file_tree` 搜索过滤主链已在 Rust projection query;后续只补更丰富搜索语义和稳定性,不作为当前 renderer/runtime gate。
|
||
|
||
### checklist
|
||
|
||
- [x] 为 `index.md / asset / asset-folder / mindmap child / book / pdf` 搜索命中补更多 fixture。
|
||
- [x] 明确 `maxResults` 与祖先补全的排序/截断规则。
|
||
- [x] 增加异步索引可见性元数据,特别是 move/embed picker 搜索结果路径。
|
||
- [x] 空结果与 fallback 文案保持稳定。
|
||
- [x] 如后续需要完整索引平台,再补真实异步索引延迟、刷新和可见性指标,而不是只依赖 projection request meta。
|
||
|
||
### 验收
|
||
|
||
- [x] `cd wolai-frontend && pnpm vitest run src/lib/tree-stream/tree-delta.test.ts`
|
||
- [x] 搜索 route / projection fixture 覆盖新增资源类型与边界。
|
||
|
||
### 当前保留边界
|
||
|
||
- 本阶段完成的是 file tree projection 搜索契约 hardening 与 projection result 可见性指标,不是独立搜索服务或外部索引平台。
|
||
|
||
## 8. 非目标
|
||
|
||
- 不拆除 Convex substrate。
|
||
- 不把 OnlyOffice 嵌入 BlockNote 画布。
|
||
- 不恢复旧 React PageTree/FileTree 作为 rust_family 主路径 fallback。
|
||
- 不把 3104 重新暴露为默认前端入口。
|
||
- 不在前端新增第二套树结构真相或排序真相。
|