Files
mnote/CURRENT_ARCHITECTURE.md
T
lix-2026 61ee4a38a2 docs: update architecture review notes
- clarify Rust SSR shell, WS/SSE transport status, and Next legacy role

- add Reasonix block edit workflow empty block ops bug record

Verification:

- git diff --check -- CURRENT_ARCHITECTURE.md design/10-review/process/11-current-full-architecture-review-v1.md bugs/07-ai/process/7-25-reasonix-block-edit-workflow-empty-block-ops-after-markdown-match-v1.md
2026-05-17 23:16:37 +08:00

167 lines
10 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 资源行仍可能被当成页面命令对象处理,违反 Resource Tree / File Tree / Page Tree 分层。
### 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-sse`,因此主壳默认走 SSE;WS 路径代码已就绪但尚未设为默认 transport,前端主消费链路仍未切换到 WS 默认。
- `wolai-frontend`Next.js legacy 侧)仅使用 SSE`use-sidebar-tree-stream.ts`),无 WS 消费者。
- SSE 内部还保留 push/polling 两种语义,WS 与 SSE 的 delta / snapshot 结构也未完全收敛。
### 2.5 Page Aggregate 层
- 文档页入口已经优先消费 Rust `page-aggregate` 快照。
- 但前端仍保留 `PageAggregateClientState` reducer 和本地 `page tree` 投影。
- 当前 page aggregate 是“Rust join + 前端局部状态”的过渡闭环,不是 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/`,但默认热启动不再作为运行时 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 主链。
- 这里存在最密集的合同漂移:工具权限、写入幂等、dryRun、revision 校验、manifest schema、tool guidance、runtime owner 都还没有统一。
## 3. 当前成立的事实与过渡态
### 3.1 已成立事实
- Rust 协议层已经成为语义主线,不再主要依赖前端拼装。
- Tree 主链已经从旧兼容入口退向 Rust Web。
- 文档页主编辑器已经切到 `leptos-tiptap` island。
- AI 页面编辑已经不再是纯前端本地逻辑。
- **前端壳已切换到 Rust**:默认 `desktop:hot` 仅启动 Rust mnote-web 作为 3000 网关 owner,不再启动 Next.js (`wolai-frontend`) 作为运行时 daemon。Next.js 仅保留为 legacy compat fallback`MNOTE_WEB_SKIP_GATEWAY=1`)与 build toolchain。
### 3.2 过渡态
- Page Aggregate 仍从 `documents.content` 侧 join 构造,而不是原生 EditorBlockDocument 真源。
- 前端 Sidebar 仍有本地投影与多源抢真相。
- `mnote.doc.markdown_edit` 已进入主线,但写入合同尚不完整。
- ACP / Reasonix 已接入,但调用字段和运行时所有权仍不统一。
## 4. 架构冲突矩阵
### 4.1 Tree realtime
- 事实:Rust Web 已注册 WS。
- 事实:前端仍只见 SSE consumer。
- 冲突:系统口径已升级,但前端主链未同步切换。
- 影响:live cache、调试、回放与验收都会出现双口径。
### 4.2 FileTree 资源行
- 事实:资源投影行带 `documentId`
- 事实:`tree.tsx` 相关路径会把它当作页面对象处理。
- 冲突:资源树与页面树边界被突破。
- 影响:误删、误重命名、误移动风险上升。
### 4.3 Page Aggregate
- 事实:Rust snapshot 已是入口事实。
- 事实:前端 reducer 与本地 page tree 还在派生第二份状态。
- 冲突:页面标题、正文、树投影可能各自取源。
- 影响:AI context、Sidebar、正文显示不一定同源。
### 4.4 AI 写入
- 事实:`markdown_edit` 已是主推路径。
- 事实:Hermes guidance、manifest、page_ai_workflow、apply_block_ops 仍在不同层保留旧习惯。
- 冲突:同一条编辑链路里存在 markdown / block / tool executor 三套合同。
- 影响:写入正确性、幂等性、回读一致性都不稳定。
## 5. 缺失功能
- 前端树流仍缺统一的 WS 主 consumer。
- Page Aggregate 仍缺前端第二真相收口。
- FileTree 资源行仍缺严格的命令面隔离。
- `mnote.doc.markdown_edit` 仍缺完整写入合同。
- ACP / Reasonix 仍缺统一身份、会话、运行、幂等字段。
- 兼容路由仍偏多,正式命令面与过渡面边界还不够硬。
## 6. 推荐收口顺序
1. 先收 `tree` 实时链路口径,让前端主消费与后端主发布一致。
2. 再收 FileTree 资源行命令边界,避免资源对象误走页面命令。
3. 再收 Page Aggregate 单一真源,减少 Sidebar / 文档页 / AI context 多源抢真相。
4. 最后收 AI 写入合同,把 `markdown_edit``apply_block_ops`、Hermes / ACP / Reasonix 的调用协议统一起来。
## 7. 相关审查与缺陷
- [设计审查:当前 mnote 项目 AI / Page Aggregate 定向 Review](./design/10-review/process/10-current-mnote-ai-runtime-review-v1.md)
- [设计审查:当前完整架构 Review](./design/10-review/process/11-current-full-architecture-review-v1.md)
## 8. 本次落档缺陷索引
### 8.1 Rust Web / Realtime / ACP
- [3-16 tree realtime WS 主链口径与前端 SSE 实现不一致](./bugs/03-rust-web/process/3-16-tree-realtime-ws-sse-doc-contract-drift-v1.md)
- [3-17 SSE push 模式跳过 polling safety net](./bugs/03-rust-web/process/3-17-sse-push-skips-polling-fallback-v1.md)
- [3-18 WS 与 SSE delta 载荷合同分裂](./bugs/03-rust-web/process/3-18-ws-sse-delta-contract-split-v1.md)
- [3-19 Reasonix ACP wrapper 调 mnote tool 缺少身份与幂等字段](./bugs/03-rust-web/process/3-19-acp-reasonix-tool-call-missing-identity-fields-v1.md)
- [3-20 ACP incoming request 只记录日志不响应](./bugs/03-rust-web/process/3-20-acp-request-permission-no-response-v1.md)
- [3-21 ACP run payload 被第一次 stream_events 消费后移除](./bugs/03-rust-web/process/3-21-acp-run-payload-consumed-and-removed-v1.md)
### 8.2 Tree Domain
- [4-46 FileTree 资源行被当成页面命令对象处理](./bugs/04-tree-domain/process/4-46-filetree-resource-row-document-command-leak-v1.md)
### 8.3 Editor Mainline
- [5-15 PageAggregateClientState 仍在前端生成第二份 page tree 真相](./bugs/05-editor-mainline/process/5-15-page-aggregate-client-state-second-truth-v1.md)
- [5-16 Sidebar preferred snapshot 中 query 可覆盖 live stream](./bugs/05-editor-mainline/process/5-16-sidebar-preferred-snapshot-query-overrides-live-stream-v1.md)
- [5-17 文档页标题优先 liveSidebarTitle 而非 Page Aggregate head](./bugs/05-editor-mainline/process/5-17-document-title-source-drift-live-sidebar-over-head-v1.md)
- [5-18 AI 写正文后本地 Page Aggregate content 可能不刷新](./bugs/05-editor-mainline/process/5-18-ai-write-body-does-not-sync-page-aggregate-content-v1.md)
### 8.4 AI
- [7-18 AI markdown_edit 阶段状态合同漂移](./bugs/07-ai/process/7-18-ai-markdown-edit-phase-state-contract-drift-v1.md)
- [7-19 Hermes 工具指导仍优先 apply_block_ops 而非 markdown_edit](./bugs/07-ai/process/7-19-hermes-tool-guidance-markdown-edit-contract-drift-v1.md)
- [7-20 page_ai_workflow 绕过 Hermes tool executor / audit / toggle](./bugs/07-ai/process/7-20-page-ai-workflow-bypasses-hermes-tool-executor-v1.md)
- [7-21 mnote.doc.markdown_edit 本地文件写入绕过 dryRun / idempotency](./bugs/07-ai/process/7-21-markdown-edit-local-write-contract-bypass-v1.md)
- [7-22 mnote.doc.apply_block_ops 批量写入缺少 revision / conflictDetectionKey 校验](./bugs/07-ai/process/7-22-apply-block-ops-missing-write-preconditions-v1.md)
- [7-23 mnote.doc.markdown_edit manifest schema 缺少 required 与写入字段](./bugs/07-ai/process/7-23-markdown-edit-manifest-schema-contract-drift-v1.md)
- [7-24 在线 markdown_edit 写回不以最终 Markdown 为真源](./bugs/07-ai/process/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/process/7-25-reasonix-block-edit-workflow-empty-block-ops-after-markdown-match-v1.md)