validator-loop-until-dry-skill-design.md 4.04 KB

Validator "未知规模扫描收敛" Skill——详细设计(SDD)

日期: 2026-08-06 性质: 详细设计,对应需求文档 docs/done/validator-loop-until-dry-skill-requirements.md(条目 B,已确认)。回答该需求文档第 8 节的开放问题。 状态: 设计草案,实施中。

1. 范围确认:纯 Skill,不动执行引擎

跟 E/F/G 不同,这条不涉及 work_graph_orchestrate.py/work_node_run.py 任何一行代码——需求文档第 1 节的"关键澄清"已经说清楚:收敛循环发生在一次 Work Node 执行内部(一次 claude -p 会话自己的多轮工具调用),不是 graph_manifest 层面的图内回路。所以本轮改动只有三处:新增一个 Skill 文件、agent_profile.py::FRONTMATTER["validator"]["skills"] 加一行、agents/validator/AGENTS.md 加一段触发指引。

2. 开放问题的最终决定

  • Skill 命名:unknown-scope-defect-sweep(需求文档 FR-1 自己给出的暂定名,评审后确认沿用,语义准确,不需要改)。目录 skills/unknown-scope-defect-sweep/SKILL.md,与 qa-task-validation 平级。不照抄 qa-task-validation/SKILL.md 里遗留的飞书 Base 内容(约束第 1 条已经点名),按 graphlemon 现有的 task/bug_record 结构化存储来写。
  • FR-3 接线方式:每个候选项复用 qa-task-validation 已经定义的 PASS/FAIL/INCONCLUSIVE 判定框架(同一次会话里 Validator 已经加载了这个 Skill,直接引用它的判定原则,不重新发明一套),不接 root_cause_trace 的三视角评审团机制——root_cause_trace/judge_root_cause_via_work_graph(F)解决的是"验证失败后,根因属于 planning/coder/skill_defect 哪一类",是验证之后的归因步骤;这里要解决的是"扫描出的候选项本身是不是真缺陷",是验证本身,两者是流水线上不同阶段,不应该混用。
  • K 值/硬上限:K=2(连续 2 轮无新发现即停止,需求文档背景部分引用的 14 步版建议值,也是 FR-1 自己写的参考值)。硬上限:20 轮——这完全是提示词层面的自我计数(一次 claude -p 会话内部没有 graphlemon 代码能从外部数轮次),保守值,风险第 2 条已经承认第一版数字要靠实测校准,不是理论推导出来的精确值。触达硬上限时 Skill 要求如实报告"可能未收敛",不能假装已经扫完。
  • AGENTS.md 触发条件:关键词信号(任务描述含"扫描/审计/全部/所有/系统性/未知规模"这类无边界表述)+ 一条更本质的判断标准("这个任务在开始前能不能说清楚验收对象的确切数量或边界"——数不清就该用这个 Skill,能数清就走默认单轮验证),写进 AGENTS.md"必须加载"一节。

3. 去重键(FR-2)——不绑定具体场景

Skill 不规定"用文件路径"还是"用函数名"这类具体键,而是给一条通用原则:去重键必须是候选项的结构性标识(能唯一定位这个候选项在代码/系统里的位置——文件路径+行号、路由路径、依赖包名之类),不能用候选项的自然语言描述做键(同一个真实缺陷,模型两次描述的措辞很可能不完全一样,用文本做键会导致同一个候选项被误判成"新发现")。

4. 唯一可测的代码触点

FR-4 的 agent_profile.py::FRONTMATTER["validator"]["skills"] 追加 + deploy_agent_definitions() 渲染进 .claude/agents/validator.md 的 skills: frontmatter——这是本轮唯一有确定性代码行为、可以用现有 test_agent_profile.py 模式写单测的部分(验收标准 4)。验收标准 1-3(真的能找全 5 处缺陷、真的能正确去重收敛、真的能在硬上限强制停止)依赖真实 claude -p 多轮工具调用行为,只能用 RUN_REAL_AGENT_E2E=1 真实验证,不在本轮 mock 测试范围内——这跟 F 设计文档第 6 节"视角节点并发时间收益的实测"是同一类限制,如实记录,不假装 mock 测试能替代它。