feat(tree): close rust family shell cutover
This commit is contained in:
+279
@@ -0,0 +1,279 @@
|
||||
# 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`;`TreeShellIframeHost` 仅在显式 `NEXT_PUBLIC_TREE_SHELL_LEGACY_IFRAME_HOST=1` 下作为 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`;当前该 host 只代表显式 legacy/debug。
|
||||
- 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 只保留在 legacy iframe host。
|
||||
- 默认真实流量已禁止 `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 已降级为显式 legacy/debug。
|
||||
- [x] `mnote-web /tree` debug shell 只保留 debug/internal runtime 验证入口。
|
||||
|
||||
### 验收
|
||||
|
||||
- [x] `pnpm vitest run src/components/sidebar/tree-shell-iframe-host.test.tsx src/components/sidebar/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-iframe-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-iframe-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 重新暴露为默认前端入口。
|
||||
- 不在前端新增第二套树结构真相或排序真相。
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
# 4-17 [process] tree 3000 route thin proxy boundary v1
|
||||
# 4-17 [done] tree 3000 route thin proxy boundary v1
|
||||
|
||||
> 创建时间:2026-04-27
|
||||
>
|
||||
@@ -37,9 +37,9 @@
|
||||
- create / copy 后创建页面 scaffold。
|
||||
- copy 后复制 mindmap 文件。
|
||||
- move 前采集 sidebar snapshot 作为 Rust preflight data。
|
||||
- `tree.node.embed` 的目标内容读取与 `pageReference` block 组装。
|
||||
- `tree.node.embed` 的目标内容读取与 Rust preflight 数据准备。
|
||||
|
||||
`tree.node.embed` 的 pageReference 组装仍是待迁移 compat,后续应进入 Page Aggregate / Rust artifact,而不是继续扩写在 route 中。
|
||||
`tree.node.embed` 的 `pageReference` block 结构与插入位置已经迁入 Rust `pageAggregateEmbedPlan`;3000 route 不再定义该语义,只负责源/目标快照读取与 preflight 桥接。
|
||||
|
||||
### `/api/tree/stream`
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
# 4-19 [done] 树域 final status 与 Rust DOM shell 切换记录 v1
|
||||
|
||||
> 更新时间:2026-04-28
|
||||
>
|
||||
> 本文由 `process/1.md` 归档而来,用于记录 `design/04-tree-domain` 当前代码已完成的最终树域收口状态。
|
||||
|
||||
## 执行状态(2026-04-28)
|
||||
|
||||
- [x] 口径收口:`task-001` 至 `task-009` 完成的是 Rust/WASM reducer runtime、runtime artifact、route thinning 与 projection hardening;`task-010` 至 `task-013` 才是 `4-18-tree-final-dom-shell-cutover-hard-gate-v1.md` 定义的 final DOM shell 默认路径切换。
|
||||
- [x] 默认 host 已从历史 `rust_runtime_artifact_host + iframe_srcdoc` 切到 `rust_wasm_dom_shell_host + dom_wasm`。`rust_runtime_artifact_host` 与 `data-tree-browser-bridge="iframe_srcdoc"` 只允许出现在显式 legacy/debug host。
|
||||
- [x] `TreeShellHost` 在 `rust_family + workspaceId` 下默认挂载 `TreeShellRustDomShellHost`;旧 `TreeShellIframeHost` 只能通过 `NEXT_PUBLIC_TREE_SHELL_LEGACY_IFRAME_HOST=1` 进入。
|
||||
- [x] 默认 DOM host 不再调用 `LOCAL_TREE_SHELL_TEMPLATE`、`buildInlinePageTreeHtml`、`buildInlineFileTreeHtml`、`buildInlinePickerHtml`,也不再把 `srcDoc` inline DOM shell 当作成功路径。
|
||||
- [x] 默认 page / filetree / picker DOM host 标注 `data-tree-runtime-artifact-host="rust_tree_shell_runtime_artifact_v1"` 与 `data-tree-browser-bridge="dom_wasm"`。
|
||||
- [x] 默认 DOM host 的 page focus / keyboard / expand / collapse / open / context / create / rename / drop,filetree selection / open / context / internal drop / external drop / drop target,以及 picker keyboard / focus / pick,均通过 `TreeShellRuntimeRequest/Result` 消费 WASM artifact 或同源 Rust HTTP seam 返回的 state、hostEvents、commandEvents。
|
||||
- [x] 旧 JS DOM renderer、inline template、fallback reducer/state machine 已从默认真实流量隔离,只保留在显式 legacy iframe host 内作为短期排障面。
|
||||
- [x] 默认主路径负向测试已覆盖:`tree-shell-host.test.tsx`、`tree-shell-surface.test.tsx`、`move-embed-picker-dialog.test.tsx` 均断言默认路径不得出现 `iframe_srcdoc` / `rust-iframe`。
|
||||
- [x] `task112-tree-rust-family-regression-smoke.js` 与 `task113-picker-keyboard-regression-smoke.js` 默认验证 `dom_wasm` DOM host;legacy iframe 仅在显式 legacy flag 下兼容。
|
||||
|
||||
## 历史 runtime 阶段保留记录
|
||||
|
||||
- Rust/WASM reducer runtime artifact 已落地:`rust/crates/tree-shell-runtime-wasm` 通过 wasm-bindgen 导出 `reduceTreeShellRuntime`,3000 同源 `/api/tree-shell-runtime/*` 发布 `mnote-tree-shell-runtime.js` 与 `mnote-tree-shell-runtime_bg.wasm`。
|
||||
- `mnote-web` 与 3000 同源均保留 `POST /api/tree/runtime/reduce` seam;默认 DOM host 优先调用 WASM artifact,HTTP seam 作为同源 Rust fallback/debug。
|
||||
- 历史 `TreeShellIframeHost` 已完成过 page/filetree/picker reducer result 回放、hostEvent/commandEvent 回放、page drop target runtime 收口、picker runtime-first、filetree drop hardening 等切片;这些能力现在作为 legacy/debug host 的保留行为,不再代表默认 DOM shell。
|
||||
|
||||
## 当前保留边界
|
||||
|
||||
- `normalizedMove` compat fallback 已删除;无 `treeWriteOperation` 的 move 不再进入主写路径。
|
||||
- `document.snapshot.saved` 已作为独立 event type 固定;`page.body.saved` 不再携带 snapshot payload。
|
||||
- `tree.node.embed` 的 `pageReference` block 结构与插入位置已迁入 Rust `pageAggregateEmbedPlan`;3000 route 只负责读取源/目标 substrate 快照并作为 preflight 传入。
|
||||
- `TreeShellIframeHost` 仍作为显式 legacy/debug host 暂留;默认路径稳定后可继续删除 legacy iframe host 与对应旧测试。
|
||||
- 3000 仍保留挂载、认证、transport、文件字节读取、浏览器 DnD `File[]`、菜单状态、实际命令调度、乐观 UI 与副作用通知等浏览器能力边界;这是浏览器公开入口职责,不再代表树域主语义滞留在 Next route。
|
||||
-215
@@ -1,215 +0,0 @@
|
||||
# 4-16 [process] 树域 Rust 家族剩余 final runtime checklist v1
|
||||
|
||||
> 创建时间:2026-04-27
|
||||
>
|
||||
> 来源:`4-9 / 4-10 / 4-11` 中仍未完成的后续目标,以及 `4-12` 到 `4-15` 完成后的剩余边界。
|
||||
>
|
||||
> 本文只规划后续目标,不回滚已完成的 3000 inline host、Rust initial DOM、rendererInput/state family 与现有 smoke 覆盖。
|
||||
|
||||
## 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;3000 主路径继续使用 same-origin inline host,`/api/tree/shell -> mnote-web:3104` debug 直连默认关闭。
|
||||
- Phase L 已引入 Rust `treeWriteOperation`,Convex `documents.move` 优先执行 Rust write operation,并保留 `normalizedMove` 作为兼容 fallback。
|
||||
- Phase M 已将 `page.body.saved`、`block.patched`、`block.moved`、`block.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` 搜索 hardening:`maxResults=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.embed` 的 `pageReference` 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 `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。
|
||||
- [ ] Rust family 真正持有 renderer runtime / DOM 执行层,不再依赖 `TreeShellIframeHost` compat JS 镜像。
|
||||
- [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。
|
||||
- [ ] 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
|
||||
|
||||
- [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 inline host 与 `mnote-web /tree` debug shell 输出并消费正式 runtime artifact contract。
|
||||
- [ ] 3000 host 不再维护主路径 JS 镜像状态机;仍需把 `TreeShellIframeHost` 内联模板 compat JS 执行层迁到 Rust wasm/runtime 或等价正式 runtime。
|
||||
- [x] `mnote-web /tree` debug shell 只保留 debug/internal runtime 验证入口。
|
||||
|
||||
### 验收
|
||||
|
||||
- [x] `pnpm vitest run src/components/sidebar/tree-shell-iframe-host.test.tsx src/components/sidebar/tree-shell-surface.test.tsx`
|
||||
- [x] `cargo test -p mnote-web page_renderer filetree_renderer picker_renderer`
|
||||
- [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。
|
||||
|
||||
### 当前保留边界
|
||||
|
||||
- 这里的完成口径是 artifact / reducer contract / debug 边界完成,不代表 `TreeShellIframeHost` 的 DOM runtime 已完全从 JS template 替换为 Rust 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 再拼。
|
||||
- [ ] 删除 `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 保留;这不是第二份主排序真相,但仍是后续可删除的 compat 面。
|
||||
|
||||
## 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`
|
||||
- [ ] `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 作为 `page.body.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 策略。
|
||||
- [ ] 将 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 等浏览器入口必须职责。
|
||||
- [ ] 将 `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/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
|
||||
|
||||
- [x] 为 `index.md / asset / asset-folder / mindmap child / book / pdf` 搜索命中补更多 fixture。
|
||||
- [x] 明确 `maxResults` 与祖先补全的排序/截断规则。
|
||||
- [x] 增加异步索引可见性元数据,特别是 move/embed picker 搜索结果路径。
|
||||
- [x] 空结果与 fallback 文案保持稳定。
|
||||
- [ ] 如后续需要完整索引平台,再补真实异步索引延迟、刷新和可见性指标,而不是只依赖 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,不是独立搜索服务或完整索引指标平台。
|
||||
|
||||
## 8. 非目标
|
||||
|
||||
- 不拆除 Convex substrate。
|
||||
- 不把 OnlyOffice 嵌入 BlockNote 画布。
|
||||
- 不恢复旧 React PageTree/FileTree 作为 rust_family 主路径 fallback。
|
||||
- 不把 3104 重新暴露为默认前端入口。
|
||||
- 不在前端新增第二套树结构真相或排序真相。
|
||||
Reference in New Issue
Block a user