fix: integrate audit findings round 1 - tools, worker, scheduler, main agent
- Unify ToolResultEnvelope (output vs content) for built-in tools - Fix shell.run AsyncGenerator consumption in ToolRegistry.call/streaming - Scheduler: consume WorkerResult.status instead of marking all running tasks completed - WorkerProcess/WorkerManager: surface exit events and generate failed/cancelled result - MainAgent: integrate ContextAssembler, Chinese destructive regex, ArchitectureDesigner impact gate - run.ts: pendingConfirmation flow, dispatch extracted, .air files filtered from /results - CapabilityRegistry wired into RuntimeApp and ServiceRegistry; DoctorService uses it - release.ts: findRepoRoot/findBun, run air e2e + depcruise + runtime regression - New gates: release-critical-gates, CLI run command regression - 14/14 e2e gates pass; 3/3 release dry-run pass Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
196
集成测试阶段MiniMax-M3审查结果.md
Executable file
196
集成测试阶段MiniMax-M3审查结果.md
Executable file
@@ -0,0 +1,196 @@
|
||||
# 集成测试阶段 MiniMax-M3 审查结果
|
||||
|
||||
**审计日期**: 2026-06-05
|
||||
**项目**: AirCoding V1.0.0 Alpha
|
||||
**审计员**: MiniMax-M3 (整合阶段)
|
||||
**审计模式**: 四视角交叉审计(系统架构师 / 开发工程师 / 真实用户 / 测试工程师)
|
||||
|
||||
---
|
||||
|
||||
## 0. 核心矛盾 (E2E Gates 失真)
|
||||
|
||||
13/13 E2E gates 全部通过,但用户视角测试**真实任务成功率近乎为零**。
|
||||
|
||||
| 维度 | 表现 |
|
||||
|---|---|
|
||||
| tsc typecheck | 0 errors |
|
||||
| 单元测试 | 169/169 passed |
|
||||
| E2E gates | 13/13 passed |
|
||||
| 真实用户场景 | **多数失败** |
|
||||
|
||||
E2E gates 仅验证"测试能跑通"和"组件存在",**从未验证"用户场景成功"**。所有 gate 仅检查语法、类型、stub 数量、单元测试通过率;没有一项 gate 验证"LLM 调通 + 文件真的写出 + 多步骤任务真完成"。
|
||||
|
||||
---
|
||||
|
||||
## 1. 系统架构师审查
|
||||
|
||||
### FR-005 (Main Agent 对话) — 部分实现
|
||||
|
||||
`MainAgent.chat_with_llm()` 每次调用仅构造 system+user 两条消息,**无 conversation history**,无 context reference,无 Anthropic canonical content blocks——严重违反 FR-014 上下文分层。
|
||||
|
||||
追问"现在什么情况"时,LLM **没有上下文**,是 stateless 单轮调用,必然幻觉。
|
||||
|
||||
### FR-016 (TUI) — 不支持交互输入
|
||||
|
||||
`TuiApp.setup_input` 只处理 `q/1/2/3/4/h` 键盘事件,**无文本输入路径**。`run.ts` 用 `readline` 在 TUI 之外独立处理 stdin,TUI 和 CLI 互相竞争字符。TUI 实际是**只读 viewer,不能输入任务**。
|
||||
|
||||
### FR-007/008 (Scheduler/Worker) — 链路通但判定错误
|
||||
|
||||
Worker 真实 spawn,IPC 真实 NDJSON,tool.call / llm.request 通过 IPC 回父进程由 ProviderManager 真实调用 LLM——**链路是通的**。
|
||||
|
||||
但 `Scheduler.step` 的 `MONITORING` 状态存在严重 bug:worker 还在跑就 mark `completed`,任务可能"假完成"。
|
||||
|
||||
### FR-009 (执行原语) — 不强制 read-before-edit
|
||||
|
||||
`ExecutorRole` 直接接受代码块写入,**不强制 read-before-edit**——违反 FR-009。run.ts 的"扫描最近 60 秒修改的文件"是 post-hoc 发现,不验证文件来源、不执行 verification-before-completion。
|
||||
|
||||
### FR-017 (C++ 完整闭环) — 工具链与主链路不联动
|
||||
|
||||
`toolchain-cpp` 实现了 cpp.detect / cpp.build / cpp.test 工具,但**无 fixture 项目、无自动 configure→build→test→fix→review e2e 集成**。Executor 用 fs.write 写 C++ 源文件,**不调用任何 cpp.* 工具**。C++ 工具链对用户不可见地存活,但与主链路不联动。
|
||||
|
||||
### 未对齐设计的关键差异
|
||||
|
||||
| 设计 | 实际 |
|
||||
|---|---|
|
||||
| ProjectionStore 消费 DB+EventBus | `run.ts` 直接 `receive_snapshot` 构造假数据绕开 EventStore |
|
||||
| 严格状态机 12 态 | 真实遍历,但 MONITORING 完成判定错误 |
|
||||
| 5 角色独立 worker | Debugger/Compactor/ExperienceMiner 未被 run.ts 触发 |
|
||||
| Anthropic canonical messages | MainAgent 用 string content,非 content block[] |
|
||||
|
||||
---
|
||||
|
||||
## 2. 开发工程师 Bug 报告
|
||||
|
||||
### P0 阻塞 (2)
|
||||
|
||||
**Bug #2 — Scheduler 早判完成** (Scheduler.ts:252-260)
|
||||
当 `worker_manager.has_running() === false` 时,将**所有** `running` 状态任务直接标记为 `completed`,**不管 worker 是否实际成功**。失败任务可能显示为成功。
|
||||
|
||||
**Bug #6 — MainAgent 确认门形同虚设** (run.ts:108-112)
|
||||
`MainAgent.classify()` 对"delete/remove"类消息返回 `{action: 'delegate', response: 'Are you sure? (y/n)'}`,但 `run.ts:115` 直接 `console.log` `classification.response` 并 `rl.prompt()`——**用户的 y/n 永远到不了 `MainAgent.handle_confirmation()`**。破坏性操作无防护。
|
||||
|
||||
### P1 重要 (3)
|
||||
|
||||
**Bug #3 — ExecutorRole 转义顺序错误** (ExecutorRole.ts:222)
|
||||
代码块内容转义还原顺序:`\\n → \n`, `\\t → \t`, `\\" → "`, `\\\\ → \\`。若 LLM 输出 `\n`(单反斜杠 n),会被错误地换成真换行,破坏 JSON/Python 字面量。
|
||||
|
||||
**Bug #4 — MainAgent 不带上下文** (MainAgent.ts:73)
|
||||
`chat_with_llm(message)` 只发送单轮 system + user。追问"现在什么情况"时,**LLM 不知道项目里有啥**。
|
||||
|
||||
**Bug #5 — DONE 竞态** (ask.ts:182-186)
|
||||
若 LLM 单次输出既有 `fs.write` 又有 `DONE`,执行完 tool_call 后立即返回 `completed`。**剩余未完成的 acceptance_criteria 被静默忽略**。
|
||||
|
||||
**Bug #7 — 多文件任务漏写**
|
||||
第一次写到 `src/main.cpp`(正确),第二次写到根 `main.cpp`(简化版 stub)。两个 task 缺乏协调。
|
||||
|
||||
### P2 nice-to-have (2)
|
||||
|
||||
- **Bug #1 — 退出码误判** (WorkerProcess.ts:127): `code || 1` 误判为错误
|
||||
- **Bug #8 — `has_running` 误判** (WorkerManager.ts:303-305): `ready` 状态也算 running
|
||||
|
||||
---
|
||||
|
||||
## 3. 真实用户测试报告 (UAT)
|
||||
|
||||
| 用例 | 状态 | 关键现象 |
|
||||
|---|---|---|
|
||||
| `air init` | ✅ PASS | 创建 .air/ 目录和 project.json |
|
||||
| `air ask "..."` 写文件 | ✅ PASS | fs.write 工作 |
|
||||
| TUI 启动 | ✅ PASS | OpenTUI 渲染正确 |
|
||||
| `air doctor` | ✅ PASS | 检测 bun/sqlite/git/shell |
|
||||
| **shell.run 任意命令** | ❌ **FAIL** | 10/10 次返回 `Error: undefined` |
|
||||
| **追问项目内容** | ❌ **FAIL** | LLM 答"我没有文件系统访问" |
|
||||
| **危险操作 (删除)** | ❌ **FAIL** | 静默通过,文件仍在 |
|
||||
| **false-positive 成功** | ❌ **FAIL** | tool 报错但 CLI 仍打印 `✅` |
|
||||
| **多文件 C++ 任务** | ❌ **FAIL** | main.cpp 内容退化为 stub |
|
||||
| `air doctor --fix` | ❌ FAIL | 标 [fixable] 不修 |
|
||||
|
||||
### 用户最痛 3 个问题
|
||||
1. **shell 工具整体坏死**,让 AI 跑任何命令都失败 10/10 次。
|
||||
2. **报错说"成功",实际没干**——用户以为工作流跑通了,回头看磁盘空的。false-positive 比直接报错危险十倍。
|
||||
3. **TUI 和 CLI 是两套东西**,`air ask` 能用工具,`air run` TUI 输入路径不可见(实际仅 readline 跑,渲染层 OK 但端到端未跑通)。
|
||||
|
||||
---
|
||||
|
||||
## 4. QA 测试矩阵
|
||||
|
||||
| Test | 状态 | 关键观察 |
|
||||
|---|---|---|
|
||||
| 1: 简单文件创建 | PASS | hello.txt 创建成功,内容正确。Worker stderr 异常但不影响产出。 |
|
||||
| 2: 多文件 (C++ + CMake) | **PARTIAL** | main.cpp 内容退化为 stub,CMakeLists.txt 正确。两文件被写到不同位置 |
|
||||
| 3: 追问项目内容 | **FAIL** | agent.handle_user_message("我的项目有哪几个文件?") 走 answer 分支,LLM 幻觉 |
|
||||
| 4: TUI 启动 | PASS | OpenTUI 渲染正确,状态栏正常 |
|
||||
| 5: E2E gates | PASS | 13/13 (但 gates 与用户场景脱节) |
|
||||
|
||||
---
|
||||
|
||||
## 5. 用户核心痛点 (按严重度排序)
|
||||
|
||||
| 排名 | 问题 | 严重度 | 触发场景 |
|
||||
|---|---|---|---|
|
||||
| 1 | **shell.run 工具完全坏死** | P0 阻塞 | 任何命令执行 (编译、运行、git) |
|
||||
| 2 | **追问上下文失效** (LLM 答"我没文件系统") | P0 阻塞 | 完成任务后问"现在什么情况" |
|
||||
| 3 | **危险操作无 confirmation 路由** | P0 安全 | 删除、覆盖文件 |
|
||||
| 4 | **Scheduler 早判完成** (假完成) | P0 阻塞 | 多步任务 |
|
||||
| 5 | **TUI 无文本输入路径** | P0 用户体验 | TUI 实际只读 |
|
||||
| 6 | **多文件任务漏写 / 覆盖** | P1 | 复杂任务 |
|
||||
| 7 | **false-positive 成功 banner** | P1 | 任何报错场景 |
|
||||
| 8 | **DONE 竞态导致提前退出** | P1 | LLM 同 turn 输出 tool+DONE |
|
||||
| 9 | **ExecutorRole 转义顺序错误** | P1 | LLM 输出含 `\n` 字符 |
|
||||
| 10 | **退出码误判** (stderr 噪音) | P2 | 排查时迷惑 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 根因分析
|
||||
|
||||
E2E gates 框架本身存在结构性缺陷:
|
||||
|
||||
- 仅做静态检查:tsc/depcruise/单元测试
|
||||
- 不做端到端真实任务验证
|
||||
- 缺"用户成功完成一个 C++ 任务"等综合场景 gate
|
||||
|
||||
需要新增的 gates:
|
||||
- 真实 LLM 端到端任务完成
|
||||
- 多文件任务产出验证
|
||||
- shell.run 工具真实执行
|
||||
- 上下文追问验证
|
||||
- 危险操作 confirmation 验证
|
||||
|
||||
---
|
||||
|
||||
## 7. 修复建议 (按优先级)
|
||||
|
||||
### 立即修复 (P0, 阻塞发布)
|
||||
1. 修复 `shell.run` AsyncGenerator 序列化问题
|
||||
2. 修复 Scheduler MONITORING 早判完成 bug
|
||||
3. MainAgent 注入工具/项目上下文到 LLM 调用
|
||||
4. 修复 confirmation 路由 (run.ts → MainAgent.handle_confirmation)
|
||||
5. TUI 增加文本输入路径 (或移除 TUI 包装直接 CLI)
|
||||
|
||||
### 必须修复 (P1, 关键)
|
||||
6. ExecutorRole 转义顺序
|
||||
7. DONE 竞态检测
|
||||
8. 多文件任务协调 (检查文件已存在)
|
||||
9. Tool 失败时正确报失败 (false-positive 修复)
|
||||
10. 真实集成测试加入 E2E gates
|
||||
|
||||
### 长期改进 (P2)
|
||||
11. 退出码误判
|
||||
12. has_running 误判
|
||||
13. Worker stderr 去噪
|
||||
14. Anthropic canonical content blocks 完整支持
|
||||
|
||||
---
|
||||
|
||||
## 8. 综合判断
|
||||
|
||||
**V1.0.0 Alpha 不应发布**。
|
||||
|
||||
- 13/13 E2E gates passed 但**用户场景真实成功率极低**——这是 E2E gate 设计缺陷
|
||||
- 5 个 P0 问题中,3 个是用户每次使用都会触发的(shell 坏死、追问失效、确认门失效)
|
||||
- C++ 工作流工具链与主链路未联动,FR-017 名存实亡
|
||||
- TUI 渲染层 OK 但无输入路径,FR-016 名存实亡
|
||||
|
||||
修复 P0 后必须**用真实任务重新端到端测试**,而不是用 E2E gates 替代。需要在 E2E gates 框架中**加入"真实 LLM 任务闭环"维度**,否则同样的审计盲点会再次出现。
|
||||
|
||||
**核心教训**: 代码质量指标 (tsc/stub 数/单元测试) 与用户可用性指标是正交的。质量分高 ≠ 产品可用。后续每个审计必须包含**真实任务端到端测试**作为硬性 gate。
|
||||
Reference in New Issue
Block a user