# AirCoding V1.0.0 Alpha — Opus 开发阶段审计报告

> **审计员**: Claude Opus 4.8 (1M context)
> **审计日期**: 2026-06-02
> **审计方法**: 4 个独立子代理对照规范文档逐文件交叉审查
> **审计依据**: interface-contracts-v1, db-schema-v1, event-registry-v1, security-model-v1, tool-registry-v1, capability-trust-v1, prompt-layering-v1, provider-capability-matrix-v1, scheduler-state-machine-v1, runtime-semantics-v1, scope-escalation-v1, main-agent-state-machine, error-taxonomy-v1, c4/code-view, system-detailed-design (§7/8/13/14/15/16/17/22)
> **审计范围**: 全部 146 个源文件 vs 全部规范文档

---

## 执行摘要

### 总体评级：**C+ — 骨架完整，规范符合度低，存在阻断级缺陷**

与 DeepSeek 审计（侧重发现问题数量）不同，本次 Opus 审计**逐字段对照规范文档**，得出更严峻的结论：

> **核心发现**：`packages/contracts/src/` 中的规范契约**忠实地**编码了全部规范文档，但下游实现（runtime/llm/workers/tui/toolchain-cpp）**系统性地重新定义了本地的、与契约冲突的类型**，几乎不 import 契约。这导致大量"实现存在但与规范不符"的偏差。

### 关键指标对比

| 维度 | DeepSeek 审计 | Opus 审计（本报告） |
|------|--------------|---------------------|
| 发现总数 | 97 | **140+** |
| 审计深度 | 阶段级 | 字段级/逐行 |
| 契约对照 | 部分 | 全部 16 合约文件 |
| 状态机验证 | 否 | 是（Scheduler/MainAgent 逐状态） |
| 阻断级缺陷 | 10 | **18** |

### 阻断级缺陷速览（18 项）

| # | 缺陷 | 文件 | 后果 |
|---|------|------|------|
| 1 | workspace 投影写入非法枚举 `'created'`/`'merging'` | EventStore.ts:900,909 | `workspace.created` 持久化必抛错 |
| 2 | 项目级 DB 表名/路径/列全面偏离 db-schema §20 | DebugKnowledgeStore.ts, LearnedMemoryStore.ts | 与契约无法对接 |
| 3 | route_prefix 查询用 `.` 拼接但存储用 `/` | EventRepository.ts:185 | 多段路由前缀过滤永久失效 |
| 4 | TaskAttemptRepository 复制粘贴 bug | TaskAttemptRepository.ts:114 | failure_signature 列永不更新 |
| 5 | ToolRegistry 权限上下文硬编码 undefined | ToolRegistry.ts:262-263 | **权限模型被完全旁路** |
| 6 | ACTION_BRANCHES 内 `this.*` 调用崩溃 | ToolRegistry.ts:62,72 | read_only/sandbox 分支运行时崩溃 |
| 7 | ModelConfig.api_key 明文内嵌 | ModelConfigLoader.ts:17 | 违反 auth_ref 规范，密钥泄露 |
| 8 | Scheduler 状态机缺 BLOCKED/CANCELLED | Scheduler.ts:18-29 | 无法表达 5 处规范转换 |
| 9 | WorkerProcess 退出码 4 错配为 blocked | WorkerProcess.ts:17,30 | parent-cancelled 语义丢失 |
| 10 | 命令注入 — CMakeConfigurator | CMakeConfigurator.ts:40 | execSync 字符串拼接 |
| 11 | 命令注入 — CppBuilder | CppBuilder.ts:27 | LLM 可控 target 注入 |
| 12 | 命令注入 — CppcheckRunner | CppcheckRunner.ts:36 | project_root 注入 |
| 13 | C++ 工具绕过 PermissionEngine | CppToolRegistrar.ts:23 | 违反 INV-3 |
| 14 | INV-2 outbox 完全未发事件 | wiring.ts:35-73 | 跨 DB 一致性断裂 |
| 15 | DeveloperLogEncryptor 硬编码弱密钥 'dev-key' | DeveloperLogEncryptor.ts:22 | 日志加密等同明文 |
| 16 | CapabilityTrustLevel 用错误枚举值 | CapabilityManifestValidator.ts:19 | 信任模型失效 |
| 17 | PermissionEngine 缺 block/refuse/announce_then_run | PermissionEngine.ts:19-26 | 无法执行高风险拒绝/备份 |
| 18 | ProjectionClient↔ProjectionStore 从未连接 | (全仓) | 投影数据无法到达 TUI |

