Files
mnote/bugs/07-ai/done/7-27-markdown-edit-full-content-retains-old-blocks-v1.md
T

77 lines
3.3 KiB
Markdown
Raw Normal View History

# 7-27 [done][bug] 在线 markdown_edit full_content 会保留旧普通块
> 发现时间:2026-05-18
>
> 状态:`[done]`
>
> 关联主线:`07-ai`
>
> 关联设计:`design/07-ai/process/7-27-online-markdown-writeback-final-content-truth-v2.md`
## 1. 问题定义
`mnote.doc.markdown_edit` 的在线 Convex 文档路径已经切到 final markdown -> block content 直接写回,但 `full_content` 模式下,最终 markdown 通常不包含任何 `<!-- block:... -->` 原始块注释。
当前 `build_page_content()` 会把所有未处理的原始块追加到写回结果尾部,导致全文替换不是“替换全文”,而是:
```text
新全文块...
旧 heading / paragraph / todo 块...
```
## 2. 影响
- AI 执行全文改写、重写大纲、把页面替换为整理后的内容时,会保留旧正文残留。
- Page Aggregate / `mnote.doc.fetch` 回读会看到新旧内容混在一起。
- 7-27 的“最终 markdown 是唯一写回真源”合同被破坏。
## 3. 根因
`parse_final_markdown_to_blocks()` 对无注释的 final markdown 行会生成 `is_new=true` 块,这是正确的。
问题在 `build_page_content()` 的末尾:
```rust
for original in &original_blocks {
if let Some(id) = block_id_of(original) {
if !processed_ids.contains(&id) {
result.push(original.clone());
}
}
}
```
该逻辑没有区分:
- 部分 search/replace 丢掉某个块注释:应保守保留缺失旧块,避免误删。
- `full_content` / 全文替换没有任何原始块 ID:应只保留复杂块,普通旧文本块应被替换掉。
## 4. 修复
- [doc.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/hermes_tools/doc.rs:727) 给 `build_page_content()` 增加策略:
- 若 parsed 中至少引用了一个原始 block id,则保留未处理原始块,维持安全降级。
- 若 parsed 中没有任何原始 block id,则视为全文重建,只保留复杂块,不保留普通旧文本块。
- [doc.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/hermes_tools/doc.rs:799) 增加 `is_complex_markdown_original_block()`,用于 full_content 重建时保留 resource / mindmap / table / image / attachment / 非 editable / unsupported / 带 children 的复杂块。
- [doc.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/hermes_tools/doc.rs:1059) 增加单元测试:
- `full_content` 无原始 ID 时不保留旧 heading / paragraph。
- 原始 resource 复杂块仍保留。
- 部分块注释丢失时仍保留缺失旧块。
## 5. 验证
```bash
cargo test --manifest-path rust/Cargo.toml -p mnote-web build_page_content -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_markdown_edit_online_full_content_rejects_unsafe_block_mapping -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_markdown_edit -- --nocapture
cargo fmt --manifest-path rust/Cargo.toml --all -- --check
git diff --check -- rust/crates/mnote-web/src/hermes_tools/doc.rs bugs/07-ai/done/7-27-markdown-edit-full-content-retains-old-blocks-v1.md
```
结果:
- `build_page_content` 相关测试:`2 passed`
- `hermes_tools_markdown_edit_online_full_content_rejects_unsafe_block_mapping``1 passed`
- `hermes_tools_markdown_edit` 相关测试:`6 passed`
- Rust workspace format check 通过。
- 相关路径 diff check 通过。