首页
/ superpowers 的 drill 迁移设计:把 LLM 行为评测提升为独立 evals/ 评测体系

superpowers 的 drill 迁移设计:把 LLM 行为评测提升为独立 evals/ 评测体系

2026-09-04 23:40:54作者:袁立春Spencer

本文基于 superpowers 仓库中的设计文档 2026-05-06-lift-drill-into-evals-design.md,完整讲解一次"评测基准搬家"的系统性设计:如何把独立的 drill skill-compliance 基准整体迁入 superpowers 仓库的 evals/ 目录、按"逐文件验证"门槛清理被完全覆盖的旧 bash 测试、并重构 tests/evals/ 的职责边界。读完本文,你可以掌握一套可复用的工程方法:如何在"源码逐字复制 + 路径契约变更 + 测试资产删除"三者之间建立可审计的验证闭环,并用子代理(subagent)门禁保证每一步都有据可查。

背景:drill 已经是 superpowers 的事实评测框架

Drill 是一个 Python 编写的 skill 合规性基准(benchmark),独立存放于 obra/drill 仓库。它的运行机制是:驱动真实的 tmux 会话、用 LLM actor 模拟用户与 Agent 对话、再用 LLM verifier 对会话转录(transcript)进行评判,并按场景(scenario)输出 pass/fail。其支持的后端包括 Claude Code、Codex、Gemini CLI,以及后来新增的 OpenCode 与 Copilot CLI。

设计文档给出的迁移动因很明确:

  • drill 已经承担了 superpowers 的"事实评测框架"角色——drill 仓库中的 PRI-1397 提交系列已将约 22 个 superpowers bash 测试提升为 drill 场景;
  • 最近一次 superpowers 提交(a2292c5)以 "replaced by drill behavioral coverage"(已被 drill 行为覆盖取代)为由显式删除了一个冗余 bash 测试——迁移势能已经形成,这份 spec 的任务是把迁移做完;
  • 具体动作三件事:把 drill 整体搬进 evals/;在逐文件验证 drill 场景覆盖之后删除冗余 bash 测试;更新顶层文档,让贡献者落到新结构上。

配套的 实施计划(约 1370 行)把设计分解为带 checkbox 的任务,并在头部声明技术栈为 "Python 3.11 + uv(drill 现有工具链,不变);rsync;bash;git",且明确要求 agentic worker 使用 superpowers 自带的 subagent-driven-development 或 executing-plans 技能来逐任务执行——这份迁移本身就是用 superpowers 方法论执行的一次实践。

目标与非目标:把边界先划清楚

目标(Goals)

  1. evals/ 成为 superpowers 的权威评测框架——包含完整的 drill 源码、场景、fixtures、prompts、后端配置和测试;
  2. tests/经逐个验证被 drill 场景 100% 覆盖的 bash 测试被删除,其余全部保留;
  3. tests/(插件基础设施:bash + node + python 集成测试)与 evals/(actor + verifier 的 LLM 行为评测)的分工是有意义的、且被文档化的;
  4. 顶层文档(README.mdCLAUDE.mddocs/testing.md)把贡献者指向正确位置;
  5. 独立仓库 obra/drill 继续存在(本 PR 不碰它),在合并后作为独立的手动步骤归档。

非目标(Non-goals)——这一节对控制 PR 规模很关键:

  • 不做 CI 集成。 仅手动运行。设计者给出了自然的后续路线(tiered:每个 PR 跑快速子集,夜间 + 按需跑全量),但那需要 API 预算决策、GitHub Actions secrets、以及一个装了 tmux + node + python + 各 CLI 的 runner 镜像,均超出范围;
  • 场景不随技能就近存放。 场景集中放在 evals/scenarios/。若将来决定每个 skill 自持场景,从源码结构看这只是一次"查找-改名"操作,YAML 格式不变;
  • 不改内部 Python 包名。 目录对用户暴露为 evals/,但 Python 包保留 drill 名以缩小 diff,在 evals/README.md 中用简短说明解释;
  • 不归档 drill 仓库。 本 PR 不碰 obra/drill,合并后手动归档(GitHub 上设为只读,README 指向 obra/superpowers/evals/);
  • 不迁移 tests/claude-code/analyze-token-usage.pyevals/bin/ 它是实用工具而非测试代码,可以以后再移。

