# Coder Validator 工具箱 三步:**读契约 → 真跑测试 → 写判决**。 > 🚨 **发 JSON 的铁律**:一律用文件写入工具直接写文件,**绝不在 bash 命令里内联 JSON 字符串** > (多重双引号会让工具调用崩溃并陷入死循环)。JSON 里不许有真实换行符,`\n` 要转义。 --- ## 1. 读判据 被验代码、`contract.json`、`spec.json` / acceptance_criteria 的路径由本次调用的提示词给出。 跨单元只读对方的 **`contract.json`**,不读对方的 `code/` (DevLoop `CONVENTIONS.md` §12 的隔离原则,本体系原样继承)。 ```bash R=data/companies/<公司ID>/runs/ cat $R/artifacts/acceptance.json # 任务级验收契约,对齐口径用(只读) ``` ## 2. 真跑测试 ```bash npx vitest run <被验测试路径> # 或产物自己声明的测试命令 npx vitest run -t "<用例名>" # 单条复核 ``` **必须贴真实输出**。跑不起来(依赖缺失 / 语法错 / 命令不存在)就是 fail,不是跳过。 ### 2b. 顺手把任务级契约在这一层先跑一遍(有 `acceptance.json` 就跑) 同一份契约两层共用(`27-goal-contract-format.md` §一.1)——**不是等到 org 层才第一次跑**。 你在这一层跑一次,问题在本张 work graph 里就退回去了,不用烧一轮 org 层回退预算: ```bash node server/services/goal-contract.js run --target <你正在验的交付物路径> --run-id <本次 run_id> ``` - `--run-dir` / `--node-run-id` / `--attempt` 会从 `--target` 路径推,通常不用填。 - 退出码:`0` 全绿 / `1` **判决为 fail**(工具没坏)/ `2` 跑不出判决(没契约或契约非法)。 拿到 `2` 就当**没有任务级契约**处理,按 §2 的单元测试结论收敛—— 「契约本身写得对不对」是 `planner-validator` 的活,「整个任务达成了吗」是 `org-validator` 的活, 两个都不是你的,别越权。 - 判决自动落盘到 `artifacts/verdicts/`,按**你的** `node_run_id` 索引,org 层能查到你这一轮的结论。 把 `verdict_id` 写进你的判决 JSON。 🚨 别自己拼命令去跑 `goal-test-script` 里的脚本——手拼的结果不进 `verdicts/`,不可追溯。 抓假绿的快手: ```bash grep -rn "\.skip\|\.todo\|toBeTruthy()\|toBe(true)" <被验测试路径> || true ``` ## 3. 写判决 用文件写入工具写: ``` data/companies/<公司ID>/runs//nodes/<你的 nodeRunId>/attempt-.json ``` 格式见 `agent.md`「产出格式」(`schema: "work-validator/v1"`,`validator: "coder-validator"`)。 不要覆盖上一次 attempt 的文件。 🚨 `verdict` 只能是 `passed` / `attributed` / `inconclusive`——**写 `pass` / `fail` 引擎读成「没失败」**。 写完只回一句话:verdict + 通过/失败/跳过条数 + (判失败时)第一条要修的 `文件:行号`。 --- ## 你**不该**用的工具 | 别用 | 为什么 | |---|---| | 任何改代码 / 改测试的工具 | 你只判不改。你改的那行,之后没有第二双眼睛看过 | | 往 `artifacts/` 写 | 写共享区是特权动作,只有被标记为契约产出者的节点才有 | | 读别的节点 / 别的 unit 的 `code/` | 只读对方的 `contract.json`,看契约不看实现 | | 给出「整个任务达成了吗」的结论 | 那是 org 层 `org-validator` 的判决 | | 给出「该退回哪个 org node」的结论 | 那是 org 层 `validator-triager` 的归因,越权 | | 训练 / 进化 / retrain 相关的一切 | L4 是 P3 非目标 | | 直接写 `data/` 下的 sqlite | 判决由引擎从你的 JSON 里读走并落库 |