关于 cheese-factory
cheese-factory 是面向编码 Agent 的多阶段开发编排技能,适用于可拆分为至少 5 个文件互不重叠行为单元的规格。它通过并行实现、顺序集成、合并审查和发布规划组织完整流程,并以清单支持恢复执行。
主要功能
- 01将规格拆分为基础项、行为单元和集成任务
- 02并行运行互不冲突的行为单元
- 03按依赖顺序执行集成任务
- 04通过 YAML 清单跟踪阶段并支持恢复
- 05合并后执行审查并规划发布
适用场景
- 01按明确验收标准实现大型功能
- 02将文件分离的任务并行交由子 Agent
- 03在中断后从最近完成阶段继续
- 04为变更安排审查及 PR 发布计划
MCP 相关
这是一项 Agent 技能,而非 MCP 服务。它可选用 milknado MCP 跟踪行为单元;若该 MCP 不可用,则使用本地 YAML 清单。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ easy-cheese --skill cheese-factory安装后在 Claude Code 中输入/cheese-factory确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/curd-prompt.mddecomposer-prompt.mdmanifest-schema.jsonpr-plan-schema.jsonpr-planner-prompt.mdspawn-primitive-reference.mdwiring-prompt.mdscripts/cheese-factory.pyz详细介绍
/cheese-factory
输入
接受:
/cheese-factory <spec-path-or-slug> [--hard] [--resume <slug>]
- 规格文件路径。若明确给出,则按原样读取其指向的文件。
- 单独的 slug。使用
SPEC=$(python3 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz artifact-path specs <slug>)将其解析为持久规格路径,然后读取"$SPEC"。解析器会将规格锚定到每个项目的持久语料库中(参见shared/formatting.md§ 语料库位置)。 --hard— 通过每个 curd 的/cook --hard --auto和 Phase 6 的/cure --hard --auto --stake medium+传递/hard-cheese元认知门控标志。编排器本身不会触发该门控。参见skills/hard-cheese/SKILL.md。--resume <slug>— 读取.cheese/cheese-factory/<slug>/manifest.yaml,找到最新标记为已完成的阶段,并从下一阶段继续。
/cheese-factory 不接受模糊或开放式的需求——应先将这类需求交给 /mold。编排器假定契约已经确定。
--auto 为隐式启用。Phase 0 门控获批后,整个流程将自主运行,不会在每一步交接时提问。
何时使用 /cheese-factory 与其他方案
只有当规格可以拆解为 5 个或更多文件互不重叠的行为 curd 时,才使用 /cheese-factory。curd 更少时使用 /ultracook;任务单一且明确时使用 /cook;在安装了定制 Agent 文件的 Anthropic Claude Code 上使用 /fromagerie。
拆解契约——行为 curd
curd 是可独立提交的最小行为单元。
Phase 0 的拆解器会根据规格生成三个制品列表:
seed[]— 基础类型/接口/枚举,有 2 个或更多 curd 依赖它们。curds[]— 并行的行为单元,文件互不重叠,每个单元各有一个验收标准。wiring[]— 具有拓扑依赖关系的集成任务(导出汇总文件、注册、路由、配置)。
五项标准
五项行为标准约束每个 curd——完整列表以及“令牌预算不是标准”的理由,请参见 references/decomposer-prompt.md § 五项标准。未通过标准 4(文件互不重叠)的 curd,应将共享内容移至 seed 或 wiring。
清单格式
每次运行的清单以 YAML 格式写入 .cheese/cheese-factory/<slug>/manifest.yaml。
YAML 是面向人类/Agent 的语法;契约保持架构模式,并记录在
references/manifest-schema.json 中。清单仅使用与 JSON 兼容的
YAML 子集:映射、列表、字符串、数字、布尔值和 null;不得使用锚点、
别名、标签或多文档流。
PR 计划遵循相同约定——以 YAML 格式写入
.cheese/cheese-factory/<slug>/pr-plan.yaml,其结构记录在
references/pr-plan-schema.json 中。${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz pr_plan_to_branches 为向后兼容,可读取 YAML
或 JSON,但 YAML 是规范格式。
验证(Phase 0)
六项检查由 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz validate_manifest 和 validate_decomposition 执行,详情请参见 references/decomposer-prompt.md § 验证。若验证失败:突出显示违规项后重新运行拆解器。最多重试 2 次,之后升级给用户处理。
阶段
共八个阶段。协调器按从上到下的顺序执行,并在到达最后一项或遇到任何停止条件时停止。
| # | 阶段 | 形式 |
|---|---|---|
| 0 | 预编译 | 阅读规范,通过通用型重型子 Agent 拆解,依据五项标准验证,等待用户把关 |
| 1 | 种子 | 协调器通过 /cheez-write(或在 tilth MCP 不可用时使用宿主编辑工具)直接编辑,提交并推送 |
| 2 | 凝乳(扇出) | 并行启动 N 个通用型子 Agent;每个都运行单个凝乳的流水线并提交 |
| 3 | 合并凝乳(扇入) | 将凝乳提交变基挑选到协调器分支 → 冲突时使用 /melt |
| 4 | 接线(每个波次内顺序执行) | 仅处理集成文件;为每个任务启动通用型子 Agent,并提供仅限接线的提示词 |
| 5 | 最终合并接线 | 将接线提交合并到协调器分支;此处出现冲突 = 停止(拆解器出错) |
| 6 | 合并后审查(新上下文,ultracook 风格) | 启动三个子 Agent:/press --auto、/age --auto、/cure --auto --stake medium+。单次通过。 |
| 7 | PR 计划 + 发布 | 重型 PR 规划器子 Agent 决定布局;协调器通过技能发现机制(/pr-stack、/gh、备用方案)委派发布 |
可选:milknado 凝乳跟踪后端
如果 milknado MCP 可用(工具集中有 mcp__milknado__milknado_todo_add),则在第 0 阶段拆解期间将凝乳列表持久化到 milknado 任务图中。对每个凝乳使用 mcp__milknado__milknado_todo_add,并使用 mcp__milknado__milknado_graph_summary 展示已跟踪的凝乳及清单。这样便可在整个工厂运行期间跨会话跟踪凝乳状态。如果没有 milknado,则继续使用报告内的凝乳拆解(.cheese/cheese-factory/<slug>/manifest.yaml 中的清单 YAML)——拆解过程本身不变。检测并降级的约定见 ../../shared/optional-plugins.md。
阶段 0 — 预编译
从参数中读取规范(或者,如果使用 --resume <slug>,则读取清单并跳转到下一个未完成阶段)。
验证输入规范的结构(这与验证器对拆解器的输出清单执行的五项标准凝乳检查不同)。规范必须包含:(a) 可枚举的验收标准或用户故事列表——至少有一个列表项(项目符号或编号均可),供拆解器一对一映射到凝乳;以及 (b) 质量门禁——至少有一条可运行的命令。不强制要求标题名称;检查内容是否存在即可。缺少任一项时立即失败。
严格的工作树门禁:检测宿主的工作树机制(Conductor、Git worktrees、普通分支),并在当前工作于默认分支时提示用户。绝不可跳过。
启动一个通用型重型拆解器子 Agent(提示模板位于 references/decomposer-prompt.md),并提供规范文本、五项标准、验证检查,以及生成 seed[]、curds[]、wiring[] 和清单脚手架的说明。
如果需要根据代码库或外部文档为拆解提供依据,拆解器可以在内部调用 /culture 或 /briesearch。
提前征求权限:向用户展示每个宿主的权限清单(Git、项目的质量门禁命令、宿主专用的启动原语)。获得批准后,将其合并到宿主设置中。
阶段门 — 用户批准
呈现完整计划:
## Cheese-Factory Plan: <slug>
### Seed (sequential)
1. <description> — files: [<list>]
### Curds (parallel)
| # | Behaviour | Acceptance criterion | Files | Test target |
|---|---|---|---|---|
### Wiring DAG
| # | Type | File | Depends on |
|---|---|---|---|
### Review Pipeline
Per-curd: /cook → /press → /age (inline-degrade) → /cure
Post-merge: /press → /age → /cure (fresh-context sub-agents)
A. Approve — start execution
B. Modify — change the decomposition
C. Re-decompose — different boundaries
D. Pause — hold off
在此审批步骤中,使用共享移交门控 ../../shared/handoff-gate.md。这四个选项都会让 cheese-factory 继续在内部运行(不会切换技能)——根据门控词汇,它们使用 continue: 标识符,而非 dispatch: 命令:
- 批准 —
continue: write-manifest-then-seed:写入.cheese/cheese-factory/<slug>/manifest.yaml,设置phase: gate_approved,然后进入阶段 1(种子执行)。 - 修改 —
continue: ask-for-decomposition-change:针对所请求的分解变更询问一个有针对性的问题,然后重新呈现计划。 - 重新分解 —
continue: re-run-decomposer:根据用户的边界指示重新运行分解器。最多重试两次。 - 暂停 —
dispatch: none:保留清单草稿并报告其路径。
未经明确批准,不得继续。
压缩接缝 C1
丢弃:完整规格文本、权限清单、分解推理。 保留:slug、规格摘要(≤2K 字符)、清单路径、质量门控命令。
阶段 1 — 种子(顺序执行,内联)
种子条目应尽量精简——只包含凝乳无法编译所必需的共享类型/协议。编排器以内联方式执行种子任务(这是对编排器“绝不编写代码”规则的刻意例外,因为种子任务始终很小)。
对每个种子条目:
- 实现变更。若存在 tilth MCP,优先使用
/cheez-write;否则回退到宿主的原生编辑工具(遵循README.md中cheez-*的可移植性规则)。当/cheez-write不可用时,技能不得直接失败。 - 运行质量门控(项目的
just check或等效命令)——如果门控失败,立即停止。 - 使用
/commit(如果可用)或直接运行git commit提交。
推送到分支——凝乳从 HEAD 创建分支。
更新清单:
python3 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz manifest_update set-phase --manifest <path> --phase seed_complete
阶段 2 — 凝乳(扇出)
派发前,针对当前工作树重新验证分解器生成的文件列表——自阶段 0 以来已经过了一段时间,种子任务也可能移动了路径:
python3 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz manifest_update check-files --manifest <path> --root <repo-root> --json
缺失文件仅供参考,不构成阻碍——凝乳可能正在创建新文件,也可能是分解路径已过时。将报告的缺失项纳入对应凝乳的派发上下文,以便工作进程(遵循 references/curd-prompt.md 中有关文件范围的指导)知晓列表可能需要调整。
通过宿主的扇出原语,在一条消息中启动所有凝乳工作进程。如果凝乳超过 5 个,则每批派发 5 个。
每个凝乳工作进程都是通用子 Agent(与编排器完全平级——使用相同模型,拥有完整工具、完整技能和完整 MCP),并接收 references/curd-prompt.md 中针对该凝乳的提示词。
随着凝乳完成,收集结果。对于失败的凝乳:结合错误上下文重试一次。将 retry_count: 1 标记为已重试;不得重试两次。
更新清单:凝乳状态、工作树路径、分支名称、提交 SHA。
压缩接缝 C2
丢弃:分解器产物、凝乳派发提示词、凝乳返回摘要。 保留:slug、清单路径、质量门控命令、凝乳分支列表。 需要时从磁盘读取:接线 DAG。
阶段 3 — 合并凝乳(扇入)
按凝乳 ID 顺序,将凝乳提交拣选到编排器分支:
对每个凝乳(按顺序):
git cherry-pick <curd_commit_sha>——或者,如果宿主扇出使用了工作树,则合并工作树分支。- 遇到冲突时:如果
/melt可用,则调用它;否则依次回退到 mergiraf →git rerere→ 手动处理。 - 如果
/melt无法解决:立即停止,回退到阶段 7 的逐凝乳 PR 方案。
所有凝乳合并后:运行质量门控。如果失败,立即停止并报告——凝乳各自单独通过,但聚合后发生冲突(分解器错误)。
第 4 阶段 — 接线(扇出,各波次内顺序执行)
根据接线 DAG 计算拓扑调度顺序:
python3 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz wiring_topo_sort --manifest <path>
按照返回的波次顺序调度接线任务,并在每个波次内顺序执行(在同一工作目录中并发提交会导致 git 的 index.lock 发生竞争)。
每个接线工作者都是通用子 Agent,使用 references/wiring-prompt.md 中的提示词模板。
对于失败的接线任务:重试一次。如果仍然失败,在清单中标记为未完成。
第 5 阶段 — 最终接线合并
将接线提交 cherry-pick 到编排器分支。
如果此处出现冲突:停止。接线冲突意味着分解器的 DAG 有误(接线涉及了实现范围,或者两个接线任务修改了 DAG 之外的同一文件)。不要自动解决。
压缩节点 C3
丢弃:接线 DAG 详情、各 curd 的差异、中间合并报告。 保留:slug、规格路径(供下游技能使用)、质量门禁、所有已更改文件的列表、所有提交 SHA 的列表(curd + seed + wiring)。
第 6 阶段 — 合并后审查(ultracook 风格的新鲜上下文)
在新鲜上下文的子 Agent 中运行最终审查流水线。
顺序启动三个子 Agent:
- 对合并后的差异运行
/press --auto— 写入.cheese/press/<slug>.md。 - 对合并后的差异运行
/age --auto— 写入.cheese/age/<slug>.md。 - 根据 age 的发现运行
/cure --auto --stake medium+— 写入.cheese/cure/<slug>.md。
每次启动的都是全权限通用子 Agent。传入禁止链式转发指令(与 /ultracook 相同),确保每次启动只运行其对应阶段。
只通过一轮,不设两轮 cure 的上限。每个 curd 都经过各自的 press/age/cure;这是集成级审查。
如果任何阶段在其 slug 中写入 status: halt: <reason>,则报告该暂停状态并停止。如果 /cure 写入 next: done,则继续执行第 7 阶段。
第 7 阶段 — PR 计划 + 发布
启动一个重型通用 PR 规划器子 Agent(提示词模板位于 references/pr-planner-prompt.md),并提供接线 DAG、清单、合并后的差异和规格摘要。
规划器会输出以下四种结构之一:
| 结构 | 适用情况 | PR 布局 |
|---|---|---|
single | 总差异较小且耦合紧密 | 所有提交放在一个 PR 中。 |
orthogonal_flat | 各 curd 修改互不重叠的部分,且 seed/wiring 之间没有耦合 | N 个 PR,均从 main 创建分支。 |
stacked_linear | 依赖关系呈线性:seed → curds → wiring | gt/gh 堆栈。 |
diamond_stack | 存在 seed 和 wiring;各 curd 彼此独立 | seed PR(基础)→ N 个并行 curd PR → wiring PR。 |
规划器将分组结果写入 .cheese/cheese-factory/<slug>/pr-plan.yaml,然后返回控制权。
技能发现(编排器侧)
发布 PR 之前,编排器会检测可用的技能并选择合适的委派方式:
| 需求 | 优先选择 | 备用方案 |
|---|---|---|
| 发布堆栈 | /pr-stack(Graphite gt 或 gh stack) | 手动串联执行 gh pr create --base <prev-branch> |
| 提交 | /commit | 直接运行 git commit |
| 发布 PR | /gh | 直接运行 gh pr create |
| 合并冲突 | /melt | 直接使用 mergiraf → rerere → kdiff3 |
检测方式:尝试通过宿主的 Skill 工具调用该技能;如果出现无法识别技能的错误,则使用备用方案。在本阶段的剩余部分缓存检测结果。
发布
对于计划中的每个 PR 组:
- 从
pr-plan.yaml读取组元数据。 - 推送分支(使用
${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz pr_plan_to_branches将pr-plan.yaml转换为创建分支的命令)。 - 创建 PR(如果
/gh可用则通过它创建,否则直接运行gh pr create)。 - 对于堆栈:使用有序分支列表调用
/pr-stack。 - 使用 PR 编号和 URL 更新清单。
最终报告
## Cheese-Factory Complete: <slug>
### Results
| Phase | Status | Detail |
|---|---|---|
| Seed | complete | 2 commits |
| Curds | 5/6 succeeded | Curd #4 failed after retry |
| Merge | complete | — |
| Wiring | 4/4 complete | — |
| Final merge | complete | — |
| Post-merge review | press: pass, age: 3 findings, cure: 3 applied |
| PR plan | diamond_stack | seed + 5 curds + wiring = 7 PRs |
### PRs
| PR | Title | Stack base |
|---|---|---|
| #101 | feat(orders): shared types | main |
| #102 | feat(orders): order entity | #101 |
| ... |
### Manual actions needed
- Curd #4 failed: {error_summary}
Manifest: .cheese/cheese-factory/<slug>/manifest.yaml
压缩策略
在每个节点,丢弃内容之前先将自我摘要写入清单:
丢弃之前,写入 phase_summary 和 carry_forward(格式见 references/manifest-schema.json)。恢复时(--resume),从清单读取 phase_summary — 这是唯一的跨节点连续性机制;不要依赖对话历史。
Spawn 原语约定(与宿主无关)
编排器从不指定特定的宿主原语。任何满足全部五项不变量的原语都可接受:(1)每次 spawn 都使用全新上下文,(2)继承完整的对等方信息,(3)不向链路前方传递(在提示词中传递),(4)返回控制权,(5)写入交接 slug。各宿主的示例以及无扇出时的回退方案(路由到 /ultracook)见 references/spawn-primitive-reference.md。
交接 slug 架构
每个阶段都会将交接 slug 写入 .cheese/<phase>/<slug>.md(对于按 curd 划分的工作线程,则写入 .cheese/cheese-factory/<slug>/curds/<curd-id>.md),其最小结构如下:
status: ok | halt: <one-line reason>
next: <phase-name | done>
artifact: <path-to-richer-report-if-any>
<one-line orientation: what this phase did>
对于已经会写入详细报告的阶段(/age、/press、/cure),该架构会添加到同一文件的顶部。
质量门禁
/cheese-factory 会在以下四个节点运行项目的质量门禁命令(通常根据 AGENTS.md 为 just check):
- Seed 之后(阶段 1)。
- 每个 curd 工作线程内部(其
/cure步骤之后)。 - Curd 合并之后(阶段 3,接线之前)。
- 阶段 6 的
/cure之后。
如果任何门禁失败:停止、报告,不要悄悄修复。
--resume <slug>
如果清单引用的提交已不存在(被变基或删除),则快速失败——不要悄悄重新执行该阶段。否则,从最近一个标记为完成的阶段之后继续;报告 Resuming <slug> from phase <N>。
错误恢复
| 失败情况 | 恢复方式 |
|---|---|
| 未提供规范参数 | 停止。报告 cheese-factory requires an approved spec; run /mold first if you need to shape one。 |
| 分解器输出存在重叠/违反标准 | 重新运行分解器(最多重试 2 次) |
| Seed 门禁失败 | 停止并报告——不要分派 curd |
| Curd 失败 | 携带错误上下文重试一次,然后标记为失败 |
| 所有 curd 均失败 | 停止,不进行合并/接线 |
| Curd 合并冲突 | 使用 /melt;如果 /melt 失败,则回退到逐个 curd 创建 PR |
| 接线 Agent 失败 | 重试一次;若仍失败,则标记为未完成 |
| 阶段 5 冲突 | 停止——这是分解器错误,向用户报告 |
阶段 6 的 /press 或 /age 停止 | 呈现停止信息并停止 |
阶段 6 的 /cure 无法应用任何发现 | 呈现报告并停止 |
/pr-stack 不可用,但计划要求使用栈 | 回退到手动创建 gh pr create --base 链 |
--resume 时清单缺失 | 快速失败 |
未经用户明确批准,绝不越过阶段 0 的门禁。 绝不声称部分工作已全部通过。
编排器绝不做的事
会做:在阶段 0 读取一次规范;读取各阶段的交接 slug(每个 ≤2KB);每个阶段结束后更新清单;根据 slug 的 status 和 next 字段决定链路推进——绝不依据子 Agent 的标准输出。
绝不:
- 读取代码库文件(由子 Agent 探索,编排器负责路由)。
- 运行构建/测试命令(由逐个 curd 的工作线程和合并后的子 Agent 负责验证)。
- 编写实现代码(由 cook Agent 和接线 Agent 实现;编排器唯一的行内写入是在阶段 1 写入少量 Seed 项)。
- 在阶段 0 之后做出分解决策(计划在门禁批准时锁定)。
- 重试超过一次(curd 和接线各有一次重试机会,之后标记为失败)。
- 自动解决阶段 5 的冲突(接线冲突 = 分解器错误)。
- 估算子 Agent 的 token 用量(分解依据行为标准,而非 token 数量)。
- 读取子 Agent 的完整报告——只根据交接 slug 摘要开展工作。
注意事项
/age嵌套深度:curd 工作进程会调用/age,而它通常会派生 6 个审查子 Agent(第 2 层,受阻)。/cheese-factory要求/age支持子 Agent 调用的内联降级模式——参见skills/age/SKILL.md中的“内联降级模式”。- C2 后上下文丢失:C2 之后,编排器不再掌握 curd 的详细信息。接线 DAG 必须在磁盘上自成一体。如果接线引用了清单中未记录的 curd 内部信息,接线 Agent 将无法正常工作。
- 接线竞态条件:接线任务会提交到同一个工作目录。第 4 阶段会按顺序(而非并行)派发这些任务,以避免
git index.lock竞态,即使它们修改的是不同文件。 - bypassPermissions 不会绕过 Bash 权限:curd 工作进程可以自由使用 Edit/Write,但未经明确的 Bash 允许列表授权,无法执行
git push或gh pr create。编排器必须处理所有推送和 PR 操作。 - 过期 worktree:第 3 阶段合并后,curd worktree 会继续保留。编排器不会清理它们——建议用户在流水线完成后运行
/worktree-sweep(或宿主环境中的等效工具)。
参考资料
references/decomposer-prompt.md— 重型分解器子 Agent 提示词模板。references/curd-prompt.md— 每个 curd 工作进程的提示词模板。references/wiring-prompt.md— 每个接线任务的提示词模板。references/pr-planner-prompt.md— PR 规划器子 Agent 提示词模板。references/manifest-schema.json— 清单的 JSON Schema。references/pr-plan-schema.json— PR 计划的 JSON Schema,由manifest-schema.json通过$ref引用。references/spawn-primitive-reference.md— 按宿主环境分类的调用示例,以及五项不变量。cheese-factory.pyz子命令(通过${CLAUDE_SKILL_DIR}/scripts/运行):validate_manifest、validate_decomposition(第 0 阶段)、validate_pr_plan、pr_plan_to_branches(第 7 阶段)、manifest_update(第 1/2/4 阶段清单写入)、wiring_topo_sort(第 4 阶段波次排序)。
规则
- 子 Agent 是完整的同级协作者,不是低一等的工作进程。不要降低模型级别、不要缩小
subagent_type范围,也不要限制工具或 MCP 访问权限。 - 流程固定为八个阶段。不要擅自增加阶段或跳过阶段(通过
--resume除外)。 - 子 Agent 返回后,读取各阶段的交接 slug。不要根据子 Agent 的最后一行推断成功与否——读取文件。
- 原样呈现暂停信息。不要转述、弱化,也不要默默“重试”已暂停的阶段。
- 未经确认第 0 阶段的用户批准权限清单,绝不要直接调用
/gh。 - 应用共享的语气内核(位于本仓库的
skills/age/references/voice.md):最终报告开头说明发生了什么,将剩余风险标记为certain | speculating | don't know,不要凭空编造后续事项。