Files
mnote/design/old/07-ai/done/7-16-page-block-ai-real-smoke-followup-matrix-v1.md
T
Agent Board b798f628ee chore: land tree view-state, vault, Pi module split, and repo hygiene
Persist PageTree expand state via control-plane view-state and align
chevron/DOM with restored expansion; keep Sidex-style shallow page-tree
scan and drop the unused recursive scanner that only added cargo noise.

Add password vault workbench routes/runtime/skill/CLI, split page_ai_pi
into a module package, and retire Hermes/ACP/OpenHub recycle + root
harness evidence from the index while gitignoring recycle and local
diag dumps.

Archive superseded design/bugs docs under old/, point architecture at
ARCHITECTURE.md, and refresh smokes for Pi S1–S7, vault, and editor
regressions so the working tree can stay clean.
2026-07-21 05:13:05 +08:00

11 KiB
Raw Blame History

[recycle] 7-16 [done] Page Block AI 真实页面 Smoke 后续矩阵 v1

创建时间:2026-05-18

当前状态:DONE

归档说明(2026-05-21):本文范围内可执行的真实页面 smoke 已完成;剩余 UI / Review Mode 属于 Phase C 冻结范围,解冻时应新建设计稿承接。

来源:

  • /mnt/Data1T/mnote/design/old/07-ai/process/7-10-page-block-ai-tooling-execution-checklist-v1.md
  • /mnt/Data1T/mnote/design/07-ai/reference/7-12-page-ai-hermes-tool-routing-and-review-surface-v1.md
  • /mnt/Data1T/mnote/design/10-review/process/08-kernel-architecture-next-priority-review-and-checklist.md

1. 目的

7-10 已完成大量工具合同、Rust route 测试和部分真实 3000 smoke,但仍有一组“必须真实页面验证”的矩阵项未完成。

本文只承接这些剩余 smoke,不新增 AI 功能面,不改变当前主路径:

  • local-first 普通 Markdown 编辑主路径仍是“授权文件引用 + agent 原生 patch/diff + watcher 同步”;本文只验证 mnote tools 的历史结构性辅助和兼容证据。
  • 2026-05-22 之后,mnote.doc.markdown_edit 不再作为 local-first 默认、fallback 或 remote fallback;本文中的 smoke 只代表历史在线 / compat 回归证据。
  • mnote.block.* 仍只作为结构性辅助。
  • mnote.page.save 仍只作为页面级粗粒度兜底。
  • Phase C review / streaming apply 仍冻结,当前只验证基础合同和安全边界。

2. 当前已具备的前置证据

  • mnote.doc.fetch scope=selection format=page_xml/textmnote.block.fetch format=page_xml/text、manifest annotations、mnote.doc.apply_block_ops allowedTargetBlockIds 越界阻断已有真实 3000 smoke
    • tmp/page-block-ai-context-format-smoke/mp8ddr4n.json
    • tmp/page-block-ai-context-format-smoke/mp8ddr4n-page.png
  • mnote.block.replace stale revision / stale blockRevisionRef / idempotency replay 已有真实 3000 smoke
    • scripts/task-page-block-ai-conflict-idempotency-smoke.js
    • 证据记录在 08 的 Page Block AI Tooling 章节。
  • mnote.block.insert_after 多块插入和 20 个边界已有 Rust route 回归:
    • cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_block_insert_after -- --nocapture
  • mnote.block.move_after 复杂块阻断矩阵已有隔离 route smoke
    • cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_block_move_after_blocks_complex_and_nested_blocks -- --nocapture

3. 后续真实页面 Smoke 矩阵

3.1 Page Aggregate Block Projection

  • 登录测试账号并创建综合页面 TEST-AI-BLOCK-TOOLS-<timestamp>
  • 写入段落、标题、todo、列表、mindmap/resource 占位。
  • /api/page-aggregate/:id 并保存响应到 tmp/hermes-tester/page-block-ai-tools-<run-id>/page-aggregate.json
  • 断言所有普通可编辑块有 blockIdrevisionRef
  • 页面刷新后 block ids 不变化。
  • projection 中 blockCount 与页面块数量一致;复杂块返回 editable=falseunsupportedReason

