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

2.7 KiB

7-24 [done][bug] 在线 markdown_edit 写回不以最终 Markdown 为真源 v1

发现时间:2026-05-17

状态:[done]

关联主线:07-ai

1. 问题定义

在线 Convex 文档的 mnote.doc.markdown_edit 先在 md 字符串上顺序应用 search/replace,但写回时没有用最终 md 生成新的文档真相,而是重新读取原始 blocks,并用原始 operations 反推 apply_block_ops

因此 markdown 层已经算出的最终结果不一定能被忠实落库。

2. 证据

  • doc.rsmd 上执行 search/replace。
  • doc.rs 写回前重新读取 aggregate / blocks。
  • doc.rs 使用原始 operations 构造 block ops,而不是解析最终 md

3. 影响

  • 跨块替换、全文替换、标题 / 列表格式变化可能在 markdown 层成功,但无法正确转换成 block ops。
  • 部分失败仍可能返回成功写入,用户看到的正文与工具返回摘要不一致。
  • 该问题与 7-17 的同块多操作覆盖同源,但影响面更宽。

4. 建议修复

  • 在线分支应明确选择一种真源:要么最终 md 可被解析并完整生成 EditorBlockDocument,要么限制 markdown_edit 只支持可安全映射的单块操作。
  • 对 full_content、跨块 search/replace、列表/标题变更增加回读一致性测试。
  • route 成功条件必须从“operationsApplied > 0”提升为“Page Aggregate 回读等于预期最终 markdown”。

5. 修复

  • doc.rs 在线分支在 markdown 层命中后重新映射为 block ops;若最终 markdown 变化无法安全映射到可写块,会返回 mnote_doc_markdown_edit_block_mapping_empty,不再把空 operations 交给 apply_block_ops 或返回伪成功。
  • hermes_tools.rs 增加 full_content 在线写回合同测试:当前没有完整 markdown->block 真源写回时必须明确拒绝,不能以 ok=true 伪成功。
  • hermes_tools.rs 保留 markdown 命中但块映射为空的提前失败测试,避免回退到 mnote.doc.apply_block_ops operations 不能为空

6. 验证

  • cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_markdown_edit_online_full_content_rejects_unsafe_block_mapping -- --nocapture
    • 结果:1 passed
  • cargo test --manifest-path rust/Cargo.toml -p mnote-web markdown_edit -- --nocapture
    • 结果:8 passed