failures.jsonl 非空的运行永远不能成为通过记录。修复之后换 run id 重跑,而不是把缺口填上。
这篇接着《样本年龄、补采与测量有效性》,还是 EdgeSched 的实验链路。上一篇讲一条样本什么时候算数,这篇讲一次运行失败之后能不能补救。
在这套实验链路里,一次运行产生的不是一张汇总表,而是一组固定产物:run_config、manifest、逐轮 JSONL、事件、时间线、summary、CSV,以及 failures.jsonl。判定规则只有一条:failures.jsonl 非空,这个 run 就永远不能成为通过记录。之后无论把缺的轮次补得多齐,都改变不了它的身份。
原因不难推。被修好的测量环境与当初失败的测量环境不是同一个:补齐的轮次跑在新代码上,失败的轮次跑在旧代码上,而曲线里没有任何字段能区分这两者。把它们画在一张图上,得到的是一条从未整体存在过的曲线。
所以修复的代价被显式化:修完必须换新的 run id 重跑整个矩阵。续跑机制 --resume 只接受完全相同的参数、源码 commit、Python 版本、平台与模型 manifest;已有的 (context, config, run) 组合直接跳过,矩阵之外的记录与重复记录一律拒绝。这个设计把补数据与重跑在机制上分开,而不是靠纪律约束。
同类禁令还有一条:不同遥测后端的曲线不许拼接。命令行轮询时代的曲线与 ctypes direct NVML 时代的曲线各成一族,跨后端合并得不到能写进论文的阈值,只能得到一条口径不明的折线。旧口径批次整体退役,2026 年 9 月 17 日三批产物被直接删除,其数值不再作为任何依据。
另一条边界区分了两种门。采样 jitter 的阈值是待测性能目标,不是证据有效性门,因此正式矩阵必须显式使用 observe 模式:超标轮次写入 performance_target_checks 并保留在完整曲线里,不会被隐藏,也不会被改写成通过。有效性门失败是另一回事:控制台直接打印失败的检查名,该轮次计为失败。混淆这两种门的结果,要么是把坏数据藏起来,要么是把系统慢误当成数据不可信。
来源追溯同样按不可变处理。git archive HEAD 只打包已提交内容,不含工作树里 modified 与 untracked 的文件,拿它当 dirty 源码快照会得到错误的 provenance;状态项数量必须实时读取,不能把上一次运行的 0 写死。dirty 运行的产物只用于排障,正式证据必须在干净 commit 上重跑。
最终进入正文的每个数字都要通过同一组晋升条件:真实后端未回退、参数冻结、多次迭代完整、manifest 在场、聚合口径一致、图表可重建、正文引用可追溯。这套流程的成本远高于跑完就信,收益只有一个:每个数字都还指着它出生时的那次运行。