# 5-29 Editor Runtime 后续收口 Checklist v1

> 创建时间：2026-05-25
> 完成时间：2026-05-25
> 状态：`done`
> 来源：承接 `design/05-editor-mainline/done/5-28-leptos-tiptap-editor-runtime-module-extraction-v1.md` 的后续未专项完成项。

## 1. 目标

在 `5-28` 已完成附件链接、history-safe delete、command sync、persistence、attachment upload intent 首批拆分后，继续把 editor runtime 的 selection / overlay / block menu / mindmap node view 切成可索引模块。Codex 维护本文件作为事实源，Reasonix 只做短批次审计、窄范围实现或浏览器 smoke；当前 goal 下每批最多 2 个 worker。

## 2. 本轮边界

本轮优先处理：

- `editor_runtime/dom_selection.rs` 第一刀。
- overlay / block menu 后续切片的只读审计。
- 仍使用 HTML 整文替换的用户编辑路径风险复核，例如块手柄拖拽重排和复制副本。
- `task488` / `task489` / `task479` 作为回归基线。

本轮不处理：

- shell host resource open / local upload 落盘语义；这些归 `3-20`。
- Page AI 流式 apply / review session。
- mindmap 事实源重构；本轮最多审计 node view 拆分边界。

## 3. Batch A 候选任务

- [x] Worker A：实现 `dom_selection.rs` 第一刀。
  - 允许修改：`rust/spikes/leptos-tiptap-spike/src/lib.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、新增 `rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs`。
  - 目标函数：`active_editor_text_selection`、`selection_summary`、`has_active_text_selection`、`selection_has_rich_marks`，以及必要的 selection payload helper。
  - 禁止：迁出 block menu DOM、overlay state、host bridge、resource open。
- [x] Worker B：只读审计 overlay / block menu 拆分 — 已完成执行。`overlays.rs` 已迁出 FloatingToolbarAnchor、sync_text_selection_overlay、open/close overlay 簇、try_close_block_menu_overlays、close_editor_floating_overlays_if_escape、should_auto_close_toolbar_overlays。剩余 `try_sync_editor_overlay_state` 和 `sync_overlays_on_selection_change` 已在 overlays.rs 中。block menu signal 编排（Effect 级）有意留在 lib.rs。
- [x] Worker C：只读审计剩余 HTML 整文替换用户编辑路径 — 完成。审计确认 `apply_html_update` 从 3 条路径被调用（拖拽重排×2 + 拷贝副本），均破坏 undo history。`apply_document_update` 是死代码。`history_safe_commands.rs` 已有可复用模式。建议后续实现 `move_top_level_block_with_history` 和 `duplicate_top_level_block_with_history`。
- [x] Worker D：浏览器 smoke 审计 editor runtime 基线 — 完成。task488、task489、task479 均 PASS（result.json 保存在 tmp/ 目录）。

## 4. 验收命令

```bash
cargo fmt --manifest-path rust/Cargo.toml --all --check
cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml
cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release
wasm-bindgen rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island
node scripts/task488-local-attachment-link-delete-undo-smoke.js
node scripts/task489-block-menu-delete-undo-smoke.js
node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js
```

UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据。

## 5. 采纳规则

- Reasonix 结果必须先查 Hindsight `reasonix` recall，再读 `process-handoff.md/json`、`result.json`、diff 和验证证据。
- 实现 worker 必须在独立 worktree 产出候选 patch；只读和 smoke worker 必须没有源码 diff。
- Codex 主工作区只维护事实源、复核证据和最终选择性合入，不直接承接 B/C/D 等实现 worker 的原始修改过程。
- 实现 worker 只能改允许范围。
- `lib.rs` 不能新增附件/history/DOM bridge 大块逻辑。
- 本文件只记录真实完成项；未验证项保持未勾选。

## 6. 本轮执行记录

- 2026-05-25：Codex 创建本续跑事实源。
- 2026-05-25：Worker A 未继续派发；Codex 主控已在主工作区完成 `dom_selection.rs` 第一刀并提交 `c7ab4e56 refactor: extract editor dom selection runtime`。
  - 已迁函数：`node_is_within_root`、`active_editor_text_selection`、`has_active_text_selection`、`selection_summary`、`selection_has_rich_marks`。
  - 未迁：`SelectionPayload`、`selection_payload`、`send_selection_state*`、`selection_event_payload`，原因是仍依赖 bridge event、`HoveredBlockState` 和 runtime block id 边界。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`task488`、`task489`、CodeGraph pending 0。
- 2026-05-25：执行口径修正：继续遵循当前 goal 的“每批最多 4 个 worker”；Reasonix 后续必须使用独立 worktree 或明确只读任务，完成后由 Codex 读取 handoff 并复核。
- 2026-05-25：Batch D 额外 runner 曾自动启动 Worker A / Worker B，未经过本轮主控计划确认；主控已终止相关 runner / ACP 进程，不采纳这些未受控 run。遗留 task 草稿暂不删除，后续如继续使用必须重新生成受控任务书。
- 2026-05-25：Reasonix runner 异常：后续实现 run 未写 `result.json`、`process-handoff.md/json`，部分 transcript 停在工具调用阶段；Codex 不采纳其文字结论，只复核实际 diff。
- 2026-05-25：Reasonix overlay / block menu 只读审计尝试未产生 `result.json` / `process-handoff`，且运行期间出现额外 Batch A2 runner，主控已终止进程；该结果不作为正式 handoff 采纳。
  - transcript 只显示探索过程，未形成函数归属表；下一次应改为更窄的单问题只读任务，例如只审计 `floating_toolbar_anchor_from_selection` / `sync_text_selection_overlay` 能否迁入 `overlays.rs`。
- 2026-05-25：Codex 主控直接完成 overlay 第一刀：新增 `editor_runtime/overlays.rs`，迁出 `FloatingToolbarAnchor`、`floating_toolbar_anchor_from_selection`、`sync_text_selection_overlay`。
  - 未迁：`sync_editor_overlay_state` / `try_sync_editor_overlay_state`，原因是仍依赖 `HoveredBlockState`、slash/block menu signal 和 overlay 关闭策略。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`node scripts/task489-block-menu-delete-undo-smoke.js`。
  - 运行中再次出现额外 Batch A2 Reasonix runner，主控已终止；这些 runner 未作为本批证据。
- 2026-05-25：采纳并复核 Worker B 候选 patch：新增 `editor_runtime/block_menu_legacy_html.rs`，迁出 `duplicate_top_level_block_html`、`reorder_top_level_block_html`；`lib.rs` 仅保留调用点和 `DropPlacement` 的 `pub(crate)` 可见性。
  - Reasonix run：`reasonix-2026-05-24T17-07-59-603Z-bfe72d77`，已读取 Hindsight recall、`process-handoff.md/json`、diff，并由 Codex 独立复核。
  - Codex 合入时保持实现逻辑同构，仅收口模块边界和 checklist 事实记录。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`node scripts/task489-block-menu-delete-undo-smoke.js`。
  - 未完成：HTML 整文替换仍是 legacy 路径，后续要用 history-safe Tiptap command 替换；`sync_editor_overlay_state`、block menu signal 仍未拆出。
- 2026-05-25：复跑浏览器 smoke 后修正上一条验收口径：`task488` 通过，但 `task489-block-menu-delete-undo-smoke` 连续两次失败，失败点是块菜单删除后 `Control+Z` 未恢复 `Beta block`。
  - 证据：`tmp/task489-block-menu-delete-undo-smoke/result.json`、`tmp/task489-block-menu-delete-undo-smoke/failure.png`。
  - 已登记缺陷：`bugs/05-editor-mainline/done/5-39-block-menu-delete-undo-regression-v1.md`。
  - Worker E（`reasonix-2026-05-24T17-34-41-774Z-85427058`）已在独立 worktree `/mnt/Data1T/mnote-worktrees/0525-b3-block-delete-undo` 派发修复任务，但 runner 仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`，worktree 无 diff，拒绝采纳。
  - 当前结论：5-29 仍未完成；下一步应先定位 `delete_top_level_block_with_history`、`sync_persisted_editor_command`、editor focus / undo keydown 之间的真实断点，再修复。
- 2026-05-25：Codex 主控修复 `5-39`：诊断确认 history 未丢，断点是块菜单删除后焦点短暂落到 `BODY`；最终修复为删除菜单项 `mousedown` 阶段阻止默认焦点转移、关闭菜单后异步 `editor.focus()` 兜底，并在 `BODY` 焦点窗口只转发 undo/redo 快捷键到当前 editor；缺陷文档已移到 `bugs/05-editor-mainline/done/5-39-block-menu-delete-undo-regression-v1.md`。
  - 同批新增 `editor_runtime/block_menu_document.rs`，迁出未走当前运行路径的 legacy 顶层块 JSON helper：`duplicate_top_level_block`、`delete_top_level_block`、`reorder_top_level_block`；`replace_top_level_block_kind` 暂不迁，因仍依赖 slash action、mindmap 和 image placeholder 语义。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`node scripts/task489-block-menu-delete-undo-smoke.js`、`node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
  - 未覆盖：`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml block_menu_document -- --test-threads=1` 被既有 `STYLE` 测试编译错误阻断，未进入本次新增 helper 测试。
- 2026-05-25：根据用户纠正，后续 B/C/D 等实现 worker 不再只读或在主工作区直接修改；Batch C 统一采用独立 worktree 候选 patch，Codex 读取 Hindsight recall、`process-handoff.md/json`、`result.json`、diff 与验证证据后再选择性合入。
- 2026-05-25：根据用户再次纠正，后续 B/C/D 等实现 worker 必须统一在独立 worktree 中产出候选 patch，再由 Codex 复核 diff / handoff / 验证证据后选择性合入；不得在主工作区直接推进实现 worker。
- 2026-05-25：Batch D Reasonix runner 再次异常：Worker A run `reasonix-2026-05-24T18-07-08-220Z-ccc4102a`、Worker B run `reasonix-2026-05-24T18-07-08-227Z-1358f36b` 仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`，对应 worktree diff 均为空；该结果拒绝采纳。为保持推进速度，本批改用独立 worktree worker 继续产出候选 patch，Codex 仍按同一采纳规则复核。
- 2026-05-25：Batch C Worker B（`reasonix-2026-05-24T17-41-07-634Z-a39f8963`）在独立 worktree `/mnt/Data1T/mnote-worktrees/0525-c-worker-b-block-delete-undo` 未产出 `final.md`、`result.json` 或 `process-handoff.md/json`，worktree diff 为空，拒绝采纳；Codex 随后在同一 worktree 独立定位根因、产出候选 patch、通过 smoke 后移植到主工作区。
- 2026-05-25：Reasonix 只读审计 `sync_editor_overlay_state` / `try_sync_editor_overlay_state` 下一刀，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-d-5-29-overlay-readonly`，run id `reasonix-2026-05-24T17-53-20-962Z-d3077308`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对 worktree `git status --short` / `git diff --stat` 为空；runner 已产出 completed handoff 但进程未自行退出，主控已终止残留 runner。
  - 审计结论：当前不宜直接把 `sync_editor_overlay_state` / `try_sync_editor_overlay_state` 迁入 `overlays.rs`，因为它们仍强依赖 `HoveredBlockState`、slash/block menu signals、`active_editor_stage` 和 8/18 overlay signal 的局部关闭策略；`on_selection_change` 仍有一套内联 signal 同步逻辑，直接迁出会造成两套 overlay reconciler。
  - 下一刀建议：先做类型/边界准备或更窄 helper，而不是迁整个 sync 函数；候选是抽出 block/overlay shared types（例如 `HoveredBlockState` 及相关 anchor 类型）或把 `active_editor_stage` 的 DOM 判断收口到 runtime helper，之后再考虑 `close_editor_floating_overlays` 整簇迁移。
- 2026-05-25：Codex 主控完成 editor focus helper 第一刀：新增 `editor_runtime/editor_focus.rs`，迁出 `schedule_editor_focus`、`body_has_focus` 与 `active_editor_stage`；`lib.rs` 仍保留 overlay / block menu signal 编排和调用点。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/editor_focus.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island wasm/js。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`node scripts/task489-block-menu-delete-undo-smoke.js`、`node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
  - 未完成：`sync_editor_overlay_state` / `try_sync_editor_overlay_state`、`HoveredBlockState` shared type、block menu signal 仍未拆出。
