Files
mnote/bugs/07-ai/done/7-30-block-tools-selection-scope-not-enforced-v1.md
T
lix-2026 a2cb1338c8 chore: 保存当前架构收口与 bug 修复快照
归档本轮 P0/P1 bug 修复、设计审查迁移、AI selection scope 收口与 stream contract 调整,并保留当前 05 主线迁移起点。
2026-05-18 17:01:35 +08:00

2.8 KiB

7-30 [done][bug] 单个 mnote.block 写工具未强制 selection scope

发现时间:2026-05-18

状态:[done]

关联主线:07-ai

1. 问题定义

mnote.doc.apply_block_ops 已经通过 allowedTargetBlockIds 限制 AI selection 范围内的结构性写入,但单个 mnote.block.replace / mnote.block.insert_after / mnote.block.delete / mnote.block.move_after 写工具没有同等服务端兜底。

这会导致模型或 ACP 调用者在 scope=selection 场景下,绕过批量工具直接调用单块写工具时,仍可能改到 selection 外的块。

2. 证据

  • block.rsdoc_apply_block_ops() 对每个操作调用 ensure_allowed_target()
  • block.rs 的单个 block 写工具当前只校验 revision / editable / precondition,缺少同等 allowedTargetBlockIds 校验。
  • 7-10 已标注“单个 mnote.block.* 写工具尚未完成 allowedTargetBlockIds 矩阵”。

3. 影响

  • AI 页面 selection 编辑边界不完整。
  • markdown_editapply_block_ops 已拒绝越界写入,但单块工具仍可能成为绕过路径。
  • ACP / Hermes tool guidance 即使要求 selection 内写入,也缺少 runtime 级强约束。

4. 修复结果

  • block.rs 已为 mnote.block.replacemnote.block.insert_aftermnote.block.deletemnote.block.move_after 增加统一 allowedTargetBlockIds 服务端校验。
  • move_after 同时校验被移动块和 anchor 块,避免 selection 内块被移动到 selection 外 anchor 后。
  • manifest.rs 已在单块写工具 schema 中公开 allowedTargetBlockIds
  • hermes_tools.rs 已增加回归测试,覆盖单块写工具越界时返回 mnote_block_target_out_of_scope

5. 验证证据

cargo test --manifest-path rust/Cargo.toml -p mnote-web block_tools_selection_scope -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_block -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_manifest -- --nocapture
cargo fmt --manifest-path rust/Cargo.toml --all -- --check

验证结果:

  • RED:修复前 block_tools_selection_scope 失败,越界单块写工具返回 200
  • GREEN:修复后 block_tools_selection_scope 通过:2 passed
  • hermes_tools_block 通过:6 passed
  • hermes_tools_manifest 通过:3 passed