11 KiB
11 KiB
7-10 [process] 页面块 AI 工具执行 checklist v1
更新时间:2026-05-16
当前状态:
PROCESS。关联文档:
/mnt/Data1T/mnote/design/05-editor-mainline/process/5-13-page-block-identity-and-command-contract-v1.md/mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/process/2-1-page-block-storage-projection-alignment-v1.md/mnt/Data1T/mnote/design/07-ai/process/7-9-page-block-ai-tooling-roadmap-v1.md/mnt/Data1T/mnote/design/07-ai/done/7-6-mnote-hermes-plugin-tool-contract-v1.md
1. 目的
本 checklist 把 7-9 的路线图拆成可验收执行链,避免页面块 AI 工具停留在“工具名已设计、真实页面不可回读”的状态。
执行顺序固定为:
fetch/find
-> block.fetch
-> plan_update
-> block.replace
-> block.insert_after
-> block.move_after
每一步都必须满足:
- Rust command 或 projection 有测试。
- Hermes tool 有结构化返回。
- 真实页面 smoke 通过。
- 写入后能通过 Page Aggregate 与 AI fetch 回读。
2. Phase 0:设计与基线冻结
5-13已冻结 block identity、command、Tiptap boundary。2-1已冻结documents.content、blocks表、Page Aggregate、revision/conflict key 的关系。7-9已更新 Tiptap AI Toolkit 对照,不再写成“Tiptap 没有官方 AI 文档工具”。7-9明确mnote.page.save是粗粒度兜底,不是精确块工具。- 当前 reference code 已在
/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/tiptap-docs与tiptap-main可读。
验收:
rg -n "Tiptap AI Toolkit|tiptapRead|tiptapEdit|UniqueID|_hash|blockDocument" design/05-editor-mainline/process design/02-convex-rust-long-term-architecture/process design/07-ai/process能找到对应设计。
3. Phase 1:Page Aggregate Block Projection
目标:
每个可编辑块都能从 Page Aggregate 读到稳定身份和冲突辅助信息。
任务:
PageBody增加blockDocument或等价稳定字段。- 从
documents.content生成EditorBlockDocument。 - 从 Tiptap JSON 生成
EditorBlockDocument的 bridge 测试覆盖当前主类型。 - 每个块输出
blockId/type/text/attrs/children/parentBlockId/order/path/depth/revisionRef/editable。 - 对无 id legacy block 生成稳定迁移策略或 warning。
- 复杂块输出
editable=false或受限能力。
验证命令:
cargo test -p core-protocol editor_tiptap_bridge
cargo test -p bridge-runtime editor_document
真实页面 smoke:
- 登录
http://localhost:3000/auth测试账号。 - 新建页面
TEST-AI-BLOCK-PROJECTION-<timestamp>。 - 输入段落、标题、todo、列表、mindmap/resource 占位至少各一个。
- 调
/api/page-aggregate/:id保存响应到tmp/hermes-tester/<run-id>/page-aggregate.json。 - 断言所有普通可编辑块有
blockId和revisionRef。
通过标准:
- 页面刷新后 block ids 不变化。
- projection 中
blockCount与页面可编辑块数量大体一致;复杂块允许受限但必须有 warning。
4. Phase 2:mnote.doc.fetch / mnote.doc.find
目标:
AI 能先读取和定位,不需要猜整页
contentshape。
任务:
- tool manifest 增加
mnote.doc.fetch。 - tool manifest 增加
mnote.doc.find。 doc.fetch支持scope=full/outline/keyword/block/selection。doc.fetch支持detail=simple/with_ids/full。doc.find支持按 text/type/blockId 查找。- 返回 page
revision/conflictDetectionKey。 - 返回可直接传入
block.fetch/replace/insert_after的blockId。
验证命令:
cargo test -p mnote-web hermes_tools
cargo test -p bridge-runtime doc_find
真实页面 smoke:
- 使用
TEST-AI-BLOCK-FETCH-<timestamp>页面。 mnote.doc.fetch scope=full detail=with_ids读取整页。mnote.doc.fetch scope=outline detail=with_ids只返回标题结构。mnote.doc.find query=<唯一前缀>定位目标段落。- 保存工具返回到
tmp/hermes-tester/<run-id>/doc-fetch-find.json。
通过标准:
- 不读取浏览器 DOM。
doc.find返回的 block id 能被block.fetch读取。- 大页面默认分块或限制输出,不默认返回无限正文。
5. Phase 3:mnote.block.fetch
目标:
AI 能读取单块、子块和同父级上下文,形成写入前确认。
任务:
- tool manifest 增加
mnote.block.fetch。 - 支持
includeChildren。 - 支持
contextBefore/contextAfter。 - 支持
format=json/markdown/page_xml/text。 - 返回
revisionRef、editable、unsupportedReason。 - 不存在 block 返回
mnote_block_not_found。
验证命令:
cargo test -p mnote-web block_fetch
真实页面 smoke:
- 从
doc.find结果选择一个段落 block。 - 调
mnote.block.fetch includeChildren=true contextBefore=1 contextAfter=1。 - 断言 before/after 只来自同父级。
通过标准:
- block 文本与页面显示一致。
revisionRef可被后续 dry-run 使用。- 复杂块不会伪装成完全可编辑。
6. Phase 4:mnote.doc.plan_update
目标:
所有写入先 dry-run,返回 diff、warnings、risk,不改变页面。
任务:
- tool manifest 增加
mnote.doc.plan_update。 - 支持
command=block_replace。 - 支持
command=block_insert_after。 - 支持
command=block_move_afterdry-run。 - 支持
command=str_replace且多重匹配阻断。 - 缺少
revision/conflictDetectionKey时只允许 dry-run。 - 返回
planId、diff、warnings、risk、blocked。
验证命令:
cargo test -p mnote-web plan_update
cargo test -p bridge-runtime doc_replace_range
cargo test -p bridge-runtime doc_insert_blocks
真实页面 smoke:
- 对目标段落执行
block_replace dryRun=true。 - 对目标段落执行
block_insert_after dryRun=true。 - 对两个同父级普通块执行
block_move_after dryRun=true。 - dry-run 前后分别保存
/api/page-aggregate/:id,确认内容 hash 不变。
通过标准:
- dry-run 不写 Convex。
- plan 能解释 before/after。
- 不支持场景返回
blocked=true。
7. Phase 5:mnote.block.replace
目标:
第一条最小精确块写入闭环。
任务:
- tool manifest 增加
mnote.block.replace。 - 输入必须包含
blockId/revision/conflictDetectionKey/idempotencyKey/dryRun。 dryRun=true只返回 plan。dryRun=false生成EditorCommand::ReplaceBlock。- Rust 应用命令生成 canonical content。
- 通过
page.body.save -> documents:updateContent持久化。 - 返回新 revision、changedBlocks、audit。
验证命令:
cargo test -p mnote-web block_replace
cargo test -p bridge-runtime doc_replace_range_tool_executes_in_rust_runtime
真实页面 smoke:
- 新建
TEST-AI-BLOCK-REPLACE-<timestamp>页面。 - 写入两段不同文本。
doc.find找到第二段 block id。block.replace dryRun=true查看 plan。block.replace dryRun=false替换第二段。- 页面截图证明只替换第二段。
/api/page-aggregate/:id回读证明持久化。mnote.doc.fetch再次证明 AI 可读回。
通过标准:
- 相邻块不变化。
- 目标 block id 保持不变。
- 旧 revision 写入返回 conflict。
8. Phase 6:mnote.block.insert_after
目标:
AI 能在指定块后插入新块,并拿到新 block id。
任务:
- tool manifest 增加
mnote.block.insert_after。 - 输入必须包含
anchorBlockId/revision/conflictDetectionKey/idempotencyKey/dryRun。 - 新块 id 由 Rust runtime 分配。
- 支持单块和最多 20 个普通块插入。
- 第一阶段支持 paragraph/heading/todo。
- 返回 inserted block ids 和新 revision。
验证命令:
cargo test -p mnote-web block_insert_after
cargo test -p bridge-runtime doc_insert_blocks_tool_emits_editor_commands
真实页面 smoke:
- 新建
TEST-AI-BLOCK-INSERT-<timestamp>页面。 - 在第一段后插入 todo。
- 截图证明位置准确。
- 刷新页面后再次确认。
mnote.block.fetch能读取新 block id。
通过标准:
- 插入位置准确。
- 新 block id 不是 AI 自造未校验 id。
- 重复同一
idempotencyKey不重复插入。
9. Phase 7:mnote.block.move_after
目标:
第一阶段只开放同父级普通叶子块移动。
任务:
- tool manifest 增加
mnote.block.move_after。 dryRun=true支持同父级叶子块 diff。dryRun=false前先继续阻断所有复杂块。- 检查
blockRevisionRef与anchorRevisionRef。 - 阻断移动到自身、移动到子树、跨页面移动。
- 返回 from/to parent/order。
验证命令:
cargo test -p mnote-web block_move_after
cargo test -p mnote-editor-core command_executor
真实页面 smoke:
- 新建
TEST-AI-BLOCK-MOVE-<timestamp>页面,包含三段普通段落。 - dry-run 移动第三段到第一段后。
- 正式执行同父级移动。
- 截图证明顺序为第一段、第三段、第二段。
mnote.doc.fetch回读顺序一致。- 对标题带子块、列表项、表格、mindmap 执行 move dry-run,必须返回 blocked。
通过标准:
- moving block id 保持不变。
- 同父级顺序正确。
- 复杂块不被误移动。
10. Phase 8:UI 与 Review Mode
目标:
AI 写入可解释、可确认,不把 preview 当持久审阅事实。
任务:
- Hermes tool event UI 展示
plan/diff/warnings/risk。 page.save标记为粗粒度高风险兜底。block.replace/insert_after/move_after展示 changedBlocks。- 本地 preview/suggestion 与持久 comment/tracked-change 分开。
- 协作可见审阅必须另走正式 comment/history/tracked-change 设计。
通过标准:
- 用户能看到 AI 将改哪个 block。
blocked=true的工具调用不会出现写入按钮。- preview 不写入正式 comment/history。
11. DONE 条件
本 checklist 不能移动到 done/,直到:
- Phase 1 到 Phase 6 全部完成。
- Phase 7 至少完成 dry-run 和阻断规则;若真实 move 未完成,
7-9必须仍标注受限。 - 每个写工具都有真实页面 smoke 证据。
- 失败项已经写入
bugs/07-ai/process/或真实 owner 分类。 mnote.page.save不再被任何设计描述为精确块编辑主入口。