关于 spec-to-code-compliance
spec-to-code-compliance 是用于核对规范文档与代码实现差异的技能,适合审计或验证系统是否遵循权威要求。它将要求逐项分派检查,并通过独立复核验证差异,生成报告及证据记录。
主要功能
- 01逐项拆分文档要求
- 02检查要求在代码中的实现
- 03独立复核候选差异
- 04提供六种检查结论
- 05记录搜索与证据
- 06生成总体及逐项报告
适用场景
- 01核对协议规范与服务实现
- 02检查 README 中的保证是否由代码落实
- 03审计代码是否符合客户发布的要求
- 04区分实现偏差与文档问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trailofbits/ skills --skill spec-to-code-compliance安装后在 Claude Code 中输入/spec-to-code-compliance确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlassets/trail-of-bits-mark.svgresources/ANALYSIS_FORMAT.mdDIVERGENCE_RUBRIC.mdDOMAIN_NOTES.mdWORKED_EXAMPLE.md详细介绍
规范与代码合规性
两份产物存在分歧,任务就是找出分歧所在。文档说明系统应如何运行;代码决定系统实际如何运行。两者之间的每处差异,要么是 Bug,要么是文档需要修正,而判定属于哪一种,就是要找出的结论。
适用场景
你同时拥有描述预期行为的文档,以及应该实现该行为的代码。例如,白皮书与协议、设计说明与服务,或 README 中声明的保证与背后的函数之间的对照。
当文档具有权威性时最有用——例如由客户编写、发布或作为审计依据的文档——因为此时偏差属于缺陷,而不是过时的描述。
不适用场景
不适用于没有描述预期行为的文档的代码。没有可供核对的依据,而从代码推断出的要求再用代码本身核对,就是自我验证。请先使用 audit-context-building 构建系统模型。
不适用于一般性 Bug 排查。它只查找一类问题:代码与文档不一致。两者都未提及的 Bug 不在范围内,而文档认可的 Bug 则属于文档方面的发现。
不适用于编写或改进文档,但它会列出需要修正的内容。
请勿在此上下文中检查要求
运行 /spec-to-code-compliance:spec-compliance <path>。斜杠命令接受路径;若要直接指定规范或扩大检查范围,请提供相应值来请求运行,例如“对照 SPEC.md 检查 ./contracts,核验 20 项要求”,这些值会以 {path, spec, limit} 的形式传给脚本。将对象原样输入斜杠命令后面并不起作用;它会作为字符串传入,并被当作路径。
该命令会查找文档,将其拆分为可单独核验的要求,为每项要求分配独立的 Agent 搜索代码,并让独立 Agent 在报告每项偏差前尝试反驳,最后写入 spec-compliance/REPORT.md,并在 spec-compliance/requirements/ 下为每项要求创建一个文件。返回到此处的只有精简记录。
对于单项要求,请将其交给 spec-to-code-compliance:spec-compliance-checker Agent 检查。
这不是对输出位置的偏好。若要认真完成检查,单个上下文窗口容纳不下:判断一项要求意味着要阅读其执行逻辑、被调用函数及调用方,而要对 30 项要求都这么做,就意味着要同时记住 30 条调用链。尝试在此处直接完成时,前几项会得到真正的检查,剩下的则会得到看似合理的检查——两者在记录中看起来完全一样,因为基于一个看起来有希望的函数名作出的结论,与基于读过函数作出的结论,读起来毫无区别。让每项要求都在独立上下文中检查,才能清楚体现这种差异。
有两项能力来自脚本,而非指令,因此无法在此处实现:
- 由未参与提出该发现的人进行反驳。 Claude 倾向于认可自己在受托检查时提出的发现。工作流会将每项偏差交给未提出该发现的 Agent——一个重新阅读代码,另一个重新阅读文档——任何一方推翻的发现都会被移除。
- 无法用散文伪装的记录。 受返回结构约束的子 Agent 必须指出自己阅读了哪些代码行,以及运行了哪些搜索。
absent结论会附带尝试过的搜索模式及其结果,这是区分真正不存在与搜索过早结束的唯一依据。
在 routes-not-inline 评测中,安装此插件后,每次运行都会派发这项工作;未安装时则从不派发——Δ +1.00。即便保留工作流,只删除本节也不会改变任何结果,因为该工作流是真正的命令,系统会自行发现并派发它。应将其理解为承载行为的机制,而非本段文字:本节的作用是让人了解会运行什么以及原因,而不是因为路由依赖本节。
会返回什么,以及如何解读
每项要求都会得到六种判定之一:implemented、partial、contradicted、stronger-than-spec、
absent 或 undecidable。最值得关注的是中间四种。
partial通常是报告中最严重的问题。要求在任何人都会测试的路径上都成立,却在无人测试的路径上失效,因此问题一直潜伏,直到被发现。absent完全依赖其searched记录。请仔细阅读。强制执行逻辑往往藏在搜索未涉及的地方——某个修饰符、基类,或先行检查的调用方。undecidable以及任何documentProblem,都是关于文档的发现。要求写得过于含糊,无法核查,客户端就无法据此追究任何人的责任。stronger-than-spec表示存在未记录的约束。它目前有效,但没有任何说明能提醒下一位修改相关代码的人:这条约束还有其他依赖方。
报告还会反向列出代码具备、但文档未提及的行为。这类问题从原理上就无法通过逐项要求的流程发现,因为该流程由文档驱动。
在将报告视为完整之前,请先查看 notChecked、unverified 和 unreadableDocuments。低于扇出阈值的要求从未经过核查;如果两个反驳 Agent 都失败了,对应的分歧就会标记为未验证,而非已确认。
工作流不会替你做出的判断
严重程度取决于后果,而不是与文本的偏离程度:DIVERGENCE_RUBRIC.md。会导致资金池损失的舍入步骤,严重程度高于以不同于文档描述的方式满足 MUST 要求;而没有行为后果的文档偏差,只需提交文档问题单。
判定结果不等于发现。强制性要求上的 absent 是一项发现;描述路线图事项的句子上的 absent 则不是。判断二者的区别正是此技能的用途,而工作流会向你提供作出判断所需的证据。
目标不一定是契约
无论在何处,问题都相同——这项要求规定了什么、应在哪里强制执行、是否在每条路径上都得到执行——但什么算作规范,以及强制逻辑藏在哪里,都会有所不同。 DOMAIN_NOTES.md 说明了契约、C 和 C++、服务及反编译固件中的差异,也涵盖规范是 RFC 或标准而非项目文档的情况。当目标不是契约,或要针对大型标准界定核查范围时,请阅读此文档。
参考资料
- ANALYSIS_FORMAT.md — 逐项要求分析的磁盘格式。扩展此插件或判断记录是否可信时请阅读。
- WORKED_EXAMPLE.md — 逐项追查三个要求并得出判定,每个示例都对应一种容易判断错误的情况:满足要求但形式看似不同的算术运算、搜索结果本身就是发现的缺失情况,以及所有路径上都存在强制逻辑,唯独无人测试的路径上没有。
- DOMAIN_NOTES.md — 各领域中的规范与强制执行映射。
- DIVERGENCE_RUBRIC.md — 严重程度,以及差距的两个方向。