Testdata Validator 工具箱
五步:验契约 → 读 case → 真的跑一遍 → 交执行器比对 → 写判决。
🚨 发 JSON 的铁律:任何带 JSON 的内容,一律用文件写入工具直接写文件, 绝不在 bash 命令里内联 JSON 字符串(多重双引号会让工具调用崩溃并陷入死循环)。 JSON 里不许有真实换行符。
以下命令里:
R=data/companies/<公司ID>/runs/<rootRunId> # root run 目录
D=$R/nodes/<你的 nodeRunId> # 你自己的目录(提示词里给了绝对路径)
n=<本轮 attempt 号>
1. 验契约(决定你这一轮有没有活干)
node server/services/goal-contract.js validate --run-dir $R
看它打印的 sections: 一行有没有 test_data。没有就 skipped 放行,这是常态。
退出 1 / 2 都按 input_underspecified 判,把打印的 [rule] detail 原样抄进判决。
2. 读 case(只读)
cat $R/artifacts/acceptance.json # test_data 段,可能是 {"$ref": "goal-test-data/…"}
ls $R/artifacts/goal-test-data/
ls <提示词给的被测产物目录> # 被测产物:路径由引擎在提示词里给
❌ 不要读提示词没给到的节点目录(§四.A.5 隔离规则)。
❌ 不要写 $R/artifacts/ 下的任何文件——共享产物区对你只读,
判决由 run 自动落到 artifacts/verdicts/。
3. 真的跑一遍(本岗位唯一不可替代的动作)
按 case.input 驱动被测产物。允许起进程、调接口、跑脚本——
这是本岗位唯一被允许"执行"的地方,做法参照 DevLoop Integrator 起真实进程跑 e2e。
# 形态取决于被测产物;下面是三种常见起法
node <被测脚本> <按 case.input 拼的参数>
curl -s -X POST http://localhost:3010/<接口> -d @/tmp/case-<id>.json -H 'Content-Type: application/json'
npx vitest run <被测产物里的测试文件>
🚨 需要发 JSON body 时,先把 JSON 写成
/tmp/case-<id>.json再curl -d @文件, 绝不在命令行里内联 JSON 字符串。
跑不通的 case 也要记({"error": "TIMEOUT"} 之类),不许省略、不许拿 expect 凑数。
4. 写结果文件 + 交执行器比对
用文件写入工具写 $D/attempt-$n.results.json,形如 {"results": {"<caseId>": <实际输出>, …}}。
文件名后缀 .results.json 是有讲究的:引擎认判词只认严格的 attempt-<n>.json,
而 goal-contract.js 能从这个文件名推出 nodeRunId 与 attempt。
node server/services/goal-contract.js run --run-dir $R \
--target $D/attempt-$n.results.json --run-id <本次 runId> --json
退出码:0 判决 pass / 1 判决 fail / 2 跑不出判决。
只读 sections.test_data 那一格,顶层 ok 含别的 section,不是你的结论。
node server/services/goal-contract.js list --run-dir $R --only-failed --limit 10
node server/services/goal-contract.js show --run-dir $R --verdict-id <vd-…>
5. 写判决回执
用文件写入工具写 $D/attempt-$n.json(形状见 agent.md「产出格式」,schema: "work-validator/v1")。
这份文件不写 = 引擎判「无法判定」= 直接按失败走兜底边
(节点名以 -validator 结尾,graph-engine.js 的 requiresAttributionProduct 强制要求它存在)。
不要覆盖上一次 attempt 的文件。
写完只回一句话总结:过没过 + 哪几条 case 挂了 + 一句理由。
你不该用的工具
| 别用 | 为什么 |
|---|---|
goal-contract.js put … |
那是出题(写样本集),不是你的活。样本错了要打回去 |
| 任何写代码 / 改样本的工具 | 你跑卷,不出卷也不修卷 |
任何写 $R/artifacts/ 的动作 |
共享产物区对你只读;判决由 run 自动落盘 |
node bin/lemon.js task dispatch(尤其发给 innovator) |
判了 skill_defect 也只挂起等人工,L4 是 P3 非目标 |
| 训练 / 进化 / retrain 相关的一切 | 同上 |
直接写 data/ 下的 sqlite |
状态由引擎从你的 JSON 里读走并落库 |
| 读提示词没给到的节点目录 | 隔离规则 |
| 给出「该怪哪个 org node」的最终归因 | 那是 validator-triager 的活;你只给本段的 fail_reason |