Files
AirCoding/AirPlan/docs/architecture/MIMO2.5三视角审查.md
AirCoding 82f3140847 Initial commit: AirCoding V1.0.0 Alpha architecture baseline
Complete architecture document set with multi-model review remediation:
- Frozen interface contracts, runtime semantics, DB schemas
- Event/tool/error/provider registries
- Scheduler and main agent state machines
- C4 module/code views, solution architecture, baseline V1
- Multi-model review reports and joint assessment
- Phase-gate remediation complete (P0/P1/P2/UX resolved)
- Implementation plan with T-000A through T-045
- Reference folders kept as placeholders only
2026-05-28 18:45:01 +08:00

330 lines
15 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.
# MIMO2.5 三角度架构审查报告
Date: 2026-05-28
Status: Second-round architecture review after major corrections
Model: MIMO v2.5 (1M context)
Reviewer scope: All architecture documents under `AirPlan/docs/architecture/`
## 审查背景
本轮审查基于第一轮审查后的修正结果,包括:
- 接口契约统一为 `snake_case` 并重写为可实现版本
- Permission 统一为 `action + grant_scope` 模型
- Error 统一为 `AirError` 嵌入式结构
- Task 依赖统一为边列表模型(含 `hard/soft/conflict/serialization`
- IPC 补齐 `tool.call/tool.result/tool.stream/worker.result/worker.checkpoint/protocol.error`
- C4/UML 修正 TUI、ProviderManager、EventIngestor、Scheduler/WorkerManager、Capability/Doctor 依赖方向
- 新增 `runtime-semantics-v1.md` 明确跨 DB 事务、heartbeat、执行原语等
- 目标从半成品 MVP 升级为 V1.0.0 Alpha含完整 C++ 工作流和插件基础)
- 明确 source-of-truth precedence
- 消除 VibeBox 双 baseline 歧义
---
## 1. 架构师视角
### 1.1 总体评价
架构方向正确,修正后的 IPC 协议、依赖方向、EventIngestor、权限模型、任务依赖边列表均已收敛。剩余问题主要是**跨文档一致性**,不是设计方向问题。
V1.0.0 Alpha 范围合理:完整 C++ 开发闭环、插件/能力基础、TUI/HUD、验证与打包都在范围内。推迟容器沙箱、第三方插件签名、Windows 原生支持等是正确的取舍。
### 1.2 可接受的取舍
| 取舍 | 理由 |
|---|---|
| 项目本地 `.air` 作为状态源 | 本地 coding agent 的合理选择,避免云端耦合 |
| Anthropic canonical 内部消息格式 | 简化多 Provider 支持,转换在 adapter 边界 |
| EventBus 用于实时、SQLite 用于恢复 | 正确的职责分离,已通过 EventIngestor 澄清 |
| 独立 Bun 子进程 + NDJSON IPC | 良好的隔离边界,协议已补齐 |
| C++ 作为第一个深度工具链 | 对架构有高验证价值,同时保持 `toolchain-*` 可扩展性 |
| Architecture Designer 作为显式升级路径 | 多 agent 编码运行时的合理治理模型 |
| `foreign_keys = OFF` | 降低迁移/恢复复杂度,但需要应用层一致性契约(见 S8 |
### 1.3 已修正的关键问题
1. **IPC 协议**:已补齐 tool.call/result/stream、worker.result/checkpoint、protocol.error
2. **依赖方向**:已消除 Scheduler↔WorkerManager、EventStore↔EventBus、CapabilityRegistry↔DoctorService 循环
3. **TUI 边界**:已明确 TUI 只依赖 `ProjectionClient`,不导入 runtime 内部
4. **ProviderManager 归属**:已明确在 `packages/llm`runtime 通过 facade 调用
5. **EventIngestor**已引入作为事件摄入边界EventStore 不再隐式触发业务动作
6. **Permission 模型**:已统一为 `action + grant_scope`
7. **Task 依赖**已改为边列表模型Scheduler 可动态追加持久化冲突边
8. **执行原语**:已通过 `runtime-semantics-v1.md` 定义 read-before-edit token、exact edit、completion gate
### 1.4 剩余架构关注点
1. **跨 DB/文件事务**`runtime-semantics-v1.md` 已定义 outbox/compensation 模型,但 `DebugKnowledgeStore``learned-memory` 服务接口尚未定义
2. **学习/技能生命周期**`candidate → approval → promotion → rollback` 流程已有文档描述,但缺少形式化状态机
3. **项目扫描**已确认无限递归无排除原则安全边界symlink 环、挂载异常)已补充
---
## 2. 工程师视角
### 2.1 阻塞级问题B1-B6
这些问题会阻止 `packages/contracts` 编译为可用 TypeScript 包,或导致运行时失败。
#### B1. `AirError.cause_ref` 类型冲突
**位置**`interface-contracts-v1.md` §3 vs `error-taxonomy-v1.md` §2
**问题**
- `interface-contracts-v1.md``cause_ref` 类型为 `EntityRef``{ type: EntityType, id: string }` 结构)
- `error-taxonomy-v1.md``cause_ref` 为内联扁平字段对象:`{ event_id?, task_id?, agent_id?, tool_run_id?, command_run_id?, artifact_id?, diagnostic_id? }`
- 两个结构体不兼容,消费者期望其中一种格式会与另一种冲突
**修复方向**:以 `interface-contracts-v1.md``EntityRef` 为准,更新 `error-taxonomy-v1.md`
---
#### B2. `DebugKnowledgeStore` 和 learned-memory 服务接口缺失
**位置**`runtime-semantics-v1.md` §6.3, §6.4
**问题**
- `runtime-semantics-v1.md` 引用 `DebugKnowledgeStore` 作为写入 `debug-records.db` 的服务
- 引用未命名的 "ExperienceMiner/Curator service" 写入 `learned-memory.db`
- 两个服务在 `interface-contracts-v1.md` 中均无接口契约
- `c4/code-view.md` 中也未列出这些运行时类
- 开发者实现 §6 的跨 DB 事务语义时没有可实现的契约
**修复方向**:在 `interface-contracts-v1.md` 中添加 `DebugKnowledgeStore``LearnedMemoryStore` 接口
---
#### B3. `debug-records.db` 和 `learned-memory.db` 无 schema 定义
**位置**`db-schema-v1.md`
**问题**
- `db-schema-v1.md` 只覆盖 `session.db`
- 这两个项目级数据库在至少 4 个文档中被引用,但无 DDL、无表定义、无列规范
- `debug.record.created` 事件载荷暗示了 `debug_record_id``failure_signature``summary` 等列,但目标表结构未定义
**修复方向**:在 `db-schema-v1.md` 中补充 `debug-records.db``learned-memory.db` 的 schema
---
#### B4. `PermissionProfile` 命名冲突
**位置**`security-model-v1.md` §3 vs `interface-contracts-v1.md` §10
**问题**
- `security-model-v1.md` 定义 `PermissionProfile``"low" | "normal" | "high" | "developer"`(安全态势)
- `interface-contracts-v1.md` 定义 `AgentRuntimeContext.permission_profile``"main_direct" | "executor" | "reviewer" | "debugger" | "system"`(角色权限模板)
- 两个不同概念使用相同名称 `permission_profile`,实现者可能混淆
**修复方向**:将 `AgentRuntimeContext.permission_profile` 重命名为 `permission_template``role_permission`
---
#### B5. `EntityType` 集合不一致
**位置**`interface-contracts-v1.md` §4 vs `event-registry-v1.md` §1
**问题**
- `interface-contracts-v1.md` 定义 `EntityType` 含 12 个值,包括 `"capability"``"provider"`
- `event-registry-v1.md` 内联定义自己的 `EntityRef` 只有 10 个值,缺失 `"capability"``"provider"`
- 如果两者编译到同一包,会有两个冲突的 `EntityRef` 定义
**修复方向**:以 `interface-contracts-v1.md` 为准event-registry 引用该定义而非内联
---
#### B6. `CompactionPolicy`、`PromptLayer`、`PromptLayerLoader` 无契约
**位置**`c4/code-view.md` §4 vs `interface-contracts-v1.md` §16
**问题**
- `c4/code-view.md` 列出 `CompactionPolicy.ts``PromptLayerLoader.ts` 并引用 `PromptLayer` 类型
- `interface-contracts-v1.md` §16 只定义了最小 `ContextAssembler` 接口
- `ContextAssembleInput.refs``string[]` 无结构,而 code-view 的 `ContextPack.refs` 有结构化形状
- 没有 `PromptLayer` 定义,`ContextAssembler` 无法实现
**修复方向**:在 `interface-contracts-v1.md` 中补充 `PromptLayer``CompactionPolicy``PromptLayerLoader` 接口
---
### 2.2 应修复问题S1-S10
这些问题不会阻止编译,但会造成混淆、重复或测试困难。
#### S1. `ToolCategory` 和 `ToolResultEnvelope` 重复定义
**位置**`interface-contracts-v1.md` §12 和 `tool-registry-v1.md` §2
**问题**:两者定义了相同的 `ToolCategory``ToolResultEnvelope`。编译到同一包时 TypeScript 会报重复标识符。
**修复方向**`tool-registry-v1.md` 引用 `interface-contracts-v1.md`,不重复定义。
---
#### S2. `TaskInsert = TaskRecord` 强制调用方传服务器生成字段
**位置**`interface-contracts-v1.md` §6
**问题**`TaskInsert` 等于 `TaskRecord`,意味着调用方必须提供 `created_at``retry_count``status`。通常 insert 应使用子集类型,服务器默认值由存储层填充。`PersistedEventRecord` 有同样问题。
**修复方向**:定义 `TaskInsert``EventInsert` 为省略服务器生成字段的子集类型。
---
#### S3. `ToolExecutor.execute` 返回未区分联合类型
**位置**`interface-contracts-v1.md` §12
**问题**:返回 `AsyncIterable<ToolEvent> | Promise<ToolResultEnvelope<O>>`,调用方需 duck-type 或 `Symbol.asyncIterator` 检查来区分流式与非流式。`streaming: boolean` 字段存在但未在类型层面强制。
**修复方向**:使用判别联合或品牌化返回类型。
---
#### S4. `EventBus.subscribe` handler 抛错行为未定义
**位置**`interface-contracts-v1.md` §7
**问题**:如果订阅 handler 抛出异常,契约未说明:(a) 错误被吞掉,(b) 传播给发布者,(c) 订阅被终止。
**修复方向**:明确 handler 错误不影响发布者,错误被记录但不传播。
---
#### S5. `JsonSchema<T>` 泛型参数 `T` 未使用
**位置**`interface-contracts-v1.md` §2
**问题**`type JsonSchema<T = unknown> = JsonObject``T` 从未在类型体中引用,是幽灵类型,不提供编译时安全。
**修复方向**:移除泛型参数或定义品牌化类型。
---
#### S6. `SchedulerWavePlan.wave_id` 是 `string` 而非品牌化 ID
**位置**`interface-contracts-v1.md` §9
**问题**:系统中其他标识符都用品牌化类型别名(`TaskID``AgentID` 等),`wave_id` 是普通 `string`,不一致且无法防止 ID 类型混淆。
**修复方向**:添加 `WaveID` 品牌化类型。
---
#### S7. `FollowUpTask.type` 允许 `"docs"` 但 `TaskType` 不含 `"docs"`
**位置**`interface-contracts-v1.md` §11
**问题**`FollowUpTask.type``TaskType | "docs"`,但 `TaskType` 不含 `"docs"`。Scheduler 收到 `type: "docs"` 的 follow-up 时无法调度。
**修复方向**:将 `"docs"` 加入 `TaskType`,或从 `FollowUpTask.type` 中移除。
---
#### S8. `foreign_keys = OFF` 无应用层一致性契约
**位置**`db-schema-v1.md` §1
**问题**:禁用外键并声明"应用层一致性检查处理引用",但无文档定义这些检查是什么、何时运行、孤立行如何处理。
**修复方向**:在 Repository 接口中明确 insert 是否验证外键存在,或在 `runtime-semantics-v1.md` 中补充孤儿清理规则。
---
#### S9. `PermissionEngine.record` 返回 `Promise<void>` 无错误指示
**位置**`interface-contracts-v1.md` §10
**问题**如果记录权限决策失败磁盘满、DB 锁),调用方无法得知。
**修复方向**:返回结果类型或指定抛出的类型化错误。
---
#### S10. `ProjectionStore.apply` 接受任意事件无过滤规范
**位置**`interface-contracts-v1.md` §14
**问题**`apply(event: RuntimeEvent): void` 未指定哪些事件类型会触发投影更新,实现者需猜测。
**修复方向**:添加文档说明预期的事件集,或使用类型窄化联合。
---
### 2.3 可接受的缺口
| 缺口 | 理由 |
|---|---|
| 无 monorepo 工具配置 | 实现选择 |
| 无具体 SQLite 迁移策略 | 单版本 V1.0.0 Alpha 可接受 |
| 无 Provider 重试/退避细节 | adapter 实现细节 |
| 无 TUI 组件细节 | TUI 仅消费投影,实现自由度高 |
| 无具体 token 计数实现 | Provider adapter 处理 |
| `ProviderCapabilityMatrix.supports/.conversion``JsonObject` | 故意保留 provider 特定形状灵活性 |
| 无具体 `semantic_signature` 算法 | 格式已定义,哈希函数为实现选择 |
| 无 IPC 传输层契约 | 信封格式已定义,传输为实现细节 |
| 无 EventStore schema 验证失败的具体错误形状 | 次要缺口 |
---
## 3. 用户视角(原始需求对齐)
### 3.1 需求对齐检查
| 原始需求 | 当前状态 | 评价 |
|---|---|---|
| 自有 AI coding agent/runtime非 Claude Code 插件包装 | 独立架构,自有运行时、调度器、工具系统 | 已满足 |
| Claude Code 级执行层质量 | D-059 + runtime-semantics 定义了 read-before-edit、exact edit、completion gate | 已满足 |
| OpenCode TUI 风格复用 | `@opentui/solid`,投影消费模式,不复用业务状态 | 已满足 |
| 项目本地 `.air` 状态 | `.air/shared` + `.air/local`session DB 项目本地 | 已满足 |
| 事件驱动 + SQLite 恢复 | EventBus 实时 + EventStore 持久化 + ProjectionStore 投影 | 已满足 |
| 独立子进程 worker + NDJSON IPC | 已定义完整 IPC 协议含 tool 调用 | 已满足 |
| C++ 作为第一个深度工具链 | `toolchain-cpp` 包含完整工作流 | 已满足 |
| 多 agent 调度 | Scheduler + TaskGraph + 边列表依赖 + 波次规划 | 已满足 |
| 权限模型 | `action + grant_scope`,路径/命令/网络/凭据分类 | 已满足 |
| VibeBox 下游分支 | `branchvibebox/` 独立 baseline + feasibility plan | 已满足 |
| 非半成品 MVP目标 V1.0.0 Alpha | 范围已升级,含完整 C++ 工作流和插件基础 | 已满足 |
### 3.2 无方向性冲突
用户视角下无设计方向性冲突。所有 B/S 级问题都是工程实现一致性问题,不影响产品定位和架构决策。
---
## 4. 优先级建议
### 必须在系统概要设计前修复B1-B6
| 优先级 | ID | 修复内容 |
|---|---|---|
| 1 | B1 | 统一 `AirError.cause_ref``EntityRef`,更新 error-taxonomy |
| 2 | B4 | 重命名 `AgentRuntimeContext.permission_profile``permission_template` |
| 3 | B5 | event-registry 引用 interface-contracts 的 `EntityRef`,不内联 |
| 4 | B2 | 在 interface-contracts 补充 `DebugKnowledgeStore``LearnedMemoryStore` 接口 |
| 5 | B3 | 在 db-schema-v1 补充 `debug-records.db``learned-memory.db` DDL |
| 6 | B6 | 在 interface-contracts 补充 `PromptLayer``CompactionPolicy``PromptLayerLoader` |
### 可在概要设计中同步修复S1-S10
| 优先级 | ID | 修复内容 |
|---|---|---|
| 1 | S7 | 将 `"docs"` 加入 `TaskType` 或从 `FollowUpTask.type` 移除 |
| 2 | S2 | 定义 `TaskInsert`/`EventInsert` 子集类型 |
| 3 | S1 | tool-registry 引用 interface-contracts不重复定义 |
| 4 | S6 | 添加 `WaveID` 品牌化类型 |
| 5 | S4 | 定义 EventBus handler 错误行为 |
| 6 | S8 | 补充 FK 一致性契约或孤儿清理规则 |
| 7 | S9 | `PermissionEngine.record` 返回结果类型 |
| 8 | S10 | `ProjectionStore.apply` 添加事件过滤文档 |
| 9 | S3 | `ToolExecutor` 返回判别联合 |
| 10 | S5 | 移除 `JsonSchema<T>` 泛型参数 |
---
## 5. 审查结论
**可以进入系统概要设计阶段**,前提是 B1-B6 先修复。S1-S10 可在概要设计过程中同步处理。
架构文档集整体质量高V1.0.0 Alpha 范围明确,接口契约基本可编译,运行时语义已澄清。本轮修正解决了第一轮审查发现的所有关键问题,剩余问题都是工程一致性层面的细节。