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
15 KiB
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 已修正的关键问题
- IPC 协议:已补齐 tool.call/result/stream、worker.result/checkpoint、protocol.error
- 依赖方向:已消除 Scheduler↔WorkerManager、EventStore↔EventBus、CapabilityRegistry↔DoctorService 循环
- TUI 边界:已明确 TUI 只依赖
ProjectionClient,不导入 runtime 内部 - ProviderManager 归属:已明确在
packages/llm,runtime 通过 facade 调用 - EventIngestor:已引入作为事件摄入边界,EventStore 不再隐式触发业务动作
- Permission 模型:已统一为
action + grant_scope - Task 依赖:已改为边列表模型,Scheduler 可动态追加持久化冲突边
- 执行原语:已通过
runtime-semantics-v1.md定义 read-before-edit token、exact edit、completion gate
1.4 剩余架构关注点
- 跨 DB/文件事务:
runtime-semantics-v1.md已定义 outbox/compensation 模型,但DebugKnowledgeStore和learned-memory服务接口尚未定义 - 学习/技能生命周期:
candidate → approval → promotion → rollback流程已有文档描述,但缺少形式化状态机 - 项目扫描:已确认无限递归无排除原则,安全边界(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 范围明确,接口契约基本可编译,运行时语义已澄清。本轮修正解决了第一轮审查发现的所有关键问题,剩余问题都是工程一致性层面的细节。