34-validator-scored-without-real-deliverable. coder-validator 在没有真实产物的情况下给了满分
日期: 2026-08-22 状态: 📝 调研记录,非设计方案,§四 checklist 已全部查完。§一/§二的核心 前提已被 §零 推翻大半——原始判断("index.html 从未被写出来")是错的,真实网站 文件其实存在,只是不在
graph_files索引里。§五追加查完三件事,且 §5.1 中途 自我订正过一次:① 最初以为"validator 没有浏览器工具、物理上做不到检查"—— 这个判断错了,bash能走到真实 Playwright(仓库自带该依赖),另一条对照 任务证明了这条路能走通;真正的差异是有没有 agent 主动想到要这么做, 这次没有;② 确实有一份真实静态断言脚本代替了 5/6 维度的检查,不是空手套白狼; ③ 抽查另外两个已存在的项目根后发现验证严谨度完全不稳定——同类任务里有的 做了真实 Playwright 级验证、有的只做了静态正则、有的没验证就被取消,"任务已 完成"背后的验收严谨程度全靠单次任务规划时 agent 会话即兴发挥与提示词是否填充 完整,没有系统性保证。顺带在unit-tester本体身上撞见一次 32 号文档 那类"招聘装配没填充完"的真实 样本——这很可能才是这次检查偏弱的直接原因,而不是工具限制。是否需要引擎级 前置闸门统一验证严谨度,留给下次设计。 触发:e2e-demo公司真实回归任务T-mt2r6fz0-125b(goalG-mt2r62ia-73af, root runrun_0e9074815130)——31 号文档 兜底边修复 + 33 号文档 契约修复之后,把这条任务 真正推到completed,回头查"最终产出在哪"时发现的
零、2026-08-22 补充:原始判断错了一半——真实网站文件其实存在
写这份文档时只查了两处:org-coder-impl/org-coder-test 各自的节点私有目录
(runs/{rootRunId}/nodes/{nodeRunId}/)和 graph_files 索引表,两处都没有
HTML/CSS/JS,于是断言"首页从未被写出来"。
后来在同一次会话里给控制台加"任务产物汇总"面板(用户反馈的另一个需求)时,
读 graph-engine.js 的 W2 段落才发现:这个引擎给每个任务的代码分配了一个跨节点
共享的项目根(ensureProjectRoot,复用 DevLoop 的 path-resolver.allocateProjectRoot,
落在 data/companies/{cid}/projects/{pid}/),这个目录不受 graph_files/
indexNodeOutputs 覆盖——后者只扫每个节点自己的私有产出目录。真去看
data/companies/e2e-demo/projects/p-v82tpc/ 才发现:
index.html 2.2KB 真实的 apple.com 风格单页站点(hero + 3 个卖点区块 + 平滑滚动导航)
script.js 1.0KB
styles.css 3.3KB
tests/unit-tester.check.js
workgraph-plan-T-mt2r6fz0-125b.md
内容核对过:3 个卖点区块的标题与顺序(多智能体协作 → 全链路自动化 → Skill 竞技场)
与 org-coder-impl 自己 _plan.md 里写的验收对照表逐字对应,不是空壳/占位文件。
这次查漏的教训:graph_files 索引 + 节点私有目录,只是这个系统里两个产出
落点中的一个;第三个(项目根)当时完全没查。下面 §一/§二 保留原文作历史记录,
但"index.html 从未被写出来"这句话是错的,请按本节订正读。
一、(原始记录,前提有误,见 §零)
一、现象
任务最终状态:completed,org-planner / org-coder / org-validator 三个 org 节点
全部 success。但查 org-coder-impl(rn_e71be3641174)的实际产出目录
(data/companies/e2e-demo/runs/run_0e9074815130/nodes/rn_e71be3641174/),
只有这些文件:
_plan.md agent 自己的规划笔记
_research.md agent 自己的调研笔记
coder.log agent 自己的执行日志
contract.json 跨节点契约快照
没有任何 HTML/CSS/JS 文件——任务原文要求的"apple.com 风格官网首页"从未被写出来过。
org-coder-test(rn_cd3e3a1c51e2)同样只有 _plan.md/_research.md,没有测试对象。
org-coder-validator 的评分(attempt-1.scores.json)
{
"hero_first_impression": 100,
"pitch_sections_completeness": 100,
"smooth_nav_no_anchor_jump": 100,
"responsive_layout": 100,
"resource_integrity": 100,
"pipeline_auto_recovery": 100
}
六维度全部满分,overall_pass_threshold=82,加权后自然通过。
二、这份评分明显没有真的检查过产物
goal-benchmark.json(本次任务的验收契约)给每个维度都写了 evidence_hint,
其中 5 个维度明确要求打开真实页面检查:
| 维度 | evidence_hint 原话(节选) |
|---|---|
hero_first_impression |
「打开 index.html,桌面宽度截图首屏;量 h1 与 tagline 的计算字号比值」 |
pitch_sections_completeness |
「滚动到底数区块数量与顺序;逐个检查 h2+p+visual 三要素是否齐全」 |
smooth_nav_no_anchor_jump |
「开发者工具 Elements 检查导航元素;点击时观察地址栏与 Network/Console 有无 hashchange」 |
responsive_layout |
「浏览器依次设置视口宽度 375/768/1440px 检查横向滚动条与重叠」 |
resource_integrity |
「打开浏览器开发者工具 Console + Network 面板刷新页面检查」 |
这五项全都以"打开浏览器 / 打开 index.html"为前提——当时以为 index.html
从没被写出来过,所以断言 validator 不可能真的执行了这些检查步骤。这个前提错了
(见 §零):index.html/styles.css/script.js 其实都在 projects/p-v82tpc/
下真实存在,内容也对得上任务要求。
订正后的结论:不能再说这是"没有产物却给了满分"——产物是有的。真正没验证过的
是更窄的一个问题:org-coder-validator 是否真的照 evidence_hint 打开了这个
页面、量了字号比例、切了三档视口、开了 Console/Network 面板检查,还是即使产物
存在,它也只是读了读源码/自己的 _plan.md 就直接给了 100 分,没有真的做那些
evidence_hint 点名要求的浏览器级验证动作。这个问题现在的证据不足以下结论——
六个维度全 100 分本身既可能是"真查过、页面确实做得不错",也可能是"没查、乐观估计",
两种情况从现有的 attempt-*.json/remediationNote 文本里区分不出来。
三、影响面(订正后,仍未核实,留给下次)
- 这不是 31/33 号文档改动引入的新问题——两次修复只是让流程不再卡死,
让这条原本会一直 blocked 的任务真的走到了
completed,才有机会去看"最终产出 在哪、验收是怎么做的"这件事。 - 真正独立于本文档、且已经确认修复的一个衍生问题:
graph_files/taskFiles索引不覆盖项目根,这意味着控制台原本设想的"任务级产物汇总"面板如果只读graph_files,会永远看不到真实交付物(这正是 §零 发现问题的路径)。这一半 已经在同一次改动里修了:graph-engine.readProjectRootRecord现在随GET /api/graph-runs/:id一起吐出来,控制台的「产物」按钮会分别列"最终交付物 · 项目根"和"节点产出索引"两节,见web/src/components/graph-console/TaskFilesPanel.vue。 - 仍然悬而未决的是 validator 有没有真的做过视觉/交互检查这件事本身——这需要
证据链(比如强制要求 validator 在
attempt-*.json里回填它量出的具体数字: h1:tagline 字号比、三档视口下的滚动条状态等),而不是只回一个分数。
四、留待下次调查的问题(不在本次范围内动手)
- [x]
coder-validator是否有可用的浏览器工具(截图、DOM 检查)去真的执行evidence_hint里描述的那些检查?没有——见 §五.1,config.json的toolPolicy.allowedTools只有bash/read_file/str_replace,物理上做不到 "打开浏览器"。 - [x]
coder-validator本体的提示词里,评分前有没有一步强制要求"回填 evidence_hint 点名要量的具体数字"?有替代方案,但不是这个形态——见 §五.2, 实际靠的是一份零依赖的静态断言脚本(unit-tester.check.js),不是"回填数字", 是"跑一个真脚本、贴真实输出",与coder-validator/agent.mdStep 2 的既有要求 ("没跑过的测试等于不存在")同一个纪律,只是换了检查对象。 - [x] 抽查其他任务(
p-bkhylu/p-v1mpcl这两个已存在的项目根)的 validator 评分记录,看这次"用静态脚本代替浏览器检查"是这条任务的一次性即兴发挥, 还是已经是这类骨架的稳定行为——是一次性即兴发挥,三条任务三种做法, 完全不稳定。见 §五.3。 - [ ] 是否需要给"必须打开真实产物检查"的维度加一道引擎级的前置闸门:至少确保
被检查的文件(如
index.html)在evidence_hint点名的路径下真实存在 (现在项目根已经可查,这道闸门补起来比 §零 之前容易)。§五.2 的静态脚本已经 部分覆盖了这个诉求(1-5 维),但它是 agent 自己想出来写的,不是引擎强制的—— 换一次任务、换一个 agent 会话,不保证还会有人主动写这份脚本。
五、2026-08-22 追加调查:coder-validator 到底有没有真的检查
5.1 工具权限:这条判断错了,见 §5.3 订正——没有"浏览器工具",但 bash 能到达真浏览器
org-coder-validator 这次跑的本体是 coder-validator(预置的 active 本体,非本次
新招聘)。它的 agent.md(10KB,读了全文)通篇讲的是代码/契约正确性验证——
npx vitest run、抓"假绿"五件套(空断言/.skip/只测 happy path/mock 掉被测对象/
覆盖率灌水)、逐条核对 acceptance_criteria、fail_reason 只在
impl_bug/input_underspecified/infra_flake/null 四个取值里选——整份提示词
没有一个字提到截图、视口、Console/Network 面板、字号比例这类视觉/交互检查。
它的输出格式(verdict/test_run/checks/fail_reason/remediation_note)也完全
不是 attempt-1.scores.json 那种六维度打分形态(那份分数文件的形态更接近
goal-benchmark.json 的 rubric 结构,猜测是 goal-contract.js run 那条工具链算出来
落盘的,不是 coder-validator 手写)。
而这次任务给 org-coder 这条支线新招的两个本体(coder、unit-tester)的
config.json 都是同一句:
"cli": { "toolPolicy": { "mode": "restricted", "allowedTools": ["bash", "read_file", "str_replace"] } }
没有专门的"浏览器/截图/DOM 检查"工具。goal-benchmark.json 的 evidence_hint
要求"打开 index.html"、"开发者工具 Console + Network 面板"、"依次设置视口宽度"——
乍看在这三个工具的权限范围内一件都做不到。但这个判断本身是错的,见 §5.3:
bash 本身没有限制"能不能启动子进程",仓库自带 playwright(package.json 里
"playwright": "^1.58.1",node_modules/playwright 真实存在),任何持有 bash
的 agent 理论上都能写一个 node verify.mjs(require('playwright') 沿目录树向上
能找到仓库根的 node_modules)去跑真实 headless Chromium——这次任务的 agent
没有这么做,不是因为工具权限拦住了它,是因为它不知道该这么做(见 §5.3 的
unit-tester 提示词空白问题)。
5.2 但也不是纯粹的空手套:真有一份可运行的静态断言脚本
data/companies/e2e-demo/projects/p-v82tpc/tests/unit-tester.check.js——零依赖
Node 脚本,读 index.html/styles.css/script.js 三个真实文件做静态解析,
不是猜的,逐条对上 goal-benchmark.json 维度 1-5:
- hero_first_impression:真解析 CSS 里
.hero-title/.hero-tagline的clamp()表达式,换算出真实的字号比例数字去比 ≥3:1(不是"看起来大概行"); 另外查.hero-visual的width声明是否 ≥90vw。 - pitch_sections_completeness:正则抓三个
<section class="pitch...">, 核对数量、顺序、标题原文("多智能体协作→全链路自动化→Skill 竞技场") 与每个区块是否同时有<h2>+<p>+.pitch-visual三要素。 - smooth_nav_no_anchor_jump:断言全文没有
<a href="#...">,script.js 里没有location.hash =赋值、且确实调用了scrollIntoView({behavior:'smooth'})—— 这组断言的判据与"点击导航不出现 # 片段、且平滑滚动"逐句对应,只是用静态代码 特征代替了真的在浏览器里点一下、看地址栏。responsive_layout:只断言 CSS 里存在1024px/480px两个媒体查询断点, 没有验证断点内的样式是否真的消除了横向滚动/重叠——这条断言比前三条弱, 是"有没有做响应式的动作"而不是"响应式做得对不对"。resource_integrity:断言三个文件里没有外部 URL 引用、有<link rel="icon">声明——覆盖的是"会不会因为外链或缺 favicon 产生 404"这一类,没有校验本地 引用的资源文件是否真实存在(比如声明了本地图片但文件不存在,这条断言抓不住)。
结论:六维度里 5 项确实有真实、可复现的检查支撑,只是形态是"静态断言脚本
- 真跑输出",不是 rubric 字面写的"打开浏览器"——两者在这次任务的具体验收点上
基本等价(尤其是前 3 项,静态解析拿到的是比"人肉截图目测"更精确的数字),
但
responsive_layout/resource_integrity两项的静态版本明显弱于浏览器版本, 真有边界情况(断点内样式写错、本地资源路径错误)会被这份脚本放过。
这份脚本是谁写的、写它是不是稳定行为,没有查:unit-tester 这个本体
(写测试的那个角色)的 agent.md 是没填充过的 _base 原始骨架(开头带
<!-- LEMONBOSS_BASE_SKELETON --> 标记,见招聘装配可靠性那条——
32 号文档),完全没有任何关于"该怎么测试
这类视觉需求"的角色指导;隔壁 coder(实现角色)的 agent.md 却正常填充过。
两个本体在同一次任务里、几乎同一分钟(17:54)被雇进来,一个填了一个没填——
是 32 号文档 那次异步装配可靠性问题的又一个
真实样本(发生在 17:54,32 号文档的修复提交 6a18379 在同一天 18:49 才落地,
所以这次踩到的是修复前的旧行为,不代表新机制仍有这个缺口,但没有再跑一次
验证新机制)。也就是说,这份相当机灵的静态断言脚本,很可能是 unit-tester
在没有任何角色指导的情况下、纯靠通用 four-phase 骨架的常识自己想出来的——
换一次任务、换一次会话,不保证还会有 agent 主动想到用这种方式弥补工具缺口。
5.3 抽查另外两个已存在的项目根:三条任务三种做法,验证方式完全不稳定
e2e-demo 公司目前一共有三个项目根,正好覆盖三种局面:
| 项目根 | 任务 | 状态 | 验证方式 |
|---|---|---|---|
p-v82tpc |
T-mt2r6fz0-125b(本文档,今天的回归任务) |
completed | tests/unit-tester.check.js:静态正则解析 HTML/CSS/JS 文本,零浏览器 |
p-bkhylu |
T-msyu6u9b-939c("做一个 lemonai 的官网") |
completed | 真实 Playwright + headless Chromium:六档视口量 scrollWidth/clientWidth、getComputedStyle 量字号、手算 WCAG 对比度、禁 JS/reduce-motion 验证、把项目整体挪到 /tmp 用 file:// 重新打开验证可移植性 |
p-v1mpcl |
T-mt1qx0c4-95bf("apple.com 风格官网",31 号文档卡住的那条原始任务) |
cancelled | 无——只有 index.html/script.js/style.css,没有 tests/、没有 DELIVERY.md,任务在验收之前就被取消了,这批文件是留在项目根里的半成品 |
p-bkhylu 的证据链明显更扎实:它的 DELIVERY.md(读了全文)逐维度贴了真实
测量数字(六档视口零溢出的表格、四组元素真实对比度数值、.section__title 真实
计算字号 48px),content_fidelity 维度因为"无法访问 lemonai.ai、内容全是占位"
这个真实限制,老实评了 80 分而不是 100(run_9168bd24f46c 的
attempt-0.scores.json 可查)——这正是"真查过"该有的样子:有一项做不到就如实
反映在分数里,不是全 100。DELIVERY.md 末尾还有一句"本轮…未运行或采信项目根内
不存在的 checks/check.mjs(本项目未创建该自证脚本),符合 SDD §0/§2 I-4 关于
验收独立性的要求"——这条"不许自己写脚本自己判"的规则是那次任务的 SDD 自己写的
(SDD §0/§2 I-4 搜遍 system//docs/ 都没有这个条目),不是仓库级别的通用约束,
换句话说:要不要认真验证、认不认可自证脚本,取决于那次任务恰好由哪个 sdd-planning
会话规划、恰好写没写这条规矩,不是系统保证的。
关键订正:p-bkhylu 那条任务的 org-coder-impl 用的是本体 org-coder
(system/agents/org-coder/config.json),工具权限是
{bash, read_file, str_replace, write_file}——跟今天新招的 coder/unit-tester
几乎一样(多一个 write_file),同样没有专门的"浏览器工具"。它能跑出真实
Playwright 测试,靠的是 bash 里 node verify.mjs,require('playwright')
沿目录树向上找到仓库根的 node_modules/playwright——这条路今天的 coder/
unit-tester 同样走得通,只是没人这么做。所以 §5.1 说"没有浏览器工具、物理上
做不到"是错的,纠正为:两条任务的 agent 拿到的工具权限本质相同,差的是
有没有人(提示词/前序 agent)教它"该用 Playwright 写一份真实测试"这件事——
org-coder/coder-validator 的 agent.md 都是正常填充过的成熟本体,unit-tester
是空白骨架(见下一段)。这把根因从"平台缺工具"改判为"这次没人教它、也没有指导它
主动想到",是一个不一样、也更能采取行动的结论。
结论(回答 §四那条 checklist):p-v82tpc 这次"用静态脚本代替浏览器检查"
不是稳定模式,是这一条任务的即兴发挥——同一个公司、同类任务,p-bkhylu
做到了真实浏览器级验证,p-v82tpc 只做到了正则解析文本,p-v1mpcl 干脆没做到
验证就被取消。三条任务的"完成"背后,验证严谨程度天差地别,而这个差异在任务列表
/ 控制台上完全看不出来——三个都显示"已完成/已取消",不会告诉你其中一个的验收
证据比另一个扎实十倍。这本身就是 §三"影响面"那条判断的实锤:"任务显示已完成"
与"真的做到了原始需求"之间的落差,在这个系统里目前完全依赖单次任务规划时
agent 会话的即兴发挥,没有系统性保证。