Files
mnote/CURRENT_ARCHITECTURE.md
T
lix-2026 a2cb1338c8 chore: 保存当前架构收口与 bug 修复快照
归档本轮 P0/P1 bug 修复、设计审查迁移、AI selection scope 收口与 stream contract 调整,并保留当前 05 主线迁移起点。
2026-05-18 17:01:35 +08:00

165 lines
11 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.
# 当前完整架构
> 更新时间:2026-05-17
>
> 范围:`/mnt/Data1T/mnote` 当前可见实现的完整架构、冲突口径、过渡态和缺失功能。
## 1. 结论
当前系统已经形成一条清晰的主线:
`Convex / 本地文件` -> `Rust kernel / bridge-runtime` -> `mnote-web` -> `前端壳与编辑器` -> `AI runtime`
但它还不是单一真源闭环。现在同时存在三类并行真相:
1. `tree` / `page` / `resource` 的 Rust 语义真相。
2. 文档页与 Sidebar 的前端本地派生真相。
3. AI 写入链路中的 markdown / block 双合同真相。
因此,项目当前更像“主线已经立住,但收口尚未完成”的状态,而不是“架构已统一完成”的状态。
## 2. 分层架构
### 2.1 事实存储层
- `Convex` 仍是在线协作、文档、媒体、树数据的实际后端存储底座。
- 本地 `.md` 文件是 `mnote.doc.fetch` / `mnote.doc.markdown_edit` 的另一条合法输入输出面。
- 本地文件路径与在线文档路径在工具层已经分叉,不能再假设只有一种存储后端。
### 2.2 Kernel / Projection 层
- `rust/crates/core-protocol/src/kernel.rs` 定义 `KernelProjectionKind``KernelProjectionResourceKind``KernelObjectIdentity` 等协议语义。
- `rust/crates/bridge-runtime/src/lib.rs` 负责从 Convex 侧数据归一化出 kernel nodes / edges / projections,并生成 command plan。
- 语义主导权已经明显从前端迁到 Rust,但前端仍保留若干本地派生投影。
### 2.3 Tree / Command 层
- 正式命令面应落在 `tree.*``tree.resource.*`
- `mnote-web` 同时暴露 `tree` 命令路由与兼容/过渡路由。
- FileTree 资源行已与页面命令对象隔离:资源 owner 只作为上下文,`data-document-id` / 页面命令目标只保留给真正页面行。
### 2.4 Transport / Realtime 层
- Rust Web 已同时注册 `/api/tree/events`SSE)与 `/api/realtime/ws`WS)两条实时链路([routes/mod.rs:170-172](rust/crates/mnote-web/src/routes/mod.rs:170))。
- Rust SSR 主壳([layout.rs](rust/crates/mnote-web/src/ssr/pages/layout.rs:7126))已内置 WS 消费者(`startWithWebSocket`),并在 WS 断开后自动切 SSE fallback`ws.onclose → startWithSseFallback`)。
- 当前默认 `bootstrap.transport` 已切到 `convex-command-log-ws`,主壳先走 WSSSE 保留为 fallback。
- `recycle/wolai-frontend`(已退役的 Next.js legacy 侧)仅使用 SSE,无 WS 消费者。
- WS 与 SSE 的 snapshot / delta 载荷合同已在 Rust 主壳消费层统一;后续重点是继续减少兼容 fallback 与 live cache 补偿链。
### 2.5 Page Aggregate 层
- 文档页入口已经优先消费 Rust `page-aggregate` 快照。
- AI context 的 page subtree 已只读 Rust Page Aggregate 的稳定 projection,不再由前端本地构造第二份 page tree 真相。
- 当前 page aggregate 仍是从 `documents.content` / local markdown content 投影出来的过渡闭环,不是 EditorBlockDocument 原生单一真源闭环。
### 2.6 Editor Runtime 层
- 前端壳:Rust mnote-web 独享 3000 入口,通过 SSR 输出 workspace shell、文档壳、Sidebar、tree 等完整 HTML[gateway.rs](rust/crates/mnote-web/src/routes/gateway.rs:156)、[web_shell.rs](rust/crates/mnote-web/src/routes/web_shell.rs:63))。Next.js 前端代码已随 wolai-frontend 整体移入 `recycle/`,不再作为运行时 daemon 维护。
- `leptos-tiptap` island 已是文档页默认编辑 host,以 WASM 形式由 Rust SSR 加载。
- 保存正文仍会经过 `documents/save` 兼容面。
- 这意味着编辑器体验已经切主,但写回语义还没有完全切到唯一主命令面。
### 2.7 AI Runtime 层
- `mnote.doc.fetch``mnote.doc.markdown_edit``mnote.doc.apply_block_ops``page_ai_workflow`、Hermes / ACP / Reasonix 构成当前 AI 主链。
- 简单正文编辑主路径已统一为模型生成 search/replace / full_content → `mnote.doc.markdown_edit` → 统一 mnote tool executor`mnote.doc.apply_block_ops` 保留为结构性块操作辅助。
- 工具权限、dryRun、幂等、revision / conflictDetectionKey、manifest schema、tool guidance、ACP payload / response 等 P0 合同漂移已收口;Phase C 的 review session / 流式 apply 仍冻结。
## 3. 当前成立的事实与过渡态
### 3.1 已成立事实
- Rust 协议层已经成为语义主线,不再主要依赖前端拼装。
- Tree 主链已经从旧兼容入口退向 Rust Web。
- 文档页主编辑器已经切到 `leptos-tiptap` island。
- AI 页面编辑已经不再是纯前端本地逻辑。
- **前端壳已切换到 Rust**:默认 `desktop:hot` 仅启动 Rust mnote-web 作为 3000 网关 owner。`wolai-frontend`Next.js 前端)已移至 `recycle/`,不再作为运行时 daemon 或 legacy fallback 维护。
### 3.2 过渡态
- Page Aggregate 仍从 `documents.content` 侧 join 构造,而不是原生 EditorBlockDocument 真源。
- 页面正文写回仍经过兼容保存面,尚未完全切到唯一主命令面。
- realtime / Page Aggregate / AI 写入的 P0 合同已基本收口,但兼容路由和历史 adapter 仍偏多。
## 4. 架构冲突矩阵
### 4.1 Tree realtime
- 事实:Rust Web 同时注册 WS 与 SSE。
- 事实:Rust SSR 主壳默认以 WS 为主链,SSE 是断线 fallback。
- 当前状态:原“WS 文档口径 / 前端 SSE 实现”冲突已修复。
- 剩余风险:live cache 与兼容 fallback 仍需要继续瘦身,避免未来再次出现多链路补偿。
### 4.2 FileTree 资源行
- 事实:资源投影行带 `documentId`
- 事实:资源行的 owner document 与页面命令目标已分离,资源行不再暴露页面命令目标 ID。
- 当前状态:原“资源行被当成页面命令对象处理”冲突已修复。
- 剩余风险:资源对象的完整 `tree.resource.*` 命令面仍应继续补齐。
### 4.3 Page Aggregate
- 事实:Rust snapshot 已是入口事实。
- 事实:AI context 的 page subtree 已只读 Rust Page Aggregate projection,外部 AI 写入后会同步本地 aggregate script。
- 当前状态:原“AI context / 文档页 / Rust Aggregate 多源抢真相”的 P0 问题已修复。
- 剩余风险:Page Aggregate 仍从 `documents.content` 投影,不是 EditorBlockDocument 原生落库真相。
### 4.4 AI 写入
- 事实:`markdown_edit` 已是简单正文编辑主路径。
- 事实:Hermes guidance、manifest、page_ai_workflow、tool executor、Reasonix ACP payload 已同步到同一合同。
- 当前状态:原“markdown / block / tool executor 三套合同漂移”的 P0 问题已修复。
- 剩余风险:复杂结构编辑仍应明确落到 `apply_block_ops` / `mnote.block.*`Phase C review / streaming apply 尚未实施。
## 5. 缺失功能
- Page Aggregate 仍缺 EditorBlockDocument 原生落库真相。
- 正文保存仍经过 `documents/save` 兼容面,唯一主命令面尚未完全闭环。
- `tree.resource.*` 仍需要补完整资源对象生命周期命令。
- 兼容路由、历史 adapter 与 fallback 仍偏多,需要继续减小长期维护面。
## 6. 推荐收口顺序
1. 先推进 Page Aggregate 原生 EditorBlockDocument 落库,减少 `documents.content` 投影过渡层。
2. 再收正文保存主命令面,把 `documents/save` 兼容写入逐步迁到正式页面 / 编辑器命令。
3. 再补齐 `tree.resource.*` 资源对象生命周期命令,避免资源操作长期停留在禁用或兼容态。
4. 最后清理兼容路由、历史 adapter 与 fallback,使 Rust kernel / Rust Web / SSR 主壳的合同成为唯一运行口径。
## 7. 相关审查与缺陷
- [设计审查:当前 mnote 项目 AI / Page Aggregate 定向 Review](./design/10-review/done/10-current-mnote-ai-runtime-review-v1.md)
- [设计审查:当前完整架构 Review](./design/10-review/done/11-current-full-architecture-review-v1.md)
## 8. 本次落档缺陷索引
### 8.1 Rust Web / Realtime / ACP
- [3-16 tree realtime WS 主链口径与前端 SSE 实现不一致](./bugs/03-rust-web/done/3-16-tree-realtime-ws-sse-doc-contract-drift-v1.md)
- [3-17 SSE push 模式跳过 polling safety net](./bugs/03-rust-web/done/3-17-sse-push-skips-polling-fallback-v1.md)
- [3-18 WS 与 SSE delta 载荷合同分裂](./bugs/03-rust-web/done/3-18-ws-sse-delta-contract-split-v1.md)
- [3-19 Reasonix ACP wrapper 调 mnote tool 缺少身份与幂等字段](./bugs/03-rust-web/done/3-19-acp-reasonix-tool-call-missing-identity-fields-v1.md)
- [3-20 ACP incoming request 只记录日志不响应](./bugs/03-rust-web/done/3-20-acp-request-permission-no-response-v1.md)
- [3-21 ACP run payload 被第一次 stream_events 消费后移除](./bugs/03-rust-web/done/3-21-acp-run-payload-consumed-and-removed-v1.md)
### 8.2 Tree Domain
- [4-46 FileTree 资源行被当成页面命令对象处理](./bugs/04-tree-domain/done/4-46-filetree-resource-row-document-command-leak-v1.md)
### 8.3 Editor Mainline
- [5-15 PageAggregateClientState 仍在前端生成第二份 page tree 真相](./bugs/05-editor-mainline/done/5-15-page-aggregate-client-state-second-truth-v1.md)
- [5-16 Sidebar preferred snapshot 中 query 可覆盖 live stream](./bugs/05-editor-mainline/done/5-16-sidebar-preferred-snapshot-query-overrides-live-stream-v1.md)
- [5-17 文档页标题优先 liveSidebarTitle 而非 Page Aggregate head](./bugs/05-editor-mainline/done/5-17-document-title-source-drift-live-sidebar-over-head-v1.md)
- [5-18 AI 写正文后本地 Page Aggregate content 可能不刷新](./bugs/05-editor-mainline/done/5-18-ai-write-body-does-not-sync-page-aggregate-content-v1.md)
### 8.4 AI
- [7-18 AI markdown_edit 阶段状态合同漂移](./bugs/07-ai/done/7-18-ai-markdown-edit-phase-state-contract-drift-v1.md)
- [7-19 Hermes 工具指导仍优先 apply_block_ops 而非 markdown_edit](./bugs/07-ai/done/7-19-hermes-tool-guidance-markdown-edit-contract-drift-v1.md)
- [7-20 page_ai_workflow 绕过 Hermes tool executor / audit / toggle](./bugs/07-ai/done/7-20-page-ai-workflow-bypasses-hermes-tool-executor-v1.md)
- [7-21 mnote.doc.markdown_edit 本地文件写入绕过 dryRun / idempotency](./bugs/07-ai/done/7-21-markdown-edit-local-write-contract-bypass-v1.md)
- [7-22 mnote.doc.apply_block_ops 批量写入缺少 revision / conflictDetectionKey 校验](./bugs/07-ai/done/7-22-apply-block-ops-missing-write-preconditions-v1.md)
- [7-23 mnote.doc.markdown_edit manifest schema 缺少 required 与写入字段](./bugs/07-ai/done/7-23-markdown-edit-manifest-schema-contract-drift-v1.md)
- [7-24 在线 markdown_edit 写回不以最终 Markdown 为真源](./bugs/07-ai/done/7-24-markdown-edit-online-write-does-not-use-final-markdown-v1.md)
- [7-25 ACP Reasonix 页面 AI block_edit_workflow 在 markdown 命中后生成空 block_ops](./bugs/07-ai/done/7-25-reasonix-block-edit-workflow-empty-block-ops-after-markdown-match-v1.md)