crucible 是做什么的?
并行领域侦查 → 对抗性审查 → 计划 → 验证 → 规格说明 → 实现 → PR。
文件所有权规则
子代理永远不写文件。 它们只返回文本结果。你(编排器)负责编写每一个工件。文件是跨阶段的手续——子代理没有记忆。
设置
解析调用中的:
- 领域(必需)——面向用户需要审计的领域,例如
player、curator - 范围提示(可选)——缩小领域内的关注范围,例如
lobby SSE、role selection
确定输出目录:.crucible/run-<N>/,其中 N 是下一个未使用的整数。
先前运行检查:扫描 .crucible/ 下现有的运行目录。读取每个 findings.json。将其已确认的 ID 作为跳过列表提供给阶段 1 的代理——不要重新发现已知已修复的问题;将精力集中在差距上。
本次运行写入的文件(全部由编排器写入):
| 文件 | 阶段 | 角色 |
|---|---|---|
codebase-map.md | 1 | 逐字注入到所有下游代理的上下文 |
recon-<domain>.json | 1 | 每个领域的原始发现 |
findings.json | 1→2→4 | 合并的发现;每个阶段附加裁决 |
PLAN.md | 3 | 按优先级排序的修复计划 |
SPEC.md | 5 | 每个发现的修复前后代码及测试用例 |
阶段 1 — 侦查
启动代理前必须阅读 references/recon-phase.md。
为每个声明的领域启动一个研究代理,全部并行运行。为每个代理提供:代码库路径、领域名称、范围提示(如果有)、要跳过的先前已知 ID。
代理返回 JSON 文本。如果代理返回的是散文而非 JSON 数组,则使用 assets/findings-schema.json 中的精确模式形状重新提示一次。如果再次失败,则写入一个空的 recon-<domain>.json([]),并在 codebase-map.md 中记录失败。继续——一个领域失败是可恢复的;不要中止本次运行。
收集有效响应,然后:
- 根据每个代理响应写入
recon-<domain>.json - 综合编写
codebase-map.md——关键文件路径、领域边界、共享模块、约定 - 将所有领域发现合并到
findings.json
完成标准:每个领域都有 recon-<domain>.json、codebase-map.md 已写入、findings.json 已写入。在阶段 2 之前不要加载 references/adversarial-phase.md。
阶段 2 — 对抗性评审
启动代理前必须阅读 references/adversarial-phase.md。
为每个发现启动一个通用代理(同一领域的发现批量处理)。每个代理获取该发现的 JSON 和 codebase-map.md——而不是侦查代理的推理过程。独立性边界是质量门。
代理返回 CONFIRMED / REJECTED / DOWNGRADED 并附带代码证据。将每个裁决附加到 findings.json 中的相应条目上。运行 node scripts/validate-findings.cjs findings.json——在阶段 3 之前修复所有模式错误。
当验证器本身无法运行时——node 不在 PATH 中、脚本或其模式缺失、使用错误、或在验证开始前发生任何失败(Failed to load schema、Failed to parse JSON)——这不是通过。在发现输出和 SPEC 交接的顶部注明 ⚠ findings unvalidated — validator unavailable: <reason>,然后继续。而模式拒绝则是相反的情况,总是阻塞:修复发现,重新运行,拒绝时不得继续。两者目前都退出 1,因此请读取错误文本,而非退出码。
完成标准:每个发现都有 adversarial_verdict 字段。模式验证通过。从此之后不要重新加载 references/recon-phase.md。
阶段 3 — 计划合成
零发现检查:在合成之前,统计 findings.json 中已确认 + 降级的条目数。如果为零,则写入 .crucible/run-<N>/REPORT.md,内容仅一行“对抗性评审后无可行发现。”停止——不要创建 PR。
将 findings.json 中已确认 + 降级的发现综合到 PLAN.md:
- P1(严重/高):核心流程损坏、数据丢失、永久断开
- P2(中):用户可见错误、缺少恢复路径
- P3(低):打磨、文档偏差、文案问题
将共享根因的发现分组——一个修复可能消除多个问题。分组时:分组中最高的严重性设置该组的优先级。如果分组后的发现存在冲突的修复方法,则拆分它们——共享根因不要求共享修复。在存在依赖关系时声明修复顺序。完全排除被拒绝的发现。
完成标准:PLAN.md 已写入;每个已确认的发现恰好出现一次。
阶段 4 — 独立验证
为每个 P1 + P2 发现启动一个研究代理,全部并行运行。每个代理被告知:“你没有编写此发现。对照当前源代码验证每一条事实性声明。”
每个代理检查:文件存在于路径、行号匹配所描述的代码、领域名称正确、描述的模式确实出现。返回 VERIFIED / CORRECTED [field: wrong → right] / REJECTED [reason]。
将所有更正应用到 PLAN.md 和 findings.json。再次运行模式验证。PLAN.md 和 findings.json 必须一致——交付物之间不得存在分歧。
完成标准:所有 P1+P2 发现已验证。所有更正已应用。模式通过。
阶段 5 — 规格说明
编写 SPEC.md,每个已确认发现一个章节(顺序 P1 → P2 → P3):
- 精确文件路径 + 行范围(已验证)
- 修改前代码(真实源代码,非伪代码)
- 修改后代码(具体修复)
- 测试用例:每个测试必须验证的行为一句话
运行 node scripts/validate-findings.cjs findings.json 最终检查。
完成标准:PLAN.md 中的每个条目都有一个 SPEC 章节。验证通过。
阶段 6 — 交接
- 更新流程文档(
docs/flows/)以反映任何更改用户可见行为的发现 - 调用
implement技能,并提供SPEC.md - 创建一个 PR——这是人机回路(HITL)门控点;不需要中间批准
PR 正文:链接到 PLAN.md、按严重性列出的发现数量、链接到 SPEC.md、更新的流程文档列表。
永远不要
-
永远不要要求子代理写入文件 相反:让代理以文本形式返回内容;你自己写入文件。 原因:跨阶段状态存在于文件中。如果代理直接写入,编排器会失去规范副本,并且在阶段 4 更正后无法协调交付物。
-
永远不要向对抗性代理提供侦查代理的推理链条 相反:仅传递结构化发现(JSON)和
codebase-map.md。 原因:看到侦查代理的逻辑会将对抗性代理锚定在相同的假设上——独立性边界正是消灭误报的关键。 -
永远不要在模式验证失败的情况下继续超过阶段 2 相反:在合成计划之前修复
findings.json中失败的字段。 原因:基于格式错误的发现构建的计划会产生包含错误文件路径和行号的 SPEC,而 implement 技能无法使用。 -
永远不要在任一 P1/P2 发现处于
verification: "pending"状态时编写SPEC.md相反:运行node scripts/validate-findings.cjs findings.json --pre-spec,并在阶段 5 之前解决所有失败。 原因:--pre-spec保护存在于验证器脚本中,但除非被调用,否则不可见——跳过此调用的代理将对未经验证的文件路径编写 SPEC,并默默将错误行号传递给 implement。