Files
mnote/design/01-tree-first-graph-kernel/process/1-3-current-priority-execution-checklist-v1.md
T
lix-2026 1b5d6a2a2d feat: advance local-first conflict and search indexing
- 补齐本地 markdown 冲突处理与合并写回路径\n- 增加本地搜索索引路由、刷新与 browser smoke\n- 同步更新 current-priority checklist 的阶段进度
2026-05-19 09:38:57 +08:00

399 lines
23 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.
# 1-3 [process] 当前主线持续推进 checklist v1
> 创建时间:2026-05-19
>
> 当前状态:`PROCESS`
>
> 上位依据:
> - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md`
> - `/mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md`
> - `/mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/process/2-3-local-workspace-access-control-productization-v1.md`
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
> - `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md`
>
> 目标:把 `01-05 当前主线与优先级总览` 转成可持续推进、可验证、可迁移到 `done/` 的执行清单。
---
## 0. 总原则
- [x] 产品形态固定为 `VSCode 简化版工作区内核 + tiptap markdown 编辑器 + Hermes / Reasonix agent + simplemindmap / office 插件 + Wolai 风格 web 壳 + 鉴权控制面`
- [x] 本地文件夹是默认数据真相;Rust kernel 是唯一语义真相。
- [x] Convex / 服务端降级为账号、分享、同步、协作和 AI 隔离控制面。
- [x] AI 默认尽量使用 agent 原生文件读写、diff、patch 能力;MNote 只提供授权 root、页面定位、必要元数据和特殊资源工具。
- [ ] 每完成一个阶段后,把对应过程稿移动到该分类 `done/`,并在本 checklist 写入验证证据。
---
## 1. P0 管理员目录授权控制面
对应 `01-05` 执行顺序:`1. 管理员目录授权 UI / API`
### 1.1 后端 API 与权限底座
- [x] 管理员身份支持 `MNOTE_ADMIN_USER_IDS`
- [x] access policy 默认路径固定为 `/mnt/Data1T/Mnote_data/control-plane/access-policy.json`
- [x] 管理员可读写任意本地目录,普通用户只能访问 owner / grant 授权目录。
- [x] read grant 只能读,write grant 可写。
- [x] 新增 `GET /api/admin/access-policy`
- [x] 新增 `POST /api/admin/access-policy/validate-root`
- [x] 新增 `POST /api/admin/access-policy/grants`
- [x] 新增 `DELETE /api/admin/access-policy/grants/{grantId}`
- [x] 全入口权限审计完成:local folder、page body、tree command、Hermes / Reasonix、shared AI session。
验证证据:
- [x] `cargo test -p mnote-web local_access_policy -- --nocapture`
- [x] `cargo test -p mnote-web local_workspace_access -- --nocapture`
- [x] `cargo test -p mnote-web local_folder -- --nocapture`
- [x] `cargo test -p mnote-web hermes_client_local_acp -- --nocapture`
- [x] `cargo test -p mnote-web hermes_tools_markdown_edit_shared_read_is_forbidden -- --nocapture`
### 1.2 管理员 UI
目标:让管理员不用手写 JSON 就能管理用户目录授权。
- [x] 定位当前 Rust SSR 设置 / 管理入口,确认管理员页面应挂在 `rust/crates/mnote-web/src/ssr/pages/` 的哪个壳内。
- [x] 增加管理员访问入口:非管理员不可见,管理员可进入本地目录授权管理页。
- 实现:`/admin/access-policy` + `PageLayout` 管理员 quick action。
- [x] 增加 policy 列表:显示 `policyPath`、env admins、policy admins、grant 列表。
- 实现:`rust/crates/mnote-web/src/ssr/pages/admin.rs` 调用 `GET /api/admin/access-policy` 并展示 JSON。
- [x] 增加 validate root 表单:输入 `rootPath``rootUri` 后显示 canonical path / rootUri。
- [x] 增加 create grant 表单:`userId``permission``recursive``capabilities`
- [x] 增加 delete grant 操作:删除前显示授权目录和用户,删除后刷新列表。
- [x] 增加 UI 错误态:未登录、非管理员、目录不存在、重复授权、无效 capability。
- 实现:页面展示 API 错误;SSR route 对非管理员返回 403;API 保持后端错误码。
- [x] 补管理员 UI smoke:真实登录管理员可新增 read grant,普通用户可读不可写。
- 验证:`node scripts/task450-admin-access-policy-ui-smoke.js`
- [x] 补普通用户 smoke:普通用户无法打开管理员授权页,直接调用 API 返回 403。
- 验证:`cargo test -p mnote-web admin_access_policy -- --nocapture`
建议验证:
- [x] `cargo test -p mnote-web local_access_policy -- --nocapture`
- [x] `cargo test -p mnote-web local_workspace_access -- --nocapture`
- [x] `node scripts/task450-admin-access-policy-ui-smoke.js`
---
## 2. P1 VSCode-like 冲突处理 UI
对应 `01-05` 执行顺序:`2. VSCode-like 冲突处理 UI`
目标:tiptap 前端保存与 agent 后台写文件同时发生时,用户可以像 VSCode 一样看见冲突、选择磁盘版本、保留编辑器版本或打开 diff 合并。
### 2.1 冲突模型收口
- [x] 盘点现有 `fileVersion` / `conflictDetectionKey` 的生成、传递和校验路径。
- 结论:本地 markdown aggregate 已暴露 `fileVersion` alias`documents/save` compat 会把 `expectedFileVersion` / `conflictDetectionKey` 收敛到 `PageBodyWriteRequest.expected_file_version``/api/page-body/write` 只接受 `expectedFileVersion`,避免 alias 重复。
- [x] 确认所有本地 markdown 写入口都携带 expected file versiontiptap 保存、`mnote.doc.markdown_edit``mnote.page.save`、documents compat save。
- 实现:tiptap local-folder 保存改走 `/api/page-body/write` 并只传 `expectedFileVersion``mnote.doc.markdown_edit` 从当前 aggregate 的 `fileVersion` / `conflictDetectionKey` 取 expected version`mnote.page.save` 读取 tool 入参 `expectedFileVersion`documents compat save 继续兼容旧 `conflictDetectionKey`
- [x] 统一冲突错误 envelope:错误码、当前磁盘版本、编辑器基线版本、documentId、rootUri、建议动作。
- 实现:本地 markdown stale 写入返回 `details.conflict`,包含 `code``currentDiskVersion``editorBaseVersion``documentId``rootUri``suggestedActions`
- [x] 让冲突错误不丢失当前编辑器内容,前端可以继续保留未保存 buffer。
- 实现:冲突态优先从当前挂载的 ProseMirror DOM 捕获文本;“保留当前编辑器版本”会用最新 `fileVersion` 重新提交当前 buffer。
### 2.2 冲突交互
- [x] 设计冲突 modal / side panel:显示当前编辑器版本、磁盘版本、文件路径、最后修改来源。
- 实现:文档页内嵌 `mnote-editor-conflict-panel`,展示文件标识、来源为本地文件变更,并提供磁盘 / 当前 / diff 三个动作。
- [x] 实现“接受磁盘版本”:重新读取文件,替换编辑器 buffer。
- [x] 实现“保留编辑器版本”:用最新 fileVersion 重新提交当前编辑器内容。
- [x] 实现“打开 diff”:支持 markdown 文本并排查看;复杂块结构先降级为 markdown 文本。
- [x] 实现“合并”:支持从 diff 面板选择合并结果并写回。
- 实现:冲突 diff 面板新增合并 textarea,可选择当前版本 / 磁盘版本作为合并基础,并写回合并结果。
- [x] 合并完成后写回本地 markdown,并刷新 page aggregate / file tree snapshot。
- 验证:`node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js` 覆盖合并写回,文件内容包含当前编辑器内容、磁盘内容和新增合并内容。
- [x] AI 写入导致冲突时,提示来源为 agent run,而不是普通外部修改。
- 实现:页面收到 `mnote:page-ai-tool-write-completed` / `agent.changed_files` 后记录 agent run 来源;冲突面板来源显示为 `agent run <runId>`
建议验证:
- [x] 新增单测:stale `expectedFileVersion` 被拒绝。
- 验证:`cargo test -p mnote-web local_folder_documents_save_rejects_stale_expected_file_version -- --nocapture`
- [x] 新增 browser smoke:浏览器打开页面后外部修改同一 `.md` 文件,保存时出现冲突 UI。
- 验证:`node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js`
- [x] 新增 browser smokeagent 修改同一 `.md` 文件后,tiptap 保存触发冲突 UI。
- 验证:`node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js` 覆盖 agent 修改同一 `.md` 后的冲突 UI,并断言面板出现 `agent run <runId>`
补充验证:
- [x] `cargo fmt --check --all`
- [x] `cargo test -p mnote-web document_shell_renders_local_markdown_with_same_sidebar_surfaces -- --nocapture`
- [x] `cargo test -p mnote-web local_folder -- --nocapture`
- [x] `npm run check:local-first-convex-guard`
---
## 3. P2 Agent changed files / diff 审计
对应 `01-05` 执行顺序:`3. agent changed files / diff 审计`
目标:agent 可以像在 VSCode 里一样直接改授权目录文件,但 MNote 要记录“谁、在哪个 root、通过哪个 run、改了哪些文件、diff 摘要是什么”。
### 3.1 审计事件模型
- [x] 设计本地审计目录:建议放在 `/mnt/Data1T/Mnote_data/control-plane/agent-audit/`
- [x] 定义审计事件 JSONL 字段:`eventId``actorId``agentKind``runId``rootUri``permission``changedFiles``diffSummary``createdAt`
- [x] 区分 agent 原生文件修改与 MNote tool 写入:二者都要能归入同一个 run audit。
- 实现:agent 原生文件修改继续由 run 前后 root snapshot 生成 `changedFiles`;MNote tool 本地成功写入额外追加 `origin=mnote_tool` 的同 `runId` audit event,只读拒绝追加 `writeAttemptRejected=true` 的同 `runId` audit event。
- [x] 对只读 grant 的 agent run 写入尝试记录拒绝事件。
- 实现:`mnote.doc.markdown_edit` / `mnote.page.save` / `mnote.block.*``read_only` AI scope 下直接拒绝写入;本地 mnote tool 写入拒绝会按同一 `runId` 追加 control-plane `agent-audit.jsonl` 事件,标记 `writeAttemptRejected=true`
### 3.2 写入采集
- [x] 在 Hermes / Reasonix run 启动前记录 root snapshot:文件 mtime、size、hash。
- [x] run 结束后对比 root snapshot,生成 changed files。
- [x] 对 markdown 文件生成简短 diff summary;大文件只记录 hash / size / path。
- [x] 把审计事件落盘到 control-plane,不写进用户正文目录。
- [ ] 在 AI 会话 UI 显示 changed files 列表,并可展开查看 diff 摘要。
- 已接入:`run.completed.agentAudit.changedFiles` 会进入 `agent.changed_files` 工具卡并可展开查看;待真实浏览器 AI run smoke 验证后勾选。
建议验证:
- [x] 单测:run 前后文件变化可生成 changed files。
- 验证:`cargo test -p mnote-web local_agent_audit_snapshot_detects_changed_files -- --nocapture`
- [x] 单测:只读授权下写入被拒绝并产生拒绝审计事件。
- 验证:`cargo test -p mnote-web hermes_tools_markdown_edit_shared_read -- --nocapture`
- [x] 单测:MNote tool 本地写入归入同一 run audit,并标记 `origin=mnote_tool`
- 验证:`cargo test -p mnote-web hermes_tools_page_save_local_folder_writes_markdown_file -- --nocapture`
- [ ] browser smokeAI 修改一篇本地 markdown 后,会话面板显示 changed files。
- 已验证 UI 展示链路:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task-hermes-page-ai-smoke.js` 可渲染 mocked `run.completed.agentAudit.changedFiles``agent.changed_files` 工具卡。
- 待补:真实 local_folder agent run 写入 `.md` 后,由后端审计事件驱动会话面板展示 changed files。
补充验证:
- [x] `cargo fmt --check --all`
- [x] `cargo test -p mnote-web hermes_client_acp_run_registers_scoped_runtime_record_in_convex -- --nocapture`
- [x] `cargo test -p mnote-web hermes_client_local_acp -- --nocapture`
- [x] `cargo test -p mnote-web document_shell_renders_local_markdown_with_same_sidebar_surfaces -- --nocapture`
---
## 4. P3 本地搜索、反链和资源引用索引
对应 `01-05` 执行顺序:`4. 本地搜索、反链和资源引用索引`
目标:本地 workspace 不依赖 Convex search 也能搜索正文、查反链、查资源引用和标签。
### 4.1 索引边界
- [x] 设计本地索引目录:建议放在 workspace `.mnote/index/``/mnt/Data1T/Mnote_data/control-plane/index/`,二者职责需明确。
- 实现:单 workspace 本地索引落在授权 root 的 `.mnote/index/search-index.json`control-plane index 只保留给后续跨 workspace / shared cache 总索引。
- [x] 确认索引只扫描授权 root 内文件,不扫描用户未授权目录。
- 实现:`/api/search/documents``local_folder` 分支先走 `ensure_local_workspace_read_access`,再对 canonical root 内 `.md` 文件重建索引。
- [ ] 定义索引输入:markdown 正文、frontmatter、附件引用、mindmap / office resource metadata。
- 已完成最小输入:markdown 正文、frontmatter `title/tags/mnote_id`、markdown 链接、双链、附件 / mindmap / office 文件引用;待补 mindmap / office 原生 metadata 索引。
- [x] 定义索引输出:全文 search、backlinks、resource refs、tags、recent changes。
- 实现:本地索引输出 `results``recentChanges`,结果包含全文命中、`backlinks``resourceRefs``tags``path``resourceType`
### 4.2 索引更新
- [ ] 本地文件 watcher 事件触发增量索引。
- [x] 手动 refresh / resync 触发 root 全量索引。
- 实现:`POST /api/search/local-index/refresh` 会在授权 root 内全量重建 `.mnote/index/search-index.json`
- 验证:`cargo test -p mnote-web search_local_index_refresh_rebuilds_authorized_root -- --nocapture`
- [x] 文件移动、重命名、删除、恢复后同步更新索引。
- 实现:本地 `tree command` 成功后统一 best-effort 刷新 `.mnote/index/search-index.json`;验证覆盖 rename 后索引路径更新。
- 验证:`cargo test -p mnote-web local_tree_command_refreshes_search_index_after_rename -- --nocapture`
- [x] AI 写入和 tiptap 保存后更新索引。
- 实现:`save_local_markdown_page` 成功写回后统一 best-effort 刷新本地搜索索引,覆盖 tiptap 保存与 MNote tool 写入兼容链。
- 验证:`cargo test -p mnote-web local_markdown_save_refreshes_search_index_after_write -- --nocapture`
- [x] 索引损坏时可重建,不影响正文文件。
- 实现:本地搜索每次从授权 root 重新生成 `.mnote/index/search-index.json`,不会读取索引作为正文真相。
### 4.3 搜索体验
- [x] 全局搜索优先搜索当前 workspace 本地索引。
- 实现:页面搜索请求携带 `sourceKind/rootUri``local_folder` 请求直接查本地索引,不先走 Convex runtime。
- [x] 搜索结果显示文件路径、标题、命中片段和资源类型。
- 实现:搜索结果行显示标题、命中片段、路径和 `resourceType` 标识;API 同步返回 `path/title/snippet/resourceType`
- [ ] 反链面板读取本地索引,不再依赖云端搜索。
- 已完成数据源:`GET /api/search/local-index/backlinks` 从授权 root 本地索引读取反链;待挂接真实反链面板 UI。
- [ ] 标签列表读取本地索引。
- 已完成数据源:`GET /api/search/local-index/tags` 从授权 root 本地索引读取标签聚合;待挂接真实标签列表 UI。
建议验证:
- [x] 单测:markdown 链接和双链可生成 backlinks。
- 验证:`cargo test -p mnote-web local_search_index -- --nocapture`
- [x] 单测:附件 / mindmap / office 引用可生成 resource refs。
- 验证:`cargo test -p mnote-web local_search_index -- --nocapture`
- [x] browser smoke:新建页面后立即可搜索,重命名后搜索结果路径更新。
- 验证:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task452-local-search-index-browser-smoke.js`
补充验证:
- [x] `cargo test -p mnote-web search_local_index_backlinks_and_tags_read_authorized_root -- --nocapture`
---
## 5. P4 分享与同步闭环
对应 `01-05` 执行顺序:`5. 分享与同步闭环`
目标:个人本地空间默认隔离,显式分享后才产生共享 workspace / shared AI sessionConvex 只作为权限、同步和协作控制面。
### 5.1 分享权限
- [ ] 定义 share grant 与 local access grant 的关系:分享不自动扩大本机文件系统权限。
- [ ] share grant 支持 read / write / ai capability。
- [ ] shared AI session 只能访问 share grant 允许的资源。
- [ ] 管理员可查看和撤销 share grant。
### 5.2 同步缓存
- [ ] 设计 shared workspace cache 目录。
- [ ] 云端同步到本地 cache 时保留来源、版本、权限和冲突信息。
- [ ] 本地修改同步回云端前进行权限和版本校验。
- [ ] 离线期间记录 pending changes,恢复在线后生成同步报告。
### 5.3 同步冲突报告
- [ ] 同步冲突复用 P1 的冲突 UI。
- [ ] 冲突报告包含本地版本、远端版本、base version、修改 actor。
- [ ] 管理员或 owner 可导出冲突报告。
建议验证:
- [ ] 单测:share read 不允许写入。
- [ ] 单测:shared AI session 不扩大 workspace root。
- [ ] browser smoke:共享页面只读用户无法通过 AI 写入正文。
---
## 6. P5 插件资源模型产品化
对应 `01-05` 执行顺序:`6. 插件资源模型产品化`
目标:simplemindmap / office 是 Resource Tree 对象;Markdown 正文只保留链接或嵌入引用,不把资源内容塞回 markdown 正文真相。
### 6.1 Resource Tree 对象统一
- [ ] 盘点 simplemindmap 当前 object identity、保存路径、打开路径。
- [ ] 盘点 office 当前 object identity、保存路径、打开路径。
- [ ] 统一资源创建、重命名、移动、删除、恢复命令到 `tree.resource.*`
- [ ] filetree 显示资源行,pagetree 只显示页面导航投影。
- [ ] Markdown 中插入资源引用时,只写相对链接或嵌入引用。
### 6.2 AI 资源工具
- [ ] 设计 `mnote.mindmap.*` 工具:读取结构、增删改节点、移动节点、导出 markdown summary。
- [ ] 设计 `mnote.office.*` 工具:读取文本摘要、写入建议、导出变更摘要;真实编辑优先复用 officecli / OnlyOffice 保存链。
- [ ] AI 资源工具必须走授权 root 和 resource capability。
- [ ] agent changed files 审计包含 mindmap / office 资源文件。
建议验证:
- [ ] 单测:resource rename 不走 document command。
- [ ] 单测:mindmap resource 删除 / 恢复不破坏 markdown 页面。
- [ ] browser smoke:从 markdown 打开 mindmap / office,修改保存后 filetree 和引用状态同步。
---
## 7. P6 旧 Convex 数据迁移产品化
对应 `01-05` 执行顺序:`7. 旧 Convex 数据迁移产品化`
目标:把旧 Convex workspace 迁移成本变成可视、可回滚、可验证的产品流程。
### 7.1 导出与备份
- [ ] 设计导出入口:选择 Convex workspace,选择目标本地 root。
- [ ] 导出前创建备份目录和 manifest。
- [ ] 导出页面为 `.md`,资源为 Resource Tree 文件,附件保持相对路径。
- [ ] 导出过程记录进度:总页面数、已完成、失败、跳过、冲突。
### 7.2 冲突与回滚
- [ ] 目标 root 已有同名文件时生成冲突报告,不直接覆盖。
- [ ] 支持 dry run:只生成迁移计划,不写文件。
- [ ] 支持回滚:根据 manifest 删除本次新增文件或恢复备份文件。
- [ ] 导出完成后自动跑本地索引重建。
建议验证:
- [ ] 脚本 smokeConvex fixture 导出到本地 root。
- [ ] 脚本 smoke:同名文件冲突时不覆盖。
- [ ] 脚本 smoke:回滚后 root 回到导出前状态。
---
## 8. P7 Page Aggregate / tree command / realtime 兼容链瘦身
对应 `01-05` 执行顺序:`8. Page Aggregate / tree command / realtime 兼容链继续瘦身`
目标:不是继续扩新功能,而是减少双真相、双命令面、补偿链和旧 Convex runtime fallback。
### 8.1 Page Aggregate 单一真源
- [ ] 盘点 `documents.content` 仍作为正文兼容源的入口。
- [ ] 让本地 `.md` 与 EditorBlockDocument projection 的读写边界写入 5-5 / 5-6。
- [ ] 标题、正文、页面设置写入后只通过 page aggregate 刷新 UI。
- [ ] 删除或降级前端手工拼 `meta + content` 的 runtime fallback。
- [ ] AI 页面设置写入走统一 page aggregate / page command 入口。
建议验证:
- [ ] `cargo test -p mnote-web page_aggregate -- --nocapture`
- [ ] browser smoke:标题、正文、页面设置保存后刷新仍一致。
### 8.2 Tree command cutover
- [ ] 盘点仍在 runtime route / adapter / bridge / CLI 中使用的 `documents.*` 命令。
- [ ] 新增命令统一命名为 `tree.*``tree.resource.*`
- [ ] 对历史 `documents.*` 命令只保留 compat adapter,不再扩展新语义。
- [ ] 资源 rename、移动、删除、恢复补齐 `tree.resource.*`
建议验证:
- [ ] `cargo test -p mnote-web tree_command -- --nocapture`
- [ ] browser smokefiletree 新建、重命名、移动、删除、恢复不触发页面 reload。
### 8.3 Tree realtime live cache
- [ ] 盘点 Sidebar、page subtree、filetree、preferred snapshot 的数据来源。
- [ ] 统一 snapshot / delta / resync consumer 到同一 live cache。
- [ ] SSE fallback 只作为 WS 不可用时的降级,不作为并行主链。
- [ ] 双浏览器文件树操作无刷新同步。
- [ ] 删除不必要的 polling / refetch 补偿链。
建议验证:
- [ ] `cargo test -p mnote-web local_folder -- --nocapture`
- [ ] 双浏览器 smoke:页面、文件、垃圾箱操作互相同步且不刷新页面。
---
## 9. 每轮推进固定验证包
后续每次持续推进本 checklist,至少执行与改动相关的子集;跨域改动需要执行完整包。
- [ ] `cargo fmt --check --all`
- [ ] `cargo test -p mnote-web local_folder -- --nocapture`
- [ ] `cargo test -p mnote-web local_access_policy -- --nocapture`
- [ ] `cargo test -p mnote-web hermes_client_local_acp -- --nocapture`
- [ ] `cargo test -p mnote-web tree_command -- --nocapture`
- [ ] `cargo test -p mnote-web page_aggregate -- --nocapture`
- [ ] `npm run check:local-first-convex-guard`
- [ ] `git diff --check -- <changed-files>`
- [ ] 影响 UI / 交互时补 browser smoke,并把脚本名写回对应阶段。
---
## 10. done 迁移标准
本文件迁入 `done/` 前必须满足:
- [x] P0 管理员目录授权 UI / API 完成并有 browser smoke。
- 证据:`node scripts/task450-admin-access-policy-ui-smoke.js``cargo test -p mnote-web admin_access_policy -- --nocapture`
- [x] P1 冲突处理 UI 完成,并覆盖 tiptap 保存与 agent 写回冲突。
- 证据:`node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js``cargo test -p mnote-web local_folder_documents_save_rejects_stale_expected_file_version -- --nocapture`
- [ ] P2 agent changed files / diff 审计完成,并能在 AI 会话 UI 查看。
- [ ] P3 本地搜索 / 反链 / 资源引用索引完成最小闭环。
- [ ] P4 分享与同步闭环完成 read / write / ai capability 最小闭环。
- [ ] P5 simplemindmap / office 资源模型完成 Resource Tree 产品化。
- [ ] P6 Convex 导出到本地 workspace 有 dry run、备份、冲突报告和回滚。
- [ ] P7 Page Aggregate / tree command / realtime 兼容链完成阶段性瘦身,并把被替代 process 稿移入 `old/``done/`
- [ ] `01-05-current-priority-overview.md` 同步更新状态,不再把已完成项描述为当前第一优先级。