Bug 复现无罪推定:开源 Agent 工具 Verdict 用证据说话
原文:https://dev.to/himanshu_748/bugs-are-innocent-until-reproduced-building-verdict-an-evidence-first-agent-harness-50lf(作者 @himanshu_748)
大多数不稳定 bug 报告的结局只有两种:要么“无法复现”,要么得到一个没人能证明真正修好了问题的补丁。
我围绕一个更严格的理念构建了 Verdict:
Bug 在被复现之前是无辜的。
Verdict 会把一个 GitHub issue 变成一次有边界的调查。它在获准的条件下反复运行获准的命令,保留每一次观测结果,并且除非证据跨过一个确定性的阈值,否则绝不声称完成了复现。
它不是一个自动补丁生成器,而是一个产出证据的 agent harness,服务于打补丁之前那个最困难的步骤。
为什么还要又一个 bug 调查工具?
LLM 读一份堆栈跟踪,很快就能给出一个看似合理的解释。但“看似合理”不等于“复现成功”。
面对一个间歇性故障,真正重要的问题都很具体:
- 到底是哪个条件触发了它?
- 在该条件下它的失败频率是多少?
- 在对照条件下会发生什么?
- 证据支持的是哪个仓库代码区间?
- 什么样的回归测试能防止同一故障卷土重来?
Verdict 把这些问题当作一场实验,而不是一轮对话。
三幕式调查
Verdict 使用三个有边界的子智能体:
GitHub issue
|
v
Hunter: find the trigger
|
v
Surgeon: localize the change
|
v
Insurance: keep it fixed
|
v
Maintainer review
Hunter
Hunter 只在维护者批准的条件矩阵和命令预算内搜索。成功、失败、部分完成和未得出结论的运行全部留在证据账本里。一个不合心意的观测结果,不能仅仅因为它削弱了叙事就凭空消失。
Surgeon
Surgeon 把已复现的条件收窄到记录所能支持的最小嫌疑区间。静态检查与已被证明的执行边界始终保持肉眼可辨的区别。Surgeon 不编写补丁。
Insurance
Insurance 把复现结果转化为一份回归计划:测试名称、fixture、失败的断言以及发布清单。草稿 pull request 只能通过维护者明确批准的工作流来创建。
每一幕被允许下的断言都比前一幕更少。任何一幕都无法说服确定性 reducer 给出更强的判定。
复现结果是一份记录,不是一张截图
Verdict 复现了 TrueForge 的 issue #417——当某个上游请求永远不返回时,快照注册可能无限等待。
锁定的运行时使用 @truefoundry/trueforge-core@0.1.4#DaytonaSandboxProvider,运行了两个条件:
| 条件 | 结果 |
|---|---|
| daytona-stalled-endpoint | 10 次运行全部命中,REPRODUCTION_PINNED |
| daytona-responsive-endpoint | 10 次中 0 次命中,NOT_REPRODUCED |
对照组才是关键的另一半。一个每次都失败的条件,旁边配上一个从不失败的条件,其证据强度胜过二十次毫无对照的失败。
任何人都可以重新计算这份记录:
pnpm --filter @verdict/agent verify:runtime-evidence
验证器返回:
{
"verdict": "REPRODUCED",
"stalledRuns": 10,
"responsiveControls": 10,
"provider": "@truefoundry/trueforge-core@0.1.4#DaytonaSandboxProvider",
"canonicalSha256": "a8bb5dd22e083782bd7782fccb0a1343b59fc77ea8525b6358fecc9b5b8baffa"
}
这份证据把各项观测绑定到 TrueForge 会话、Hunter 线程、仓库 commit、npm 溯源 commit 以及共享的源码 blob 上。
探索与证明是两套系统
模型负责收集候选观测,但不决定这些观测证明了什么。
Verdict 的证据契约很简单:
- Issue 文本和仓库内容一开始都视为不可信输入。
- 调查只能使用获准的命令、配置项和预算。
- 每一条被接受的观测都必须符合证据 schema。
- 由纯 reducer 决定记录支持哪种断言。
- 证据缺失或冲突时,产出一个诚实的部分结果。
- 维护者掌握唯一的公开写入权限。
同样的记录永远产出同样的判定。这就是“一个 agent 在探索问题”和“一个系统在下断言”之间的边界。
哪些是真实运行,哪些是演示夹具
这个记录案例渲染的是实际执行过的产物,包含两个条件、全部二十次运行以及可重新计算的哈希。
交互式工作区则是一个概念演示夹具。每一个生成的值都带有标注,不会被悄悄包装成真实的运行时证据。
对于一个核心主张就是“断言需要记录”的产品来说,这个区分至关重要。
批准权始终属于维护者
Verdict 还在真实的 GitHub 上演练了它的发布边界。在获得明确批准后,一个绑定 nonce 的工作流运行起来,验证了外部复现引用,并在 Verdict 自己的仓库里创建了一个草稿 pull request。上游的 TrueForge 仓库始终保持只读。
工作流证明里写着 runtimeReproducedByThisWorkflow: false。这是有意为之。provider 运行复现了 bug;GitHub Actions 验证了 harness 并发布了可独立核查的证明。若把这两件事合并成一个含糊的“已验证”标志,这条边界就消失了。
Qodo 审查的不只是代码,还有声明
每一次实质性改动在合并前都要先提交 pull request,由 Qodo 审查。
最有价值的发现并不是什么戏剧性的崩溃,而是实现与项目声明之间的不一致:
- 一张落地页卡片仍把真实的复现过程描述为模拟。
- CI 直接信任了记录中的判定结果,而不是重新计算它的哈希。
- README 文案声称每次 push 都会运行覆盖率检查,而工作流实际只覆盖
main分支和 pull request。 - 一次代码清理之后,一个格式错误的 CSS 选择器静默失效了。
这些审查结论恰好契合产品哲学:不要发布超出证据支撑力度的声明。
当前的验证流程
这个仓库在本地和 CI 中运行同一套门禁:
pnpm lint pnpm typecheck pnpm test pnpm build pnpm --filter @verdict/agent verify:runtime-evidence
目前的测试套件共包含 220 个测试,覆盖 agent、protocol 和 web 三个包。
试用 Verdict
Verdict 采用 MIT 许可证开源,是为 WeMakeDevs x TrueFoundry Agent Harness 黑客松而构建的。
它的目标不是让智能体听起来确定无疑,而是让确定性变得可检验。
原文:https://dev.to/himanshu_748/bugs-are-innocent-until-reproduced-building-verdict-an-evidence-first-agent-harness-50lf(作者 @himanshu_748)