证据(2026-05-18):

  • JSONtmp/page-block-ai-tools-smoke/mpag4966.json
  • Page Aggregatetmp/hermes-tester/page-block-ai-tools-mpag4966/page-aggregate.json
  • 覆盖:Page Aggregate blockProjectionVersion=1projectionSource=documents.contentaggregateBlockCount=10,与 mnote.doc.fetch 块顺序一致;刷新后 afterRefreshBlockIds 保持最终顺序;table_1/mindmap_1/resource_1 返回 editable=falseunsupportedReason=复杂块暂不开放 AI 精确写入

3.2 mnote.doc.fetch / mnote.doc.find

  • 使用综合页面 TEST-AI-BLOCK-TOOLS-<timestamp>
  • mnote.doc.fetch scope=full detail=with_ids 读取整页。
  • mnote.doc.fetch scope=outline detail=with_ids 只返回标题结构。
  • mnote.doc.find query=<唯一前缀> 定位目标段落。
  • 保存工具返回到 tmp/hermes-tester/page-block-ai-tools-<run-id>/doc-fetch-find.json
  • 确认读取不依赖浏览器 DOM。
  • doc.find 返回的 block id 能被 block.fetch 读取。
  • 大页面默认分块或限制输出,不默认返回无限正文。

证据(2026-05-18):

  • 命令:PLAYWRIGHT_CHROME_EXECUTABLE=/snap/bin/chromium MNOTE_UI_BASE_URL=http://127.0.0.1:3000 MNOTE_AUTH_BASE_URL=http://127.0.0.1:3000 node scripts/task-page-block-ai-tools-smoke.js
  • JSONtmp/page-block-ai-tools-smoke/mpag4966.json
  • 工具返回:tmp/hermes-tester/page-block-ai-tools-mpag4966/doc-fetch-find.json
  • 覆盖:doc.fetch.initial 读取 heading_1/p_1/p_2/p_3 等 10 个块;doc.fetch scope=outline 只返回 heading_1/heading_parentdoc.find query="第二段 <suffix>" 定位 p_2maxBlocks=2 返回 truncated=true
  • 静态边界:mnote.doc.fetch 从 Page Aggregate block projection 构建上下文,不读取浏览器 DOM;默认 maxBlocks=120 且 clamp 到 1..=240

3.3 mnote.block.fetch

  • doc.find 结果选择一个段落 block。
  • mnote.block.fetch includeChildren=true contextBefore=1 contextAfter=1
  • 断言 before/after 只来自同父级。
  • revisionRef 可被后续 dry-run 使用。
  • 复杂块不会伪装成完全可编辑。

证据(2026-05-18):

  • JSONtmp/page-block-ai-tools-smoke/mpag4966.json
  • 覆盖:block.fetch 读取 p_2,返回 revisionRef=pageRev:1:block:p_2:...,同父级 before=["p_1"]after=["p_3"]table_1/mindmap_1/resource_1 均返回 editable=falseunsupportedReason=复杂块暂不开放 AI 精确写入

3.4 mnote.doc.plan_update / dry-run

  • command=str_replace 不再作为当前 plan_update 目标;普通正文 search/replace 已由 mnote.doc.markdown_edit 合同承接。
  • 对目标段落执行 block_replace dryRun=true
  • 对目标段落执行 block_insert_after dryRun=true
  • 对两个同父级普通块执行 block_move_after dryRun=true
  • dry-run 前后分别读取 /api/page-aggregate/:idmnote.doc.fetch,确认 revision / conflictDetectionKey / 正文文本不变。
  • dry-run 不写 Convex。
  • plan 能解释 before/after。
  • 不支持场景返回 blocked=true

证据(2026-05-18):

  • JSONtmp/page-block-ai-tools-smoke/mpag4966.json
  • 覆盖:plan_update.dry_run.replaceDiff.before/afterinsertDiff.after/content、不支持 move_after p_3 -> p_3 返回 blocked=true、dry-run 后 revisionAfterDryRun=1 且正文未变化。

3.5 mnote.block.replace

  • 使用综合页面 TEST-AI-BLOCK-TOOLS-<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。