---

## 第一部分：契约层审计（packages/contracts）

### 评级：✅ 忠实编码规范（少量缺失）

合约层是整个项目**最符合规范**的部分。16 个文件忠实编码了 interface-contracts-v1 的 §2-§21。

| 合约区块 | 状态 | 说明 |
|---------|------|------|
| §2 ID 别名 (17) + Clock/IdGenerator | ✅ | 完全一致 (ids.ts) |
| §3 ErrorKind(22)/Severity/Retryability/AirError | ✅ | 字段完全匹配 (error.ts) |
| §4 EntityType(12)/EntityRef | ✅ | 一致 (event.ts) |
| §5 RuntimeEvent/EventSource/EventFilter | ✅ | 一致 |
| §6 SessionRecord/MessageRecord | ⚠️ | 定义在 runtime 而非 contracts（违反 §22.1） |
| §6 PersistedEventRecord/PersistedEventInsert | ❌ | contracts 包完全缺失 |
| §7 EventBus/EventStore/EventIngestor/SchemaRegistry 接口 | ❌ | 6 个核心接口在 contracts 中全部缺失（仅作 runtime class 存在） |
| §8-§21 其余契约 | ✅ | 大部分一致 |
| §16 ContextAssembler/CompactionPolicy 接口 | ❌ | contracts 中未找到 |

**关键发现**: 契约层缺失存储/事件层接口定义，导致下游实现"无契约可依"，进而各自定义本地类型。

---

## 第二部分：P1 存储与事件审计

### 评级：⚠️ 表结构正确，投影与项目级 DB 有阻断缺陷

| 检查项 | 状态 | 详情 |
|--------|------|------|
| 17 张会话表全列匹配 | ✅ | MigrationRunner.ts 逐列核对 db-schema §2-§18 |
| 55 持久 + 7 短暂事件注册 | ✅ | 程序化 diff 验证零差异 |
| EventStore.project() 域投影 | ⚠️ | session/task/agent/tool/command 等已覆盖 |
| **workspace 投影非法枚举** | ❌ | `status:'created'`/`'merging'` 不在闭合枚举 → assertEnum 抛错 |
| **context.compaction.* 缺投影** | ❌ | 4 个事件落入 default，规范要求标记压缩任务 |
| **debug-records.db schema** | ❌ | 路径 `.air/shared` (应 `.air/local`)，列集合全面偏离 |
| **learned-memory.db schema** | ❌ | 表名 `learned_memory` (应 `learned_memories`)，列偏离 |
| **route_prefix 查询 bug** | ❌ | EventRepository.ts:185 用 `.` 拼接但存储用 `/` |
| **TaskAttempt update bug** | ❌ | failure_signature 分支错误 push failure_summary |
| EventBus.subscribe 返回 Subscription | ⚠️ | 缺 `unsubscribe()` 方法 |
| EventStore.append 缺 EventAppendOptions | ⚠️ | 无乐观并发校验、无外部事务复用 |
| INV-1 status 写入 | ✅ | 5 仓库已修复为硬编码默认值 |

---

## 第三部分：P2 工具/权限/能力审计

### 评级：❌ 系统性偏离规范，存在权限旁路

这是**问题最严重的阶段**。实现几乎全部重新定义本地类型，忽略契约。

### 3.1 PathClassifier vs security-model §4（8 路径类别）