- 2026-05-25：Batch E 计划继续采用独立 worktree 候选 patch：Worker A 负责把 `HoveredBlockState`、`BlockMenuLayout`、`DropPlacement`、`DropIndicatorState` 迁入 `editor_runtime/block_hover_state.rs`，只做共享类型边界，不迁 DOM 查询、signal 编排或 block menu 行为。
- 2026-05-25：Codex 独立复核并移植 Batch E Worker A 候选 diff：新增 `editor_runtime/block_hover_state.rs`，迁出 `HoveredBlockState`、`BlockMenuLayout`、`DropPlacement`、`DropIndicatorState`、`PendingDragState`；`lib.rs` 仍保留 DOM 查询、布局计算、signal 编排和 block menu 行为。
  - Reasonix 协作证据：runner `reasonix-2026-05-24T18-25-26-836Z-aa546442` / `reasonix-2026-05-24T18-26-04-414Z-9476214d` 均仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`；因此不作为完整 handoff 采纳。Codex 已查 Hindsight recall、核对 worktree diff，并拒绝移植 worktree 中未跟踪 `reference-code` symlink。
  - 候选 worktree：`/mnt/Data1T/mnote-worktrees/0525-e-worker-a-5-29-block-hover-state`。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_hover_state.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。
  - 已验证：`git diff --check`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`node scripts/task489-block-menu-delete-undo-smoke.js`、`node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
  - 未完成：`sync_editor_overlay_state` / `try_sync_editor_overlay_state`、block menu signal 编排、HTML 整文替换 legacy 路径仍未拆出。
- 2026-05-25：Batch E 派发异常并终止：Worker A 任务被重复启动为两个 runner / ACP 进程（`reasonix-2026-05-24T18-25-26-836Z-aa546442`、`reasonix-2026-05-24T18-26-04-414Z-9476214d`），同一 worktree `/mnt/Data1T/mnote-worktrees/0525-e-worker-a-5-29-block-hover-state` 出现并发写入风险；Codex 已终止相关 Reasonix 进程，未读取到 `final.md`、`result.json`、`process-handoff.md/json`，该 diff 只保留为后续人工审计素材，不采纳。
- 2026-05-25：Codex 独立复核并推进 block hover state 类型边界拆分：新增 `editor_runtime/block_hover_state.rs`，迁出 `HoveredBlockState`、`BlockMenuLayout`、`DropPlacement`、`DropIndicatorState`、`PendingDragState`；`lib.rs` 仍保留 DOM 查询、signal 编排、block menu 行为和拖拽逻辑。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_hover_state.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island wasm。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
  - 未完成：`sync_editor_overlay_state` / `try_sync_editor_overlay_state`、block menu signal 和拖拽重排行为仍在 `lib.rs`，后续应继续按更窄 helper 拆分。
- 2026-05-25：Batch F 计划继续采用独立 worktree 候选 patch：Worker A 负责把 `hover_anchor_top`、`hover_anchor_transform`、`block_menu_layout` 或其几何计算部分迁入 `editor_runtime/block_menu_overlay.rs`，不迁拖拽 hit-test、signal 编排或 block menu 行为。
- 2026-05-25：采纳并复核 Batch F Worker A 候选 patch：新增 `editor_runtime/block_menu_overlay.rs`，迁出 `hover_anchor_top`、`hover_anchor_transform`、`block_menu_layout` 的纯几何计算；`lib.rs` 仍保留 `editor_stage_element` DOM 查询、拖拽 hit-test、signal 编排和 block menu 行为。
  - Reasonix run：`reasonix-2026-05-24T18-39-34-366Z-631ed269`，已读取 Hindsight recall、`process-handoff.md/json`、`result.json`、diff 与验证摘要；Reasonix 自报 smoke 挂起，Codex 不采信该部分。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_overlay.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island wasm/js/d.ts。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
  - 未完成：`pointer_in_handle_corridor`、`drop_indicator_from_target` / `drop_indicator_from_point`、`sync_editor_overlay_state` / `try_sync_editor_overlay_state` 仍在 `lib.rs`。
- 2026-05-25：Batch G Worker D 先按用户纠正使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-g-worker-d-5-29-block-dnd-helpers`；Reasonix run `reasonix-2026-05-24T18-51-00-541Z-17d61f43` 仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 handoff/result/final，worktree 初始 diff 为空，拒绝作为 Reasonix handoff 采纳。Codex 随后在该独立 worktree 产出候选 patch，经复核后选择性移植到主工作区。
  - 修改：新增 `rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_dnd.rs`，迁出 `pointer_in_handle_corridor` / `drop_indicator_from_target` 使用的纯几何 helper；`lib.rs` 仍保留 DOM 查询、signal 编排、拖拽事件和 HTML reorder 行为。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
  - 未覆盖：`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml block_dnd -- --test-threads=1` 仍被既有 `STYLE` 测试编译错误阻断，未进入本次新增 helper 测试。
  - 未完成：`drop_indicator_from_point` 的 DOM target lookup、拖拽 listener 编排、`sync_editor_overlay_state` / `try_sync_editor_overlay_state` 仍在 `lib.rs`。
- 2026-05-25：Batch H 只派发 1 个只读 Reasonix worker 复核 block DnD helper 边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-h-5-29-block-dnd-readonly`，run id `reasonix-2026-05-24T18-59-12-393Z-b5d95a7b`，并显式使用 `--no-memory-recall` 降低任务串线风险。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对 worktree `git status --short` / `git diff --stat` 为空。
  - 审计结论：只迁纯几何 helper 是合理边界；DOM 查询、`document.element_from_point`、event listener、Leptos signal 和拖拽重排行为继续留在 `lib.rs`。
  - 主控裁决：采纳审计方向，但保留当前 `editor_runtime/block_dnd.rs` 的 `HandleCorridorGeometry` 参数结构，避免 Reasonix 建议的长参数列表降低可读性。
- 2026-05-25：Batch J 同时启动 Worker B（`0525-j-worker-b-5-29-close-overlays`）和 3-20 Worker C/D，3 个 worker 超过当时旧“每批最多 2 个 worker”口径。Reasonix run `reasonix-2026-05-24T19-14-46-705Z-ebcc8980` 仅有 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`，worktree diff 为空；不采纳。
- 2026-05-25：Batch J Codex 在独立 worktree `/mnt/Data1T/mnote-worktrees/0525-j-worker-b-5-29-close-overlays` 产出并复核候选 patch：删除无调用方的 `sync_editor_overlay_state`，新增 `try_close_block_menu_overlays` 承接 `try_sync_editor_overlay_state` 中的 slash / turn-into / block menu / hovered block 关闭子集；不迁 `try_sync_editor_overlay_state`，不合并 `on_selection_change` 的内联 overlay 路径。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island `js/d.ts/wasm/wasm.d.ts`。
  - 已验证：在独立 worktree 中运行 `cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`；主工作区复跑 `NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js` 均通过，结果分别位于 `/mnt/Data1T/mnote/tmp/task489-block-menu-delete-undo-smoke/result.json`、`/mnt/Data1T/mnote/tmp/task488-local-attachment-link-delete-undo-smoke/result.json`。
  - 未完成：`try_sync_editor_overlay_state`、`on_selection_change` overlay 同步、block menu signal 编排仍未迁出；本轮未扩大迁移边界。
- 2026-05-25：当前 goal 按用户最新要求明确为每批最多 4 个 worker；后续 Batch 计划和 Reasonix 派发以 4 个为硬上限。
- 2026-05-25：用户纠正 B/C/D 等实现任务也应在新的 worktree 中修改后再由 Codex 合并；主控已采用该口径：实现 worker 一律独立 worktree，主工作区不再直接扩大实现 diff，只保留事实源、复核和最终采纳。
- 2026-05-25：Batch K 只派发 1 个只读 Reasonix worker 审计 `close_editor_floating_overlays` 迁出边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-k-5-29-close-overlays-readonly`，run id `reasonix-2026-05-24T19-18-51-566Z-90f11977`，并显式使用 `--no-memory-recall` 降低任务串线风险。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对 worktree `git status --short` / `git diff --stat` 为空。
  - 审计结论：先把 `ImageToolbarAnchor`、`TableOverlayAnchor`、`TableSelectionKind`、`TableSelectionOverlayState` 迁入 `editor_runtime/overlays.rs`，再迁出纯 WriteSignal setter `close_editor_floating_overlays`；`close_editor_floating_overlays_if_escape`、`open_slash_menu_overlay`、`open_image_toolbar_overlay`、`open_block_menu_overlay`、`try_sync_editor_overlay_state` 和 `on_selection_change` overlay 同步继续留在 `lib.rs`。
  - Codex 主控在主工作区采纳该边界，并保留 Batch J 候选中已复核过的 `try_close_block_menu_overlays` 小 helper；该 helper 只收窄 `try_sync_editor_overlay_state` 内部的 block menu 关闭子集，不迁出 signal 编排。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/overlays.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island `js/d.ts/wasm/wasm.d.ts`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`。主工作区 editor smoke 仍需复跑后再提交。
  - 未完成：`try_sync_editor_overlay_state`、`on_selection_change` overlay 同步、block menu signal 编排、Escape 条件判断仍未迁出。
- 2026-05-25：Batch L 派发 2 个只读 Reasonix worker：Worker A `reasonix-2026-05-24T19-30-30-474Z-c3f28f20` 审计 5-29 overlay sync，Worker B `reasonix-2026-05-24T19-30-30-509Z-18f62949` 审计 3-20 sidebar refresh；运行中又出现两个额外自动 runner，主控已终止，不采纳。
  - Worker A handoff 出现任务串线迹象，final 同时讨论 3-20 和 5-29；Codex 只采纳其中由本地代码复核确认的 5-29 结论：`on_selection_change` 和 `try_sync_editor_overlay_state` 不能直接统一，因为 toolbar lock 语义不同。
  - Codex 主控采纳最小机械切片：把 `try_close_block_menu_overlays` 迁入 `editor_runtime/overlays.rs`；`try_sync_editor_overlay_state`、`close_editor_floating_overlays_if_escape` 和 `on_selection_change` 仍留在 `lib.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
