归档本轮 P0/P1 bug 修复、设计审查迁移、AI selection scope 收口与 stream contract 调整,并保留当前 05 主线迁移起点。
2.8 KiB
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.rs 的
doc_apply_block_ops()对每个操作调用ensure_allowed_target()。 - block.rs 的单个 block 写工具当前只校验 revision / editable / precondition,缺少同等
allowedTargetBlockIds校验。 - 7-10 已标注“单个
mnote.block.*写工具尚未完成allowedTargetBlockIds矩阵”。
3. 影响
- AI 页面 selection 编辑边界不完整。
markdown_edit和apply_block_ops已拒绝越界写入,但单块工具仍可能成为绕过路径。- ACP / Hermes tool guidance 即使要求 selection 内写入,也缺少 runtime 级强约束。
4. 修复结果
- block.rs 已为
mnote.block.replace、mnote.block.insert_after、mnote.block.delete、mnote.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。