| 规范类别 | 实现 | 状态 |
|---------|------|------|
| project_air_shared / project_air_local | 笼统归入 project_internal | ❌ 缺失 |
| project_git | 混入 project_internal | ❌ 缺失（.git 需独立保护） |
| credential_store | 无（~/.ssh 归为 user_home） | ❌ 缺失（安全关键） |
| unknown | 默认归类为 project_config | ❌ 方向错误（应保守） |

8 个规范类别仅对应 3 个，且全部命名不一致。

### 3.2 PermissionEngine vs security-model §13

| 项 | 状态 | 详情 |
|----|------|------|
| 6 层评估顺序 | ✅ | capability→profile→task_scope→risk→credential→prompt |
| **PermissionAction 枚举** | ❌ | 缺 `block`/`refuse`/`announce_then_run`；多 `read_only`/`sandbox`/`audit_log` |
| **PermissionDecision 结构** | ❌ | 缺 grant_scope/risk_level/backup_required/evidence_refs |
| **profile 概念** | ❌ | 被替换为 AgentType，缺 low/normal/high/developer 四档 |
| capability/prompt 层 | ⚠️ | 桩实现，恒 allow |
| record 发事件 | ❌ | 仅 push 内存数组 |
| **decision.redacted 字段** | ❌ | ToolRegistry 引用不存在的字段 |

### 3.3 ToolRegistry vs tool-registry-v1

| 项 | 状态 | 详情 |
|----|------|------|
| **权限上下文硬编码 undefined** | ❌ | build_permission_context 把 task_scope/profile 设为 undefined → Layer 2/3 恒放行，**权限旁路** |
| **ACTION_BRANCHES this 崩溃** | ❌ | 模块级常量内 `this.downgrade_to_readonly` → 运行时 TypeError |
| 6 分支 | ❌ | 仅 allow/deny 正确，缺 block/refuse/announce_then_run |
| 生命周期事件 | ❌ | 无 tool.started/completed/failed 发射 |
| schema 校验 | ❌ | validate_input 自承"simplified" |
| 28 个 MVP 工具 | ❌ | 仅 ~7 个命中，cpp/debug/gui/network/process/fs.stat 全缺 |

### 3.4 CapabilityTrustLevel vs capability-trust-v1

| 规范值 | 实现 | 状态 |
|--------|------|------|
| built_in | core | ❌ 错误值 |
| project_local | 无 | ❌ 缺失 |
| user_installed | 无 | ❌ 缺失 |
| verified_publisher | 无 | ❌ 缺失 |
| untrusted | untrusted | ✅ |
| — | trusted | ❌ 规范外 |

实现 `core/trusted/untrusted` 中仅 1 个命中。

---

## 第四部分：P3 提供者/上下文审计

### 评级：❌ 能力矩阵严重不全，上下文 L5-L9 未实现

### 4.1 ProviderCapabilityMatrix vs provider-capability-matrix-v1

| 规范 supports 字段 | 实现 | 状态 |
|-------------------|------|------|
| 16 个能力字段 | 仅 ~7 个（命名偏差） | ❌ 一半缺失 |
| quality_tier | 无 | ❌ 缺失（模型选择核心） |
| cost_tier | 无 | ❌ 缺失 |
| default_use（按角色） | 无 | ❌ 缺失（Scheduler 分配依赖） |
| max_tokens_output: 200000 | 数据错误 | ⚠️ 把上下文窗口误填为 output |

### 4.2 ContextAssembler vs prompt-layering-v1 (L0-L9)