- 2026-05-25：Batch M 按用户纠正尝试并行派发 3 个 Reasonix 实现 worker，均使用独立 worktree；run `reasonix-2026-05-24T19-40-19-806Z-81099224` 仅有 `prompt.md`、`memory-recall.json`、`reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`，不采纳。
  - 失败原因：Reasonix ACP 并发串线，transcript 出现读取非本 worker worktree 的行为；不满足 handoff 合同。
  - 主控处置：不从 Batch M 合入任何 diff；改用 Batch N 的独立 worktree 子 agent worker 继续推进，仍由 Codex 复核 diff 和验证。
- 2026-05-25：Batch N 继续收口 overlay escape 小切片：Codex 主控把 `close_editor_floating_overlays_if_escape` 机械迁入 `editor_runtime/overlays.rs`，`lib.rs` 仅保留调用和仍需壳层状态的 open / sync overlay 编排。
  - 未迁：`try_sync_editor_overlay_state`、`on_selection_change`、`open_slash_menu_overlay` / `open_image_toolbar_overlay` / `open_block_menu_overlay`，原因是仍依赖 DOM event、toolbar lock、selection bridge 或 Leptos shell signal 编排。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
- 2026-05-25：Batch O 继续收口 overlay open helper：Codex 主控把 `open_slash_menu_overlay`、`open_image_toolbar_overlay`、`open_block_menu_overlay` 迁入 `editor_runtime/overlays.rs`。这三者只复用 `close_editor_floating_overlays` 并设置 Leptos signals；`open_block_menu_overlay` 仅读取 `block_menu_open` 判定是否重新打开。
  - 未迁：`try_sync_editor_overlay_state`、`on_selection_change` 和各调用点 DOM / selection bridge 逻辑，原因是仍属于 editor shell 编排。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
- 2026-05-25：Batch O Worker B 使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-o-worker-b-5-29-dnd-target-helper`，Codex 已读取 subagent handoff、worktree diff 和验证证据，并选择性移植。
  - 修改：`editor_runtime/block_dnd.rs` 新增 `event_target_from_point(client_x, client_y)`，封装 `document.element_from_point` 到 `EventTarget` 的窄 DOM lookup；`lib.rs` 的 `drop_indicator_from_point` 只委托该 helper 后继续调用 `drop_indicator_from_target`。
  - 未迁：`drop_indicator_from_target`、拖拽 listener、Leptos signal、`editor_stage_element` / `editor_root_element` 查询和 block reorder 行为仍留在 shell。
  - Worker 验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`git diff --check`、`rustfmt --edition 2021 --check rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_dnd.rs` 通过；`cargo check -p leptos-tiptap-spike` 因包名不匹配失败，主控改用正确 manifest 复核。
  - Codex 主控验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
- 2026-05-25：Codex 主控完成 overlay 状态纯 helper 小切片：`toolbar_overlay_locked(turn_into_open, color_menu_open, more_menu_open)` 迁入 `editor_runtime/overlays.rs`；`lib.rs` 仍保留 runtime state/status payload、overlay sync、block menu signal 和 DOM 编排调用点。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/overlays.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island wasm。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 未迁：`try_sync_editor_overlay_state`、`on_selection_change` overlay 同步、`drop_indicator_from_target`、拖拽 listener 和 block reorder 行为。
- 2026-05-25：Batch S 只派发 1 个只读 Reasonix worker 审计 `try_sync_editor_overlay_state` 迁出边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-s-worker-a-5-29-overlay-sync-readonly`，run id `reasonix-2026-05-24T20-44-23-926Z-3436b5dd`，并显式使用 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`、`final.md`，并核对 worktree `git status --short` / `git diff --stat` 为空；Reasonix 未修改源码。
  - 审计结论经 Codex 复核后采纳：`try_sync_editor_overlay_state` 已无 `lib.rs` 私有依赖，只依赖 `editor_focus::active_editor_stage`、`floating_toolbar_anchor_from_selection`、`try_close_block_menu_overlays`、`FloatingToolbarAnchor` 和 `HoveredBlockState`，可机械迁入 `editor_runtime/overlays.rs`。
  - Codex 主控完成迁移：`try_sync_editor_overlay_state` 迁入 `editor_runtime/overlays.rs`，`lib.rs` 仅保留 mouseup / keyup listener 调用和仍属于 shell 的 DOM / selection bridge 编排；清理本次迁移产生的孤儿 import。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/overlays.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island `js/wasm`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 环境阻塞：`MNOTE_UI_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task158-e30-menu-state-smoke.js` 在创建 cloud 临时文档时返回 `503 convex_unavailable`，当前 3001 服务未配置 Convex mutation；本地文件夹型 editor smoke 已通过。
  - 未迁：`on_selection_change` overlay 同步、`drop_indicator_from_target`、拖拽 listener、block reorder 行为和 selection bridge 仍留在 `lib.rs`。
- 2026-05-25：Batch T 只派发 1 个只读 Reasonix worker 审计 `drop_indicator_from_target` 边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-t-worker-a-5-29-drop-indicator-readonly`，run id `reasonix-2026-05-24T20-56-16-647Z-35de7d21`，并显式使用 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`、`final.md`，并核对 worktree `git status --short` / `git diff --stat` 为空；Reasonix 未修改源码。runner 完成后残留父进程未自行退出，主控已终止。
  - 审计结论经 Codex 复核后采纳：`drop_indicator_from_target` 不能整体迁入 `editor_runtime/block_dnd.rs`，因为仍依赖 `hovered_block_from_target`、`target_element`、`direct_block_from_element`、`top_level_block_index`、`block_state_from_index`、`HANDLE_SHELL_SELECTOR` 等 `lib.rs` DOM -> block 状态解析链。
  - Codex 主控完成最小几何切片：`block_dnd.rs` 新增 `drop_indicator_from_geometry(block_index, block_top, block_height, stage_top, client_y)` 和单元测试；`lib.rs::drop_indicator_from_target` 仍负责 DOM 查询与 hovered block 解析，只委托新 helper 计算 `DropIndicatorState`。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_dnd.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island wasm。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 单元测试阻塞：`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml block_dnd -- --test-threads=1` 被既有 `STYLE` 测试编译错误阻断，未进入本次新增 helper 测试；该阻断在此前 `block_dnd` 批次已存在。
  - 未迁：`hovered_block_from_target`、`drop_indicator_from_target`、`drop_indicator_from_point`、拖拽 listener、block reorder 行为和 DOM -> block 状态解析链仍留在 `lib.rs`。
- 2026-05-25：Batch U 只派发 1 个只读 Reasonix worker 审计 `on_selection_change` overlay 同步边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-u-worker-a-5-29-selection-overlay-readonly`，run id `reasonix-2026-05-24T21-09-36-422Z-477b50a6`，并显式使用 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`、`final.md`，并核对 worktree `git status --short` / `git diff --stat` 为空；Reasonix 未修改源码。runner 完成后残留父进程未自行退出，主控已终止。
  - 审计结论经 Codex 复核后采纳：`on_selection_change` 不能整体迁出，因为 selection state 写入和 `send_selection_state_to_target` bridge dispatch 仍属于 `lib.rs` 壳层；其中 text-selection overlay 状态机和互斥 overlay 关闭可作为小 helper 迁入 `editor_runtime/overlays.rs`。
  - Codex 主控完成最小切片：`overlays.rs` 新增 `sync_overlays_on_selection_change(...)`，封装 toolbar lock、text selection overlay 同步、image/block overlay 互斥关闭；`lib.rs` 的 `on_selection_change` 仅保留 selection state 写入、helper 调用和 bridge dispatch。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/overlays.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 未迁：`send_selection_state_to_target` / `selection_payload` bridge 链路、`runtime_block_id_from_index`、selection bridge event、`drop_indicator_from_target`、拖拽 listener 和 block reorder 行为仍留在 `lib.rs`。
- 2026-05-25：Batch V 只派发 1 个只读 Reasonix worker 审计 selection bridge 迁出边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-v-worker-a-5-29-selection-bridge-readonly`，run id `reasonix-2026-05-24T21-22-36-118Z-1e489f85`，并显式使用 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`、`final.md`，并核对 worktree `git status --short` / `git diff --stat` 为空；Reasonix 未修改源码。
  - 审计结论经 Codex 复核后采纳：selection bridge 的事件分发层必须留在 `lib.rs`，但 `SelectionPayload`、`selection_payload`、`runtime_block_id_from_index` 及其 block id 读取 helper 属于可迁出的 selection 数据层。
  - Codex 主控基于只读审计结论在主工作区完成最小实现；本批没有实现 worker 候选 patch，因此不记录虚构 worktree 采纳链。
  - 已合入最小切片：`SelectionPayload`、`selection_payload`、`runtime_block_id_from_index`、`block_id_from_element`、`block_id_from_json_node` 迁入 `editor_runtime/dom_selection.rs`；`send_selection_state_to_target`、`dispatch_selection_event_to_target`、`CustomEvent` bridge 和 `selection_event_target` 壳层调用继续留在 `lib.rs`。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 未迁/未删：`send_selection_state_to_target`、selection event dispatch、`send_selection_state`、`selection_event_payload`、`runtime_state_payload`、`runtime_status_payload` 等未使用 bridge/helper 函数；死代码清理后续单独切片处理。
- 2026-05-25：Batch W 只派发 1 个只读 Reasonix worker 审计 selection / bridge 死代码清理边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-w-worker-a-5-29-selection-deadcode-readonly`，run id `reasonix-2026-05-24T21-36-28-065Z-75d6e2e8`，并显式使用 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对 worktree `git status --short` / `git diff --stat` 为空；Reasonix 未修改源码。
  - 主控发现随后残留/未授权 Reasonix runner：除本只读 worker 外还存在 Worker B/C/D runner 或 ACP 进程；该批超过当时旧 2-worker 上限，但不满足主控明确派发与完整 handoff 合同，已终止相关进程，且不采纳被终止 worker 的任何输出。
  - 审计结论经 Codex 复核后采纳：删除无调用方私有函数 `send_selection_state`、`selection_event_payload`、`dispatch_bridge_event`、`current_runtime_block_info`、`current_runtime_block_info_from_hovered`、`runtime_state_payload`、`runtime_status_payload`。
  - 保留：`send_selection_state_to_target`、`dispatch_selection_event_to_target`、`current_block_info_from_index`、`state_payload`、`status_payload`，原因是仍有真实调用方或作为当前替代链路使用。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island wasm。
  - 当前执行约束同步修正：`3-20` / `5-29` checklist 均保持“当前 goal 下每批最多 4 个 worker”。
  - 已验证：`git diff --check`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`、`codegraph sync .`、`codegraph status . --json` pending 0。
- 2026-05-25：Batch X 计划只派发 1 个只读 Reasonix worker 审计 block DnD DOM 边界，任务书 `.codex/reasonix-tasks/2026-05-25-batch-x-worker-a-5-29-dnd-dom-readonly.md`，worktree `/mnt/Data1T/mnote-worktrees/0525-x-worker-a-5-29-dnd-dom-readonly`。
  - 派发异常：启动本只读 worker 后，又出现未由主控批准的 Worker A/B/C/D runner 与 ACP 进程；该批超过当时旧 2-worker 上限，但不满足主控明确派发与完整 handoff 合同。主控已终止全部 `reasonix-coding-runner` / `reasonix acp` / `reasonix/dist/cli/index.js acp` 进程，本批不采纳任何 Reasonix 输出。
  - Codex 主控改为本地最小机械切片：`editor_runtime/block_dnd.rs` 新增 `element_within_handle_shell(element, handle_selector)`，只封装 handle-shell DOM predicate；`lib.rs` 的 `hovered_block_from_target`、editor stage click / mousemove / dragover 调用点改为委托该 helper。
  - 未迁：`hovered_block_from_target`、`drop_indicator_from_target`、`drop_indicator_from_point`、拖拽 listener、block reorder 行为和 DOM -> block 状态解析链仍留在 `lib.rs`。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_dnd.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`、`git diff --check`、`codegraph sync .`、`codegraph status . --json` pending 0。