分支策略:从 dev 拉出独立分支 f/evals-lift,与当时开放的 f/cross-platform PR 无依赖;除 README.md 外无共享文件改动,若有冲突在合并时小范围解决即可。

迁移后的架构:evals/ 目录结构与 tests/ 的职责划分

设计文档给出了目标目录树(evals/ 为逐字复制 drill 后的完整结构):

superpowers/
  evals/                              ← NEW (full drill copy)
    pyproject.toml                    (Python 3.11, uv-managed)
    uv.lock
    .gitignore                        (drill's own; results/, .venv/, .env)
    README.md                         (was drill's README; install instructions updated)
    CLAUDE.md                         (was drill's CLAUDE.md; paths updated)
    docs/
      design.md                       (drill's design — preserved verbatim, cross-linked from this spec)
      manual-testing.md
      pressure-and-red-testing.md
    drill/                            (Python package; name kept; cli, engine, actor, verifier, etc.)
    backends/                         (claude-*.yaml, codex.yaml, gemini.yaml)
    scenarios/                        (32+ YAML scenarios)
    setup_helpers/                    (15 Python helpers; create_base_repo, sdd_*, spec_*, worktree, etc.)
    fixtures/                         (template-repo, sdd-go-fractals, sdd-svelte-todo)
    prompts/                          (actor.md, verifier.md)
    bin/                              (assertion helper scripts: tool-called, tool-count, etc.)
    tests/                            (drill's own pytest suite)

  tests/                              ← bash tests preserved by default
    brainstorm-server/                ← KEEP (node tests for brainstorm-server JS code)
    opencode/                         ← KEEP (plugin loading tests)
    codex-plugin-sync/                 ← KEEP (sync verification)
    claude-code/                      ← MOSTLY KEEP — see deletion gate
    explicit-skill-requests/          ← KEEP unless verified replaced
    skill-triggering/                 ← KEEP unless verified replaced
    subagent-driven-dev/              ← KEEP unless verified replaced

  docs/
    testing.md                        ← UPDATED (split into "Plugin tests" + "Skill behavior evals")
    superpowers/
      specs/
        2026-05-06-lift-drill-into-evals-design.md   ← THIS SPEC

  README.md                           ← small Contributing-section pointer to evals/
  CLAUDE.md                           ← one-line "Eval harness lives at evals/" pointer

迁移后两个目录承担清晰不同的角色

  • tests/ —— 回答"插件的非 LLM 代码是否正常工作?" 覆盖 brainstorm-server JS 代码的单测/集成测试、OpenCode 插件加载、codex-plugin-sync 同步验证;技术栈为 bash + node + python;
  • evals/ —— 回答"Agent 在真实 LLM 会话上行为是否正确?" 运行 drill 场景,含 actor + verifier,纯 Python,驱动真实 tmux 会话。

这一划分在今天的仓库中依然可见:docs/testing.md 开头正是这两段分工描述("does the plugin's non-LLM code work?" / "do agents behave correctly on real LLM sessions?"),并按 "Plugin tests" 与 "Skill behavior evals" 两节组织——设计目标 3 和 4 已落成文档现状。

删除门槛(Deletion gate):逐文件验证,默认保留

bash 测试的删除不是批量操作,而是每个文件都要过一道门槛:只有当一个 drill 场景可验证地覆盖了该 bash 测试做出的每一条断言时才删除。验证流程是:读 bash 测试 → 列出它的所有检查项 → 找到对应 drill 场景 → 逐条确认每个检查项在场景的 verify.assertionsverify.criteria 中有匹配条目。只要有一条检查项没有匹配,选项只有两个:扩展 drill 场景,或保留 bash 测试。默认是保留。

设计文档附了一张基于提交信息整理的"暂定覆盖地图"(tentative coverage map),并强调"删除前必须逐文件验证":

Bash 测试 声称的 drill 替代 覆盖状态
tests/skill-triggering/prompts/*(6 个 prompt 文件) triggering-*.yaml(6 个场景) 候选——删除前逐 prompt 验证
tests/skill-triggering/run-test.shrun-all.sh 不适用(runner,非测试) 保留——运行脚本
tests/explicit-skill-requests/prompts/please-use-brainstorming.txt 待验证——drill 尚无明确对应场景 除非补 drill 场景,否则保留
tests/explicit-skill-requests/prompts/use-systematic-debugging.txt 待验证——drill 尚无明确对应场景 除非补 drill 场景,否则保留
tests/explicit-skill-requests/run-claude-describes-sdd.sh 部分 → mid-conversation-skill-invocation.yaml 候选——逐脚本验证
tests/explicit-skill-requests/run-haiku-test.sh 没有 drill 场景覆盖 Haiku 特有行为 保留
tests/explicit-skill-requests/run-multiturn-test.shrun-extended-multiturn-test.sh 没有 drill 场景覆盖多轮构建 保留,除非补充 drill 场景
tests/explicit-skill-requests/run-test.shrun-all.sh 不适用(runner) 保留
tests/subagent-driven-dev/go-fractals/svelte-todo/ sdd-go-fractals.yamlsdd-svelte-todo.yaml 候选——删除前验证(含"测试套件通过"这类真实断言)
tests/claude-code/test-document-review-system.sh spec-reviewer-catches-planted-flaws.yaml 候选——删除前验证
tests/claude-code/test-requesting-code-review.sh code-review-catches-planted-bugs.yaml 候选——删除前验证
tests/claude-code/test-subagent-driven-development-integration.sh sdd-rejects-extra-features.yaml(YAGNI 子集) 部分——bash 测试还断言 ≥3 个 commit / npm test 通过 / 运行 analyze-token-usage.py;drill 场景断言 forbidden-exports + reviewer-as-gate,两者大体不相交——几乎确定保留 bash + 扩展 drill 场景
tests/claude-code/test-subagent-driven-development.sh 元/文档类测试(让 Agent 描述 SDD);无 drill 场景覆盖"描述类测试" 保留,除非补 drill 场景
tests/claude-code/test-worktree-native-preference.sh worktree-creation-under-pressure.yaml 候选——删除前验证
tests/claude-code/test-helpers.shrun-skill-tests.shanalyze-token-usage.py 不适用(工具,非测试) 保留——库/工具

这张地图与当前仓库状态可以互相印证:tests/explicit-skill-requests/ 目录下至今保留着 prompts/please-use-brainstorming.txtprompts/use-systematic-debugging.txtrun-haiku-test.shrun-multiturn-test.shrun-extended-multiturn-test.sh 等被判为"keep"的文件;而 tests/claude-code/test-worktree-native-preference.shtests/claude-code/test-subagent-driven-development-integration.sh 被保留下来,且内部已标注 drill 覆盖范围(drill 只覆盖 PRESSURE / YAGNI 子集,bash 侧补充覆盖 RED/GREEN 基线、commit 数与 token 遥测断言);tests/claude-code/test-subagent-driven-development.sh 同样保留("描述类"测试无 drill 对应物)。而 skill-triggering/subagent-driven-dev/ 两个目录已不在 tests/ 下——符合"候选项验证通过后删除"的处置。RELEASE-NOTES.md 中还保留了历史说明:test-requesting-code-review.shtest-document-review-system.sh 已于 2026-05-06 被提升为 drill 场景并从 tests/ 移除,原引用被保留为"dated artifact"(带日期的历史工件),正是设计文档要求的历史引用"注释而非改写"策略的落地。

子代理门禁:每类变更都有独立验证人

设计文档的"Verification protocol (subagent-gated)"规定:实施计划中的每一处变更,在提交前都由独立子代理交叉检查。这是整份设计最有辨识度的部分——验证责任被分配到了与变更类型一一对应的子代理任务上:

变更类别 子代理验证方式
每个 bash 测试的删除 派发子代理,输入:(a) bash 测试文件内容,(b) 候选 drill 场景 YAML,(c) 提示词:"列出 bash 测试的每条断言;列出 drill 场景的每条 verify 项;对每条 bash 断言找到匹配的 drill 检查项,否则报告未匹配。输出逐断言表格。" 子代理输出即门槛——只有每条断言都有匹配才允许删除。
初始 evals/ 复制 子代理验证:(a) 被复制的 drill SHA 记录在 lift 提交信息中,来源可审计;(b) 逐文件 SHA-256 校验和与 drill 仓库一致(不是只数文件数);(c) 排除路径(.git/.venv/results/.env__pycache__/*.egg-info/、任何 .private-journal/)在 evals/ 中不存在;(d) 所有 backend YAML 引用的路径在迁移后依然存在;(e) pyproject.tomluv.lock.gitignore 完整无损。
drill 自带的 pytest 套件 子代理在路径默认值变更后运行 cd evals && uv run pytest。drill 自带 pytest 套件(evals/tests/,含 test_backend.py,它演练 SUPERPOWERS_ROOT 环境变量行为),这些测试必须更新以匹配新 helper 并继续通过。
删除后的引用清扫 子代理对 superpowers 全树 grep 被删 bash 测试路径(排除 node_modules/.venv/evals/),搜索目标:docs/docs/superpowers/plans/RELEASE-NOTES.mdCLAUDE.mdGEMINI.mdAGENTS.mdREADME.md.github/scripts/.opencode/INSTALL.md.codex-plugin/INSTALL.mdlefthook.yml。任何命中要么更新、要么暴露一个被遗漏的依赖。
路径默认值变更(SUPERPOWERS_ROOT 子代理在路径变更后至少运行一个便宜的 drill 场景(如 triggering-test-driven-development)并确认其通过——是真实行为验证,而非仅代码评审。
最终 PR 前对抗性评审 两个子代理并行,采用"5 分给找到最多有效问题的人"的框架——与 cross-platform PR 所用协议相同。同时验证源码与行为。

每个子代理任务在实施计划中都有独立条目,带明确的输入与通过标准;子代理输出被摘要进相应提交信息("Subagent verification: …"),使整条验证轨迹可审计。

路径与配置契约:SUPERPOWERS_ROOT 的自动默认化

这是迁移中最精细的部分——让 drill 搬进 evals/ 后"开箱即用",同时不破坏任何现有行为。

前置验证(写 spec 之前已核实)drill/cli.py 定义了 PROJECT_ROOT = Path(__file__).parent.parent。迁移后 cli.py 位于 evals/drill/cli.py,因此 PROJECT_ROOT 解析为 evals/PROJECT_ROOT.parent 解析为 superpowers 仓库根目录——这正是 SUPERPOWERS_ROOT 应取的默认值。

YAML 替换审计:只有 4 个 claude*.yaml 后端配置会在 args 中插值 ${SUPERPOWERS_ROOT}(用于 --plugin-dir 标志);codex.yamlgemini.yaml 只是在 required_env 中列出 SUPERPOWERS_ROOT(由 engine.py:233 / setup.py:25 中前置/后置运行钩子处的 os.environ["SUPERPOWERS_ROOT"] 查找消费)。helper 对 os.environ 的修改同时覆盖这两条代码路径。

具体的文件级修改清单(当前 → 迁移后):

文件 当前 迁移后
drill/cli.py 模块导入时 load_dotenv(PROJECT_ROOT / ".env");与 SUPERPOWERS_ROOT 无关 load_dotenv 之后调用新 helper _set_superpowers_root_default():当且仅当未设置时,把 os.environ["SUPERPOWERS_ROOT"] 设为 str(PROJECT_ROOT.parent)。顺序:load_dotenv → 设默认值 → click group 定义。
drill/engine.py:233drill/setup.py:25 直接访问 os.environ["SUPERPOWERS_ROOT"](未设置时 KeyError) 不变。CLI 启动钩子保证引擎/设置执行时环境变量已就位。
backends/claude*.yaml(5 个文件) args 中的 ${SUPERPOWERS_ROOT} 用于 --plugin-dir 替换 不变。YAML 替换在后端加载时读 os.environ,此时已是 CLI 启动之后。
backends/codex.yamlbackends/gemini.yaml 仅在 required_env 中列 SUPERPOWERS_ROOT required_env 移除(由 helper 供给)。claude*.yaml 保留 required_env 以向后兼容(环境变量仍可覆盖)。
evals/tests/test_backend.py 测试断言 SUPERPOWERS_ROOTrequired_env 列表中,另有路径解析测试 更新测试以匹配新契约:helper 提供默认值、环境变量覆盖仍可用、codex/gemini 不再需要 required_env
evals/README.md "export SUPERPOWERS_ROOT=/path/to/superpowers" 删除 export 行;说明该变量自动默认为 evals/ 的父目录;唯一必需的配置是 ANTHROPIC_API_KEY(或 OPENAI_API_KEY / Gemini 鉴权)。
evals/CLAUDE.md 同上 同上
evals/.gitignore drill 既有模式(results/.venv/__pycache__/.env*.pyc*.egg-info/dist/build/.claude/ 逐字复制。模式相对文件位置生效,因此在 evals/ 下同样正确。
evals/lefthook.yml drill 自带 lefthook.yml,定义 pre-commit: uv run ruff check && uv run ty check 移至 evals/lefthook.yml。两种方案:(a) 在 superpowers 根安装 lefthook 并联邦到 evals/lefthook.yml;或 (b) 文档化让贡献者手动运行 cd evals && lefthook run pre-commit实施决策:选 (b) 求简——superpowers 顶层工作流不变。

.env 位置:保留 evals/.env(gitignore),贡献者从那里 source,或在 shell 环境中直接设置 ANTHROPIC_API_KEY

顶层 superpowers 文件的小幅增补

  • superpowers/.gitignore:增加 evals/results/evals/.venv/evals/.env(双保险;evals/.gitignore 已在本地覆盖这些);
  • superpowers/CLAUDE.md:增加一行指针 "Eval harness lives at evals/ — see evals/README.md",让 Agent 能发现它(当前 CLAUDE.md 中仍保留了 "Skill-behavior evals live in … see evals/README.md" 的指引行,是这一设计的延续);
  • superpowers/docs/testing.md:拆分为 "## Plugin tests"(现有 tests/ 内容,裁掉被删测试的引用)与 "## Skill behavior evals"(一段话摘要 + 指向 evals/);
  • superpowers/README.md:在 Contributing 节加一行,指向 evals/ 做 skill 行为测试。

迁移顺序:十个原子化步骤

每一步是一个独立提交(或小提交组)。第 2 步是最大的单提交(drill 逐字复制),后续步骤小而原子:

1. Branch off `dev` (f/evals-lift)

2. Copy drill repo into evals/ (single commit, easy to revert)
   ├─ Record drill SHA at copy time → commit message
   ├─ Use `rsync -a --exclude=.git --exclude=.venv --exclude=results
   │  --exclude=.env --exclude=__pycache__ --exclude='*.egg-info'
   │  --exclude=.private-journal /path/to/drill/ evals/`
   │  (rsync chosen over `cp -r` for explicit excludes; verify with
   │  `find evals -name '.git' -type d` returns nothing)
   ├─ Subagent gate: per-file SHA-256 checksum matches drill repo for every
   │  non-excluded file; excluded paths absent from evals/
   └─ Smoke check: `cd evals && uv sync` succeeds (proves install only;
      not a behavioral test)

3. Update path defaults
   ├─ Add _set_superpowers_root_default() helper to drill/cli.py
   ├─ Wire it after load_dotenv, before click group definition
   ├─ Update evals/README.md and evals/CLAUDE.md (drop SUPERPOWERS_ROOT install step)
   ├─ Drop SUPERPOWERS_ROOT from required_env in codex.yaml/gemini.yaml
   │  (keep in claude*.yaml as override)
   └─ Update evals/tests/test_backend.py to match new contract

4. Validate from new location (TWO checks)
   ├─ Run drill's own pytest: `cd evals && uv run pytest` — must pass
   └─ Run cheap drill scenario: `cd evals && uv run drill run
      triggering-test-driven-development -b claude` — must pass.
      Real behavioral validation, not just code review.

5. Bash test deletion phase — per-file with subagent gate
   For each file in the candidate-deletion list:
   a. Subagent compares bash test assertions vs drill scenario verify block
   b. Pass criterion: every bash assertion has a matching drill check
   c. If pass → delete the bash test file (one commit per file or per
      coherent group)
   d. If fail → either extend drill scenario (separate commit + verify) or
      keep the bash test (no commit)

6. Stale-reference scrub
   ├─ Subagent greps the superpowers tree (excluding node_modules/, .venv/,
   │  evals/) for deleted file paths
   ├─ Search targets: docs/, docs/superpowers/plans/, RELEASE-NOTES.md,
   │  CLAUDE.md, GEMINI.md, AGENTS.md, README.md, .github/, scripts/,
   │  .opencode/INSTALL.md, .codex-plugin/INSTALL.md, lefthook.yml
   ├─ Update active references (e.g., docs/testing.md, README.md install)
   └─ Historical references in docs/superpowers/plans/*.md and
      RELEASE-NOTES.md are PRESERVED with a brief annotation
      ("(test removed; behavior covered by drill scenario X)") rather
      than rewritten — these are dated artifacts, not living docs.

7. Top-level docs
   ├─ docs/testing.md split
   ├─ CLAUDE.md pointer
   └─ README.md Contributing section

8. Re-run smoke checks (regression gate)
   ├─ `cd evals && uv run pytest`
   └─ `cd evals && uv run drill run triggering-test-driven-development -b claude`

9. Final adversarial review
   └─ Two parallel subagents, full diff, "5 points to whoever finds the
      most legitimate issues" framing. Address findings before push.

10. Push branch + open PR against dev
    └─ PR description includes: drill SHA pinned at copy, archival action
       item ("after merge: archive obra/drill, add README pointer to
       obra/superpowers/evals/"), per-deleted-file coverage receipts.

几个值得注意的设计取舍:rsync 而非 cp -r 是为了显式排除列表,且可用 find evals -name '.git' -type d 这类命令独立复核;第 4 步坚持"两次检查"(pytest + 一个真实场景)区分"能安装"与"行为正确";第 6 步对历史文档(docs/superpowers/plans/*.mdRELEASE-NOTES.md)采取"加注释不改写"原则,因为它们是带日期的工件而非活文档。

实施后的验收清单

实施计划必须展示以下证据链:

  • 第 2 步后 evals/ 中存在全部非排除的 drill 源文件(子代理逐文件 SHA-256 校验和比对 vs obra/drill@<recorded-sha>);
  • 排除路径(.git/.venv/results/.env__pycache__/*.egg-info/.private-journal/)在 evals/ 中不存在;
  • 第 2 步提交信息记录了 drill 源 SHA;
  • 未设置 SUPERPOWERS_ROOTcd evals && uv sync 成功;
  • cd evals && uv run pytest 通过(drill 自带 pytest 套件);
  • cd evals && uv run drill list 返回的场景数与记录 SHA 处的独立 drill 仓库一致;
  • cd evals && uv run drill run triggering-test-driven-development -b claude 通过(端到端证明路径默认值工作);
  • 每个被删 bash 测试的提交信息中包含子代理验证表,逐条断言映射到 drill 检查项;
  • 对已删文件路径的 grep 在活文档中零命中(第 6 步之后);docs/superpowers/plans/*.mdRELEASE-NOTES.md 中的历史引用被注释而非改写;
  • docs/testing.md 同时拥有 "Plugin tests" 与 "Skill behavior evals" 两节;
  • drill 仓库历史不受影响;PR 描述点名"合并后归档 obra/drill"的行动项。

设计中的未决问题:全部已决

文档最后列出了所有澄清性决策("Open questions: None"):

问题 决策
drill 在 superpowers 中的位置? evals/(从 drill 改名而来);独立仓库另行归档
冗余 bash 测试的命运? 逐文件删除,由子代理验证覆盖;默认保留
场景布局? 集中在 evals/scenarios/
Python 工具链位置? 自包含于 evals/
CI 集成? 本 PR 仅手动;文档化未来路线
迁移机制? 普通复制;drill 仓库历史保留在归档仓库中,而非进树
内部 Python 包名? 保留 drill(目录为 evals/
分支策略? 独立基于 dev(不叠加在 f/cross-platform 之上)

仓库现状对照:设计被实施后的演化轨迹

把这份 2026-05-06 的设计放回仓库时间线中看,其实施结果在 git 历史与现存文档中留有清晰痕迹(以下均可在仓库内核实):

  • 迁移按设计执行:git 历史中存在提交 6bc6f22 "Lift drill into evals/ at 013fcb8b7dbefd6d3fa4653493e5d2ec8e7f985b",提交信息完整记录了 rsync 排除列表、源 SHA(写入 evals/.drill-source-sha 供分歧检测),以及"drill 仓库不受影响、归档为合并后的独立手动步骤"——与设计的步骤 2 和验收清单一一对应;其后是 03cc20d(SUPERPOWERS_ROOT 默认值化)、671ec37(从 codex/gemini 的 required_env 移除)、09046c0(README/CLAUDE 去掉 export 步骤)等对应步骤 3 的小提交,以及 ea8aad812ef68d1f0ad38 等逐文件删除提交(分别移除 test-document-review-system.shtest-requesting-code-review.sh 与 subagent-driven-dev fixtures,提交信息注明对应的 drill 场景),315ef09 则对三个保留的 bash 测试加注了 drill 覆盖说明——与上文覆盖地图中"候选/保留"的分判完全吻合。
  • RELEASE-NOTES.md 的相应版本说明写道:"Skill-behavior testing moved out of tests/ into a new evals/ submodule built on 'drill' … Several in-tree bash suites retired once a stricter drill scenario covered them; the few with no equivalent stayed. From here on, tests/ holds plugin-code tests and evals/ holds skill-behavior tests"(#1541)——目标 3 的"分工被文档化"直接落成了版本说明文字;并保留了历史引用注释(指向 evals/scenarios/code-review-catches-planted-bugs.yamlevals/scenarios/spec-reviewer-catches-planted-flaws.yaml),即"注释而非改写"策略的实际产物。
  • 值得说明的是:从仓库后续演化看,evals/ 在成为 submodule 后,最终因"插件安装对部分用户报错"而在 v6.0.2 停止随插件发布,评测框架移入独立仓库(见 RELEASE-NOTES.mdCLAUDE.md 现行措辞)。这属于设计合并之后的独立决策,但反过来也印证了设计文档非目标里"独立仓库与主仓库解耦"的保守取向:先让 evals/ 在结构上自包含,后续无论继续内置还是拆出去,成本都很低。

小结

这份设计的可取之处不在于"搬一个目录",而在于它把三件高危操作——逐字复制(靠逐文件 SHA-256 校验和与源 SHA 记录保证可审计)、契约变更SUPERPOWERS_ROOT 自动默认化,且引擎/设置/后端的三处消费路径逐一审计)、资产删除(每个 bash 测试都要过"逐断言匹配"的子代理门槛,默认保留)——都装配了独立于执行者的验证环节,并且把"tests/ 测插件代码、evals/ 测 Agent 行为"的职责边界写进了贡献者会看到的每一层文档。对任何想把评测体系从散装 bash 脚本升级为结构化 LLM 行为评测的团队,这份 spec 提供了一份可直接套用的清单:先画职责边界,再定删除门槛,最后用"真实跑一个便宜场景"替代"只看 diff"作为验收底线。

登录后查看全文
热门项目推荐
相关项目推荐