某测试套件报告稳定但实际存在12%失败率,问题根源是fixture丢弃了stderr输出导致错误被掩盖,揭示了CI绿色报告的盲区。
TL;DR: 绿色报告不是证据,直到你把报告中的命令重新跑在磁盘上的产物上;这一次,两个失败在 16 次运行中暴露了出来。父级 slice 日志记录了这个结果。
你的测试报告写着稳定。套件真的稳定了,还是报告先到了一步?这个问题能让你避免批准一个你根本看不见的缺陷。一套耐久性测试套件报告了稳定,通过了两位独立审查者的批准,然而当有人把它在磁盘上的工作树重新跑一遍时,还是失败了。
没有经受住磁盘检验的批准
你的绿色报告本身无法告诉你的事
在你的流水线中追查这些形态
这个 slice 实际证明了什么——以及它没有证明什么
你的下一次批准需要一份产物
失败率大约是 12%。它不是藏在某种复杂的攻击后面。一个 fixture 丢弃了本可以指出问题的 stderr。
如果你在跑 CI 流水线、审查 Agent 工作成果、或者签署一个发布,这件事也跟你有关。绿色报告是一句声明。文件和命令结果才是那句声明必须回应的东西。
没有经受住磁盘检验的批准
这套测试套件在报告稳定并被批准两次之后仍然不稳定。不稳定性只出现在 supervisor 重新对实际工作树跑了一遍每个 gate,而不是去读创建它的那条 session 时才显现出来。
左侧的报告被批准了两次。右侧的重新跑取的是磁盘上的工作树,三个 tile 在闪烁。

