Files
mnote/bugs/07-ai/done/7-27-markdown-edit-full-content-retains-old-blocks-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

77 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 通过。