- 2026-05-25：Batch Y 暂停派发新 Reasonix worker，原因是 Batch X 刚出现自动扩散 runner；主控先用 CodeGraph 复核 `target_element`、`direct_block_from_element`、`top_level_block_index`、`hovered_block_from_target`、`drop_indicator_from_target` 调用关系后，本地完成最小机械切片。
  - Codex 主控把 `direct_block_from_element`、`top_level_block_index` 迁入 `editor_runtime/block_dnd.rs`；`lib.rs` 仅保留 root/stage 查询、`block_state_from_index`、`hovered_block_from_target` / `hovered_block_from_selection` 的壳层状态组装。
  - 未迁：`target_element` 仍被图片 toolbar 和事件 listener 共用；`hovered_block_from_target`、`drop_indicator_from_target`、`drop_indicator_from_point`、拖拽 listener、block reorder 行为和 DOM -> block 状态解析链仍留在 `lib.rs`。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_dnd.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island `js/wasm`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch Z 曾一次派发 4 个 Reasonix worker，均使用独立 worktree：A 只读审计 block transform、B 实现 block transform、C 实现 3-20 filetree refresh helper、D 运行 3-20 live smoke；该批超过当时旧 2-worker 上限，但四个 run 均不满足 handoff 合同。
  - Reasonix run `reasonix-2026-05-24T22-02-32-495Z-dfd6bb89` / `reasonix-2026-05-24T22-02-32-511Z-ea50d6e0` / `reasonix-2026-05-24T22-02-32-635Z-4edc4f8a` / `reasonix-2026-05-24T22-02-32-644Z-1180a395` 均只有 `prompt.md`、`memory-recall.json`、`reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`；四个 worktree diff 为空，按采纳规则全部拒收。
  - 额外异常：Reasonix 仍创建 `.codex/reasonix-tasks/2026-05-25-batch-x-worker-a-5-29-dnd-dom-readonly.md` 草稿，违反叶子 worker 约束；该草稿不纳入本文件事实源、不提交。
  - Codex 随后在独立 worktree `/mnt/Data1T/mnote-worktrees/0525-x-worker-b-5-29-block-transform-impl` 产出并复核候选 patch：把仍有真实调用方的 `paragraph_node`、`collect_plain_text`、`mindmap_paragraph_node` 迁入 `editor_runtime/block_menu_document.rs`，删除 `lib.rs` 中无调用方的旧 JSON transform 死链 `list_item_node`、`task_item_node`、`inline_from_first_child`、`extract_inline_content`、`turn_into_block`、`replace_top_level_block_kind` 及图片占位常量。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。
  - 已验证：候选 worktree中 `git diff --check`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen` 通过；主工作区复跑 `git diff --check`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js` 通过。
  - 未完成：`block_menu_document.rs` 中 `duplicate_top_level_block`、`delete_top_level_block`、`reorder_top_level_block` 仍显示无 runtime 调用；是否删除需另起只读审计确认历史测试 / future intent，不在本批扩大。
- 2026-05-25：Batch AA 未派发 Reasonix worker；上一轮刚出现未授权 runner，主控先用 CodeGraph 和 `rg` 核实 `block_menu_document.rs` 中 `duplicate_top_level_block`、`delete_top_level_block`、`reorder_top_level_block` 无 runtime 调用。
  - Codex 主控完成死链清理：删除上述三组无调用方 JSON helper 和只覆盖该死链的模块内测试；保留真实运行路径 `history_safe_commands::delete_top_level_block_with_history`、`block_menu_legacy_html::{duplicate_top_level_block_html,reorder_top_level_block_html}` 不动。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3002 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3002 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3002 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。
  - 验证说明：复用已有 3001 长跑服务时 `task479` 连续两次卡在 missing 标记等待点；改用本批临时启动的干净 3002 服务复跑后通过，判定为长跑服务状态问题，不作为本批回归。
- 2026-05-25：Batch AA 后续按用户纠正重新执行“B/C/D 必须在独立 worktree 修改后再由 Codex 合并”流程；本轮最多 3 个并行 worker，超过当时旧 2-worker 上限。
  - Reasonix B/C/D 分别在 `/mnt/Data1T/mnote-worktrees/0525-aa-worker-b-5-29-block-transform-finish`、`/mnt/Data1T/mnote-worktrees/0525-aa-worker-c-3-20-filetree-refresh-helper`、`/mnt/Data1T/mnote-worktrees/0525-aa-worker-d-3-20-live-smoke` 运行；B/C run 仅有空 transcript / 无 handoff / 零 diff，拒收；D run `reasonix-2026-05-24T22-26-26-122Z-62733e93` 有完整 `process-handoff.md/json`、`result.json` 和截图，源码零 diff。
  - Codex 随后改派独立 worktree worker 完成 B/C：B 的 block transform 结果已被当前主线提交 `ee81fafe` / `d59a248c` 覆盖，不再重复套旧 worktree patch；C 的 3-20 helper 由主控复核后选择性合入 3-20 事实源。
  - D smoke 证据：`task487-local-folder-tree-live-consumer-smoke.js` 在 3001 通过，`transport=local-folder-events`、PageTree/FileTree 外部创建/删除均为 `treeLiveApplied=resync`，主框架导航数为 0；截图位于 `/mnt/Data1T/mnote-worktrees/0525-aa-worker-d-3-20-live-smoke/tmp/task487-local-folder-tree-live-consumer-smoke/`。
- 2026-05-25：Batch AB 未派发 Reasonix worker；继续清理 5-29 中无调用的壳层 bridge wrapper。
  - CodeGraph / `rg` 结论：`runtime_mount_options`、`dispatch_ready_event`、`dispatch_selection_event`、`bridge_ready_payload`、`STANDALONE_ROOT_ID` 均无调用方；`set_runtime_mount_options`、`dispatch_ready_event_to_target`、`dispatch_selection_event_to_target` 仍有调用方，保留不动。
  - Codex 主控完成死链清理：删除上述无调用 wrapper / 常量，不改变真实 bridge dispatch 和 mount context 路径。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/lib.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3002 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3002 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3002 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 本轮主控复核：`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js` 均通过。