| 层 | 状态 | 详情 |
|----|------|------|
| L0 runtime_invariant | ✅ | 加载正确 |
| L1 role | ⚠️ | 仅支持 worker 角色，main/architecture/scheduler 无法加载 |
| L2 safety | ⚠️ | 硬编码字符串，非来自 permissions.yaml |
| L3 project_rules | ⚠️ | 路径/来源不符，缺全局与 toolchain rules |
| L4 architecture | ⚠️ | 无 AGENTS.md/plan.md/ADR 加载 |
| **L5 task_spec** | ❌ | 硬编码假任务"Current Task" |
| **L6 evidence** | ❌ | TODO 未实现 |
| **L7 conversation** | ❌ | TODO 未实现 |
| **L8 tool_output** | ❌ | TODO 未实现 |
| **L9 user_override** | ❌ | TODO 未实现 |
| Anthropic canonical 输出 | ❌ | 用 `{role,content:string}` 非 content blocks |

---

## 第五部分：P4 Worker IPC / 调度器审计

### 评级：❌ 状态机终态模型错误，核心状态为存根

### 5.1 Scheduler 状态机（11 状态）

| 规范状态 | 实现 | 评级 |
|---------|------|------|
| IDLE/LOADING_GRAPH/PLANNING_WAVE | 存在 | ⚠️ 转换简化 |
| DISPATCHING | 🔧 存根 | 未创建 workspace/context/事件 |
| MONITORING | ⚠️ | 缺 cancel/blocker 转换 |
| COLLECTING_RESULTS/MERGING/REVIEWING_WAVE/REPAIRING | 🔧 存根 | 无条件跳转 |
| COMPLETED | ✅ | 终态 |
| **BLOCKED** | ❌ | SchedulerState 联合类型根本没有 |
| **CANCELLED** | ❌ | 同上 |
| TERMINATED | ⚠️ | 规范中不存在的多余状态 |

### 5.2 其他 P4 发现

| 项 | 状态 | 详情 |
|----|------|------|
| RetryDecision 6 枚举 | ✅ | 齐全 |
| **RetryPlanner.skip 分支** | ❌ | decide() 从不返回 skip |
| **RetryPlanner 未接线** | ❌ | Scheduler 仅注释，不调用 decide() |
| **退出码 4=parent cancelled** | ❌ | 错配为 blocked |
| 工作空间三策略枚举 | ✅ | main/worktree/isolated_copy |
| worktree git merge | 🔧 存根 | 仅改内存 state |
| **Recovery 8 步** | 🔧 | 仅第 5 步实现，其余存根/缺失 |
| ScopeImpactLevel | ❌ | 未定义（scope-escalation §13 必须） |
| BlockerReport | ❌ | 角色仅返回裸 {error} |
| WorkerProtocol 方向验证 | ✅ | 逻辑正确，但未知类型放行 |

---

## 第六部分：P5 C++ 工具链审计

### 评级：❌ 命令注入 + 绕过权限 + signature 格式错误

| 项 | 状态 | 详情 |
|----|------|------|
| **命令注入 ×3** | ❌ | CMakeConfigurator/CppBuilder/CppcheckRunner execSync 拼接 |
| **绕过 PermissionEngine** | ❌ | CppToolRegistrar executor 直接 execSync（违反 INV-3） |
| **semantic_signature 格式** | ❌ | 输出 `diag_<hex>`，应为 `<kind>:<surface>:<class>:<loc>:<hash>` |
| signature 丢弃 line/column | ⚠️ | 同消息不同位置会冲突 |
| 无 LLM | ✅ | 纯正则+哈希 |
| ClangdClient | 🔧 | 两方法纯存根 |
| find_cpp_sources | 🔧 | 永远返回 [] |
| 错误映射 AirError | ❌ | 仅返回 {ok:false}，无 kind/retryability |
| capability.ts 类型 | ✅ | 已修复对齐 CapabilityManifestV1 |

---

## 第七部分：P6 投影 / TUI 审计

### 评级：❌ 投影不符契约，数据链路断裂

