Commit 033865be0e7689e1f1087810fee811d630b41fc9
1 parent
a991468d
Real verification: narrative-output risk not reproduced in Coder self-planning
Spot-check (real API spend, user-authorized) of whether the historical "narrative text standing in for real output" failure mode (docs/todo/validator-test-script-narrative-output-issue.md) recurs now that Coder self-plans its implementation graph (Org Graph unification Phase 2). Built a non-self-target temp repo with a real rate-limiter module containing a planted bug, and a goal requiring Coder to read it and produce an audit report -- the same "explore then produce content" trigger condition the original incident's root-cause analysis identified. Ran the real production path (plan_work_graph + run_graph) with RUN_REAL_AGENT_E2E=1. Result: not reproduced. The self-planned node's content was a real, line-cited audit report (correctly found the planted bug plus four other genuine issues), not narration standing in for missing work -- despite the Coder catalog's "impl" entry having no suggested_judgment, the planning LLM voluntarily attached its own narrative-detection judgment, closely mirroring work-graph-node-review's methodology. Recorded as a new timeline entry with an explicit single-run-confidence caveat and a concrete next step (_NODE_REVIEW_JUDGE_PROMPT wired directly into the catalog) if a real recurrence shows up later. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Showing
1 changed file
with
4 additions
and
3 deletions
docs/todo/validator-test-script-narrative-output-issue.md
| 1 | 1 | # test_script 节点偶发输出叙述文字而非代码——问题记录(Planner + Validator 都会中招) |
| 2 | 2 | |
| 3 | -**日期**: 2026-08-07(最后更新 2026-08-12) | |
| 3 | +**日期**: 2026-08-07(最后更新 2026-08-13) | |
| 4 | 4 | **性质**: 问题记录——源于真实生产复现,根因已定位(§6),已落地两轮缓解(§7/§8),结构性修复推迟到另一份文档(见时间线第 6 轮)。 |
| 5 | -**状态**: 根因已定位。当前生产状态:test_script/validator_test_script 节点已禁用(§8),`_NARRATION_RETRY_HINT` 缓解代码保留但当前不会触发(§7)。**结构性修复不在本文档范围**——已并入 `docs/todo/org-graph-unification-and-universal-self-planning-requirements.md` Phase 2(FR-2/FR-3,Coder 接入自规划时一并处理,该文档非目标 §5.2 记录了这条已知复发风险)。 | |
| 5 | +**状态**: 根因已定位。当前生产状态:test_script/validator_test_script 节点已禁用(§8),`_NARRATION_RETRY_HINT` 缓解代码保留但当前不会触发(§7)。**结构性修复不在本文档范围**——已并入 `docs/done/org-graph-unification-and-universal-self-planning-requirements.md` Phase 2(FR-2/FR-3,Coder 接入自规划时一并处理,该文档非目标 §5.2 记录了这条已知复发风险)。**2026-08 Coder 自规划场景专项复核:未复现**(时间线第 8 轮)——真实非 self-target 任务,Coder 自规划出的"先探索、再产出审计报告"内容型节点,产出是真实、具体、逐行引用证据的审计发现,不是空洞叙述;细节见第 8 轮。 | |
| 6 | 6 | |
| 7 | 7 | **更新时间线**(压缩自原先六轮分散更新,2026-08-08): |
| 8 | 8 | |
| ... | ... | @@ -15,8 +15,9 @@ |
| 15 | 15 | | 5 | 08-08 | **真实复现,推翻第 3 轮判断**:任务 `2084590a` 的 `benchmark` 节点(不是 test_script)连续 4 次输出叙述文字(详见 §1 末尾),LLM judge 第 3 次已精确诊断出问题但未能强制拦住,第 4 次原样复现,`loop_back` 耗尽后 `blocked_pending_human`。触发条件改判为"这次任务需不需要模型先探索真实代码",不是"节点类型是不是 test_script"——benchmark 也没有类似 `check_script_compiles` 的机械拦截网,只能靠 LLM judge 自己识别,识别到不等于能强制拦住。 | |
| 16 | 16 | | 6 | 08-08 | 结构性修复的落脚点确定为 `org-graph-unification-and-universal-self-planning-requirements.md` Phase 2——该文档非目标 §5.2 已记录这条已知风险,要求 Phase 2 落地时专门验证是否复现。 | |
| 17 | 17 | | 7 | 08-12 | **Phase 1 真实端到端验证期间三次独立复现,进一步坐实第 5 轮的判断**:验证 `org-graph-unification-phase1-review-gate-design.md` 落地效果时,`run_end_to_end()` 走完整 Planner 自规划链路,连续 3 次真实运行、3 个不同 goal,全部撞上同一类失败——(a) "add(a,b) 求和" goal:`benchmark_add` 节点 `loop_back` 耗尽 `max_attempts=2`;(b) "shout(s) 转大写" goal:`test_script_shout` 节点同样耗尽 `max_attempts=2`;(c) 接入真实生产 backend_server(重启后,见 `bd1404d` 的 FK 迁移修复)、走真实 API 创建的 "reverse_words(s)" goal(task `b4892aae-8a44-4a33-a53e-7521838baef5`):`benchmark` 节点连续两轮被 judge 拒绝("material given is a narrative summary of scenario categories and counts... rather than actual scenario content with real input/expected-output pairs"),第二轮的 judge 反馈甚至精确指出"this same narrative-summary content class was already rejected once before for this goal",`loop_back` 仍然原样复现,最终 `task.status` correctly 落到 `blocked_pending_human`(`blocked_reason='prd_consistency_check_failed'`,走的是既有 `ConsistencyCheckFailedError` 路由,不是 Phase 1 新增的 `planner_review_loop_limit_reached`——因为失败发生在 `plan_documents()` 内部,`planner_reviewer` 本身根本没被触发到)。三次复现全部跟 Phase 1 本身的改动无关(`plan_documents()` 是既有代码,未改动),但确认了第 5 轮"触发条件是'任务需不需要模型先给出可判定的具体场景',不是'节点类型是不是 test_script'"的判断——即使是"实现一个纯函数+单测"这种几乎不需要探索真实代码的极简 goal,也会被诱导成"叙述场景类别和数量的总结"而不是"具体输入输出对"。3 个新任务里,(a)(b) 是本地临时仓库,(c) 是真实生产 task(保留在 `~/.graphlemon/graphlemon.db` 里未清理,供后续复核)。 | |
| 18 | +| 8 | 08-13 | **Coder 自规划场景专项复核(Org Graph unification Phase 2 落地后),真实非 self-target 任务,未复现**:为隔离"self-hosting 词汇污染"这个混淆变量,专门构造了一个全新的 tempfile 临时 git 仓库(不是 graphlemon 自己),种入一个真实的、带一个精心设计的浮点截断 bug 的 `token_bucket.py`(`_refill()` 用 `int(elapsed * refill_rate)` 截断小数 token 且把丢弃的小数余量算进 `_last_refill = now`,导致小数 `refill_rate` 场景系统性少发 token)。goal 明确要求"先读懂已有代码、再产出一份纯审计报告"(`docs/token_bucket_audit.md`,含设计说明/逐条问题证据/修复建议三段),是 §6.2 根因结论里"先探索、再产出内容"这个触发条件的直接构造。直接调用生产代码路径 `work_graph_plan.plan_work_graph(conn, "coder", ...)` + `work_graph_orchestrate.run_graph()`(跟 `e2e_pipeline.implement_code()` 内部调用序列完全一致,只是省略了它外层的 code_diff/test_report 包装,便于直接读每个自规划节点的原始 `content`)。**结果**:Coder 自规划出单节点图 `audit_token_bucket`(`node_type="impl"`)——即使 `_CODER_NODE_CATALOG` 的 `impl` 目录条目本身没有 `suggested_judgment`,规划 LLM 仍然自己给这个节点声明了 `judgment.kind="llm"`,`judge_prompt` 文字明确针对"narrative description of an action taken...standing in for the real content itself"(跟 `_NODE_REVIEW_JUDGE_PROMPT`/`work-graph-node-review` skill 的方法论高度一致,说明该 skill 挂载到 coder 角色后确实在影响自规划行为),外加 `on_fail: retry_self`。真实执行后(`work_node_execution` 表只有一行 `status='done'`,没有 `-reflect` 重试行,说明第一次尝试就通过了这个自加的 LLM judge):`content` 字段是"The graphlemon coder workflow finished — it audited `token_bucket.py`...`"开头(这句开场白措辞跟历史叙述事故的"The ... workflow completed"高度相似,是一个残留的文体尾巴,值得记录),但紧跟着是 5 条具体到行号(如"L21-27")、带可运行复现脚本证据(如"`refill_rate=2.5` 时理论应发 25 个 token,实测仅 20 个")、逐条给出修复建议的真实发现——不是空洞叙述冒充产出。磁盘上的真实交付物 `docs/token_bucket_audit.md`(1.5K+ 字)同样是结构完整(三段式)、逐条引用真实代码行/片段作为证据的审计报告,精确命中了预先埋入的截断 bug,另外还发现了 4 个未预设的真实问题(负数 `n` 绕过容量上限、构造函数无参数校验、非单调时钟回拨冻结刷新、公开属性无并发保护)。**结论**:这次真实非 self-target 复核里,`content` 字段的"体裁"仍有历史叙述事故的措辞痕迹(开场白),但没有复现"内容整体被叙述文字替代、真实交付物缺失"这个核心失败模式——真实交付物存在、具体、可验证;`_CODER_NODE_CATALOG` 的 `impl` 条目虽然本身缺 `suggested_judgment`,但 Phase 2c 新增的 `work-graph-node-review` skill + `_NODE_REVIEW_JUDGE_PROMPT` 的方法论已经外溢到自由规划阶段,规划 LLM 会自发给内容型节点补一道等价的反叙述 judgment,不是完全没有防线。样本量为 1 次真实运行(用户仅明确同意"跑一次"),结论置信度有限,不排除低概率仍会复现——如果后续生产真实任务里再看到这类节点复现叙述性 `content`,应重新评估要不要把 `_NODE_REVIEW_JUDGE_PROMPT` 直接接到 `impl` 目录条目的 `suggested_judgment` 上(而不是完全依赖规划 LLM 自愿声明)。复核脚本未入库(一次性验证,未固化为回归测试),本轮未修改任何生产代码。 | | |
| 18 | 19 | |
| 19 | -后续讨论方向记在 `docs/todo/org-graph-unification-and-universal-self-planning-requirements.md`(原草案 `org-graph-as-work-graph-unified-loop-requirements.md` 已并入此文档并删除)——包括要不要给 benchmark 也加一个类似的启发式机械检查、以及要不要在 Coder 开始实现之前对 Planner 产出多一道独立复核(后者已在该文档 Phase 1 SDD `docs/done/org-graph-unification-phase1-review-gate-design.md` 落地为具体设计)。 | |
| 20 | +后续讨论方向记在 `docs/done/org-graph-unification-and-universal-self-planning-requirements.md`(原草案 `org-graph-as-work-graph-unified-loop-requirements.md` 已并入此文档并删除)——包括要不要给 benchmark 也加一个类似的启发式机械检查、以及要不要在 Coder 开始实现之前对 Planner 产出多一道独立复核(后者已在该文档 Phase 1 SDD `docs/done/org-graph-unification-phase1-review-gate-design.md` 落地为具体设计)。 | |
| 20 | 21 | |
| 21 | 22 | ## 1. 现象 |
| 22 | 23 | ... | ... |