- 2026-05-25：Batch AC Codex 主控复核并补充验证 block DnD 小切片。
  - 修改：`editor_runtime/block_dnd.rs` 新增 `direct_block_index_from_element(element, root, handle_selector)`，统一封装“排除 handle shell + 解析直接顶层块 index”；`lib.rs::hovered_block_from_target` 改为委托该 helper，仍保留 `target_element`、`block_state_from_index`、拖拽 listener 和 reorder 行为在壳层。
  - 边界：未迁 `target_element`、`drop_indicator_from_target`、`drop_indicator_from_point`、block reorder HTML 行为、DOM event listener 或 Leptos signal 编排。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`git diff --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AC 按用户纠正继续采用独立 worktree 流程；本轮实际 3 个 worker，符合当前 goal 每批最多 4 个 worker 的上限；任务书均写入各 worktree `tmp/`，未新增主工作区 `.codex/reasonix-tasks`。
  - Worker B `/mnt/Data1T/mnote-worktrees/0525-ac-worker-b-5-29-hover-target-helper`，Reasonix run `reasonix-2026-05-24T22-52-30-715Z-4b6e4d37`，Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json` 和 worktree diff；worker 临时创建的未跟踪 `reference-code` symlink 未采纳。
  - Codex 选择性合入 Worker B 的两文件候选 patch：`editor_runtime/block_dnd.rs` 新增 `direct_block_index_from_element(element, root, handle_selector)`，封装 handle-shell 过滤、direct block 解析和 top-level index 查询；`lib.rs::hovered_block_from_target` 仍负责 root/target 壳层获取和 `block_state_from_index` 状态组装。
  - Worker D `/mnt/Data1T/mnote-worktrees/0525-ac-worker-d-smoke-regression`，Reasonix run `reasonix-2026-05-24T22-52-30-854Z-dfad6786`，源码零 diff；`task489`、`task488`、`task487`、`task451` 在 3001 均通过，其中 `task487` 为 `transport=local-folder-events`、PageTree/FileTree 外部创建/删除均 `treeLiveApplied=resync`、导航数为 0。
  - 未迁：`hovered_block_from_target` 的壳层函数、`drop_indicator_from_target`、拖拽 listener、block reorder 行为仍留在 `lib.rs`。
- 2026-05-25：Batch AD 采用 3 个独立 worktree worker（B/C/D），符合当前 goal 每批最多 4 个 worker 的上限；任务书均写入各 worktree `tmp/`，未新增主工作区 `.codex/reasonix-tasks`。
  - 涉及 worktree：`/mnt/Data1T/mnote-worktrees/0525-ad-worker-b-5-29-drop-indicator-block-rect`、`/mnt/Data1T/mnote-worktrees/0525-ad-worker-c-3-20-upload-target-readonly`、`/mnt/Data1T/mnote-worktrees/0525-ad-worker-d-regression-smoke`。
  - Worker B run `reasonix-2026-05-24T23-05-57-072Z-aa9927f0` 仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`；Reasonix 结论拒收。Codex 仅把 worktree 中的两文件 diff 当作候选 patch 独立复核，确认范围只涉及 `drop_indicator_from_target` 内部 block/stage rect 读取封装后选择性合入。
  - 修改：`editor_runtime/block_dnd.rs` 新增 `drop_indicator_from_block_rects(block_index, block, stage, client_y)`；`lib.rs::drop_indicator_from_target` 仍负责 hovered block、root/stage DOM 查询和 shell 状态，只委托新 helper 计算 `DropIndicatorState`。
  - 边界：未迁 `drop_indicator_from_target` 壳层函数、`drop_indicator_from_point`、拖拽 listener、block reorder 行为或 Leptos signal 编排；Worker C/D 输出不采纳。
  - Worker D run `reasonix-2026-05-24T23-05-57-257Z-c917f1ef` 有完整 `process-handoff.md/json`、`result.json`、`final.md`，源码零 diff；`task489`、`task488`、`task487`、`task451` 在 3001 均通过。
  - Codex 已读取 Hindsight recall 与 handoff/result，并独立复跑主控验收。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`git diff --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task487-local-folder-tree-live-consumer-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js`。
- 2026-05-25：Batch AE 采用 4 个独立 worktree worker，符合当前 goal 每批最多 4 个 worker 的上限；任务书均写入各 worktree `tmp/`，未新增主工作区 `.codex/reasonix-tasks`。
  - Worker A `/mnt/Data1T/mnote-worktrees/0525-ae-worker-a-5-29-handle-corridor-rects`，run `reasonix-2026-05-24T23-18-29-397Z-f4574b43` 仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 `final.md`、`result.json`、`process-handoff.md/json`；worktree 有候选 diff 和未跟踪 `reference-code` symlink，Reasonix 结论拒收。候选 diff 将 `handle_lane_left` 及一组 content column 常量复制到 `block_dnd.rs`，主控暂不采纳，避免在未完整 handoff 情况下引入第二份布局常量。
  - Worker B `/mnt/Data1T/mnote-worktrees/0525-ae-worker-b-5-29-overlay-readonly`，run `reasonix-2026-05-24T23-18-29-427Z-8bb6f43e` 有完整 `process-handoff.md/json`、`result.json`、`final.md`，源码零 diff；审计结论经主控复核后作为下一刀参考：table/image overlay anchor、`block_label_for_element`、`target_element` 等仍可继续拆，event listener / host bridge / `on_selection_change` 继续留在 `lib.rs`。
  - Worker C `/mnt/Data1T/mnote-worktrees/0525-ae-worker-c-3-20-upload-target-readonly`，run `reasonix-2026-05-24T23-18-29-419Z-3e999c4d` 有完整 handoff/result，源码零 diff；结论归 3-20 事实源：`resolveFileTreeUploadTarget` 暂不迁，`refreshLocalFolderSidebarSnapshot` 仍留 shell，append/reveal 系列已足够外置。
  - Worker D `/mnt/Data1T/mnote-worktrees/0525-ae-worker-d-regression-smoke`，run `reasonix-2026-05-24T23-18-29-435Z-3225d16e` 串线执行成 Worker B overlay 审计，未运行 smoke；本轮 smoke worker 输出拒收。
  - Codex 主控基于 Worker B 审计和本地 `rg` 复核完成低风险机械切片：新增 `editor_runtime/dom_events.rs`，迁入 `target_element(target)` 与 `event_target_matches_selector(target, selector)`；`lib.rs` 通过 import 继续调用，不改事件 listener、图片 toolbar、block hover、DnD 或 overlay 编排。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_events.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AF 未派发 Reasonix worker；基于 Batch AE Worker B 只读审计和 CodeGraph/`rg` 本地复核，主控完成 table overlay 小切片。
  - 修改：`editor_runtime/overlays.rs` 新增 `table_overlay_anchor_from_table`、`current_table_overlay_anchor`、`table_row_aux_style`、`table_col_aux_style`；`lib.rs` 删除同名实现并通过 import 继续调用。
  - 边界：未迁 table selection signal、row/column click handler、overlay DOM view 或 `table_selection_overlay_style`；本批只外置表格 overlay anchor / aux style 的纯 DOM rect 与 CSS 计算。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AG 未派发 Reasonix worker；主控本地完成 block label helper 小切片。
  - 修改：`editor_runtime/block_hover_state.rs` 新增 `block_label_for_element(block)`；`lib.rs` 删除同名实现并通过 import 继续调用。
  - 边界：未迁 `block_state_from_index`、`hovered_block_from_target`、DOM listener 或 block menu signal；本批只外置 Element -> block label 的纯映射。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3013 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3013 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3013 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3013 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3013 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AH 未派发 Reasonix worker；主控本地完成 table selection overlay style 小切片。
  - 修改：`editor_runtime/overlays.rs` 新增 `table_selection_overlay_style(anchor, selection)`；`lib.rs` 删除同名实现并通过 import 继续调用。
  - 边界：未迁 table selection signal、row/column click handler、overlay DOM view、`current_table_overlay_anchor` 之外的 table 控件编排或 listener；本批只外置 `TableOverlayAnchor + TableSelectionOverlayState -> CSS style` 的纯样式计算。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3015 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3015 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3015 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3015 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3015 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AI 派发 1 个只读 Reasonix worker 审计 `hovered_block_from_target` / `drop_indicator_from_target` 的下一刀边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-ai-worker-a-5-29-dnd-boundary-readonly`，run id `reasonix-2026-05-25T00-03-35-386Z-3c494bf2`，显式 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、worktree `process-handoff.md`，并核对 worktree `git diff --stat` / `git status --short` 仅有 handoff 文件；runner 未生成完整 `result.json` / `final.md` / `process-handoff.json`，因此不按完整 Reasonix handoff 采纳，只把只读结论作为审计输入。
  - 审计结论经主控复核后采纳：`hovered_block_from_target` / `drop_indicator_from_target` 的 listener 壳层与 signal 编排仍留在 `lib.rs`；下一刀优先迁 `block_state_from_index(index)`，因为它是 9 个调用方共享的纯 DOM/rect -> `HoveredBlockState` 投影逻辑。
  - Codex 主控完成最小机械切片：`editor_runtime/block_dnd.rs` 新增 `block_state_from_index(index)`，承接 root/stage/block rect 与 `block_label_for_element` 计算；`lib.rs` 的同名函数退化为薄 wrapper，继续供现有 hover/keyboard/mindmap 调用链使用。
  - 边界：未迁 `hovered_block_from_target`、`drop_indicator_from_target`、`drop_indicator_from_point`、drag/drop listener、keyboard signal 分支或 block reorder 行为；本批只外置共享 block state projection。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3017 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3017 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3017 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3017 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3017 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AI 只派发 1 个只读 Reasonix worker 审计 `handle_lane_left` / block DnD 几何边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-ai-worker-a-5-29-handle-lane-readonly`，run id `reasonix-2026-05-25T00-04-47-885Z-b85d144f`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`，并核对 worktree `git status --short` / `git diff --stat` 为空；过程中发现另一组未纳入本批的旧 `0525-ai-worker-a-5-29-dnd-boundary-readonly` runner / ACP 仍在运行，主控已终止，不采纳其任何输出。
  - 审计结论经 Codex 复核后采纳：`handle_lane_left(stage_rect_width)` 属于 editor layout helper，不应迁入 `editor_runtime/block_dnd.rs`；若继续推进 DnD 边界，下一刀应迁 `pointer_in_handle_corridor` 这一层 DOM 查询包装，而不是复制 `CONTENT_COLUMN_*` / `HANDLE_*` 常量。
  - Codex 主控完成后续小切片：`editor_runtime/block_dnd.rs` 新增 `pointer_in_handle_corridor(client_x, client_y, block, handle_selector, handle_left_fallback, handle_width)`，承接 block/stage/handle DOM 查询与 `HandleCorridorGeometry` 组装；`lib.rs` 删除同名 wrapper，调用点改为显式委托 `block_dnd` helper，并继续由壳层传入 `handle_lane_left(stage_rect.width())` fallback，不复制布局常量。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3018 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3018 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3018 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3018 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3018 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch BB 由 Codex 主控按当前 goal 明确派发 4 个独立 worktree worker；其中 5-29 侧 Worker A 只产出候选 patch，最终未直接采纳。
  - Worker A `/mnt/Data1T/mnote-worktrees/0525-af-worker-a-5-29-block-label-helper`，run `reasonix-2026-05-24T23-33-43-253Z-8083f267` 有完整 `process-handoff.md/json`、`result.json`、`final.md`，worktree diff 只涉及 `block_label_for_element` 从 `lib.rs` 迁到 `editor_runtime/block_dnd.rs`。主控读取 Hindsight recall、handoff 与 diff 后裁决：不直接采纳该候选 patch，因为当前主工作区已存在更贴近 `HoveredBlockState` 所属边界的本地实现，`block_label_for_element` 已迁入 `editor_runtime/block_hover_state.rs`，与该候选的 `block_dnd.rs` 归属不同。
  - 采纳规则执行：本批不把 Worker A diff 合入主工作区，只把它作为“block label helper 已适合迁出 `lib.rs`”的旁证；实际主链以后续主控本地切片 `block_hover_state.rs` 为准，不重复记录第二条实现真相。
  - 本批 5-29 结论：`block_label_for_element` 已完成从 `lib.rs` 迁出，但应归 `block_hover_state` 而非 `block_dnd`；后续 5-29 Reasonix 实现 worker 如涉及同一区域，必须先避开主工作区现有未提交 Rust 改动，再由 Codex 复核合并。
