SuperAPI AI 工具集

tdd-repair

测试与质量

查看项目

更新于 10-15 15:16

技能介绍

用途

tdd-repair 将「测试驱动修复」(Test-Driven Repair)循环封装为一个 ruflo 技能。当你有一个失败的测试,并希望自动修复被测源码时使用它。验证门槛是测试本身的通过/失败结果,而不是让 LLM 充当评判者。

何时使用

  • 近期提交导致的 CI 失败测试:将本工具指向该测试文件,获得经过验证的修复(或一份明确的「在预算内无法修复」回执)。
  • 本地 TDD 工作流:先编写失败测试(tdd-workflow 技能),再运行 tdd-repair 驱动其变绿。
  • 回归分诊:一个此前通过的测试变红;在开 issue 之前,花约 1 美元看看修复是否简单。

何时不要使用

  • 不存在失败测试。符合模式(--no-test-oracle)被划归为后续 ADR 的范围,需要在复现生成上使用 MCTS。目前请先编写一个失败测试。
  • 架构性变更。本技能用于战术性的「让红变绿」修复。会顺带破坏测试的跨模块重构应由人工或 swarm 完成。
  • 不受信任的代码。无头 claude -p 以 --allowedTools Read,Edit,Bash 运行——没有 MCP、没有网络、没有任意文件写入——但 Bash 仍可触及文件系统。不要把它指向你不愿意执行 git checkout . 的代码。

算法

实现位于 scripts/tdd-repair/tdd-repair.mjs。

  1. 预检验证——运行测试命令。如果它已经通过,退出码 2(test-already-passes)。修复一个已通过的测试要么是无操作,要么是 --test-command 拼写错误。
  2. 以聚焦的提示启动 claude -p:
    • 失败测试文件路径(只读意图)
    • 测试命令(仅运行)
    • 硬约束:不要修改测试
    • 硬约束:不要新增依赖
    • --allowedTools Read,Edit,Bash 限制能力。--max-budget-usd 限制每次尝试的成本。--permission-mode acceptEdits 在允许集合内自动接受文件编辑。
  3. 重新运行测试以验证。测试的退出码就是适应度函数——无需单独的沙箱或 LLM 评判者。
  4. 如果变绿:输出 success: true 及每次尝试的用量。如果在 --max-attempts 后仍为红:输出 success: false 及回执。无论哪种情况,工作区都保持为 claude -p 修改后的状态(调用方可执行 git diff 审查)。

输出结构

{
  "success": true,
  "data": {
    "repaired": true,
    "attemptsTaken": 1,
    "mode": "test-driven",
    "before": { "passed": false, "exitCode": 1 },
    "after":  { "passed": true,  "exitCode": 0, "durationMs": 4321 },
    "attempts": [
      { "attempt": 1, "claude": { "ok": true, "durationMs": 38421, "usage": { "cost_usd": 0.0234 } }, "verify": { "passed": true } }
    ],
    "totalCostUsd": 0.0234,
    "budgetUsd": 5.0,
    "budgetExhausted": false,
    "shape": { "repo": "...", "test": "...", "testCommand": "...", "maxAttempts": 1, "model": "haiku" }
  }
}

退出码

代码 含义
0 修复后测试变绿(成功)
1 在 --max-attempts 后测试仍为红
2 配置错误(测试文件缺失、测试已通过、--no-test-oracle 不受支持等)
3 Claude CLI 以非零退出(基础设施故障)
99 保留给安全触发线(依据 ADR-153)

安全姿态

层级 机制
成本上限 --max-budget-usd 默认 $5,在 --max-attempts 之间分配。硬性上限——达到时 claude 退出。
能力上限 --allowedTools Read,Edit,Bash——没有 MCP、没有网络、没有任意写入。
范围上限 提示禁止修改测试或新增依赖。
确认门槛 --confirm 必需——没有它则返回 dry-run 计划(与 harness-evolve / harness-mint 约定一致)。
硬超时 总墙钟时间 15 分钟;每次尝试的预算为 timeoutMs / maxAttempts。
预检 如果测试已通过则拒绝运行(捕获 --test-command 拼写错误)。

灵感来源

仿照 agent-harness-generator/packages/darwin-mode ADR-175 中的 Test-Driven Repair 模式。关键设计差异:不包装 metaharness-darwin evolve(基于种群的搜索),而是驱动单次 claude -p 调用。理由:

  • 测试命令就是适应度函数——无需变体评分
  • claude -p 已在我们的技术栈中——无需新增可选依赖
  • 有界成本/能力是一等标志
  • 如需迭代,可通过 --session-id 恢复

符合模式(无测试,通过 MCTS 自行编写复现)推迟到未来的 ADR。

示例

# 冒烟 / dry-run(尚无 --confirm)
node plugins/ruflo-testgen/scripts/tdd-repair/tdd-repair.mjs \
  --repo /path/to/myrepo \
  --test tests/auth.test.ts \
  --test-command "npx vitest run tests/auth.test.ts"

# 实际修复(Haiku 层级,$5 预算,1 次尝试)
node plugins/ruflo-testgen/scripts/tdd-repair/tdd-repair.mjs \
  --repo /path/to/myrepo \
  --test tests/auth.test.ts \
  --test-command "npx vitest run tests/auth.test.ts" \
  --confirm

# 更大模型 + 更多尝试以应对更难的 bug
node plugins/ruflo-testgen/scripts/tdd-repair/tdd-repair.mjs \
  --repo . --test tests/regression-2456.test.ts \
  --test-command "npm test -- tests/regression-2456.test.ts" \
  --model sonnet --max-attempts 3 --budget 15.00 \
  --confirm

成本阶梯

层级 模型 每次尝试典型成本 使用时机
1 Haiku $0.02 – $0.20 首次尝试——大多数「让红变绿」的 bug 是战术性的
2 Sonnet $0.30 – $2.00 Haiku 失败,或 bug 涉及多文件范围
3 Opus $1.50 – $8.00 Sonnet 失败——需要架构性推理(对单个失败测试而言很少值得)