证据(2026-05-18):

  • JSONtmp/page-block-ai-tools-smoke/mpag4966.json
  • 截图:tmp/page-block-ai-tools-smoke/mpag4966-page.png
  • 覆盖:block.replace.changedBlocks[0]={blockId:"p_2",op:"replace"}targetBlockStillExists=trueadjacentTexts=["第一段 mpag4966","第三段 mpag4966"]mnote.doc.fetch 与 Page Aggregate 均回读到 第二段已替换 mpag4966Page Aggregate aggregateRevision=2aggregateConflictDetectionKey=tree_1779062903017_3:2
  • 冲突 / 幂等补充 JSONtmp/page-block-ai-conflict-idempotency-smoke/mpafrevs.json,截图:tmp/page-block-ai-conflict-idempotency-smoke/mpafrevs-page.png
  • 覆盖:首次 block.replace 写入 p_2 后,重复 idempotencyKey=idem_conflict_replace_mpafrevs replay 同一 commandId=page_body_save_req_1779062303997_525revisionAfterFirst=2revisionAfterReplay=2;旧 revision/conflictDetectionKey 与旧 blockRevisionRef 均返回 HTTP 400 / mnote_tool_conflict,最终文本保持 第二段首次替换 mpafrevs

3.6 mnote.block.insert_after

  • 使用综合页面 TEST-AI-BLOCK-TOOLS-<timestamp>
  • 在第一段后插入 todo。
  • 截图证明位置准确。
  • 刷新页面后再次确认。
  • mnote.block.fetch 能读取新 block id。
  • 插入位置准确。
  • 新 block id 不是 AI 自造未校验 id。
  • 重复同一 idempotencyKey 不重复插入。

证据(2026-05-18):

  • 命令:PLAYWRIGHT_CHROME_EXECUTABLE=/snap/bin/chromium MNOTE_UI_BASE_URL=http://127.0.0.1:3000 MNOTE_AUTH_BASE_URL=http://127.0.0.1:3000 node scripts/task-page-block-ai-tools-smoke.js
  • JSONtmp/page-block-ai-tools-smoke/mpag4966.json
  • 截图:tmp/page-block-ai-tools-smoke/mpag4966-page.png
  • 说明:该 smoke 使用 TEST-AI-BLOCK-TOOLS-* 综合页面,不是单独 TEST-AI-BLOCK-INSERT-* 页面;已覆盖 todo 插入、插入后顺序、block.fetch 回读、刷新后可见和重复 idempotencyKey replay。

3.7 mnote.block.move_after

  • 使用综合页面 TEST-AI-BLOCK-TOOLS-<timestamp>,包含三段普通段落。
  • dry-run 移动第三段到第一段后。
  • 正式执行同父级移动。
  • 截图证明顺序为第一段、第三段、第二段。
  • mnote.doc.fetch 回读顺序一致。
  • 对标题带子块、列表项、表格、mindmap 执行 move dry-run,必须返回 blocked。
  • moving block id 保持不变。
  • 同父级顺序正确。
  • 复杂块不被误移动。

证据(2026-05-18):

  • JSONtmp/page-block-ai-tools-smoke/mpag4966.json
  • 截图:tmp/page-block-ai-tools-smoke/mpag4966-page.png
  • 覆盖:heading_parent/list_item_1/table_1/mindmap_1/resource_1plan_update block_move_after dryRun=true 与正式 mnote.block.move_after dryRun=false 均返回 blocked=true / block_move_after_blocked,阻断后 revisionAfterBlocked=1 且正文不变化;普通 p_3 -> p_1 正式移动后顺序为 heading_1,p_1,p_3,ai_block_...,p_2,...movingBlockStillExists=true

3.8 UI / Review Mode 边界

  • Hermes tool event UI 展示 plan/diff/warnings/risk
  • 本地 preview/suggestion 与持久 comment/tracked-change 分开。
  • 协作可见审阅必须另走正式 comment/history/tracked-change 设计。
  • 用户能看到 AI 将改哪个 block。
  • blocked=true 的工具调用不会出现写入按钮。
  • preview 不写入正式 comment/history。

4. 验证原则

  • 所有真实页面 smoke 必须使用测试账号,优先从 http://localhost:3000/auth 快速登录。
  • 证据必须保留 JSON 和截图,默认放入 tmp/hermes-tester/<run-id>/ 或专项 tmp/page-block-ai-* 目录。
  • 发现失败时按 owner 写入 bugs/<category>/process/,不要只在本矩阵中留描述。
  • 不用此矩阵扩展新 AI 功能;只补真实页面证据和安全边界。