- 2026-05-25：Batch AJ 未派发 Reasonix worker；主控直接收口 `hovered_block_from_target` 的共享 DnD/hover 解析层。
  - 修改：`editor_runtime/block_dnd.rs` 新增 `hovered_block_from_target(target, root, handle_selector)`，承接 `target_element`、handle shell 过滤、direct block index 解析和 `block_state_from_index(index)` 委托；`lib.rs` 的同名函数退化为只负责获取 `editor_root_element()` 后调用 runtime helper。
  - 边界：未迁 `hovered_block_from_selection`、`drop_indicator_from_target`、`drop_indicator_from_point`、drag/drop listener、keyboard signal 分支或 block reorder 行为；本批只外置共享 target -> `HoveredBlockState` 解析层。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3020 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3020 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3020 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3020 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3020 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AM 只派发 1 个只读 Reasonix worker 审计 `hovered_block_from_selection` / `slash_menu_anchor_style` 的下一刀边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-am-worker-a-5-29-selection-anchor-readonly`，run id `reasonix-2026-05-25T00-26-34-892Z-8f7e4a81`，并显式使用 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对 worktree `git status --short` 为空；Reasonix 未修改源码。
  - 审计结论经 Codex 复核后采纳：`hovered_block_from_selection` 不适合迁入 `editor_runtime/block_dnd.rs`，更合理的下一刀是把“selection 锚点 -> 顶层块 index”抽成 `editor_runtime/dom_selection.rs` 中的纯 helper，再继续由 `lib.rs` 组装 `HoveredBlockState`。
  - Codex 主控完成最小机械切片：`editor_runtime/dom_selection.rs` 新增 `block_index_from_selection()`，封装 selection anchor、element、root、direct block 与 top-level index 解析；`lib.rs::hovered_block_from_selection` 退化为 `block_index_from_selection().and_then(block_state_from_index)`。
  - 边界：未迁 `HoveredBlockState` 本身、`slash_menu_anchor_style`、viewport clamp、`drop_indicator_from_target`、拖拽 listener、keyboard signal 分支或 block reorder 行为；本批只外置 selection -> block index 解析层。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Codex 主控继续收口 `slash_menu_anchor_style` 的纯 overlay helper。
  - 修改：`editor_runtime/overlays.rs` 新增 `selection_bounding_rect()`、`viewport_dimensions()`、`clamp_overlay_anchor(...)`；`lib.rs::slash_menu_anchor_style` 改为复用 selection rect helper 与位置 clamp helper，仍保留 fallback 到 `hovered_block_from_selection()`、`editor_stage_element()` 与 `content_text_left(stage_rect.width())` 的壳层编排。
  - 边界：未迁 `slash_menu_anchor_style` 整体、`content_text_left`、hovered block fallback 计算、DOM listener、overlay signal 或 slash menu 行为；本批只外置 selection rect / viewport / clamp 纯计算层。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：主控重新验证当前未提交 `5-29` 切片，确认可作为独立批次继续推进。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`、`codegraph sync .`、`codegraph status . --json`。
  - 结果：上述命令全部通过，CodeGraph `pendingChanges=0`；当前主工作区只保留本批 `dom_selection.rs` / `overlays.rs` / `lib.rs` 与生成物改动，不再混入新的实现写集。
- 2026-05-25：Batch BA 计划只派发 1 个只读 Reasonix worker 审计 `slash_menu_anchor_style` 剩余 fallback 与 DnD 边界。
  - 目标：判断 `hovered_block_from_selection` fallback 几何、`content_text_left(stage_rect.width())`、`drop_indicator_from_point` 当前是否还有可继续外置的纯 helper，避免在 `lib.rs` 残留第二套 overlay / DnD 几何路径。
  - 约束：只读、独立 worktree、源码零 diff；不得建议迁 listener、signal 编排、`HANDLE_SHELL_SELECTOR` 常量或 block reorder 行为。
- 2026-05-25：Batch BA 只派发 1 个只读 Reasonix worker 审计 `slash_menu_anchor_style` 剩余 fallback 与 DnD 边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-ba-worker-b-5-29-slash-drop-readonly`，run id `reasonix-2026-05-25T00-47-26-272Z-dbfa4fc7`，显式 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对 worktree `git status --short` / `git diff --stat` 为空；worker 未修改源码。
  - 审计结论经主控复核后采纳：`drop_indicator_from_point` / `drop_indicator_from_target` 当前已经充分收口，`lib.rs` 中仅剩 `HANDLE_SHELL_SELECTOR` 注入薄壳；`slash_menu_anchor_style` 本体不宜整体迁出，但 `image_toolbar_anchor_from_image` / `image_element_from_target` 是下一刀最合适的纯 DOM/几何 helper。
  - 当前决定：按该结论继续推进最小机械切片，只迁 `image toolbar` 相关 helper，不扩散到 overlay signal 编排、listener、`content_text_left` 共享布局模块或 `drop_indicator_*` 壳层。
- 2026-05-25：Codex 主控按 Batch BA 审计结论完成 `image toolbar` 纯 helper 小切片。
  - 修改：`editor_runtime/overlays.rs` 新增 `image_toolbar_anchor_from_image(image)`、`image_element_from_target(target)`；`lib.rs` 删除同名实现，仅保留调用点和 image toolbar 打开编排。
  - 边界：未迁 `open_image_toolbar_overlay`、image toolbar signal 编排、DOM listener、`slash_menu_anchor_style` 本体、`content_text_left` 共享布局常量或 `drop_indicator_*` 壳层；本批只外置 image target 解析与 image toolbar anchor 几何。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：Batch AK 派发 1 个只读 Reasonix worker 审计 `drop_indicator_from_target` / `drop_indicator_from_point` 的最小外置边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-ak-worker-a-5-29-drop-indicator-readonly`，run id `reasonix-2026-05-25T00-23-12-071Z-5cb35e3f`，显式 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`，并核对 worktree `git status --short` / `git diff --stat` 为空；只读结论经主控复核后采纳。
  - 审计结论：`drop_indicator_from_target` 已具备迁入 `editor_runtime/block_dnd.rs` 的条件，`drop_indicator_from_point` 可同刀迁出；`hovered_block_from_target` 的 hover listener 壳与现有 drag/drop 调用点暂留 `lib.rs`，通过 `HANDLE_SHELL_SELECTOR` 参数注入 runtime helper。
  - Codex 主控完成最小机械切片：`editor_runtime/block_dnd.rs` 新增 `drop_indicator_from_target(target, client_y, handle_selector)`、`drop_indicator_from_point(client_x, client_y, handle_selector)`；`lib.rs` 同名函数退化为只透传 `HANDLE_SHELL_SELECTOR` 的薄壳，不扩散 drag/drop listener 或 block reorder 调用点。
  - 边界：未迁 `hovered_block_from_selection`、drag/drop listener、keyboard signal 分支、block reorder 行为或 `HANDLE_SHELL_SELECTOR` 常量定义；本批只外置 drop indicator 的 target/point 解析 helper。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3032 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3032 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3032 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3032 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3032 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
- 2026-05-25：主控对当前未提交 `5-29` 切片重新做 fresh 验证，确认这批仍可独立提交。
  - 切片范围：`editor_runtime/dom_selection.rs` 新增 `block_index_from_selection()`；`editor_runtime/overlays.rs` 新增 `selection_bounding_rect()`、`viewport_dimensions()`、`clamp_overlay_anchor(...)`；`lib.rs` 的 `hovered_block_from_selection` / `slash_menu_anchor_style` 退化为调用上述 helper 的壳层编排；生成物只更新 `generated/island` 对应 `js/wasm`。
  - 本轮 fresh 验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`wasm-bindgen --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3021 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3021 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3021 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3021 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3021 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 结果：上述命令全部通过；`task479` 确认附件生命周期、主编辑区附件缺失态、文件树打开附件和“文件名作为本地 Markdown 默认页头标题”的基线行为未被本批回归。
- 2026-05-25：Batch BB 只派发 1 个只读 Reasonix worker 审计 `slash_menu_anchor_style()` 剩余 fallback 是否还有可继续外置的纯几何 helper 边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-bb-worker-b-5-29-slash-fallback-readonly`，run id `reasonix-2026-05-25T00-57-16-369Z-153f8ae2`，显式 `--no-memory-recall`。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对该 worktree 源码 `git diff --stat` 为空；worktree 中仅新增 `final.md`、`process-handoff.*`、`result.json` 等审计产物，不视为源码修改。
  - 该 run 违反任务边界：worker 把 `3-20` 与 `5-29` 两个只读审计混成一份总体报告，因此不作为正式 handoff 全量采纳。
  - 当时主控根据其 `5-29` 线索做了本地代码复核，判断 `content_text_left()` / 内容列布局常量若要统一，应另起独立收口，而不是继续从 `slash_menu_anchor_style()` fallback 中抽 3-5 行几何包装。
- 2026-05-25：Batch BC 派发 1 个 browser smoke Reasonix worker 在当前 head 做只读回归，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-bc-worker-b-smoke-head-readonly`，预期 run id `reasonix-2026-05-25T01-03-07-032Z-a487a063`，显式 `--no-memory-recall`。
  - 结果拒收：该 run 仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，无 `result.json`、`process-handoff.md/json`、`final.md`；worktree 源码零 diff。
  - 处置：不采纳其 smoke 结论；后续如需浏览器验收，仍需由主控亲自复跑，或重新派发受控 smoke worker。
