关于 work-refute
work-refute 是用于对代码或设计判断进行对抗式验证的技能,面向需要审查主张和发现的开发者。它优先运行可确定结果的直接检查,再让独立验证者从不同视角寻找反证,并按证据汇总结论。
主要功能
- 01先执行命令、测试等直接验证
- 02为主观判断并行分派独立反驳者
- 03针对安全与正确性采用多元视角
- 04按证据权重处理投票与弃权
- 05汇总反证、存疑项及未检查路径
适用场景
- 01核查代码审查中提出的缺陷
- 02评估设计安全性或正确性主张
- 03从多个视角检查认证与数据完整性
- 04对一组发现逐项验证并报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ djalmajr/ skills --skill work-refute安装后在 Claude Code 中输入/work-refute确认已加载。
详细介绍
/work-refute — 反驳竞赛
此技能实现 对抗式验证 质量模式。
它是 ../work-tournament/SKILL.md 的 破坏性 变体(并行 创作 + 选择),也是 ../work/references/workflow-mode.md 中工作流的验证阶段。
它将 ../work/references/anti-error-lessons.md 中的经验教训 L1、L2、L3、L5、L6、L7、L8 落到实践中。
工作流形态 — 此技能是针对各项主张的 PIPELINE
验证一组主张是一个 PIPELINE,而非屏障。每项主张的反驳小组都独立运行——各项主张之间没有屏障。 主张 A 可以先完成投票并报告,同时主张 B 的反驳者仍在调查。墙钟时间 = 最慢的单项主张的反驳小组所需时间,而非所有主张所需时间的总和。
- 针对单项主张,N 个反驳者并行展开,存活投票是一个小型的单项主张屏障(等待该主张的反驳者——且仅等待这些反驳者——完成后再为它投票)。这是唯一的屏障,而且只在局部生效。
- 在报告任何结果之前,不要对整个批次设置屏障(“等待所有主张的反驳者完成”)——这是一个虚假屏障(参见 workflow-mode §1)。每项主张一旦自己的小组得出结果,就立即给出其判定。
- LOOP 模式是一种可选的外层封装(参见下方的循环模式说明),适用于攻击角度数量未知的情况——逐轮重新攻击存活的主张,直到没有新发现。默认的单轮模式是纯粹的流水线。
为什么不采用 PARALLEL/BARRIER:只有存在真正的跨项依赖(去重/合并、结果为零时提前退出、对所有候选项排序)时,屏障才合理。验证主张 B 不依赖主张 A 的判定,因此没有需要设置屏障的理由。
核心理念(源自原始技术)
单个 Agent(或单轮评审)容易受到确认偏误影响。形成假设(“这是个 bug”“这是根本原因”“此设计是安全的”)后,我们会自然地寻找支持该假设的证据。
对抗式验证颠倒了举证责任:
- 启动相互独立的验证者,明确要求他们反驳,而非确认。
- “只要有任何疑虑,且你已收集证据支持它,就标记为已反驳。”
- 只有通过按证据加权的存活规则(如下所述)的主张才能存活——不能简单采用 2 票对 3 票的计数方式。只有实际重新阅读引用来源的判定才计入;敷衍或空白的判定属于弃权(已过滤并记录,L8)。一条高置信度、证据充分的反驳,可以胜过两条敷衍的“没有疑虑”存活判定。
- 对于安全性 / 身份验证 / 多租户 / 数据完整性 / 正确性主张,默认采用视角多样化——为每位反驳者自动选取不同视角,而非设为可选项(L3)。相同的反驳者只是冗余,并非多样化。
规则 #1 — 优先使用直接判定依据(不可妥协,L1): 如果可以通过运行命令、测试、类型检查、git 差异、精确字符串搜索、构建或类似判定依据来确定性地验证主张——先直接验证。这严格优于任意数量的 Agent 投票,因为它更省成本、更快、更可靠。
判定依据以失败即拒绝的方式把关结果:如果主张通过反驳者的验证而存活,但存在可用且尚未运行的判定依据,那么它就还不算“完成”——报告前必须运行该判定依据。
仅将对抗式验证用于概率性 / 主观 / 需判断的主张:
- “这确实是个 bug”
- “这是根本原因”
- “此更改在意图上是安全的 / 高性能的 / 正确的”
- “此设计优于备选方案”
用法
/work-refute [N] "the claim or finding to attack"
可组合使用以下选项:
/work-refute 5 "the claim"— 使用 5 个验证者(默认值 = 3)/work-refute lenses=correção,segurança,reproduz "claim"— 使用明确指定的视角,进行多视角验证/work-refute "claim" --direct-first(默认行为)- 聚焦于已有发现:
/work-refute the 4 findings from my last review
如果主 Agent 已提取候选项,也可以传入结构化输入(发现列表)。
决策表(内置于技能中)
| 声明类型 | 优先使用的技术 |
|---|---|
| 可通过命令 / 测试 / 类型 / git 验证 | 直接验证(运行并观察结果) |
| 对代码 / 设计 / 原因的判断 | 对抗式验证(N 个独立反驳者) |
| 可能以多种不同方式失败 | 多视角验证(不同视角) |
| 大小未知的集合(找出所有 X) | work-exhaust(重复直到连续 K 轮结果为空) |
该技能始终会先尝试直接验证步骤,然后才启动开销较大的反驳者。
技能的工作方式(编排)
-
对声明进行分类
- 这是一个明确的事实陈述,可以使用 Agent 已有的工具进行检查吗(运行 shell 命令、
grep、读取文件、git命令、构建 / 测试等)? - 如果是 → 先执行直接检查。将结果记录为真实依据。
- 这是一个明确的事实陈述,可以使用 Agent 已有的工具进行检查吗(运行 shell 命令、
-
如果属于判断 / 主观内容(或用户明确要求使用对抗模式)
- 确定 N(默认值为 3,用户可指定 2-7)。遵守并发上限和预算(参见执行机制);如果必须缩小 N,则记录下来(不得悄悄缩减)。
- 确定模式:
- 对于任何安全 / 身份验证 / 多租户 / 数据完整性 / 正确性声明(L3),多视角验证是默认方式。自动选择不同视角——无需用户提供。对于隔离 / 身份验证声明,标准视角包括: 伪造 / 欺骗、配置或 realm 混淆(错误的租户 / 共享的 issuer / 错误的环境)、替代代码路径(另一条路由到达同一 sink)、下游影响(此处确认的漏洞随后会破坏什么)。相关时再加入回归和与规范 / AGENTS.md 的一致性。
- 冗余验证(仅用于风险较低、只有一种失败模式的声明):使用相同且有力的“反驳”提示词,让 N 个反驳者在完全独立的上下文中进行验证。
- 用户提供明确视角时,逐字使用(例如
lenses="correção funcional, injection / secrets, reproduz no runtime?")。
-
派生真正独立的反驳者——为每位反驳者派生一个子 Agent;在同一条消息中派生多个,以实现真正的并行处理;为其指定恰当的子 Agent 角色(general-purpose),并在后台运行。只有在反驳者会修改文件时,才使用隔离的工作树(只读反驳者无需工作树)。每位反驳者只接收原始主张和最少的上下文——绝不接收主 Agent 或其他反驳者的推理过程。提供完整的工具访问权限以便调查(读取代码、运行命令、查看 git 历史)。
- 每个子 Agent 都要设定严格的反驳者角色,并包含以下三项强制条款(不可协商——忽略这些条款的反驳者在投票时视为弃权):
你是一个充满敌意的怀疑者。你唯一的任务就是反驳这个主张。假定这个主张在试图欺骗你。不要客气;不要抱有任何侥幸。
- (L2——自行重新读取源代码。) 重新打开主张引用的每个
file:line,并引用你现在看到的真实、当前代码行。绝不要相信主张引用的证据——请从实时源代码中核实。准确列出你在reReadSources中重新读取的内容。 - (L3——使用你独有的视角。) 只能从
[LENS]视角攻击该主张(例如伪造/欺骗、配置或 realm 混淆、替代代码路径、下游影响)。不要扩展到其他视角——那些由其他反驳者负责。 - (L8——只有实际完成调查,反驳才有效。) 只有在重新读取代码、实际尝试指定的攻击角度并提供具体
file:line证据后,refuted: true才有效。如果你没有完成调查,就设置workDone: false和refuted: false——敷衍地说“看起来没问题/没有疑点”属于弃权,不算通过投票。同样的标准也适用于“通过”:没有证据的空泛通过同样属于弃权。
返回符合结构化 JSON 契约的内容(参见 schema)。设置
severity(critical|high|medium|low),并以经核实的现实影响(L6)为依据,而不是凭感觉。 - (L2——自行重新读取源代码。) 重新打开主张引用的每个
- 每个子 Agent 都要设定严格的反驳者角色,并包含以下三项强制条款(不可协商——忽略这些条款的反驳者在投票时视为弃权):
-
收集并验证裁决
- 每位反驳者都必须输出符合下方结构化 I/O 契约的带围栏的
json代码块。验证其结构;若回复格式错误,重新请求一次,若仍然格式错误,则丢弃并记录(绝不要默默接受普通文本)。
- 每位反驳者都必须输出符合下方结构化 I/O 契约的带围栏的
-
基于证据权重的通过规则(取代简单的三分之二多数)
- 先过滤弃权。 只有满足
workDone === true、reReadSources非空,且包含具体evidence(file:line+ 引用)的裁决才计入。其他任何情况——已终止/出错的反驳者(null)、敷衍的“看起来没问题”、没有证据的“没有疑点”——都属于弃权:将其丢弃并记录丢弃日志(哪位反驳者、哪个视角、原因)(L8 + null 处理)。 - 根据剩余票数重新计算门槛。 设剩余的有效裁决数为
k(N 个裁决中),通过门槛为k的多数票,而不是 N 的多数票。记录重新计算过程(N=3 → 丢弃 1 票 → 对 k=2 进行投票,至少需要 2 票通过)。一个已终止的反驳者绝不能被视为反驳票或通过票(L7,禁止静默封顶)。 - 按证据权重而非票数计权。 一条
refuted:true裁决若confidence:"high"、workDone:true,且提供可复现的file:line攻击证据,其权重高于两条没有证据的refuted:false裁决 → 该主张被驳回。反过来,也不要让敷衍的反驳推翻一个论据充分的主张。 - 裁决映射:
confirmed_bug/refuted/survives/needs_oracle(某个计入的反驳者表示只有确定性检查才能定论 → 按规则 #1,在最终报告前运行 oracle)。
- 保留所有攻击意见(包括针对最终通过主张的意见)——它们对用户极有价值。
- 先过滤弃权。 只有满足
-
投票后:Oracle 门控、完整性与校准(不得跳过)
- **Oracle 门控(L1,失败即关闭):**任何仍然成立且有可用但尚未运行的 Oracle → 立即运行;Oracle 失败则翻转判定。
- 完整性移交(L5):将仍然成立的集合交给
../work-gaps/SKILL.md,并逐字询问 “有哪些代码路径 / 模态没有受到任何反驳者攻击?”——此外运行一个 全局 Oracle(在整个仓库中搜索核心实体,或执行范围覆盖差异比较),以发现 从未列入清单的声明 / 路径。 - 严重性校准(L6):根据已验证的现实影响重新校准每个
severity,避免 两种错误——绝不将表面问题 / 开发时问题升级为critical/high(误报),也绝不将 可利用且可触达的问题留在low(漏报)。high及以上必须给出具体的可触达性论证。
-
返回结果
- survivors[](附上在 Oracle 检查后仍能支撑它们的证据)。
- refuted[] + 最有力的攻击及其
file:line。 - abstentions[] + 每项被舍弃的原因(保持透明,L7/L8)。
- 对于采用多视角运行的情况:按视角分类的细目。
- work-gaps 的“未触及路径”说明及明确建议。
结构化 I/O 约定
每个反驳者都必须在回复末尾附上符合此结构的围栏式 json 代码块。调用方会解析并验证它(格式错误时重新请求一次,之后丢弃并记录)。这是
../work/references/workflow-mode.md §4 中约定在
各技能中的具体应用。
{
"claimId": "host-param-storage",
"lens": "config-or-realm confusion",
"verdict": "confirmed_bug",
"refuted": true,
"severity": "high",
"confidence": "high",
"workDone": true,
"reReadSources": [
"src/http/routes/upload-handler.ts:171",
"src/auth/middleware.ts:88",
"docs/adr/tenant-isolation.md"
],
"evidence": [
"upload-handler.ts:171 — storage tenant taken from ?hostname, post-auth, no session binding",
"middleware.ts:88 — issuer check shared across realms, does not pin tenant"
],
"attack": "An authenticated tenant A can pass ?hostname=tenantB and read tenant B storage; the issuer check does not close it because the realm is shared.",
"scenario": "Repro: login as A, GET /upload?hostname=tenantB → B's objects listed."
}
| 字段 | 类型 / 枚举 | 必填 | 经验教训 |
|---|---|---|---|
claimId | string | 是 | — |
lens | string | 是(适用于多视角) | L3 |
verdict | confirmed_bug | refuted | survives | needs_oracle | 是 | L1、L6 |
refuted | boolean | 是 | — |
severity | critical | high | medium | low | 是 | L6 |
confidence | high | medium | low | 是 | — |
workDone | boolean | 是 | L8 |
reReadSources | string[](实际重新打开的 file:line) | 是(非空才计入) | L2 / L8 |
evidence | string[](file:line + 简短引文) | 是(计入时必填) | L2 |
attack | string(最有力的反驳) | 当 refuted 时必填 | — |
scenario | string(具体复现步骤 / 说明为何无法利用) | 建议填写 | L6 |
workDone:false、reReadSources 为空或 evidence 为空的判定都属于弃权——不会参与投票(会在步骤 5.1 中筛除并记录)。
执行机制
这些机制可确保流水线可靠。它们与 workflow-mode §3 保持一致——不要重新推导。
- 空值处理(失效反驳者):
null/ 出错 / 超时 / 弃权的反驳者会被 过滤掉(.filter(Boolean)加上 5.1 中的弃权过滤器)——绝不会 计为反驳或存活。过滤后,根据剩余反驳者重新计算存活阈值,并将 丢弃情况记录为具名条目 (refuter#2 (lens=alternative-code-path) dropped: workDone=false → vote over k=2)。 - 并发上限: 以受控波次启动反驳者,数量约为
min(16, cores−2)。在包含多个 声明的流水线中,上限是全局的——超出上限的声明所对应的反驳者组会排队; 不会全部同时启动。 - 预算意识: 预算不足时,明确减少 N 或停止启动。 绝不要悄悄缩减评审组。
- 不得设置静默上限(L7): 每项缩减——反驳者数量少于请求数、未运行某个视角、 因预算推迟某项声明、报告存活结果却未提供其预言机——都必须作为具名条目 写入决策记录,并且通过你的测试框架的待办/计划工具呈现出来。读者必须能区分 “完整无缺”和“已截断”。
- 工作树隔离: 只有会修改文件的反驳者才在隔离的工作树中运行。 纯只读的反驳者不需要隔离。
- 日志记录(长时间运行 / 循环运行): 在
quality-journals/<task-id>.json(位于你的 Agent 数据目录下)中写入{ phasesDone[], seen[], anglesUsed[], survivors[], droppedDueToCaps[] }。恢复时, 加载seen[],且绝不重置,以防已被反驳的声明重新进入,以及已耗尽的视角被重新运行。
示例(证据加权存活的实际应用)
声明:"?hostname 存储覆盖安全,因为 auth middleware 的 issuer 检查可以阻止它。"
视角多样化,N=3,自动挑选视角。
| 反驳者 | 视角 | workDone | reReadSources | 判定 |
|---|---|---|---|---|
| #1 | 伪造 / 欺骗 | true | auth.ts:40 | survives(issuer 检查能抵御令牌伪造) |
| #2 | 配置与 realm 混淆 | true | upload-handler.ts:171、middleware.ts:88、租户隔离 ADR | confirmed_bug、severity:high、confidence:high |
| #3 | 替代代码路径 | false | [] | “看起来没问题,没有疑问” |
朴素的 2/3 多数表决会让该声明存活(2 票未反驳)——从而漏掉一个真实的 多租户漏洞(即 anti-error-lessons §“the case” 中的基准案例)。
证据加权规则:
- 过滤: #3 属于弃权(
workDone:false,reReadSources为空)→ 丢弃并 记录日志。计入判定的结果数k=2。 - 重新计算并记录:
N=3 → 丢弃 1 个 → 按 k=2 进行表决。 - 加权: #2 的反驳具有高置信度,重新阅读了来源,并有
file:line证据。 它的权重高于 #1 的单一存活结果 → 判定 =confirmed_bug,严重性为high。 - 预言机关卡 / 完整性: 交由 work-gaps 处理——“哪个路径没有反驳者检查?”
由此发现存储列表路由;严重性重新锚定为
high(可触达 + 有害 + 未覆盖)。
提示词模板(内部使用)
优先直接验证(始终在适用时尝试): “在进行任何 Agent 投票之前,先判断能否通过确定性方式得出结论。运行显而易见的命令、测试、git 检查、类型检查或搜索。如果能从环境中得到明确的是/否结论,就执行并报告结果,同时提供确切的命令和输出。”
反驳提示词(此技术的核心——包含三个强制条款): “尽可能无情地反驳这一断言:‘[CLAIM]’。
严格规则:
- 你是一名充满敌意的怀疑论者。你的使命是摧毁这一断言,而不是验证它。不要客气;不要给予对方怀疑时的宽容。
- (L2——亲自重新阅读源文件。) 重新打开所引用的每个
文件:行号,并引用你现在看到的真实、当前行内容。绝不要相信断言引用的证据。将重新阅读的内容列入reReadSources。 - (L3——采用你独有的视角。) 仅从 [LENS] 这一视角进行攻击;其他反驳者会覆盖其他视角。
- (L8——只有完成实际工作,反驳才有效。) 只有在重新阅读代码、尝试指定视角并提供
文件:行号证据时,refuted: true才有效。如果没有完成这些工作,则设为workDone: false和refuted: false——空洞的“看起来没问题/没有疑问”属于弃权,不是支持该断言的投票。 - 根据已核实的实际影响(L6)确定
severity(critical|high|medium|low)。 - 回复时以合同规定的
json代码块结束(字段:claimId、lens、verdict、refuted、severity、confidence、workDone、reReadSources、evidence、attack、scenario)。”
[LENS] 槽位会根据自动选取的不同视角(步骤 2)为每位反驳者填入。
循环模式说明(针对幸存者集合持续迭代,直至无新发现)
当攻击角度的数量未知时,将单轮流水线放入 ../work-exhaust/SKILL.md 循环中,每轮使用新的视角重新攻击幸存者:
- 在日志中维护持久的
seen/attacked集合(已尝试过的断言 × 视角组合)。每轮都要与seen去重,而不是与当前幸存者去重(L4)——与幸存者去重会让已被否决的角度重新出现,导致循环永远无法收敛。 - 连续 K 轮安静轮后停止(K≥2);这些轮次中,新的反驳或新攻击角度都必须为 零(持续迭代直至无新发现)。
seen是事实来源,恢复时绝不重置。 - 防止误判为无新发现:某个视角已穷尽,不代表某个断言已穷尽——在已尝试的视角中出现安静轮,并不能证明断言安全;只有安静轮条件与完整性门槛(L5)同时满足才可以。
与现有技能集成
../work-tournament/SKILL.md的同类/演进版本(并行独立尝试 + 选择)——使用相同的编排术语(启动子 Agent、隔离的工作树、在后台运行、等待全部完成、收集结果),但用途是破坏而非创造。../work-check/SKILL.md(跟踪审查 + 直接状态验证 + 严格 PASS/FAIL)——经过强化的 work-check 验证器在适当情况下可用作反驳者。实施后纯粹验证代码变更时,优先使用/work-check;当问题在于变更的含义或影响时,再使用 work-refute。- 投票后的交接交给
../work-gaps/SKILL.md(L5“哪些内容没有任何反驳者攻击?”门槛);对于角度数量未知的集合,则交给../work-exhaust/SKILL.md。 - 为此技能提供一组断言的上游查找器:
../work-sweep/SKILL.md。 - 组合这些功能的完整测试框架位于
../work/references/workflow-mode.md§2。
示例调用
-
审查中的单条高风险发现:
/work-refute "The new AI drawer can cause the form state to get out of sync when the user collapses it during an adjustment" -
从多个视角审视安全敏感的主张:
/work-refute lenses="functional correctness, injection / secrets, authentication bypass, data exposure" "The new endpoint is safe for unauthenticated access because we check the tenant in middleware" -
一次处理多条发现(主 Agent 先提取这些发现):
/work-refute the 6 review findings I just listed about the upload stage machine -
长时间运行 Agent 会话后,在宣布胜利之前:
/work-refute "We have correctly implemented the SLA calculation and the UI now shows the right amber/red states"
此技能应拒绝或降级处理的情况
- 主张是可以通过一条命令/预言机核实的纯事实 → 直接运行预言机 并报告结果(L1;不要在确定性问题上浪费评审组)。
- N=1 → 警告用户:至少需要 2 个计入统计的(非弃权)裁决,投票才有意义;如果弃权导致
k低于 2,请明确说明并重新启动,不要在k<2时作出判断。 - 用户要求“确认”某事 → 改写为反驳模式,或拒绝请求。
这种模式以廉价的信心换取昂贵但诚实的信心。只在重要之处使用;对于琐碎任务,拒绝运行繁重流程,并说明原因(workflow-mode §5)。
运行此技能的 Agent 实现说明
调用此技能时,你必须:
- 首先使用常规工具尝试直接核验,并对未排除的问题采用默认失败关闭的预言机门控 (L1,规则 #1)。
- 将一组主张作为流水线运行——每当某条主张的反驳组得出结果,就单独输出该主张的裁决;不要等整批全部完成。
- 对抗性审查部分,为每位反驳者各启动一个子 Agent(通过一条消息同时启动多个,以实现真正的并行),在后台运行,并使用全新且隔离的上下文;仅当子 Agent 会修改文件时,才使用隔离的工作树。等待所有子 Agent 完成并收集各自的结果。
- 明确要求他们不要查看彼此的推理,并附上三项强制条款(L2 重新阅读、L3 不同视角、L8 完成的工作)。
- 子 Agent 返回后,排除弃权项,重新计算并记录幸存项的阈值, 并应用基于证据权重的存续规则,而不是简单计数(第 5 步)。
- 在宣布胜利之前,执行完整性移交(L5)和严重性校准(L6)。
- 即使攻击未能推翻主张,也要展示攻击内容,列出弃权项及其被排除的原因,并明确说明是哪位反驳者推翻了什么,以及每项幸存主张为何成立(禁止无声截断)。
这是最具杠杆效应的质量保障模式之一。请善加利用。