Test Skill — skill 盲测复盘
任务
在隔离沙箱中驱动一次多轮 headless 会话。被测进程只看到自然的用户任务,不知道自己正在被测试。运行结束后,把每个语义步骤与目标 SKILL.md 的指令逐项对齐,产出可复核的中文报告。
先按 platform-runners.md 选择 Claude Code 或 Codex runner,再用同一个 runner 完成该次盲测的全部轮次。不要自行拼接 claude -p 或 codex exec;运行器负责超时、会话 ID、逐轮状态、JSONL、stderr、参数传递和唯一报告路径。
流程
阶段 0 定位与 CLI 预检
阶段 1 创建隔离目录并清单化指令
阶段 2 铺设 fixture 与注入目标 skill
阶段 3 生成剧本并取得成本确认
阶段 4 驱动盲测会话
阶段 5 重建时间线并双侧判定
阶段 6 写入持久报告
阶段 0:定位与 CLI 预检
- 定位目标
SKILL.md。支持仓库 id、文件路径和已安装 skill 名;存在多个候选时请用户指认,不要猜测。 - 记下三个绝对路径:本 skill 目录、发起测试时的项目目录、会话 scratchpad。后续每次工具调用都直接使用绝对路径;不要依赖 shell 变量、当前目录或上一次 Bash 调用的状态。
- 完整读取 platform-runners.md,按用户指定平台选择 runner;用户未指定时,以当前宿主和目标安装来源为判断依据,仍无法判断才询问。只执行该平台的
doctor预检,不发起模型调用。预检失败即停,不切换到另一平台,也不删除隔离参数降级运行。
阶段 1:创建隔离目录并清单化指令
在 scratchpad 下规划两个尚不存在的同级目录:测试沙箱
<运行名>/与编排目录<运行名>-run/。持久报告目录固定为发起测试项目下的skill-test-reports/<被测-id>/,不得放进目标 skill 原目录。按 platform-runners.md 的对应命令初始化运行;路径全部使用绝对路径,权限或 sandbox 选择按场景取最小值。
init必须先成功,它会创建沙箱和编排目录并写入带platform或平台配置的run-config.json。随后由编排者在沙箱执行git init;初始化仓库不需要交给被测进程。通读目标
SKILL.md全文。把可独立判定的行为要求拆为 R1..Rn,把纯背景和示例拆为 B1..Bm;frontmatter 中“不适用”限制也属于指令。将清单写入编排目录checklist.md,每条记录原文、章节和适用条件。
阶段 2:铺设 fixture 与注入目标 skill
- 只在沙箱中铺设场景 fixture。fixture 和文件名不得透露测试意图。
- 按平台注入目标 skill 的完整副本:Claude Code 使用
沙箱/.claude/skills/<被测-id>/,Codex 使用沙箱/.agents/skills/<被测-id>/。对应平台目录只允许出现这个受控副本和确有必要的空项目配置;不得复制原项目的 settings、插件、hooks、rules 或 MCP 配置。Codex 的首轮自然语言任务显式使用$<被测-id>,Claude Code 自然地点名目标 skill。 - 编排产物只能放在同级编排目录,不能放进沙箱。被测进程的 cwd 始终是沙箱。
阶段 3:生成剧本并取得成本确认
- 按 persona-template.md 生成
编排目录/persona.md。保留现有隐藏痛点模型,不额外扩展人设维度。 - 向用户呈现场景、剧本要点、预计轮数,以及
run-config.json中的实际工具边界和成本量级。取得明确确认后才执行start;成本确认门不可跳过。 - 将首轮自然语言任务写入
编排目录/turn-001.txt。被测进程收到的任何 prompt 都不得包含“测试、评估、复盘、检查你”等措辞;自然地点名目标 skill 是允许的。
阶段 4:驱动盲测会话
- 首轮仅用本次已选 runner 执行
start --run-dir <编排目录绝对路径> --prompt-file <编排目录绝对路径>/turn-001.txt,完整命令见 platform-runners.md。
运行器把 transcript、stderr、session-id 和逐轮字节范围写入编排目录,不写入沙箱。
- 解析本轮新增 transcript。若输出在等待用户输入,按剧本生成回复,写入下一个
turn-NNN.txt,再用同一 runner 执行resume --run-dir <编排目录绝对路径> --prompt-file <编排目录绝对路径>/turn-NNN.txt。
运行器自行从 session-id 恢复会话,不要在 shell 中保存 SID。剧本未覆盖的问题可按人设即兴,但必须追记进 persona.md 附录。
- 满足任一条件即停:被测进程收尾;达到
max_turns;单轮超时;CLI、权限或会话校验失败。失败后不得在同一运行目录继续或覆盖记录;保留样本进入分析。若确需重跑,创建全新的沙箱与编排目录,并重新取得成本确认。 - 需要查看可靠状态时执行
status --run-dir <编排目录绝对路径>,以run-state.json为准,不从 shell 变量推断。
阶段 5:重建时间线并双侧判定
- 先读 judging-criteria.md,再解析编排目录的
transcript-run.jsonl。遇到未知事件类型或损坏行时记录并跳过,不得让整个分析中断。 - 核对 transcript 中实际触发的 skill 名与来源是否为沙箱注入副本。若不是,或来源无法确认且会影响结论,把结果标为无效或存疑,不得伪装成有效盲测。
- 双侧判定:每个语义步骤三选一——
依据 Rx、偏离 Rx、无依据;每条指令四选一——已遵守、被违反、被跳过、未触发。 - transcript 超过约 200k 字符时,按对话轮切分给子 agent;每段必须同时提供完整 checklist 和判定标准,最后统一口径。
阶段 6:写入持久报告
- 按 report-template.md 写六节中文报告。先用同一 runner 执行
report-path --run-dir <编排目录绝对路径>,原子预留唯一文件名。
把报告写入命令返回的路径;重复调用会返回同一路径。同日多次运行由时间与 run_id 区分,不得覆盖旧报告。
- 报告中的原始证据路径必须指向编排目录的
transcript-run.jsonl、stderr.log、run-state.json、checklist.md和persona.md,不能指向沙箱。提醒用户 scratchpad 会被清理,如需长期留存应复制原始证据。
Fail-closed 边界
- 两个平台的权限模型不同,必须完整遵守 platform-runners.md 的对应边界,不把 Claude Code 的工具白名单语义套到 Codex,也不把 Codex sandbox 语义套到 Claude Code。
- 禁止
--dangerously-skip-permissions和--dangerously-bypass-approvals-and-sandbox,禁止绕过 runner 直接运行 headless CLI,禁止为兼容旧 CLI 删除隔离参数。 - 系统或组织托管策略仍可能生效;发现相关 hook、插件、MCP、skills 或权限影响时必须写入报告。无法确认实际加载来源且会影响结论时,结果标为无效或存疑。
红线
- 盲测:被测进程的一切输入不得透露测试意图。
- 零侵入:不得修改目标 skill 原目录;持久报告只能写入独立的
skill-test-reports/。 - 隔离:checklist、persona、transcript、stderr、状态文件不得进入沙箱。
- 成本确认:用户确认之前不得执行
start或任何真实 headless 轮次。