- 2026-05-25：Batch BE 由 Codex 主控为 `5-29` 侧追加 1 个独立 worktree 只读审计 worker `/mnt/Data1T/mnote-worktrees/0525-be-worker-d-5-29-layout-constant-readonly`。
  - 目标：不再复述 `slash_menu_anchor_style()` fallback，而是只回答 `content_text_left()` / 内容列布局常量 是否值得作为下一刀独立 design 或只读收口主题。
  - 约束：任务书写入该 worktree `tmp/`；禁止修改源码、禁止 `.codex/reasonix-tasks/*`、禁止子 agent。Codex 仅在拿到 Hindsight recall、`process-handoff.md/json`、`result.json` 与源码零 diff 证据后才会裁决是否采纳。
- 2026-05-25：Batch BE 的 5-29 侧 Worker D `/mnt/Data1T/mnote-worktrees/0525-be-worker-d-5-29-layout-constant-readonly` 已由 Codex 主控独立复核后采纳为方向证据。
  - Codex 已读取 Hindsight recall、`process-handoff.md/json`、`result.json`，并核对该 worktree 源码零 diff；worktree 中仅新增 `final.md`、`process-handoff.*`、`result.json` 等审计产物，不视为源码修改。
  - 主控本地代码证据与只读结论在当时一致：`content_text_left()` / `content_column_left()` / `content_column_width()` 与相关 `CONTENT_COLUMN_*` 常量曾分别留在 `lib.rs` 与 `block_menu_overlay.rs` 两处。
  - 后续真实代码已完成这条收口：提交 `12b64935` / `0a15ede8` 新增 [content_layout.rs](/mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/src/editor_runtime/content_layout.rs:1)，并让 [block_menu_overlay.rs](/mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_overlay.rs:11) 与 [lib.rs](/mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/src/lib.rs:43) 共同复用 `content_text_left()` / `content_column_left()`。因此这条“是否值得统一”的方向问题已经被真实实现关闭，不再作为后续待办。
- 2026-05-25：Batch BF 只派发 1 个只读 Reasonix worker 审计 `selection_payload / send_selection_state_to_target` 的下一刀边界，使用独立 worktree `/mnt/Data1T/mnote-worktrees/0525-bf-worker-a-5-29-selection-payload-readonly`，run id `reasonix-2026-05-25T01-11-58-275Z-2b2e8a66`，显式 `--no-memory-recall`。
  - 结果拒收：该 run 仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`，没有 `result.json`、`process-handoff.md/json`、`final.md`；worktree 源码零 diff。
  - 过程异常：主控在等待 BF run 期间发现未批准 residual runner 自动启动了 Batch BE 的 4 个 worker（`0525-be-*`），已统一终止并拒收；在当前 2-worker 上限下，后续不再采纳任何未明确派发的 run。
  - 主控本地代码结论：`SelectionPayload`、`block_id_from_element`、`block_id_from_json_node`、`runtime_block_id_from_index`、`selection_payload` 已经落在 `editor_runtime/dom_selection.rs` 的合理边界内，继续迁出收益有限；`dispatch_selection_event_to_target`、`send_selection_state_to_target`、`on_selection_change` 仍绑定 `EventTarget`、Leptos signal、overlay 同步与 editor lifecycle，必须留在 `lib.rs` 壳层。
  - 最小下一刀建议：若继续推进，只做 `current_block_info_from_index()` 的单刀收口，把它与 `runtime_block_id_from_index()` 组合成 `dom_selection` 中的轻量 block info helper，供 runtime state / host status / selection bridge 共用；不要继续触碰 `send_selection_state_to_target` 或把 bridge dispatch 下沉进 runtime 模块。
- 2026-05-25：Codex 主控已按上述建议创建新的 clean candidate worktree `/mnt/Data1T/mnote-worktrees/0525-bg-worker-a-5-29-current-block-info`，从 `0a15ede8` 起步独立复现 `current_block_info_from_index()` 小切片。
  - 当前 clean diff：仅修改 [dom_selection.rs](/mnt/Data1T/mnote-worktrees/0525-bg-worker-a-5-29-current-block-info/rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs:23)，新增 `CurrentBlockInfo` 与 `current_block_info_from_index(index)`；其余源码不动。worktree 中为满足 path 依赖额外创建了本地 `reference-code` 符号链接，仅用于验证环境，不作为源码变更。
  - 已验证：`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release` 均在该 clean worktree 中通过。
  - 含义：`current_block_info_from_index()` 已经从“主区未提交半成品”转成“独立 worktree 的可复核候选 patch”，下一步可补 wasm-bindgen / browser smoke 后再选择性合入。
- 2026-05-25：Codex 主控按 Batch BF 结论完成 `current_block_info_from_index()` 最小切片。
  - 修改：`rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs` 新增 `CurrentBlockInfo` 与 `current_block_info_from_index(index)`；`rust/spikes/leptos-tiptap-spike/src/lib.rs` 删除本地 `CurrentBlockInfo` 与同名 helper，改为复用 runtime helper。
  - 边界：未迁 `dispatch_selection_event_to_target`、`send_selection_state_to_target`、`on_selection_change`、`selection_event_target` 或任何 bridge dispatch；本批只收口 selection 数据层的 block info helper。
  - 已验证：`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`wasm-bindgen rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island`、`MNOTE_WEB_BIND=127.0.0.1:3034 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3034 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3034 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3034 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3034 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 浏览器证据：`tmp/0525-selection-payload-slice-workspace.png` 展示 3034 当前源码服务登录后工作区首屏；本轮使用 Playwright 只读截图替代 `browser-use`，原因是 in-app browser `iab` backend 当前不可用。
- 2026-05-25：Codex 主控继续收口共享内容列布局 helper，去掉 `lib.rs` 与 `block_menu_overlay.rs` 的重复常量与几何函数。
  - 修改：新增 `rust/spikes/leptos-tiptap-spike/src/editor_runtime/content_layout.rs`，迁入 `content_column_width()`、`content_column_left()`、`content_text_left()` 及对应常量；`editor_runtime/block_menu_overlay.rs` 与 `lib.rs` 改为复用该共享模块，`lib.rs` 仅保留 `handle_lane_left()` 这一层 handle 专属偏移计算。
  - 边界：未迁 `handle_lane_left()`、`HANDLE_*` 常量、`slash_menu_anchor_style()`、drop indicator 壳层、block menu overlay 自身布局策略或 DOM 查询；本批只消除内容列布局 helper 的重复定义。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`wasm-bindgen --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3023 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3023 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3023 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3023 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3023 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 结果：`task489`、`task488`、`task479` 均通过，说明共享布局 helper 外置未破坏块菜单删除/撤销、附件删除/撤销和本地 Markdown 附件生命周期基线。
- 2026-05-25：Codex 主控完成 `selection payload / bridge` 线的最小后续刀。
  - 修改：`editor_runtime/dom_selection.rs` 新增 `CurrentBlockInfo` 与 `current_block_info_from_index(index)`，把 `index + runtime_block_id_from_index(index)` 的纯数据组合收口到 selection runtime；`lib.rs` 后续只负责 bridge dispatch、Leptos signal 和 editor lifecycle 壳层。
  - 边界：未迁 `dispatch_selection_event_to_target`、`send_selection_state_to_target`、`on_selection_change`、`selection_event_target` 或 overlay sync；这些仍绑定 `EventTarget`、CustomEvent、Leptos signal 和 Tiptap lifecycle。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`git diff --check -- rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs rust/spikes/leptos-tiptap-spike/src/lib.rs`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`wasm-bindgen rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3026 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3026 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3026 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3026 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3026 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 结果：三条 smoke 均通过；本批继续保持 selection payload 纯数据层与 bridge dispatch 壳层分离。
- 2026-05-25：Codex 主控按 Batch BF 的最小下一刀建议，继续收口 `current_block_info_from_index()`。
  - 修改：`editor_runtime/dom_selection.rs` 新增 `CurrentBlockInfo` 与 `current_block_info_from_index(index)`，把 `current_block_index + runtime_block_id_from_index()` 的轻量 block info 组装迁入 selection runtime；`lib.rs` 删除本地 `CurrentBlockInfo` 结构与同名 helper，改为复用 runtime helper。
  - 边界：未迁 `selection_payload`、`dispatch_selection_event_to_target`、`send_selection_state_to_target`、`on_selection_change` 或任何 bridge dispatch；本批只收口 “index -> {index, block_id}” 的轻量数据 helper。
  - 影响点：`HostCommandKind::RequestCurrentBlockId` 分支继续在 `lib.rs` 壳层里取 hovered block index，但由 `dom_selection::current_block_info_from_index()` 返回 `block_id`；其余 selection event / runtime state 路径不变。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`wasm-bindgen --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3025 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3025 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3025 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3025 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3025 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。
  - 结果：`task489`、`task488`、`task479` 均通过，说明当前块信息 helper 下沉未破坏块菜单删除/撤销、附件删除/撤销和本地 Markdown 附件生命周期基线。
- 2026-05-25：Codex 主控复核 `image_toolbar_anchor_from_image` / `image_element_from_target` 候选，确认当前代码已在 `editor_runtime/overlays.rs` 中完成，不再重复拆分。
  - 代码证据：`editor_runtime/overlays.rs` 已定义 `ImageToolbarAnchor`、`image_toolbar_anchor_from_image(image)` 与 `image_element_from_target(target)`；`lib.rs` 只保留 click handler 壳层，负责选择图片节点、设置 editor focused 和打开 image toolbar overlay。
  - 决定：该候选从后续待办移除；继续改找仍留在 `lib.rs` 的小型 DOM event helper。
