技能回归测试器(skill-regression-checker)
一句话定位
发布前/迭代前的运行时门禁:用固定用例集跑回归拿通过率、扫描 MCP/连接器依赖是否已连通、对比上一版本基线,把"我这个技能到底行不行"第一次变成可量化结论。它是 skill-package-check(静态体检)的兄弟——一个查结构,一个查运行。
适用场景与触发词
- 你刚写完一个 SKILL.md,准备发布,想确认"它真能跑、不会静默失效"。
- 你改了一版 description/工作流,想证明"改完变好了还是变坏了"。
- 你的技能依赖某个 MCP/连接器(如 GitHub、浏览器、文档),想确认当前环境是否已连上。
触发词见 frontmattertriggers(一句话定位里已列 14 条)。
涉及角色:技能作者(写用例、回填 results.json)、宿主环境(实际运行技能)、本技能(扫描与评分),三者互不越界。
能力边界(只做 / 不做)
只做:用 tests/cases.json 跑回归算通过率;扫描 SKILL.md 与脚本列出引用的 MCP/连接器/CLI 并标注未连通项;提供上一版 results.json 时对比通过率给出 Δ。
不做:静态体检→skill-package-check;触发词盲测→skill-trigger-tuner;调用率诊断→diagnose-skill-callrate;写正文→skill-writing-coach。边界争议:结构/元数据归 package-check,运行时归本技能。
工作流步骤
- 定位:读取用户给定的待验技能目录或 slug,找到 SKILL.md。
- 依赖体检:运行
scripts/audit_deps.py <目录> [--connectors <已连接清单.json>],输出引用的 MCP/连接器/CLI 与"未连接依赖清单"。 - 用例就绪:若含
tests/cases.json→ 用score_cases.py --cases校验结构;否则用references/test-case-template.json生成脚手架(先确认是否写入),指导作者补全。 - 触发一致性:把每条用例
query与 SKILL.mdtriggers匹配,标注"会/不会触发",识别"意图命中但 triggers 未覆盖"的静默失效。 - 回归评分:作者/宿主把每条 query 实际喂给技能,回填
tests/results.json,跑score_cases.py --cases --results得通过率;提供旧 results 则给 Δ。 - 汇总+埋点:输出报告(通过率、失败 diff、未连接依赖),并向
~/.workbuddy/skill-calls.jsonl追加一行。
输入契约(参数)
skill_dir(必填):待验技能目录路径或 slug。cases(选填):用例文件路径,默认<skill_dir>/tests/cases.json。results(选填):回填的实际运行结果,默认<skill_dir>/tests/results.json;缺失时只做结构校验与就绪度提示。connectors(选填):JSON 文件,列出当前已连接的连接器句柄;用于精确判定未连接依赖。baseline(选填):上一版本的results.json,用于对比通过率变化。
输出契约(预期输出格式)
依赖体检(audit_deps.py,JSON 或文本):
引用外部依赖 N 项
MCP 服务: mcp__github__...
连接器句柄: @user_x/some-connector
未连接依赖: @user_x/some-connector ← 需作者确认当前环境
回归评分(score_cases.py):
回归结果:8/10 通过,通过率 80% → yellow
✓ c1 (触发:True 内容:True 工具:True)
✗ c4 (触发:True 内容:False 工具:True) ← 期望含"GitHub"但输出缺失
依赖环境
- 运行两个脚本需 Python 3.8+(平台自带,无需安装)。
- 依赖体检纯静态扫描,不要求目标技能可运行。
- 回归"真跑"依赖宿主环境:把
cases.json的 query 逐条喂给技能,再把实际触发/输出回填results.json。skillhub run仅支持"服务化 skill",非服务化技能请用宿主内的 Skill 调用完成回填(见references/regression-protocol.md)。 - 依赖检测的具体规则与扩展方式见
references/dep-rules.md;回归方法论与用例设计原则见references/regression-protocol.md;用例模板见references/test-case-template.json。
权限要求
- 只读:用户给定的技能目录、可选的连接器清单。
- 只写:经用户确认后在技能目录内生成
tests/cases.json脚手架;写入本地埋点~/.workbuddy/skill-calls.jsonl。 - 不碰用户其他文件、不发网络请求、不修改目标技能源码。
错误处理
- 目录不存在 / 无 SKILL.md → 明确报错并提示正确路径,不臆造结果。
cases.json格式错误(缺cases数组 / 缺id/query/expect)→ 定位到具体 case 行并给修复建议。results.json缺失 → 退回"脚手架就绪,待回填"状态,不猜通过率。connectorsJSON 解析失败 → 退回"列出全部引用到的连接器句柄"模式,标注"未提供连通状态"。- 任何异常均输出结构化错误信息而非崩溃,保证可复盘。
质量门禁与红线
- 质量门禁(通过率判级):通过率 ≥90% 判 green(可发布);60%–89% 判 yellow(需修关键用例再发);<60% 判 red(禁止发布,先修再回归)。判级由
score_cases.py自动给出。 - 红线(绝不突破):① 不修改用户其他文件、不发网络请求、不改目标技能源码;② 没有
results.json绝不编造通过率,只能给"待回填"提示;③ 依赖体检发现的未连接依赖,必须在发布前于宿主连上,否则如实标注而非忽略。
示例用法
正面示例(常规·发布前回归)
用户:"帮我对 skills/skill-topic-validator 做发布前回归。"
→ 跑 audit_deps.py 得依赖清单(本案无外部 MCP,纯净);检测到 tests/cases.json 存在则评分,否则生成脚手架并提示作者回填 results.json 后再评分。
反面示例 / 反例(边界·异常输入)
用户:"对 某个不存在的目录 做回归。"
→ 脚本返回 {"error":"目录不存在: ..."},技能提示用户核对路径,不编造通过率。
用户:"我的技能依赖 GitHub MCP,但没连上。"
→ audit_deps.py 在"未连接依赖"里列出 @github/...,报告明确标注"需先在宿主连接该连接器再发布"。
自测清单(发布前验证本技能自身行为)
- [ ] 触发词命中:用户说"技能回归测试"能激活本技能。
- [ ] 输入不完整:只给 slug 不给路径 → 能在本机定位或明确询问。
- [ ] 异常输入:目录不存在 / 无 SKILL.md → 报错不崩、不臆造。
- [ ] 无 results.json → 退回就绪提示,不猜通过率。
- [ ] 依赖扫描:含
mcp__xxx__的技能能被识别并列入未连接清单。 - [ ] 连通判定:提供
--connectors后能正确区分已连/未连。
变更记录
- v1.0.0(2026-10-18)首次发布:依赖体检脚本(audit_deps.py)+ 回归评分脚本(score_cases.py)+ 用例模板与回归协议文档;覆盖封装与调试环节的运行时门禁,与 package-check/trigger-tuner/diagnose-callrate 互不重叠。