Merges 8 V1 plugins into 1 unified plugin, adds 4 new components (dep, tst, sec, rvr). 12 sub-modes: arc, eng, do, dbg, xdb, sdb, ndb, ctx, dep, tst, sec, rvr. L1 code-level guarantees: atomic writes, file locks, evidence gating, forced debug routing, 3-phase arc gate, evidence-first debug gate, Chinese language lock, scheduler boundary. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
210 lines
11 KiB
Markdown
210 lines
11 KiB
Markdown
# AirPlan V2 设计文档 — OPUS 4.8 审查报告
|
||
|
||
> **原文档**: airplanV2-Qwen3.7-Max设计.md (Draft 0.1, 2026-06-09)
|
||
> **审查日期**: 2026-06-09
|
||
> **审查结论**: 整体架构方向正确,设计深度足够,存在 12 项需修正问题和 8 项需补充内容
|
||
|
||
---
|
||
|
||
## 一、需修正问题
|
||
|
||
### 1.1 编号错误:两个 3.7.4
|
||
|
||
Section 3.7 中 AirRvr 和事件索引层均编号为 `3.7.4`。事件索引层应为 `3.7.5`。
|
||
|
||
### 1.2 AirArc 工具限制配置格式不对
|
||
|
||
3.2.6 中给出了 JSON 格式的工具白名单配置:
|
||
|
||
```json
|
||
{
|
||
"allowed_tools": ["Read", "Glob", "Grep"],
|
||
"denied_tools": ["Write", "Edit", "Bash", "NotebookEdit"],
|
||
"deny_plan_mode": true
|
||
}
|
||
```
|
||
|
||
Claude Code 的 SKILL.md 使用 YAML frontmatter 定义工具限制,格式应为:
|
||
|
||
```yaml
|
||
---
|
||
name: AirArc
|
||
allowed-tools: [Read, Glob, Grep]
|
||
---
|
||
```
|
||
|
||
不存在 `denied_tools` 和 `deny_plan_mode` 字段(这两个是虚构的 API)。实际的 plan mode 阻断依赖 SKILL.md 中的强制性文本指令 + `allowed-tools` 白名单双重保障。文档中的伪 JSON 配置块应修正为实际可用的 YAML frontmatter。
|
||
|
||
### 1.3 P0-7 修复方案核心仍为 Prompt 指令,非代码级保障
|
||
|
||
P0-7(AirEng 无子线程状态轮询)的修复方案(3.2.8)主体是一个 SKILL.md 中的伪代码循环指令,依赖 LLM 自觉执行。尽管末尾有「技术补充:engine monitor_engine() 增加 wall-clock 超时检测」,但:
|
||
|
||
- wall-clock 超时只是兜底检测(2小时硬上限),不能替代 5 分钟级的状态轮询
|
||
- 真正解决 P0-7 需要在 `engine.py` 中增加代码级定时轮询循环(如 `while` 循环 + `time.sleep`),而非依赖 prompt 指令
|
||
- 建议将 3.2.8 的主体从 SKILL.md 文本改为 `engine.py` 中的 `monitor_engine()` 重构,SKILL.md 指令仅作为辅助提醒
|
||
|
||
### 1.4 Phase 2 实现 PlanDelta 消费者,但生产者到 Phase 4 才实现
|
||
|
||
3.2.11 的 `TaskGraph.apply_delta()` 在 Phase 2 (T-2.9) 实现,但其数据来源——AirArc 的增量重规划(产出 `PlanDelta`)——在 Phase 4 (T-4.6) 才实现。这意味着 Phase 2~4 期间,`apply_delta()` 没有真正的生产者。建议:
|
||
|
||
- 将 AirArc 增量重规划从 Phase 4 提前到 Phase 2,与 T-2.9 同步交付;或
|
||
- Phase 2 先实现全量 replace 模式(Arc 产出完整 DAG,Eng 整体替换),Phase 4 再升级为增量 delta 模式
|
||
|
||
### 1.5 区域冲突检测未定义「区域」概念
|
||
|
||
3.2.12 的 `RegionConflictDetector._check_region_overlap()` 是核心判断逻辑,但设计中没有定义什么是「区域」、如何从任务中提取区域信息、两个区域如何判重叠。这是 worktree 隔离并行的关键前提,不能留空。建议至少明确:
|
||
|
||
- 区域定义来源:函数边界 / 类定义 / CSS 选择器块 / 标记注释分隔
|
||
- 区域信息由谁提供:Arc 规划时静态分析 / Worker 执行前动态分析 / todo.md 中的区域标注
|
||
- 重叠判据:行号区间重叠 / AST 节点冲突 / 文本 diff 冲突
|
||
|
||
### 1.6 Token 估算比率命名容易误解
|
||
|
||
3.3.2 中 `RATIOS` 字典的值实际含义是「每 token 对应的字符数」,但命名 `RATIOS` 和注释「中文字符 → token」暗示反向。建议重命名为 `CHARS_PER_TOKEN` 并在注释中明确。
|
||
|
||
### 1.7 AirDbg 快照可能包含无关变更
|
||
|
||
3.5.2 的 `pre_fix_snapshot` 使用 `git commit -am` 提交所有修改。在无 worktree 隔离的场景下,这会混入其他并行任务的文件变更,导致回滚时误伤。建议改为仅提交当前任务写集范围内的文件,或仅在 worktree 隔离模式下使用。
|
||
|
||
### 1.8 AirTst 结果格式不支持嵌套测试结构
|
||
|
||
3.7.2 的结果格式为扁平结构,但 GoogleTest 有 test suite → test case 层级,pytest 有 module → class → function 层级。建议扩展为:
|
||
|
||
```json
|
||
{
|
||
"framework": "googletest",
|
||
"totalTests": 128, "passed": 127, "failed": 0, "disabled": 1,
|
||
"duration": "4.2s",
|
||
"suites": [
|
||
{
|
||
"name": "NetworkTest",
|
||
"totalTests": 32, "passed": 32, "failed": 0,
|
||
"testCases": [
|
||
{"name": "ConnectTimeout", "status": "passed", "duration": "0.05s"}
|
||
]
|
||
}
|
||
],
|
||
"failures": []
|
||
}
|
||
```
|
||
|
||
### 1.9 KMS 截图硬编码 sudo
|
||
|
||
3.6.1 中 `KmsGrabCapture` 直接使用 `sudo ffmpeg`,这要求密码免密 sudo 配置,在生产环境中是安全隐患。建议增加权限检测和降级策略:
|
||
|
||
- 检测当前用户是否有 `/dev/dri/card0` 读写权限
|
||
- 无权限时提示用户配置 udev 规则或将用户加入 video 组,而非直接 sudo
|
||
- sudo 仅作为显式 opt-in 的 fallback
|
||
|
||
### 1.10 迁移策略未覆盖 todo.md → DAG 过渡
|
||
|
||
Section 5 的迁移策略讨论了 state.json 的兼容性,但未涉及最核心的格式变迁——todo.md 被 TaskGraph 替代。现有项目的 todo.md 如何转换为 DAG?转换后人类如何查看/编辑任务状态(todo.md 的双重角色:机器可读 + 人类可读)?建议:
|
||
|
||
- 保留 todo.md 作为人类可读视图,DAG 作为内部调度结构
|
||
- 提供 `todo.md → DAG` 导入器和 `DAG → todo.md` 导出器
|
||
- 或明确声明 V2 放弃人类直接编辑 todo 的便利性,改为通过 AirArc 间接操作
|
||
|
||
### 1.11 度量指标缺少量化手段
|
||
|
||
Section 7 中部分指标无法客观测量:如「AirEng 非中文输出」「AirEng 轮询遗忘」「AirDo 跳过 AirDbg」的目标值设为 0 次,但当前没有机制检测这些行为是否发生。建议为每个指标定义检测方法:
|
||
|
||
- 非中文输出:事件日志中记录 AirEng 输出语言,正则检测非中文字符比例
|
||
- 轮询遗忘:monitor_engine 事件日志的时间间隔分析,超过 10 分钟无轮询记录即为遗忘
|
||
- 跳过 AirDbg:事件日志中 blocked→merge 路径无 debug.session 事件即为跳过
|
||
|
||
### 1.12 worktree 合并冲突处理缺失
|
||
|
||
3.2.12 描述了 SOFT 冲突时创建 worktree 并行执行,完成后 `git merge` 回主分支。但未定义合并冲突时的处理流程。两个 worktree 即使修改同一文件的不同区域,git merge 仍可能因相邻行冲突而失败。建议增加合并冲突升级策略:
|
||
|
||
```
|
||
MergeResult.CONFLICT → 自动升级到 AirDbg 解决 → 仍失败则降级为串行重执行
|
||
```
|
||
|
||
---
|
||
|
||
## 二、需补充内容
|
||
|
||
### 2.1 插件发现与加载机制
|
||
|
||
文档新增了 AirDep、AirTst、AirSec、AirRvr 四个插件,但未说明引擎如何发现和加载它们。V1 的插件加载机制是什么?V2 是否保持一致?建议在 3.7 新增一节说明插件注册规范。
|
||
|
||
### 2.2 AirRvr 的成本模型
|
||
|
||
AirRvr 对每个任务运行独立的 LLM 审查(加载需求文档 + diff + 验证证据),Token 消耗可能远超任务执行本身。以 100 任务项目为例,AirRvr 全量审查的 API 成本需要估算。建议:
|
||
|
||
- 定义审查触发策略:默认逐任务,可配置为波次审查或里程碑审查
|
||
- 给出不同模式下的 Token 消耗估算
|
||
- 考虑轻量审查模式(仅对比 Done When 文本,不加载完整 diff)
|
||
|
||
### 2.3 环境修复持久化方案
|
||
|
||
P3-4(环境特定修复不可持久化)在问题列表和痛点汇总中出现多次,但在 Phase 实施计划中无对应修复任务。建议在 Phase 2 或 3 增加 T-X.Y:「运维模式库:持久化环境修复脚本,支持跨重启自动应用」。
|
||
|
||
### 2.4 AirEng 与 AirRvr 的集成协议
|
||
|
||
AirRvr 的审查结果(pass / conditional-pass / fail)需要集成到 AirEng 的 merge 流程中,但文档未定义两者之间的接口协议。3.7.4 第 5 点仅概念性描述,缺少:
|
||
|
||
- AirEng 如何调用 AirRvr(文件系统 / 函数调用)
|
||
- AirRvr 审查的超时和失败处理(审查本身卡死怎么办)
|
||
- 审查结果与修复预算的关系(fail 后重试几次)
|
||
|
||
### 2.5 事件日志的保留策略
|
||
|
||
3.7.5 的事件日志是 JSONL 格式无限追加,与 state.json 的 P2-2(列表无界增长)面临同样问题。建议定义事件日志的轮转/截断策略。
|
||
|
||
### 2.6 安全扫描的误报处理
|
||
|
||
AirSec(3.7.3)发现敏感数据时「阻止合并并通知用户」,但没有误报处理机制。静态扫描的正则匹配容易产生误报(如代码中的示例密钥、Base64 编码的二进制数据)。建议增加:
|
||
|
||
- 白名单机制(已知安全的值、测试 fixture)
|
||
- 人工确认流程(首次发现时通知用户判断,后续同模式自动放行)
|
||
- AirSec 的判定为 advisory 而非 blocking(可配置)
|
||
|
||
### 2.7 并发度可配置的具体机制
|
||
|
||
T-2.7 提到「并发度可配置」,但未说明配置方式。是通过配置文件?环境变量?引擎命令行参数?`engine.py:527` 的硬编码常量替换为什么?建议明确。
|
||
|
||
### 2.8 AirContext 压缩失败后的降级路径
|
||
|
||
3.3.1 提到压缩验证失败后「重试一次,仍失败则放弃压缩并通知用户」。但放弃压缩意味着上下文持续增长直到超过模型窗口,最终导致任务失败。建议增加三级降级:
|
||
|
||
1. 重试(换 prompt)
|
||
2. 换模型压缩(如切换到更便宜的模型做摘要)
|
||
3. 激进截断(保留最近 N 轮 + ADR 引用,丢弃中间轮次)
|
||
|
||
---
|
||
|
||
## 三、架构层面评论
|
||
|
||
### 3.1 Prompt 指令 vs 代码保障的边界
|
||
|
||
文档中有多处将 prompt/SKILL.md 文本指令作为 P0 级缺陷的主要修复手段(P0-5 AirArc 阻断、P0-6 中文锁定、P0-7 轮询循环、P0-8 AirDbg 强制路由)。这些 prompt 级修复在 LLM 遵循度足够高时有效,但不构成硬性保障。
|
||
|
||
建议在文档中明确标注每项修复的保障层级:
|
||
|
||
- **L1 代码级**:由引擎代码强制执行,不依赖 LLM 行为
|
||
- **L2 指令级**:由 SKILL.md 指令约束,LLM 可能偏离
|
||
- **L3 建议级**:最佳实践文档,无强制机制
|
||
|
||
对于 P0 级缺陷,修复应至少达到 L1 或 L1+L2 双重保障。当前 P0-7 的修复仅为 L2,应升级。
|
||
|
||
### 3.2 DAG 调度与人类可读性的平衡
|
||
|
||
TaskGraph 替代静态 todo.md 表格是架构上正确的方向,但会牺牲 V1 的核心优势之一:任何人都可以用文本编辑器打开 todo.md 了解项目状态。建议在 DAG 之上保持 todo.md 作为导出视图(非调度数据源),确保人类可读性不丢失。
|
||
|
||
### 3.3 Phase 优先级合理性
|
||
|
||
Phase 1 集中修复 P0 缺陷,方向正确。但 T-1.10~T-1.13 均为 prompt 指令修改(0.5d 每项),实际工作量可能被低估——prompt 调优往往需要多轮测试验证,而非一次性编写。建议将 0.5d 调整为 1d 或合并为 2 个任务(AirArc/AirEng 指令重写 + AirDo/AirDbg 路由重写)。
|
||
|
||
---
|
||
|
||
## 四、审查总结
|
||
|
||
| 类别 | 数量 | 严重程度 |
|
||
|------|------|---------|
|
||
| 需修正(事实性错误或设计缺陷) | 12 | 1.1/1.2 为事实错误,其余为设计需要完善 |
|
||
| 需补充(缺失内容) | 8 | 影响完整性和可实施性 |
|
||
| 架构评论 | 3 | 建议性,非阻塞 |
|
||
|
||
**总体评价**:文档对 V1 问题的诊断全面准确,V2 的架构改进方向正确且设计深度足够。12 项修正是实施前应解决的前置条件,8 项补充可在实施过程中逐步完善。推荐在修正 1.1~1.12 后进入 Phase 1 实施。
|