# Benchmark Validator 工具箱 四步:**验契约 → 逐维度找证据给分 → 交执行器算 → 写判决**。 > 🚨 **发 JSON 的铁律**:任何带 JSON 的内容,一律用**文件写入工具**直接写文件, > **绝不在 bash 命令里内联 JSON 字符串**(多重双引号会让工具调用崩溃并陷入死循环)。 > JSON 里不许有真实换行符,`remediation_note` 的换行写成 `\n`。 以下命令里: ```bash R=data/companies/<公司ID>/runs/ # root run 目录 D=$R/nodes/<你的 nodeRunId> # 你自己的目录(提示词里给了绝对路径) n=<本轮 attempt 号> ``` --- ## 1. 验契约(决定你这一轮有没有活干) ```bash node server/services/goal-contract.js validate --run-dir $R ``` 看它打印的 `sections:` 一行有没有 `benchmark`。退出码:`0` 合法 / `1` 契约非法 / `2` 没契约或参数错。 `1` 和 `2` 都按 `input_underspecified` 判,把打印的 `[rule] detail` 原样抄进判决。 ## 2. 读标准与被测产物(**只读**) ```bash cat $R/artifacts/goal-benchmark.json # 维度 / 权重 / 及格线 / rubric / evidence_hint ls $R/artifacts/ # 别的段写了没有 cat $R/artifacts/acceptance.json # 三段合成的契约入口 # 被测产物:路径由引擎在提示词里给(上游节点的 output_ref),按 evidence_hint 去里面找证据 ls <提示词给的被测产物目录> ``` ❌ **不要读提示词没给到的节点目录**(§四.A.5 隔离规则)。 ❌ **不要写 `$R/artifacts/` 下的任何文件**——共享产物区对你只读, 判决由 `run` 自动落到 `artifacts/verdicts/`,不用你动手。 ## 3. 写分数文件 + 交执行器 用文件写入工具写 `$D/attempt-$n.scores.json`,形如 `{"scores": {"<维度名>": 87, …}}`。 文件名后缀 `.scores.json` 是有讲究的:引擎认判词只认严格的 `attempt-.json`, 而 `goal-contract.js` 能从这个文件名推出 `nodeRunId` 与 `attempt`,两边都不出错。 ```bash node server/services/goal-contract.js run --run-dir $R \ --target $D/attempt-$n.scores.json --run-id <本次 runId> --json ``` 退出码:`0` 判决 pass / `1` 判决 fail / `2` 跑不出判决。 **只读 `sections.benchmark` 那一格**,顶层 `ok` 含别的 section,不是你的结论。 查历史判决(判断"是不是同一个问题反复出现"时用得上): ```bash 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 ``` ## 4. 写判决回执 用文件写入工具写 `$D/attempt-$n.json`(形状见 `agent.md`「产出格式」,`schema: "work-validator/v1"`)。 **这份文件不写 = 引擎判「无法判定」= 直接按失败走兜底边** (你的节点名以 `-validator` 结尾,`graph-engine.js` 的 `requiresAttributionProduct` 强制要求它存在)。 **不要覆盖上一次 attempt 的文件**——判决过程要可审计。 写完只回一句话总结:过没过 + 哪一维拖后腿 + 一句理由。不要把整份 JSON 复述一遍。 --- ## 你**不该**用的工具 | 别用 | 为什么 | |---|---| | `goal-contract.js put …` | 那是**出题**,是 `goal-benchmark` 的活。改标准要打回去,不是顺手改 | | 任何写代码 / 改文档的工具 | 你判卷,不修卷 | | 任何写 `$R/artifacts/` 的动作 | 共享产物区对你只读;判决由 `run` 自动落盘 | | `node bin/lemon.js task dispatch`(尤其发给 `innovator`) | 判了 `skill_defect` 也只挂起等人工,L4 是 P3 非目标 | | 训练 / 进化 / retrain 相关的一切 | 同上 | | 直接写 `data/` 下的 sqlite | `fail_reason` / `remediation_note` 由引擎从你的 JSON 里读走并落库 | | 读提示词没给到的节点目录 | 隔离规则 | | 给出「该怪哪个 org node」的最终归因 | 那是 `validator-triager` 的活;你只给本段的 `fail_reason` |