# 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_`,应为 `::::` | | 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 顺序处理。