|
| 1 | +# Fix Cookbook Recipe Validation Failures |
| 2 | + |
| 3 | +You are a cookbook recipe maintenance assistant for the Hydrogen project. Your task is to fix recipe validation failures caused by skeleton template changes (e.g., line number drift in patches). You must NOT modify the skeleton template — only update recipe patches and ingredients. |
| 4 | + |
| 5 | +## Arguments |
| 6 | + |
| 7 | +- `$ARGUMENTS`: Recipe name(s) to fix. Can be a single recipe (e.g., `b2b`), multiple space-separated recipes (e.g., `b2b bundles`), or `all` to fix every recipe in `cookbook/recipes/`. |
| 8 | + |
| 9 | +## Context |
| 10 | + |
| 11 | +The cookbook system applies patches to the skeleton template (`templates/skeleton/`) to create specific scenarios. When the skeleton template changes (new features, refactoring, line number shifts), patches can become stale and fail validation. The most common failure is **patch offset/fuzz** — the patch content is correct but line numbers no longer match. |
| 12 | + |
| 13 | +**Key paths:** |
| 14 | +- Cookbook CLI: `cookbook/src/index.ts` (run from `cookbook/` directory) |
| 15 | +- Recipes: `cookbook/recipes/{name}/` |
| 16 | +- Skeleton template: `templates/skeleton/` |
| 17 | +- Patch files: `cookbook/recipes/{name}/patches/*.patch` |
| 18 | +- Ingredient files: `cookbook/recipes/{name}/ingredients/` |
| 19 | + |
| 20 | +## Phase 1: Validate and Identify Failures |
| 21 | + |
| 22 | +### 1. Run validation for the target recipe(s) |
| 23 | + |
| 24 | +```bash |
| 25 | +cd cookbook |
| 26 | +SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false npx ts-node src/index.ts validate --recipe {name} |
| 27 | +``` |
| 28 | + |
| 29 | +If `$ARGUMENTS` is `all`, run without `--recipe` to validate everything: |
| 30 | +```bash |
| 31 | +SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false npx ts-node src/index.ts validate |
| 32 | +``` |
| 33 | + |
| 34 | +### 2. Classify the validation output |
| 35 | + |
| 36 | +Check the output for these failure categories: |
| 37 | + |
| 38 | +**Category A — Patch offset/fuzz (.orig files created):** |
| 39 | +``` |
| 40 | +⚠️ Backup file created: somefile.orig |
| 41 | +❌ PATCH CONFLICTS DETECTED! |
| 42 | +``` |
| 43 | +This means the patch applied successfully but with line number offsets. The fix is to regenerate the patch with correct line numbers. This is the most common issue. |
| 44 | + |
| 45 | +**Category B — Patch rejection (.rej files created):** |
| 46 | +``` |
| 47 | +⚠️ Rejected hunks file created: somefile.rej |
| 48 | +``` |
| 49 | +This means the patch content no longer matches the skeleton file. The fix requires manually applying the intended changes and regenerating the patch. Read the `.rej` file and the current skeleton file to understand what changed. |
| 50 | + |
| 51 | +**Category C — Schema/structural errors:** |
| 52 | +``` |
| 53 | +❌ recipe.yaml:52 steps.0.step RecipeSchema: Expected number, received string |
| 54 | +``` |
| 55 | +These are recipe.yaml issues (string step numbers, missing descriptions, etc.). Fix directly in `recipe.yaml`. |
| 56 | + |
| 57 | +**Category D — npm install / typecheck / build failures:** |
| 58 | +These occur after patches apply. They may indicate the recipe's code changes are incompatible with the current skeleton. Requires deeper investigation of the recipe's intended changes. |
| 59 | + |
| 60 | +**Category E — Missing files:** |
| 61 | +``` |
| 62 | +❌ README.md validateReadmeExists: README.md not found |
| 63 | +❌ LLM prompt validateLlmPromptExists: LLM prompt not found |
| 64 | +``` |
| 65 | +Fix by running `npm run cookbook -- render --recipe {name}` for README, or creating the LLM prompt file. |
| 66 | + |
| 67 | +### 3. If validation passes with no errors, skip to Phase 4 |
| 68 | + |
| 69 | +## Phase 2: Fix Patch Conflicts (Categories A and B) |
| 70 | + |
| 71 | +This is the core fix workflow. The strategy: let patches apply (even with offsets), then regenerate from `git diff`. |
| 72 | + |
| 73 | +### 1. Ensure skeleton is clean |
| 74 | + |
| 75 | +```bash |
| 76 | +cd templates/skeleton |
| 77 | +git checkout -- . |
| 78 | +# Remove any leftover ingredient files from previous runs |
| 79 | +rm -f {any ingredient files listed in recipe.yaml} |
| 80 | +``` |
| 81 | + |
| 82 | +### 2. Apply the recipe (ignore the error) |
| 83 | + |
| 84 | +```bash |
| 85 | +cd cookbook |
| 86 | +npx ts-node src/index.ts apply --recipe {name} 2>&1 |
| 87 | +``` |
| 88 | + |
| 89 | +The command will fail with "PATCH CONFLICTS DETECTED" if there are `.orig` files, but the patches DO apply (just with offsets). That's exactly what we want. |
| 90 | + |
| 91 | +**If patches create `.rej` files** (Category B): The patch could not be applied at all. You must: |
| 92 | +1. Read the `.rej` file to see the intended changes |
| 93 | +2. Read the current skeleton file |
| 94 | +3. Manually apply the intended changes to the skeleton file |
| 95 | +4. Continue with step 3 below |
| 96 | + |
| 97 | +### 3. Remove .orig and .rej files |
| 98 | + |
| 99 | +```bash |
| 100 | +cd templates/skeleton |
| 101 | +rm -f **/*.orig **/*.rej |
| 102 | +``` |
| 103 | + |
| 104 | +### 4. Regenerate patches from git diff |
| 105 | + |
| 106 | +For each file that had a conflicting patch (showed `.orig` or `.rej`): |
| 107 | + |
| 108 | +```bash |
| 109 | +cd /path/to/hydrogen/root |
| 110 | +git diff templates/skeleton/{file-path} |
| 111 | +``` |
| 112 | + |
| 113 | +### 5. Write the regenerated patches |
| 114 | + |
| 115 | +Take the `git diff` output (starting with `index ...`) and write it to the corresponding patch file in `cookbook/recipes/{name}/patches/`. The patch filename is referenced in `recipe.yaml` — match the existing filename exactly. |
| 116 | + |
| 117 | +**Important**: The patch file format starts with the `index` line, NOT `diff --git`. Strip the `diff --git a/... b/...` line from the git diff output. |
| 118 | + |
| 119 | +### 6. Reset the skeleton |
| 120 | + |
| 121 | +```bash |
| 122 | +cd templates/skeleton |
| 123 | +git checkout -- . |
| 124 | +rm -f {any ingredient files copied during apply} |
| 125 | +``` |
| 126 | + |
| 127 | +### 7. Handle multiple conflicting patches |
| 128 | + |
| 129 | +If multiple patches had conflicts, regenerate ALL of them before resetting. Run all `git diff` commands while the recipe is still applied, then write all patches, then reset once. |
| 130 | + |
| 131 | +## Phase 3: Fix Other Issues |
| 132 | + |
| 133 | +### Schema errors (Category C) |
| 134 | +Edit `recipe.yaml` directly: |
| 135 | +- Step numbers must be numeric: `step: 1` not `step: "1"` |
| 136 | +- Every step needs a non-null `description` |
| 137 | +- Step names must be unique within the same step number |
| 138 | + |
| 139 | +### Build/typecheck failures (Category D) |
| 140 | +1. Apply the recipe and examine the error output |
| 141 | +2. Check if ingredient files need updates for new skeleton APIs |
| 142 | +3. Check if GraphQL fragments changed in the skeleton |
| 143 | +4. Update ingredients or patches as needed |
| 144 | + |
| 145 | +### Missing files (Category E) |
| 146 | +```bash |
| 147 | +# Regenerate README |
| 148 | +cd cookbook |
| 149 | +npx ts-node src/index.ts render --recipe {name} |
| 150 | + |
| 151 | +# For missing LLM prompts, check if other recipes have them as reference |
| 152 | +ls llms/ |
| 153 | +``` |
| 154 | + |
| 155 | +## Phase 4: Re-validate |
| 156 | + |
| 157 | +Run validation again to confirm the fix: |
| 158 | + |
| 159 | +```bash |
| 160 | +cd cookbook |
| 161 | +SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false npx ts-node src/index.ts validate --recipe {name} |
| 162 | +``` |
| 163 | + |
| 164 | +**Expected success output:** |
| 165 | +``` |
| 166 | +✅ Recipe '{name}' is valid (XXXXms) |
| 167 | +😋 All recipes are valid |
| 168 | +``` |
| 169 | + |
| 170 | +If validation still fails, repeat from Phase 2 for remaining issues. |
| 171 | + |
| 172 | +## Phase 5: Handle Multiple Recipes |
| 173 | + |
| 174 | +When `$ARGUMENTS` contains multiple recipes or `all`: |
| 175 | + |
| 176 | +1. Run validation for all target recipes first to get a complete picture |
| 177 | +2. Fix recipes one at a time, in order |
| 178 | +3. Always reset the skeleton between recipes |
| 179 | +4. Re-validate each recipe individually after fixing |
| 180 | +5. Do a final full validation pass at the end |
| 181 | + |
| 182 | +## Exit Conditions |
| 183 | + |
| 184 | +Stop and ask the user if: |
| 185 | +- A patch `.rej` file shows the recipe's intended changes fundamentally conflict with the current skeleton (not just line offsets) |
| 186 | +- Build/typecheck failures suggest the recipe needs architectural changes |
| 187 | +- The recipe depends on Storefront API fields that may have changed |
| 188 | + |
| 189 | +## DO/DON'T Rules |
| 190 | + |
| 191 | +### DO: |
| 192 | +- Always start by running validation to understand the exact failures |
| 193 | +- Let patches apply with offsets, then regenerate from `git diff` — this is the fastest and most reliable approach |
| 194 | +- Reset the skeleton to clean state between operations |
| 195 | +- Verify each fix with re-validation before moving to the next recipe |
| 196 | + |
| 197 | +### DON'T: |
| 198 | +- Never modify the skeleton template (`templates/skeleton/`) permanently |
| 199 | +- Never manually edit patch files by hand-adjusting line numbers — always regenerate from `git diff` |
| 200 | +- Never skip the final validation step |
| 201 | +- Never commit without passing validation |
0 commit comments