- 2026-05-25：Codex 主控完成菜单滚轮拦截 helper 下沉。
  - 修改：`editor_runtime/dom_events.rs` 新增 `current_target_html_element(event)` 与 `trap_scroll_inside_menu(event)`；`lib.rs` 删除本地同名实现，菜单 `on:wheel` 调用改为复用 `dom_events` helper。
  - 边界：未迁 block menu / slash menu / turn-into menu 的 Leptos view、signal、命令执行、focus 或 overlay 状态；本批只迁滚轮事件的 prevent/stop 与局部 scrollTop clamp。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`。
  - 结果：spike check/build 均通过；仍有既有 unused/dead_code warning，本批未触碰这些历史 warning。

- 2026-05-25（Reasonix 第一批）：修复测试阻断 + toolbar overlay 外置。
  - STYLE 测试修复：`STYLE` → `SPIKE_STYLE` + `block_dnd` 测试坐标语义修正。`cargo test` 从编译失败恢复为 13/13 全部通过。
  - `should_auto_close_toolbar_overlays` 迁入 `editor_runtime/overlays.rs`（7 信号判定），`lib.rs` Effect 委托调用。

- 2026-05-25（Reasonix 第二批）：`mindmap_node_view.rs` 完整提取。
  - 从 `lib.rs` 迁出 ~877 行 mindmap 代码至 `editor_runtime/mindmap_node_view.rs`（新增模块 909 行）。
  - 内容：5 个 event 常量、11 个 Shell 类型 struct、5 个 payload struct、dispatch helper、渲染函数、`MindmapShell` 组件（~500 行 Leptos）、mount/unmount 注册表。
  - `#[wasm_bindgen]` 保留在 `lib.rs` 作为薄包装器（`mount_mindmap_shell` / `unmount_mindmap_shell` 各 1 行委托）。
  - `next_mount_id` 改为 `pub(crate)` 共享。
  - 已验证：`cargo check`、`cargo build --target wasm32-unknown-unknown --release`。

- 2026-05-25（Reasonix 第三批）：`bridge_events.rs` 类型层提取。
  - 从 `lib.rs` 迁出事件常量（12 个）和 payload 类型（11 个 struct）至 `editor_runtime/bridge_events.rs`（149 行）。
  - dispatch 函数（`dispatch_runtime_event`、`dispatch_runtime_state` 等）保留在 `lib.rs`（与信号/overlay 耦合度高）。
  - lib.rs 改为 `use editor_runtime::bridge_events::{...}`` 命名导入。
  - 已验证：`cargo check`、`cargo build --target wasm32-unknown-unknown --release`。

- 2026-05-25（Reasonix 第四批）：HTML 整文替换审计。
  - 确认 `apply_html_update` 从 3 条路径调用（拖拽重排×2 + 拷贝副本），均通过 `editor.set_content(TiptapContent::html(...))` 破坏 undo history。
  - `apply_document_update` 是死代码（零调用方）。
  - `history_safe_commands.rs` 已有 `delete_top_level_block_with_history` / `delete_selected_attachment_link_with_history` 可复用模式。
  - 建议：实现 `move_top_level_block_with_history` 和 `duplicate_top_level_block_with_history`。

## 7. 5-29 阶段完成状态

> 注：本节记录 5-29 归档时的阶段状态。后续 `design/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md` 已继续拆分 `leptos-tiptap-spike/src/lib.rs`，当前根文件已降到 5,000 行以下。

### 文件规模变化

| 文件 | 原大小 | 现大小 | 变化 |
|------|--------|--------|------|
| `lib.rs` | 9,873 行 | 7,951 行 | **-19%** |
| `editor_runtime/mindmap_node_view.rs` | — | 906 行 | 新建 |
| `editor_runtime/bridge_events.rs` | — | 154 行 | 新建 |
| `editor_runtime/slash_actions.rs` | — | 237 行 | 新建 |
| `editor_runtime/table_commands.rs` | — | 180 行 | 新建 |
| `editor_runtime/table_toolbar_view.rs` | — | 371 行 | 新建 |
| `editor_runtime/bridge_dispatch.rs` | — | 86 行 | 新建 |

### editor_runtime/ 最终模块清单（20 模块，另有 `mod.rs`）

| 模块 | 说明 | 来源 |
|------|------|------|
| `attachment_links.rs` | 附件链接识别 | 5-28 P1 |
| `attachment_upload.rs` | 上传 intent | 5-28 P3 |
| `block_dnd.rs` | 块拖拽几何 | 5-29 |
| `block_hover_state.rs` | HoveredBlockState 共享类型 | 5-29 |
| `block_menu_document.rs` | legacy JSON helper | 5-29 |
| `block_menu_overlay.rs` | block menu 几何 | 5-29 |
| `bridge_dispatch.rs` | host command kind 解析 | **本批新建** |
| `bridge_events.rs` | 事件常量 + payload 类型 | **本批新建** |
| `command_sync.rs` | 命令同步 | 5-28 P2 |
| `content_layout.rs` | 内容布局 | 5-29 |
| `dom_events.rs` | DOM 事件工具 | 5-29 |
| `dom_selection.rs` | 选区查询 | 5-29 |
| `editor_focus.rs` | focus 管理 | 5-29 |
| `history_safe_commands.rs` | history-safe 命令 | 5-28 P1 |
| `mindmap_node_view.rs` | mindmap shell 完整实现 | **本批新建**（5-28 P5） |
| `overlays.rs` | overlay 管理 | 5-29 |
| `persistence.rs` | 持久化 | 5-28 P2 |
| `slash_actions.rs` | slash 菜单 action 数据 | **本批新建** |
| `table_commands.rs` | table toolbar / option 命令 | **本批新建** |
| `table_toolbar_view.rs` | table controls / toolbar / options view | **本批新建** |

### 未完成（后续独立任务）

| 项 | 说明 |
|----|------|
| `bridge_events` dispatch 函数外置 | `dispatch_runtime_event`/`dispatch_runtime_state` 等与信号耦合，暂留 lib.rs |
- 2026-05-25：Reasonix 独立收口完成。更改本 checklist 状态为 `done`。
  - STYLE 测试修复：`STYLE` → `SPIKE_STYLE` 引用修复 + `block_dnd` 测试坐标语义修正，`cargo test` 13/13 全部通过。
  - Toolbar auto-close Effect 外置：`should_auto_close_toolbar_overlays` 迁入 `editor_runtime/overlays.rs`，`lib.rs` Effect 委托调用。
  - HTML 整文替换审计（Worker C）：完成。`apply_html_update` 从 3 条路径被调用（拖拽重排×2 + 拷贝副本），均破坏 undo history。`apply_document_update` 是死代码。`history_safe_commands.rs` 已有可复用模式。
  - 浏览器 smoke 基线（Worker D）：task488、task489、task479 全部 PASS。
  - 已验证：`cargo fmt --check`, `cargo check -p mnote-leptos-tiptap-spike`, `cargo build --target wasm32-unknown-unknown --release`, `cargo test (13/13)`。
  - 未迁移（有意保留的 shell 编排）：`try_sync_editor_overlay_state` 和 `sync_overlays_on_selection_change` 已在 `overlays.rs` 中。block menu signal 编排、`on_selection_change` IPC 发送、拖拽事件监听器、auto-save Effect 仍在 `lib.rs`。
- 2026-05-25：Codex 复核 Reasonix “未激活”结论后完成实际激活与 history-safe 收口。
  - `editor_runtime/mod.rs` 正式注册 `mindmap_node_view.rs` 与 `bridge_events.rs`；`lib.rs` 删除重复 mindmap shell / bridge payload 代码，`mount_mindmap_shell` / `unmount_mindmap_shell` 保留为 `wasm_bindgen` 薄包装。
  - 拖拽重排两条路径与块菜单“拷贝副本”不再读取/写回整文 HTML，改为 `move_top_level_block_with_history` / `duplicate_top_level_block_with_history` + `sync_persisted_editor_command`。
  - 删除本轮变成无调用方的 `block_menu_legacy_html.rs` 与 `apply_html_update`，generated island JS/WASM 已重新生成。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`wasm-bindgen --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm`、`task489`、`task488`、`task479`、临时 Playwright 拷贝副本 undo/redo + 块拖拽重排回归。
- 2026-05-25：Codex 继续完成低风险模块提取。
  - 新增 `slash_actions.rs`，迁出 `SlashActionKind` / `SlashAction` / `SLASH_ACTIONS`，`lib.rs` 继续持有 slash 命令执行与 Leptos view。
  - 新增 `table_commands.rs`，迁出 table toolbar / option action、命令执行和 checked 状态计算。
  - 新增 `bridge_dispatch.rs`，迁出 `HostCommandKind` 及 host command payload 解析；真实 command 执行 match 仍留在 `lib.rs`。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml command -- --test-threads=1`、wasm release build、`wasm-bindgen`、task489、task488、task479、临时 slash 插入简单表格 + 表格行 aux 命令 Playwright 回归。
- 2026-05-25：Codex 完成本轮 warning / dead-code 清理。
  - 删除无调用方的 `command_sync::apply_document_update`、`dom_selection::selection_has_rich_marks`，移除 `lib.rs` 中未用 import / 变量。
  - 将 `should_auto_close_toolbar_overlays` 接回两个实际 auto-close 判断点，避免 helper 外置后仍有重复手写判定。
  - 对必须持有生命周期但 Rust 编译器无法直接观察用途的 mount handle、host envelope 反序列化字段加局部 `#[allow(dead_code)]`，不扩大到模块级。
  - 已验证：`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml` 无 warning，`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml -- --test-threads=1` 13/13 通过。
- 2026-05-25：Codex 完成 `table_toolbar_view.rs` 第一刀。
  - 新增 `editor_runtime/table_toolbar_view.rs`，迁出 table controls、table toolbar 和 table options view；`lib.rs` 保留 signal 创建与单一调用点。
  - 边界：表格命令仍由 `table_commands.rs` 提供，持久化同步仍委托 `command_sync::sync_persisted_editor_command`，未修改 Tiptap table bridge 或保存语义。
  - 已验证：`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml -- --test-threads=1` 13/13、wasm release build、`wasm-bindgen`。
  - 浏览器验证：`task158-e30-menu-state-smoke.js` 受旧 Convex mutation `127.0.0.1:3210` 503 阻塞；已用 Playwright 在 `http://127.0.0.1:3000` 登录测试账号后直接设置表格 fixture，确认 table toolbar、options menu、row aux、col aux 均可见。
