Refiner
Apply targeted fixes to the codesmith's output based on structured QA failures. Conservative — patches the listed failures only, doesn't refactor.
When to use
When qa/qa-report.json has passed === false and the orchestrator has not yet hit its 3-iteration cap.
Output contract
Output ONLY a JSON object:
{
"files": [
{ "path": "src/scenes/Game.js", "content": "<full new contents>" }
],
"rationale": "<one short paragraph explaining the fixes>"
}
- Provide full file contents, not patches.
- Don't modify files outside
src/.
- Preserve the GameScene contract (
init, create, scene-ready event, window.__gameState shape).
- If a failure is
console-error: <X>, fix the cause — do not silence the log.
- If
winCondition is unreachable, fix the level OR the code so the QA scenario can complete.
Process
- Read the latest QA report from
qa/qa-report.json.
- Read the GDD + manifest from
game-state.json.
- Read all relevant source files under
src/ (use scripts/collect_files.mjs <dir>).
- Build context: failures, GDD essentials, manifest, current files.
- Produce the JSON.
- Run
scripts/apply_fixes.mjs <project-dir> <fixes-json> — refuses paths outside src/.
- Re-invoke
playtester (orchestrator's job, not yours).
Failure → fix recipe
| Failure kind |
Likely cause |
Fix to consider |
boot-timeout |
scene-ready never emitted, or asset 404 |
Verify events.emit('scene-ready') at end of create(); verify manifest paths |
exception |
Runtime JS error |
Read message; locate file; correct |
console-error |
Asset 404, animation key missing, etc. |
Cross-check manifest |
no-movement (walk-right Δx ≤ 0) |
Player blocked by wall, or input wiring wrong |
Check spawn is on passable tile + body size; check input dispatch |
no-jump (jumpDelta ≤ 0) |
Using isDown instead of JustDown for jump; or no ground beneath spawn |
Switch to JustDown(SPACE); check b.blocked.down |
screenshot-diff (≥ 5%) |
Visual regression OR genuine improvement |
Inspect diff image; if intentional, run with --update-baselines |
low-fps |
Too many objects, missing culling |
Pool projectiles, cull off-screen |
blank-canvas |
Render layer setup wrong |
Confirm tilemap layer created; confirm pixelArt config |
Halt conditions
- 3 iterations reached → halt, surface to user with the persistent failures.
- Refiner output references a file outside
src/ → reject, request resubmit.
- Refiner output references a non-existent animation key → reject, request resubmit.
Persistent debug library
After every successful fix, call scripts/debug_library.mjs --add to record the lesson so future generations don't repeat the same mistake:
node scripts/debug_library.mjs --add "<symptom>" "<cause>" "<one-line fix>" [genre]
# e.g.
node scripts/debug_library.mjs --add \
"Cannot read properties of null (reading 'setVelocity')" \
"body accessed before physics world resolves the sprite" \
"guard all body access with: if (!sprite.body) return;" \
"any"
The library lives at ~/.game-creation-agent/debug-library.json. The codesmith reads the top entries on each generation to pre-empt known bugs. View library: node scripts/debug_library.mjs --list.
Scripts
scripts/collect_files.mjs <project-dir> — emits all .js/.mjs under src/ with contents.
scripts/apply_fixes.mjs <project-dir> <fixes-json> — safety-checked file writer.
scripts/debug_library.mjs --add <symptom> <cause> <fix> [genre] — record a fix.
scripts/debug_library.mjs --list — view all entries sorted by hit count.
References
references/failure-taxonomy.md — the canonical list of failure kinds and recipes.
1---2name: refiner3description: Reads a structured QA failure report and the current source files, emits replacement file contents that fix the listed failures. Bounded — at most 3 iterations per generation pipeline. Use after playtester reports failures.4---56# Refiner78Apply targeted fixes to the codesmith's output based on structured QA failures. Conservative — patches the listed failures only, doesn't refactor.910## When to use1112When `qa/qa-report.json` has `passed === false` and the orchestrator has not yet hit its 3-iteration cap.1314## Output contract1516Output ONLY a JSON object:1718```jsonc19{20 "files": [21 { "path": "src/scenes/Game.js", "content": "<full new contents>" }22 ],23 "rationale": "<one short paragraph explaining the fixes>"24}25```2627- Provide **full file contents**, not patches.28- Don't modify files outside `src/`.29- Preserve the GameScene contract (`init`, `create`, `scene-ready` event, `window.__gameState` shape).30- If a failure is `console-error: <X>`, fix the cause — do not silence the log.31- If `winCondition` is unreachable, fix the level OR the code so the QA scenario can complete.3233## Process34351. Read the latest QA report from `qa/qa-report.json`.362. Read the GDD + manifest from `game-state.json`.373. Read all relevant source files under `src/` (use `scripts/collect_files.mjs <dir>`).384. Build context: failures, GDD essentials, manifest, current files.395. Produce the JSON.406. Run `scripts/apply_fixes.mjs <project-dir> <fixes-json>` — refuses paths outside `src/`.417. Re-invoke `playtester` (orchestrator's job, not yours).4243## Failure → fix recipe4445| Failure kind | Likely cause | Fix to consider |46|---|---|---|47| `boot-timeout` | `scene-ready` never emitted, or asset 404 | Verify `events.emit('scene-ready')` at end of `create()`; verify manifest paths |48| `exception` | Runtime JS error | Read message; locate file; correct |49| `console-error` | Asset 404, animation key missing, etc. | Cross-check manifest |50| `no-movement` (walk-right Δx ≤ 0) | Player blocked by wall, or input wiring wrong | Check spawn is on passable tile + body size; check input dispatch |51| `no-jump` (jumpDelta ≤ 0) | Using `isDown` instead of `JustDown` for jump; or no ground beneath spawn | Switch to `JustDown(SPACE)`; check `b.blocked.down` |52| `screenshot-diff` (≥ 5%) | Visual regression OR genuine improvement | Inspect diff image; if intentional, run with `--update-baselines` |53| `low-fps` | Too many objects, missing culling | Pool projectiles, cull off-screen |54| `blank-canvas` | Render layer setup wrong | Confirm tilemap layer created; confirm pixelArt config |5556## Halt conditions5758- 3 iterations reached → halt, surface to user with the persistent failures.59- Refiner output references a file outside `src/` → reject, request resubmit.60- Refiner output references a non-existent animation key → reject, request resubmit.6162## Persistent debug library6364After every successful fix, call `scripts/debug_library.mjs --add` to record the lesson so future generations don't repeat the same mistake:6566```bash67node scripts/debug_library.mjs --add "<symptom>" "<cause>" "<one-line fix>" [genre]68# e.g.69node scripts/debug_library.mjs --add \70 "Cannot read properties of null (reading 'setVelocity')" \71 "body accessed before physics world resolves the sprite" \72 "guard all body access with: if (!sprite.body) return;" \73 "any"74```7576The library lives at `~/.game-creation-agent/debug-library.json`. The codesmith reads the top entries on each generation to pre-empt known bugs. View library: `node scripts/debug_library.mjs --list`.7778## Scripts7980- `scripts/collect_files.mjs <project-dir>` — emits all `.js`/`.mjs` under `src/` with contents.81- `scripts/apply_fixes.mjs <project-dir> <fixes-json>` — safety-checked file writer.82- `scripts/debug_library.mjs --add <symptom> <cause> <fix> [genre]` — record a fix.83- `scripts/debug_library.mjs --list` — view all entries sorted by hit count.8485## References8687- `references/failure-taxonomy.md` — the canonical list of failure kinds and recipes.