| name | refiner |
| description | 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. |
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]
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.