| 项 | 状态 | 详情 |
|----|------|------|
| **ProjectionStore 实现契约 §17** | ❌ | 方法签名全错 |
| **8 类投影** | ❌ | 仅有 tasks/agents，缺 tool_runs/command_runs/artifacts/permission_prompts/blockers/updated_at |
| **apply 处理事件名** | ❌ | 处理 `task.status.changed` 等不存在的事件名 |
| 订阅 EventBus | ❌ | 无注入/订阅 |
| **ProjectionClient↔Store 桥接** | ❌ | receive_snapshot 无调用者，投影到不了 TUI |
| TUI 仅渲染（INV-4） | ✅ | 组件纯函数，仅 import contracts |
| **TUI 实际渲染** | 🔧 | render() 仅 console.log，无 OpenTUI 依赖 |
| **PermissionPrompt UiCommandChannel** | ❌ | 用回调，UiCommandChannel 全仓零引用 |
| HUD 三预设 | ✅ | Full/Essential/Minimal |

---

## 第八部分：P7 Agent 集成审计

### 评级：❌ MainAgent 状态机缺 7 态，INV-2 未发事件

### 8.1 MainAgent 状态机（13 状态）

| 项 | 状态 | 详情 |
|----|------|------|
| 实现状态数 | ❌ | 仅 6 态，缺 CLASSIFYING/SCHEDULING/ARCHITECTURE_DESIGNING/EXECUTING/INTERRUPTING 等 7 态 |
| CLASSIFYING 经 LLM | ❌ | 用正则匹配首词，规范要求 LLM |
| DELEGATING 分支 | ❌ | 硬编码 tasks:['task-1']，无 Scheduler 调用 |
| /direct /done 触发 | ⚠️ | 用正则非命令 |
| permission_template 映射 | ❌ | 无 main_direct 设置 |
| requirement.changed | ❌ | 缺失 |

### 8.2 INV-2 Outbox

| 项 | 状态 | 详情 |
|----|------|------|
| **debug.record.created 发射** | ❌ | wiring.ts 写库后仅注释，无 ingest |
| **memory.promoted 发射** | ❌ | 同上，且 status='draft' 与 promote 语义矛盾 |
| 单写者结构 | ✅ | 每 store 独立 db |
| 外部失败补偿 | ❌ | 无 task.failed 路径 |
| ArchitectureDesigner 经 LLM | ❌ | 关键字匹配，无 ProviderManager |
| 四类结果枚举 | ✅ | 齐全 |

---

## 第九部分：P8 CLI / Doctor / RuntimeApp 审计

### 评级：❌ DI 容器虚设，Doctor 多为存根

| 项 | 状态 | 详情 |
|----|------|------|
| DoctorService 契约签名 | ❌ | run_diagnostics vs 契约 run(input) |
| self_bootstrap 顺序 | ✅ | 先于 capability |
| self_bootstrap 真实性 | ⚠️ | sqlite/shell 硬编码 passed:true |
| capability 检查 | ❌ | 全硬编码 passed:true |
| read_only/fix/bundle 三模式 | ❌ | fix/bundle 存根 |
| doctor.* 事件 | ❌ | 无发射 |
| **ServiceRegistry 使用** | ❌ | RuntimeApp/createRuntime 均绕过，自行 new |
| RuntimeApp 服务完整 | ❌ | 缺 ProjectStore/SessionManager/Event* |
| shutdown 清理 | 🔧 | 仅 log |
| CLI 命令表（11） | ✅ | 全覆盖 |
| **CLI 副作用经 RuntimeApp** | ❌ | doctor 直接 new DoctorService |
| run 启动 TUI | 🔧 | console.log 占位 |
| **Logger 双日志** | ⚠️ | 只写 air.log，不写 developer.log |
| **DeveloperLogEncryptor 连接** | ❌ | 无调用者，且硬编码弱密钥 |

---

## 第十部分：不变量合规总评

