From easy-cheese
Parallelizes approved specs into 5+ independent behavioral curds, runs pipeline fanned out, and produces reviewable PRs via /pr-stack. Use for spec decomposition and parallel implementation.
How this skill is triggered — by the user, by Claude, or both
Slash command
/easy-cheese:cheese-factoryThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Accept:
Accept:
/cheese-factory <spec-path-or-slug> [--hard] [--resume <slug>]
SPEC=$(python3 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz artifact-path specs <slug>), then read "$SPEC". The resolver anchors specs at the per-project durable corpus (see shared/formatting.md § Corpus location).--hard — propagate the /hard-cheese metacognitive gate flag through per-curd /cook --hard --auto and the Phase 6 /cure --hard --auto --stake medium+. The orchestrator does not fire the gate itself. See skills/hard-cheese/SKILL.md.--resume <slug> — read .cheese/cheese-factory/<slug>/manifest.yaml, find the latest phase marked complete, and continue from the next phase./cheese-factory does not accept fuzzy or open-ended asks — route those to /mold first. The orchestrator assumes the contract is locked.
--auto is implicit. After Phase 0 gate approval, the chain runs autonomously with no per-step handoff questions.
/cheese-factory vs alternativesUse /cheese-factory only when the spec decomposes into 5+ file-disjoint behavioural curds. Fewer curds → /ultracook; single unambiguous task → /cook; on Anthropic Claude Code with bespoke agent files installed → /fromagerie.
A curd is the smallest commit-worthy unit of behaviour.
The Phase 0 decomposer produces three artifact lists from the spec:
seed[] — foundational types / interfaces / enums that 2+ curds depend on.curds[] — parallel units of behaviour, file-disjoint, one acceptance criterion each.wiring[] — integration tasks with topological dependencies (barrels, registrations, routes, config).Five behavioural criteria govern every curd — see references/decomposer-prompt.md § The five criteria for the full list and the "token budgets are NOT a criterion" rationale. Curds that fail criterion 4 (file-disjoint) move their shared content to seed or wiring.
The per-run manifest is written as YAML at .cheese/cheese-factory/<slug>/manifest.yaml.
YAML is the human/agent-facing syntax; the contract stays schema-shaped and is
documented in references/manifest-schema.json. Keep manifests in the JSON-compatible
subset of YAML: mappings, lists, strings, numbers, booleans, and nulls only; no anchors,
aliases, tags, or multi-document streams.
The PR plan follows the same convention — written as YAML at
.cheese/cheese-factory/<slug>/pr-plan.yaml, with its shape documented in
references/pr-plan-schema.json. ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz pr_plan_to_branches reads either YAML
or JSON for backward compatibility, but YAML is the canonical format.
See references/decomposer-prompt.md § Validation for the six checks run by ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz validate_manifest and validate_decomposition. If validation fails: re-run decomposer with violations highlighted. Max 2 retries before escalating to the user.
Eight phases. The orchestrator walks them top-to-bottom and stops after the last entry or any halt.
| # | Phase | Shape |
|---|---|---|
| 0 | Pre-compile | Read spec, decompose via heavy general-purpose sub-agent, validate against the five criteria, user gate |
| 1 | Seed | Orchestrator inline edits via /cheez-write (or host edit tool if tilth MCP is unavailable), commit, push |
| 2 | Curds (fan-out) | N parallel general-purpose spawns; each runs the per-curd pipeline and commits |
| 3 | Merge curds (fan-in) | Cherry-pick curd commits → orchestrator branch; /melt on conflicts |
| 4 | Wiring (sequential within wave) | Integration files only; per-task general-purpose spawn with wiring-only prompt |
| 5 | Final merge wiring | Wiring commits → orchestrator branch; conflicts here = halt (decomposer error) |
| 6 | Post-merge review (fresh-context, ultracook-style) | Three sub-agent spawns: /press --auto, /age --auto, /cure --auto --stake medium+. Single pass. |
| 7 | PR plan + publish | Heavy PR planner sub-agent decides layout, orchestrator delegates publish via skill discovery (/pr-stack, /gh, fallbacks) |
If milknado MCP is available (mcp__milknado__milknado_todo_add in toolset), persist the curd list to the milknado task graph during Phase 0 decomposition. Use mcp__milknado__milknado_todo_add per curd and mcp__milknado__milknado_graph_summary to surface the tracked curds alongside the manifest. This provides cross-session tracking of curd status across the factory run. If milknado is absent, proceed with the in-report curd decomposition (manifest YAML at .cheese/cheese-factory/<slug>/manifest.yaml) — the decomposition itself is unchanged. See ../../shared/optional-plugins.md for the detect-and-degrade contract.
Read the spec from the argument (or, if --resume <slug>, read the manifest and skip to the next incomplete phase).
Validate the spec has: Executive Summary, Problem Statement, User Stories, Acceptance Criteria, Quality Gates. Fail fast if any is missing.
Hard worktree gate: detect the host's worktree mechanism (Conductor, git worktrees, plain branches) and prompt if working on the default branch. Never skipped.
Spawn a heavy general-purpose decomposer sub-agent (prompt template at references/decomposer-prompt.md) with the spec text, the five criteria, the validation checks, and instructions to produce seed[], curds[], wiring[], and a manifest scaffold.
The decomposer may invoke /culture or /briesearch internally if it needs to ground its decomposition against the codebase or external docs.
Front-load permissions: present the per-host permission manifest (git, the project's quality gate command, the host-specific spawn primitive) to the user. On approval, merge into the host's settings.
Present the full plan:
## 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
Use the shared handoff gate in ../../shared/handoff-gate.md for this approval step. All four options keep cheese-factory running internally (no skill transition) — they use continue: identifiers rather than dispatch: commands per the gate vocabulary:
continue: write-manifest-then-seed: write .cheese/cheese-factory/<slug>/manifest.yaml, set phase: gate_approved, then proceed with Phase 1 (seed execution).continue: ask-for-decomposition-change: ask one targeted question for the requested decomposition change, then re-render the plan.continue: re-run-decomposer: re-run the decomposer with the user's boundary instruction. Retry at most twice.dispatch: none: leave the manifest draft and report its path.Do NOT proceed without explicit approval.
Drop: full spec text, permission manifest, decomposition reasoning. Keep: slug, spec summary (≤2K chars), manifest path, quality gate commands.
Seed items are minimal — only the shared types / protocols that curds cannot compile without. The orchestrator executes seed inline (a deliberate exception to the orchestrator's "never write code" rule because seed is always small).
For each seed item:
/cheez-write when tilth MCP is present; otherwise fall back to the host's native edit tool (per the cheez-* portability rule in README.md). The skill must not hard-fail when /cheez-write is unavailable.just check or equivalent) — if gates fail, STOP./commit (if available) or git commit direct.Push to branch — curds branch from HEAD.
Update manifest:
python3 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz manifest_update set-phase --manifest <path> --phase seed_complete
Spawn ALL curd workers in a single message via the host's fan-out primitive. If more than 5 curds, dispatch in waves of 5.
Each curd worker is a general-purpose sub-agent (full peer of the orchestrator — same model, full tools, full skills, full MCP) given the per-curd prompt at references/curd-prompt.md.
Collect results as curds complete. For failed curds: retry ONCE with error context. Mark retry_count: 1; do not retry twice.
Update manifest: curd statuses, worktree paths, branch names, commit SHAs.
Drop: decomposer artifacts, curd dispatch prompts, curd return summaries. Keep: slug, manifest path, quality gate commands, curd branch list. Read from disk when needed: wiring DAG.
Cherry-pick curd commits onto the orchestrator branch in curd-id order:
For each curd (in order):
git cherry-pick <curd_commit_sha> — or, if the host fan-out used worktrees, merge the worktree branch./melt if available, else fall back to mergiraf → git rerere → manual./melt cannot resolve: STOP, fall back to per-curd PRs in Phase 7.After all curds merged: run quality gates. If failing, STOP and report — curds passed individually but conflict in aggregate (decomposer error).
Compute topological dispatch order from the wiring DAG:
python3 ${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz wiring_topo_sort --manifest <path>
Dispatch wiring tasks in the returned wave order, sequentially within each wave (concurrent commits to the same working directory race on git's index.lock).
Each wiring worker is a general-purpose sub-agent with the prompt template at references/wiring-prompt.md.
For failed wiring tasks: retry ONCE. If still failing, mark incomplete in manifest.
Cherry-pick the wiring commits onto the orchestrator branch.
If conflicts arise here: STOP. Wiring conflicts mean the decomposer's DAG was wrong (wiring touched implementation territory, or two wiring tasks shared a file outside the DAG). Do not auto-resolve.
Drop: wiring DAG details, per-curd diffs, intermediate merger reports. Keep: slug, spec path (for downstream skills), quality gates, list of all changed files, list of all commit SHAs (curds + seed + wiring).
Run the final review pipeline in fresh-context sub-agents.
Three sequential spawns:
/press --auto on the merged diff — writes .cheese/press/<slug>.md./age --auto on the merged diff — writes .cheese/age/<slug>.md./cure --auto --stake medium+ on the age findings — writes .cheese/cure/<slug>.md.Each spawn is a full-peer general-purpose sub-agent. Pass the no-chain-forward directive (same as /ultracook) so each spawn runs its phase only.
Single pass through — no two-cure-pass cap. Curds each had their own press/age/cure; this is integration-level review.
If any phase writes status: halt: <reason> in its slug, surface the halt and STOP. If /cure writes next: done, continue to Phase 7.
Spawn a heavy general-purpose PR planner sub-agent (prompt template at references/pr-planner-prompt.md) with the wiring DAG, the manifest, the merged diff, and the spec summary.
The planner emits one of four shapes:
| Shape | When | PR layout |
|---|---|---|
single | Small total diff, tightly coupled | All commits in one PR. |
orthogonal_flat | Curds touch disjoint slices, no seed/wiring coupling | N PRs each branching from main. |
stacked_linear | Linear dependencies seed → curds → wiring | gt/gh stack. |
diamond_stack | Seed and wiring exist; curds independent of each other | seed PR (base) → N parallel curd PRs → wiring PR. |
The planner writes its grouping to .cheese/cheese-factory/<slug>/pr-plan.yaml and returns control.
Before publishing PRs, the orchestrator detects which skills are available and picks the right delegate:
| Need | Prefer | Fallback |
|---|---|---|
| Stack publish | /pr-stack (Graphite gt or gh stack) | manual gh pr create --base <prev-branch> chain |
| Commits | /commit | git commit direct |
| PR publish | /gh | gh pr create direct |
| Merge conflicts | /melt | mergiraf → rerere → kdiff3 direct |
Detection: attempt to invoke the skill via the host's Skill tool; on unrecognised-skill error, fall back. Cache the result for the rest of the phase.
For each PR group in the plan:
pr-plan.yaml.${CLAUDE_SKILL_DIR}/scripts/cheese-factory.pyz pr_plan_to_branches to convert pr-plan.yaml to branch-creation commands)./gh if available, else gh pr create direct)./pr-stack with the ordered branch list.## 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
At each seam, write a self-summary to the manifest before dropping:
Write phase_summary and carry_forward (shapes in references/manifest-schema.json) before dropping. On --resume, read phase_summary from the manifest — the only cross-seam continuity mechanism; do not rely on conversation history.
The orchestrator never names a specific host primitive. Any primitive satisfying all five invariants is acceptable: (1) Fresh context per spawn, (2) Full-peer inheritance, (3) No chain-forward (passed in prompt), (4) Returns control, (5) Writes handoff slug. Host-by-host examples and the no-fan-out fallback (route to /ultracook) live in references/spawn-primitive-reference.md.
Every phase writes a handoff slug to .cheese/<phase>/<slug>.md (or, for per-curd workers, to .cheese/cheese-factory/<slug>/curds/<curd-id>.md) with the minimum shape:
status: ok | halt: <one-line reason>
next: <phase-name | done>
artifact: <path-to-richer-report-if-any>
<one-line orientation: what this phase did>
For phases that already write rich reports (/age, /press, /cure), the schema is prepended at the top of the same file.
/cheese-factory runs the project's quality gate command (typically just check per AGENTS.md) at four points:
/cure step)./cure.If any gate fails: STOP, report, do not silently fix.
--resume <slug>If the manifest references commits that no longer exist (rebased, deleted), fail fast — do not silently re-execute the phase. Otherwise continue from the phase after the latest one marked complete; report Resuming <slug> from phase <N>.
| Failure | Recovery |
|---|---|
| No spec argument | STOP. Report cheese-factory requires an approved spec; run /mold first if you need to shape one. |
| Overlap / criterion violation in decomposer output | Re-run decomposer (max 2 retries) |
| Seed gate failure | STOP, report — do not dispatch curds |
| Curd fails | Retry once with error context, then mark failed |
| All curds fail | STOP, no merge/wiring |
| Curd merge conflict | /melt; if /melt fails, fall back to per-curd PRs |
| Wiring agent fails | Retry once, mark incomplete if still failing |
| Phase 5 conflicts | STOP — decomposer error, report to user |
Phase 6 /press or /age halt | Surface halt, STOP |
Phase 6 /cure cannot apply any finding | Surface report, STOP |
/pr-stack not available, plan calls for stack | Fall back to manual gh pr create --base chain |
--resume on missing manifest | Fail fast |
Never proceed past Phase 0 gate without explicit user approval. Never claim green on partial work.
Does: reads the spec once at Phase 0; reads per-phase handoff slugs (each ≤2KB); writes manifest updates after each phase; decides chain progression from slug status and next fields — never from sub-agent stdout.
Never:
/age nesting depth: curd workers invoke /age which normally fans out to 6 review sub-agents (level 2, blocked). /cheese-factory requires /age to support an inline-degrade mode for sub-agent invocation — see skills/age/SKILL.md "Inline-degrade mode".git index.lock races even when files differ.git push or gh pr create without explicit Bash allowlist. The orchestrator must handle all push / PR operations./worktree-sweep (or host equivalent) after the pipeline completes.references/decomposer-prompt.md — heavy decomposer sub-agent prompt template.references/curd-prompt.md — per-curd worker prompt template.references/wiring-prompt.md — per-wiring task prompt template.references/pr-planner-prompt.md — PR planner sub-agent prompt template.references/manifest-schema.json — JSON Schema for the manifest.references/pr-plan-schema.json — JSON Schema for the PR plan, $ref'd from manifest-schema.json.references/spawn-primitive-reference.md — host-by-host invocation examples plus the five invariants.cheese-factory.pyz subcommands (run via ${CLAUDE_SKILL_DIR}/scripts/): validate_manifest, validate_decomposition (Phase 0), validate_pr_plan, pr_plan_to_branches (Phase 7), manifest_update (Phase 1/2/4 manifest writes), wiring_topo_sort (Phase 4 wave ordering).subagent_type, do not restrict tools or MCP access.--resume)./gh directly without confirming via the user-approved permission manifest from Phase 0.skills/age/references/voice.md in this repo): lead the final report with what happened, flag residual risk as certain | speculating | don't know, do not manufacture follow-ups.npx claudepluginhub paulnsorensen/easy-cheeseDecomposes large tasks (migrations, multi-issue fixes, big features) into parallel work packages with quality gates. Useful for reducing PR cycle time and avoiding merge conflicts.
Decomposes specs/PRDs/plans into independent tasks, assigns to builder agents for parallel execution in waves respecting dependencies, then integrates results. For fast multi-file feature implementation.
Orchestrates a full build pipeline from PRD: plans tasks, implements in parallel, and reviews results. Routes simple work to a lighter workflow.