{ "intent": "Run the diffusion route on the 3090, wire the Blender 3D cell, and complete vector coverage to twelve subjects - then report what the four routes actually measure against each other.", "scope": [ "python_pkg/artgate/contrast.py - new check_margin gate", "python_pkg/artgate/routes/{vector_shapes,blender,blender_scene}.py - 7 more vector subjects, 3D route", "python_pkg/artgate/{cli,codes,spec}.py - margin gate wired, evaluate() refactored to a gate table", "python_pkg/artgate/routes/{shapes,vector_shapes}.py - sword/meat shape fixes for edge clipping", "python_pkg/artgate/tests/test_blender.py + margin tests - 22 new tests", "NON-GOAL: no route declared the winner; that needs the human verdicts" ], "changes": [ "THE FINDING OF THIS PHASE: all twelve diffusion icons measured 100% opaque coverage - square tiles with no sprite silhouette - and passed every gate. Gate-pass was measuring hygiene, not usability. Added MARGIN_TOO_SMALL, which inverted the table from a meaningless 12/12/12 tie to diffusion 0/12, vector 10/12, procedural 11/12.", "The two non-diffusion failures were true positives in MY shapes, not gate error: the procedural sword pommel ran off the bottom edge and the vector meat bone clipped the top. Fixed the shapes; both routes returned to 12/12.", "Blender exits 0 even when its embedded script raises - measured, not assumed: a wrong render-engine enum (BLENDER_EEVEE_NEXT does not exist in 5.2) produced a clean exit and no file. render() now asserts the output exists, or the route would report phantom successes.", "Model gating checked at execution time, not from memory: SDXL base and nerijs/pixel-art-xl are ungated (HTTP 200, gated=False), FLUX.1-dev is gated=auto, and runwayml/stable-diffusion-v1-5 now 307-redirects - which is exactly why the plan forbids recalling gating status.", "evaluate() became an ordered gate table rather than an if-chain, keeping the load-bearing alpha-before-colour ordering explicit.", "routes/__init__.py imports vector_shapes so all_shapes() cannot silently return a partial registry depending on import order." ], "verification": [ { "command": "GPU + diffusers smoke test in the uv 3.12 venv", "result": "pass", "evidence": "torch 2.11.0+cu128, diffusers 0.39.0, transformers 5.15.0, cuda True, RTX 3090, 22.1 GiB free." }, { "command": "generate 12 subjects with SDXL + pixel-art LoRA, gate raw then finished", "result": "pass", "evidence": "RAW 1024px: 0/12 (CANVAS_SIZE, TOO_MANY_COLORS). After finishing: 12/12 on the pre-margin gate stack. After adding MARGIN_TOO_SMALL: 0/12, because every output was fully opaque." }, { "command": "measure opaque coverage across routes", "result": "pass", "evidence": "diffusion mean 100% (12/12 fully opaque, no transparency at all); vector mean 35% (min 18%, max 47%, 0/12 fully opaque). This is the quantified reason diffusion output is not usable as an item sprite." }, { "command": "diffusion + flood-fill background removal, re-gated", "result": "pass", "evidence": "12/12 machine-pass, so the route IS recoverable - but visual inspection shows the fill eats into the subjects (bone reduced to a fragment, sword nearly erased). Reported as inadequate; a real matting step is needed." }, { "command": "headless Blender render of 5 subjects, gate raw then finished", "result": "pass", "evidence": "RAW: 0/5 (CANVAS_SIZE, ALPHA_NOT_BINARY, TOO_MANY_COLORS). After the same finishing stage: 5/5. The finisher now generalises across three different continuous-tone sources." }, { "command": "python -m pytest python_pkg/artgate/tests/ --cov --cov-branch; pre-commit run", "result": "pass", "evidence": "114 tests, 100% branch coverage on all 13 modules, zero suppressions, ALL HOOKS PASS." } ], "risks": [ "The flood-fill background removal is a demonstration, not a solution - it damages the art. Do not treat diffusion's recovered 12/12 as a usable pipeline until proper matting exists.", "The 3D cell covers 5 of 12 subjects and its materials render washed out; its contact-sheet row is visibly the weakest and should not be read as a fair 3D result.", "A local pytest run masked a missing branch (spec.py:233) that the pre-commit hook caught. The hook's run is authoritative; a green local run is not sufficient evidence.", "All four routes now sit at or near 12/12 on the machine gate again, which continues to mean 'not malformed'. The decision table still needs the human accept column before any route can be called the winner." ], "rollback": [ "Revert this commit; the Phase 3 harness and routes at 691a228 stand alone. The margin gate is the only change that alters existing verdicts, and removing it restores the previous (misleadingly permissive) results.", "After rollback, re-run the full suite and confirm 100% branch coverage, then re-gate the stored route outputs to confirm the expected pre-margin numbers return." ] }