| 不变量 | DeepSeek 评级 | Opus 评级 | 关键差异 |
|--------|--------------|-----------|---------|
| INV-1 Status 投影 | ✅ | ⚠️ | Opus 发现 workspace 投影写非法枚举 + Scheduler/WorkspaceManager 仅改内存 |
| INV-2 Outbox | ⚠️ | ❌ | 完全未发事件，跨 DB 一致性断裂 |
| INV-3 副作用门控 | ⚠️ | ❌ | ToolRegistry 权限旁路 + C++ 工具绕过 PermissionEngine |
| INV-4 导入方向 | ✅ | ✅ | 一致通过 |
| INV-5 EventBus 传输 | ✅ | ✅ | 一致通过（但 rebuild 是存根） |

---

## 第十一部分：与 DeepSeek 审计的对比结论

| 方面 | DeepSeek | Opus |
|------|----------|------|
| 总体评级 | B+ | C+ |
| 侧重 | 问题计数 + 高层分类 | 逐字段对照规范 |
| 独特发现 | — | 权限旁路、状态机终态缺失、能力矩阵不全、ProjectionClient 断裂、退出码错配、signature 格式错误 |
| 共识 | 命令注入、INV-2 未实现、合约漂移、存根率高 | 同 |

**Opus 的更严峻判断**：DeepSeek 评 B+ 反映"文件齐全、骨架正确"；Opus 评 C+ 反映"逐字段对照规范后，实现与规范的偏差是系统性的，且包含权限旁路这一安全致命缺陷"。

---

## 第十二部分：整改优先级

### P0 — 安全致命（发布前必修）
1. **ToolRegistry 权限旁路**（ToolRegistry.ts:262-263）— 真实加载 task_scope/profile
2. **ACTION_BRANCHES this 崩溃**（ToolRegistry.ts:62,72）— 改为实例方法或独立函数
3. **3 处命令注入**（CMake/CppBuilder/Cppcheck）— execSync → execFileSync + args 数组
4. **C++ 工具绕过 PermissionEngine** — 经 CapabilityRegistry.register_tools
5. **明文 API key**（ModelConfigLoader.ts:17）— 改用 auth_ref
6. **硬编码弱密钥 'dev-key'** — 强制 env 变量

### P1 — 阻断运行时
7. **workspace 投影非法枚举** — 修正为合法 workspaces.status 值
8. **route_prefix 查询 `.` vs `/`** — 统一分隔符
9. **TaskAttempt update bug** — 修正 failure_signature 分支
10. **Scheduler 缺 BLOCKED/CANCELLED** — 补回状态
11. **退出码 4 错配** — 4=parent cancelled, 5=hard timeout

### P2 — 规范符合
12. **INV-2 outbox 发事件** — wiring/stores 注入 EventIngestor
13. **ProjectionClient↔Store 桥接** — 接通投影数据链路
14. **下游 import 契约类型** — 删除本地重定义（PermissionAction/TrustLevel/Diagnostic/投影）
15. **项目级 DB schema** — 对齐 db-schema §20
16. **semantic_signature 格式** — 对齐 error-taxonomy §6

### P3 — 完整性
17. ContextAssembler L5-L9、Recovery 8 步、ClangdClient、MainAgent 状态机、Doctor 检查、TUI OpenTUI 集成

---

## 附录：审计方法论

本次审计派发 4 个独立 general-purpose 子代理，每个负责 2-3 个阶段：
- **代理 1**: contracts + P1（存储/事件）— 266K tokens, 44 工具调用
- **代理 2**: P2（工具/权限/能力）+ P3（提供者/上下文）— 160K tokens, 24 工具调用
- **代理 3**: P4（Worker/调度器状态机）— 134K tokens, 29 工具调用
- **代理 4**: P5-P8（C++/TUI/Agent/CLI）— 154K tokens, 44 工具调用

每个代理先完整阅读对应规范文档，再逐文件对照实现，输出 ✅符合/⚠️偏差/❌缺失/🔧存根 四级评定，附精确 文件:行。

合约文件被全部 4 个代理交叉引用，确保契约层评估的一致性。

---

**报告结束** — 共发现 140+ 项，其中 18 项阻断级。建议按整改优先级 P0→P3 顺序处理。
