迁移路径: /run/media/airlongdian/EasyU/AirCoding -> /home/airlongdian/DataDevices/AirWorkSpace/AirCoding Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
16 KiB
Executable File
MIMO 2.5 Pro 系统详细设计全量交叉审查
Date: 2026-05-29
Reviewer: MIMO 2.5 Pro (single-model, independent pass)
Status: Full cross-verification of system-detailed-design.md against all frozen baselines, frozen overview, and internal architectural consistency
Scope: Coverage + consistency + architecture soundness audit
1. 审查方法
审查对象:AirPlan/docs/architecture/system-detailed-design.md(2033 行,23 节)
审查三维度:
- 覆盖性:基线/概要设计的每个 item 是否在详细设计中有对应项
- 一致性:详细设计内部是否存在矛盾、基线引用是否准确
- 架构合理性:类职责划分、依赖方向、边界执行是否合理,是否存在内在冲突
审查输入:
| 文档 | 角色 |
|---|---|
interface-contracts-v1.md (23 节) |
接口契约 |
event-registry-v1.md (55 durable + 7 ephemeral) |
事件注册表 |
db-schema-v1.md (19 表, 18 个关闭枚举) |
数据库 Schema |
runtime-semantics-v1.md (19 节) |
运行时语义 |
scheduler-state-machine-v1.md (11 节) |
调度器状态机 |
main-agent-state-machine.md |
主代理状态机 |
prompt-layering-v1.md (L0-L9) |
提示分层 |
scope-escalation-v1.md (13 节) |
作用域升级 |
security-model-v1.md (8 PathRisk + 10 CommandRisk) |
安全模型 |
capability-trust-v1.md |
能力信任 |
system-overview-design.md (FROZEN, 1222 行) |
概要设计 |
DeepSeek系统详细设计审查.md |
前一轮审查报告 |
方法:
- 逐契约接口字段比对
- 逐事件投影映射核对
- 逐表仓储核对
- 逐状态机转换核对
- PromptLayer 三方比对(contracts / prompt-layering / overview)
- 依赖方向一致性验证
- 内在冲突检测
2. 总体评估
2.1 评分
| 维度 | 得分 | 说明 |
|---|---|---|
| 契约覆盖 | 9.5/10 | 接口字段全覆盖,1 处 PromptLayerLevel 枚举与层名不完全对齐 |
| 事件覆盖 | 10/10 | 55 durable + 7 ephemeral 全覆盖 |
| DB Schema 覆盖 | 10/10 | 19 表全仓储 |
| 状态机覆盖 | 10/10 | 6 个状态机全覆盖 |
| 内在一致性 | 8.5/10 | 1 处真实内部矛盾(PromptLayer),1 处架构弱点(EventStore 错误隔离) |
| 架构合理性 | 9.5/10 | 边界清晰、职责分离良好、依赖方向正确 |
| 序列图覆盖 | 8.0/10 | 4 个关键序列覆盖,2 个可补充 |
| 可实现性 | 9.5/10 | 方法签名可直接编码,无歧义 |
综合评分:9.4/10
2.2 结论
详细设计是一个高质量的实现导向文档。架构边界清晰,依赖方向正确,类职责分离良好。发现了 1 处真实内部矛盾 和 1 处架构弱点 需要解决,但均不阻塞实现阶段——可以通过明确的设计决策澄清来修复。
3. P0 发现(0 项)
未发现 P0 项。
4. P1 发现(2 项)
P1-01: PromptLayerLevel 枚举与 L0-L9 层名结构性不对齐
严重度:P1(真实内部矛盾,影响实现一致性)
问题:interface-contracts-v1.md §16 定义了 10 个 PromptLayerLevel 枚举值,prompt-layering-v1.md §2 定义了 L0-L9 共 10 个层名。概要设计 §13 已将 L0-L9 逐层与基线对齐。但三方存在结构性不匹配:
| L# | prompt-layering-v1 §2 | contracts §16 枚举值 | 对齐状态 |
|---|---|---|---|
| L0 | Runtime invariant | runtime_invariant |
✓ |
| L1 | Role / agent mode | role |
✓ |
| L2 | Safety and permission policy | (无对应枚举值) | ✗ |
| L3 | Project rules and user preferences | project_rules |
✓ |
| L4 | Architecture baseline and current plan | architecture |
✓ |
| L5 | Task specification and acceptance criteria | task_spec |
✓ |
| L6 | Relevant code / artifacts / evidence | evidence |
✓ |
| L7 | Recent conversation and decision context | conversation |
✓ |
| L8 | Tool result history / diagnostics | tool_output |
✓ |
| L9 | Immediate instruction | user_override(名字不同) |
△ |
| — | (无对应层) | system_debug |
✗ |
矛盾点:
- L2 "Safety and permission policy" 没有对应的
PromptLayerLevel枚举值——但它是 prompt-layering-v1 定义的独立层 user_override映射到 L9,但概要设计 §13 说 L9 = "Immediate instruction",名字不一致system_debug枚举值没有对应的 L 层——DD §10.2 说"applied within L9 when present",但这是一个缩写而非结构映射
影响:实现时 ContextAssembler.load_layers() 需要 10 个加载点,但 PromptLayerLoader 接口只有 4 个方法(load_runtime_invariant, load_role, load_project_rules, load_task_context)。L2 safety、L4 architecture、L6 evidence、L7 conversation、L8 tool_output、L9 immediate instruction 都没有明确的 loader 方法。
修复建议(需要设计决策):
- 选项 A:在 contracts §16 添加
safety_permission枚举值,将user_override改名为immediate_instruction,删除system_debug或并入 L9 - 选项 B:保持枚举不变,在实现层将 L2 映射到
runtime_invariant(immutable=true),L9 由user_override+system_debug合并 - 选项 C:扩展
PromptLayerLoader接口添加 L2/L4-L9 的显式加载方法
无论选哪个,需要一个明确的设计决策记录。
P1-02: EventStore.project() 错误处理未定义
严重度:P1(架构弱点,影响运行时鲁棒性)
问题:DD §5.3 EventStore.append() 在事务内执行 EventRepository.insert() 和 project(event, tx)。但 project() 执行的是多行 domain update(如 task.started 需要更新 tasks 表 + 插入 task_attempts 行)。如果 project() 中间步骤失败,事务会回滚——但此时 EventBus.publish() 不会执行(正确行为),然而 没有描述 project() 内部的错误语义:
- 如果
project()抛出异常,是整个append()回滚?(应该) - 如果 domain update 因 FK-off 不一致失败(如引用了不存在的
tasks.id),错误如何传播? project()是否有部分失败的恢复逻辑?
影响:在高并发或重启恢复场景下,如果 project() 的某一步 domain update 失败(如引用的 task 已被删除),整个事件追加会回滚——这是正确的原子行为,但 DD 没有显式描述这个错误路径。
修复建议:在 DD §5.3 或 §18.2 添加:project() 异常 → 事务回滚 → EventBus.publish() 不执行 → 返回 AirError{kind: "system_error"}。如果是因为 FK-off 不一致导致,记录到 developer log 并触发 referential_check()。
5. P2 发现(5 项)
P2-01: DeepSeek 审查报告中的 3 项 P2 已验证
DeepSeek 审查报告的 3 项 P2 均确认属实:
| ID | DeepSeek 发现 | MIMO 验证 |
|---|---|---|
| DeepSeek P2-01 | PromptLayerLevel 枚举与 L0-L9 不完全 1:1 | 确认(已升级为 MIMO P1-01) |
| DeepSeek P2-02 | Architecture Designer gate 无独立序列图 | 确认,P2 |
| DeepSeek P2-03 | CLI catalog 命令类归属未指定 | 确认,P2 |
P2-04: agent.started 投影映射措辞
DD §5.4 投影映射表中 agent.started 的域更新描述为 "insert agents (starting/running)"。这暗示 project() 可能选择 starting 或 running,但 event-registry §3.3 固定为 "insert agents row with status = running or starting"——具体选择哪个取决于调度器上下文(spawn 前 vs 握手后)。
建议:DD 应明确 starting 是初始状态,running 是握手完成后的状态(与 db-schema §10 agent status 一致)。当前描述可接受但含糊。
P2-05: WorkspaceManager 与 Scheduler 状态机 MERGING 阶段的职责边界
DD §7.5 WorkspaceManager.merge_workspace() 和 DD §20.2 Scheduler 的 MERGING 状态都描述了合并逻辑。但 Scheduler 状态机的 MERGING 包含了冲突处理路由(trivial → repair/debugger, semantic → Reviewer/Architecture Designer, architecture → block, user → Main Agent)——这些是 Scheduler 级别的决策,而 WorkspaceManager 只负责 git 操作。
建议:明确 WorkspaceManager 返回 MergeResult{status: success|conflict, conflict_files?, conflict_type?},Scheduler 根据 conflict_type 做路由决策。当前描述隐含了这个分工但没有显式标注。
6. 架构合理性分析
6.1 依赖方向
contracts → (none)
llm → contracts
toolchain-cpp → contracts
tui → contracts
runtime → contracts, llm (facade only)
cli → contracts, runtime, tui, llm, toolchain-cpp
workers → contracts + WorkerRuntime IPC (no direct runtime import)
评估:完全正确。contracts 是叶节点,cli 是根节点,runtime 依赖 llm 但仅通过 facade(ProviderManager 接口),workers 通过 IPC 间接依赖 runtime(不直接 import)。这个依赖方向避免了循环依赖,允许各包独立编译。
6.2 职责分离
| 组件 | 职责 | 边界 | 评估 |
|---|---|---|---|
| EventIngestor | 事件入口 | 不创建 scheduler/permission/memory 决策 | ✓ 正确隔离 |
| EventStore | 持久化事件 + 投影 | 不直接暴露 EventBus | ✓ 正确(投影在事务内,发布在事务后) |
| EventBus | 实时发布/订阅 | 不是恢复源 | ✓ 正确 |
| SessionStore | 聚合所有仓储 | 不含调度/权限/投影策略 | ✓ 正确(code-view §9) |
| Scheduler | 编排服务 | 不是编码代理 | ✓ 正确(scheduler-state-machine §intro) |
| ToolRegistry | 工具调用 | 所有 side effect 必须经过 PermissionEngine | ✓ 正确(contracts §23) |
| PermissionEngine | 权限决策 | 不绕过 credential/system-sensitive override | ✓ 正确 |
| TUI | UI 渲染 | 只依赖 ProjectionClient/contracts | ✓ 正确(contracts §23) |
| ContextAssembler | 上下文组装 | 不自行压缩 | ✓ 正确(概要设计 §13) |
评估:所有组件的职责边界与基线一致。没有发现职责泄漏或边界违反。
6.3 状态机一致性
6 个状态机之间的交互路径:
| 源状态机 | 目标状态机 | 事件/数据流 | 一致性 |
|---|---|---|---|
| Main Agent → Scheduler | DELEGATING → SCHEDULING | task.created |
✓ |
| Scheduler → Worker | DISPATCHING → worker spawn | agent.start IPC |
✓ |
| Worker → Scheduler | worker.return → COLLECTING_RESULTS | worker.result IPC |
✓ |
| Scheduler → Architecture Designer | architecture-sensitive review | architecture.impact.completed |
✓ |
| Architecture Designer → Scheduler | impact assessment done | Scheduler consumes impact | ✓ |
| Main Agent ← Scheduler | progress/blocked/complete | task.progress/blocked/completed events |
✓ |
| EventBus → ProjectionStore | all events | subscribe/apply | ✓ |
| ContextAssembler → Scheduler | compaction_requested |
Scheduler creates compact task | ✓ |
评估:所有状态机交互路径的事件名称、方向和触发条件一致。没有发现状态机之间的死锁或悬空事件路径。
6.4 事务语义一致性
关键事务边界:
| 操作 | 事务范围 | 后置操作 | 一致性 |
|---|---|---|---|
| EventStore.append | event insert + domain projection | EventBus.publish (after commit) | ✓ |
| ArtifactStore.create | temp→rename→DB record | event ingest | ✓ |
| Task.start | task.started event + tasks update + task_attempts insert | agent.started event | ✓ |
| Compaction | summary.created event + summaries insert | context.compaction.completed | ✓ |
| Cross-DB write (outbox) | session event → external DB → completion event | recovery on restart | ✓ |
评估:所有事务边界遵循 runtime-semantics §3 规则(durable event + domain update 同事务,EventBus 发布在事务后)。
7. 与 DeepSeek 审查的交叉验证
| 发现 | DeepSeek 判定 | MIMO 判定 | 差异 |
|---|---|---|---|
| PromptLayerLevel 结构性不对齐 | P2 | P1 | MIMO 升级:这不是"措辞差异"而是真实内部矛盾,影响实现一致性 |
| Architecture gate 无独立序列图 | P2 | P2 | 一致 |
| CLI catalog 类归属 | P2 | P2 | 一致 |
| EventStore.project() 错误处理 | 未报告 | P1 | MIMO 独立发现 |
| agent.started 投影措辞 | 未报告 | P2 | MIMO 独立发现 |
| WorkspaceManager/Scheduler 职责边界 | 未报告 | P2 | MIMO 独立发现 |
差异分析:DeepSeek 将 PromptLayer 问题标记为 P2,理由是"DD §10.2 正确记录了此映射"。MIMO 认为这是 P1,因为虽然 DD 记录了差异,但没有给出明确的解决决策——实现时仍然面临"枚举值和层名不完全对应"的问题,而这个差异发生在两个已冻结的基线之间(contracts 和 prompt-layering),属于需要明确澄清的架构级问题。
8. 覆盖性检查
8.1 契约接口字段抽样
| 接口 | 基线字段数 | DD 覆盖数 | 缺失 |
|---|---|---|---|
| TaskSpec | 9 fields | 9 | 0 |
| WorkerResult | 12 fields | 12 | 0 |
| IpcEnvelope | 9 fields | 9 | 0 |
| PermissionDecision | 7 fields | 7 | 0 |
| AirError | 11 fields | 11 | 0 |
| ProviderCapabilityMatrix | 10 fields | 10 | 0 |
| CapabilityManifestV1 | 13 fields | 13 | 0 |
| DebugRecord | 10 fields | 10 | 0 |
| LearnedMemory | 9 fields | 9 | 0 |
| Diagnostic | 14 fields | 14 | 0 |
10/10 接口字段完整性抽样全部通过。
8.2 事件投影映射核对
55 个持久化事件逐一对比 event-registry §3 的 Domain update 描述。全部 55/55 覆盖且域更新描述准确。
8.3 DB Schema 表核对
19 张表(db-schema §2-§18 + §20.1-§20.2)逐一对比 DD §4.3 仓储清单 + §11.3 项目级 DB Store。19/19 全覆盖。
8.4 禁止路径核对
10 条 contracts §23 禁止路径逐一对比 DD §2 + §18.5。10/10 全覆盖。DD 额外添加 1 条 C4 规则(runtime → TUI import)。
9. 与前轮审查的一致性
| 维度 | DeepSeek | MIMO 2.5 Pro |
|---|---|---|
| P0 | 0 | 0 |
| P1 | 0 | 2 |
| P2 | 3 | 5 |
| 综合评分 | 9.6/10 | 9.4/10 |
| 新发现 | — | P1-02, P2-04, P2-05 |
一致性结论:两轮审查在 P0 层面一致(0 项)。MIMO 发现了 DeepSeek 未报告的 P1 级 EventStore 错误处理问题,并将 PromptLayer 结构性矛盾从 P2 升级为 P1。
10. 门禁判定
| 条件 | 状态 |
|---|---|
| P0 = 0 | PASS |
| P1 ≤ 2(均有明确修复路径) | PASS |
| 契约覆盖 100% | PASS |
| 事件覆盖 100% | PASS |
| DB Schema 覆盖 100% | PASS |
| 状态机覆盖 100% | PASS |
| 禁止路径全执行 | PASS |
| 架构无循环依赖 | PASS |
| 职责分离无泄漏 | PASS |
| 状态机交互无死锁 | PASS |
| 事务语义一致 | PASS |
门禁结果:PASS(附 2 项 P1 修复建议)
详细设计可以进入实现阶段,但建议在实现开始前明确 P1-01(PromptLayer 设计决策)和 P1-02(EventStore 错误路径文档化)。
11. P1 修复建议
P1-01 修复路径
需要一个设计决策(ADR 或详细设计补充):
推荐方案 B:保持枚举不变,在实现层建立映射:
L0 → runtime_invariant (immutable=true)
L1 → role (immutable=true)
L2 → (safety layer loaded by ContextAssembler as a runtime_invariant variant with immutable=true,
source from ~/.air/permissions.yaml + project permissions)
L3 → project_rules
L4 → architecture (loaded from plan/todo/ADR context)
L5 → task_spec
L6 → evidence (loaded from artifacts/diagnostics/evidence_refs)
L7 → conversation (loaded from messages/summaries)
L8 → tool_output (loaded from recent tool_runs/command_runs/diagnostics)
L9 → user_override + system_debug (merged, highest priority non-immutable layer)
PromptLayerLoader 接口扩展为:
load_safety_policy(): PromptLayer // L2
load_architecture_context(refs): PromptLayer[] // L4
load_evidence_context(refs): PromptLayer[] // L6
load_conversation(session_id): PromptLayer[] // L7
load_tool_output(recent_runs): PromptLayer[] // L8
load_immediate_instruction(): PromptLayer // L9
P1-02 修复路径
在 DD §5.3 或 §18.2 补充:
EventStore.append error semantics:
- project() 内部异常 → 整个事务回滚
- EventBus.publish() 不执行(正确:post-commit only)
- 返回 AirError{kind: "system_error", message: "event projection failed"}
- 如果是因为 FK-off 不一致(如引用不存在的 task_id):
- 记录到 developer log
- 触发 SessionStore.referential_check()
- Scheduler 将受影响的 task 标记为 interrupted/blocked
- 不会部分投影:SQLite 事务保证原子性