测试一直在写你的真实数据根

测试一直在写你的真实数据根

开发记录 · 2026-08-10 · RepoPilot

给权威层补 e2e 的时候,全量跑出 3 条红。重跑一遍,红的换了两条。再跑,全绿。

偶发红最烦人的地方不是它红,是它绿。

起因:三条"接线靠 typecheck"的欠账

README 的「尚未证明的」里攒了三条同型缺口:交叉审核收敛闭环、挽救封存、 failureClass ------ 语义各有单测钉着,但 authority 侧的真实接线没有独立验证, 靠的是类型检查。类型检查能证明函数签名对得上,证明不了"这条线真的通"。

所以写了 authority.e2e.test.ts:驱动整个 RunAuthority,真 ModelGateway、 真协议适配器、真 preflight、真 egress 记账、真命令执行(spawn node)、真落盘。 模型脚本化在 HTTP 层,按 origin 分路:

ts 复制代码
const host = new URL(String(url)).host;      // deepseek = 实现方,moonshot = 审核方
const queue = this.queues.get(host);
if (!queue || queue.length === 0) {
  throw new Error(`${host} 的模型脚本已耗尽。最后请求:${bodyText.slice(-600)}`);
}

脚本耗尽即抛错并带上下文,不复读最后一条 ------ 复读会把死循环伪装成通过。

三条链路:黄金路径(→ SUCCEEDED,账本逐轮对账)、失败路径(自修复用尽 → FAILED

  • failureClass + 挽救补丁,接受被状态门禁拒绝)、整改闭环(阻断 → 整改 → 重验 → 重封存 digest 变化 → 第二轮通过)。

后两条首跑即绿。这本身是个信息:之前那些单测钉住的语义,在真接线里一处都没对不上。

然后偶发红出现了

perl 复制代码
× 端到端:Vite + React + TS 构建失败修复
  → expected 'PREVIEW' to be 'VERIFIED'
× 用户拒绝计划:结果是 PLAN_REJECTED,且工作区与宿主都零改动
  → EINVAL: invalid argument, copyfile '.../T/repopilot-scen-8OSv9R/package.json'
    -> '~/Library/Application Support/RepoPilotPrototype/snapshots/snap_71c850...'
× exact-span replace > 唯一命中时原子提交,并推进 generation
  → ENOENT: no such file or directory, lstat '.../snapshots/snap_cc77b503...'

三条错得毫不相干:一条是 profile 支持度降级,一条 copyfile 参数非法, 一条快照目录不存在。但路径全都指向同一个地方 ------ ~/Library/Application Support/RepoPilotPrototype

测试在往我的真实数据根里读写。

写个循环扫一遍谁没 mock:

bash 复制代码
MOCKED   src/core/patch.test.ts
REAL!!   src/core/mutation.test.ts
REAL!!   src/core/retention.test.ts
REAL!!   src/core/agent.e2e.test.ts
... 11 个文件

11 个测试文件直接用真实数据根。而 retention.test.ts清理器 的测试 ------ 它会真的执行清扫。vitest 并行跑文件,于是:retention 正在删"无引用的快照", mutation 那边刚创建的快照撞上去了。ENOENTEINVAL、profile 降级, 全是同一件事的不同表现。

这债不是这次欠的,是一直都在 ------ 只是文件少的时候撞不上。 「528 全绿的套件偶发红 3-4 条」的谜团,到这里破了。

修:统一注入私有数据根

11 个文件统一挂 vi.mock('./paths'),指向 mkdtemp 出来的进程私有目录。 vi.mock 会被提升到 import 之前,所以模块图里所有拿 PATHS 的地方都换掉了。

验证不能只看"绿了"------绿也可能是这次没撞上。用文件系统本身证明零写入:

bash 复制代码
touch /tmp/marker-before
npx vitest run src/core/mutation.test.ts
find "$HOME/Library/Application Support/RepoPilotPrototype" -newer /tmp/marker-before
# (空)

整轮测试对真实数据根一次写入都没有。这条以前是不变式里写着的 (「自检和测试不能留下持久化改动」),现在才第一次有机器证据。

连续 4 轮全量 531 通过,之前那个组合再没出现过。

反向验证

新加的 e2e 得证明它真在管事。把 VERIFICATION_FAILED 分支的挽救封存接线拆掉:

scss 复制代码
× 验证失败路径:自修复用尽 → FAILED + failureClass + 挽救补丁封存且不可接受
Tests  1 failed | 2 passed (3)

红了,接回去,绿。

可以带走的

  1. 偶发红是基建债的信号,不是运气问题。 三条互不相干的错,路径全指向 同一个目录 ------ 错误信息里最有用的往往不是错误类型,是那个共同的名词。
  2. 共享可变状态的测试没有"暂时没事"。 文件少的时候撞不上,只是采样不够。 retention 那种会主动删东西的测试,一旦跑在共享根上,就是个定时器。
  3. "绿了"不是隔离的证据。 要证明隔离,得证明没有发生什么 ------ find -newer 这种否定式检查比断言返回值更贴近命题本身。
  4. typecheck 证明签名对得上,证明不了线是通的。 那三条 README 里的 "靠 typecheck",补完 e2e 才变成真证据;而它们首跑即绿这件事, 反过来说明单测钉的语义是对的。
相关推荐
烟漠河洛1 小时前
拆解跨平台统一发货架构及亚马逊MCF降本三成技术落地
架构
Mr.huang1 小时前
自注意力机制(Self‑Attention)
人工智能·深度学习
真上帝的左手1 小时前
10. 软件设计&架构-Spring Security 7 整合CAS SSO 单点登录
java·spring·架构·sso
执子念的飞鱼1 小时前
File Viewer 进入 2K 节点后,我更在意这 3 条回归
前端·typescript
richdata1 小时前
动态OTB vs 静态OTB:鞋服零售该选哪种管理模式?
前端·html·零售
Jodie同志1 小时前
第16~23天:持久化、HITL、流式、MCP与安全
前端·后端·agent
Jodie同志1 小时前
第1~15天:原生Agent、RAG与LangGraph基础(完整代码实操)
前端·后端·agent
品牌测评1 小时前
大模型推理算力平台推荐分享|六家平台计费与架构拆解
大数据·人工智能·架构
sunly_1 小时前
React useActionState 的用法详解
前端·javascript·react.js