SLICE-011 是一个用于验证五条耐久性声明的一次性原型。它没有交付任何生产物。它的任务是:先让不安全行为红着测出来,再让提议的控制措施绿着证明出来,保留一条出口记录,并让后续的生产工作在没有那份摘要绑定记录的情况下拒绝推进。
第五条声明覆盖了 session 所有权。首先,原型要证明两个进程可以共用一个 session。然后它要证明现有的围栏拒绝了第二个所有者。这个形态是对的:先演示漏洞,再庆祝门上的锁。
报告的结果看起来没问题。所有权检查标记为 5/0,然后在 fixture 修复后 20/20 稳定。但在那次修正之前,重新跑在 16 次完整套件运行中测出了两次失败。
fixture 在 journal_mode 之后设置了 PRAGMA busy_timeout。两个 worker 同时打开时可能在 Effect catch 之外遇到 database is locked。失败信号是存在的。fixture 捕获了 worker 的 stderr 然后丢弃了它。
证据才是问题所在,不是审查者。两位独立的审查者批准了他们看到的东西。磁盘上的产物说的是另一回事。
两次失败都不是靠读报告发现的。
同一个 slice 中还有第二次命中。它的编译 gate 建得对要覆盖的场景来说不正确,因为遵循了一条错误的 supervisor 指令。一位审查者抓住了这个问题,并在磁盘上复现后才做了修复。gate 从 open slice 推导了记录,而它应该从 open 和 completed 两个 slice 位置解析原型记录。
这就是那道疤。本该保持耐久性记录诚实的流程里面藏了一个错误的 gate 和一个不稳定的控制。两者都没有被润色的文字所化解。
你的绿色报告本身无法告诉你的事
一份绿色报告无法确认命令是否被重新跑过、fixture 是否暴露了它的诊断信息、或者 gate 是否测了它自己的拒绝路径。你需要产物、命令,和一次独立的重新运行。
session 摘要对导航有用。它不是证据。SLICE-011 的记录说得很清楚:session 自己的摘要被当作自我报告丢弃了。
在测试涉及时序、并发、进程销毁、重试或共享状态时,这一点最为关键。恰恰就是这些地方,一次干净的运行可以让你相信某个机制在工作,而下一次运行就能证明那个控制从来都不够稳定,不值一提。
事情是这样的:你的负向控制也必须稳定。
SLICE-011 缺少一条写明的负向控制:负向控制本身需要是稳定的。一个不稳定的控制无法告诉你你发现的是竞态还是改了机制。它把每个结果都变成了关于噪声的争论。
不要用对审查的更多信心来替代这个要求。审查能抓住一条错误的指令,像它在这里做到的那样。它没法把一份没有重新跑过的产物变成一次测量。
在你的流水线中追查这些形态
从那些阻挡发布、批准 Agent 变更或认证安全控制的检查开始。你要找的是:流水线可以在不保留产生它的结果的情况下描述成功。
找一个从 worker、Agent 或 session 摘要接受结果的检查。在检出的工作树上重新跑它的精确命令。
找那些捕获了 stdout 或 stderr 的 fixture。制造一次刻意的失败,确认诊断信息能到达评判它的那个人。
找只有一次成功运行的并发或时序测试。反复跑完整套件,把失败记为失败,而不是当作麻烦。
找每一条负向控制。问问它是否稳定到足以区分旧机制和竞态。
找保护记录或工作流的 gate。破坏它被创造出来去拒绝的那条路径,然后验证它确实因为所述原因而拒绝了。
找那些改变了控制查找路径或输入的指令。把那条指令当作一个假设,然后在磁盘上测试行为。
做这些之前不要再加一个仪表盘了。你不需要一个新的报告层来了解一个 fixture 是否吞掉了那一行关键信息。
这个 slice 实际证明了什么——以及它没有证明什么
原型在临时线束工作树中用负向控制和摘要绑定记录证明了它的五条耐久性声明从红到绿。它没有交付生产级耐久性。
这个边界很重要。这条记录的存在是为了给后续耐久性生产 slice 充当 gate。它不是宣称生产中已内置耐久性重试、耐久性阻断器或 session-ID 围栏的依据。README 称那三条剩余的生产声明为未构建,并说明 Ranex 是预发布版本。
修正后的所有权控制达到了 20/20 稳定。那是 fixture 修复后原型的结果,不是你代码库中所有并发检查都健全的证明。我没有那方面的证据。
有用的证明更窄但更强:supervisor 在磁盘上重新跑产物时,套件的自我描述输给了实际测量。当审查者挑战编译后的 gate 时,gate 在磁盘上被复现并修正了。流程得到改进是因为它让声明对产物负责,而不是对生成它们的 session 负责。
这同样是内核的要义:判决来自可执行的检查和证据,而不是来自 worker 的信心。Ranex 仍是预发布,有一条可行的判决路径和大量尚待设计的工作。slice 记录存在于仓库的 docs/slices/done/ 下,包括那些在修复之前失败过的部分。
人们真正会问的问题
这些问题帮助你在接受一个绿色对勾之前检查不稳定的套件。
为什么测试报告不够作为证据?
报告可能不准确地描述了一次运行,或者隐藏了产生它的产物。把 gate 对着磁盘上的工作树重新跑一遍。
这个不稳定的测试套件是如何被发现的?
supervisor 对着磁盘上的工作树重新跑了每个 gate,在 16 次完整套件运行中测出了两次失败。
什么导致了 SLICE-011 的不稳定?
fixture 在 journal_mode 之后设置了 PRAGMA busy_timeout,并且丢弃了包含 database-lock 消息的 worker stderr。
你的下一次批准需要一份产物
在你批准下一个看起来不稳定的检查之前,把报告中的命令拿出来对着磁盘跑一遍。逼迫失败路径。读 stderr。再跑一遍完整套件。然后问问那个证明旧行为的控制是否稳定到足以说明问题。
试试看。把它弄坏。告诉我哪里坏了。如果这帮助你抓住了一个经受不住重新跑的绿色报告,给 Ranex 在 GitHub 上点个星,再送上一份诚实的批评。有用的批评是能发现下一个漏洞的那种。
披露:这篇文章在 AI 辅助下起草。每个事实声明都可追溯到仓库的 README 或 slice 记录——与产品对代码执行的事实 gate 相同。它只在 Anthony 自己的审查后才会发布。