# Session 3 — Pipeline d'assets **Date :** 2026-07-27 · **Livrable :** deux pipelines, un par filière. ## Porte de sortie | Critère | Cible | Mesuré | |---|---|---| | Assets non validés dans le build | 0 | **0** — le pipeline refuse les 39 médias non validés ✅ | | Assets de filière B dans une épreuve | 0 | refusé par `validate:data`, prouvé par `test:porte` ✅ | | Reproductibilité des seeds | deux exécutions identiques | **vérifié avec `PYTHONHASHSEED` différent** ✅ | | Poids par image | ≤ 200 Ko | AVIF 1200 px à **106 Ko**, 800 px à **79 Ko**, 480 px à **36 Ko** ✅ | | Appels réseau au runtime | 0 | les médias sont rapatriés au build, jamais chargés depuis Commons ✅ | | Compositing sur média SA ou NC | 0 | refusé par `validate:data` ✅ | ## Filière A — `npm run fetch:medias` Rapatrie les photographies **validées** depuis Commons, les encode en AVIF et WebP à trois largeurs (480, 800, 1200), et inscrit `fichier_local` dans les données. Deux raisons de ne pas pointer vers les URLs de Commons dans le jeu : le projet s'interdit toute requête tierce au runtime, et un jeu qui doit fonctionner hors ligne ne peut pas dépendre d'un serveur distant. Le script **ne télécharge que ce qui est validé**. Aujourd'hui : 0 traité, 39 ignorés. Le pipeline ne contourne pas la porte, il la respecte. Vérifié sur une copie de travail, sans toucher aux données réelles : source de 256 Ko → 106 Ko en AVIF 1200 px, 36 Ko en 480 px. La qualité baisse d'un cran tant que le budget de 200 Ko est dépassé. ImageMagick est une dépendance **système**, pas un paquet npm : l'outil existe sur la machine de build et n'a rien à faire dans le bundle. ## Filière B — `tools/assets/comfyui_client.py` Client ComfyUI en bibliothèque standard seule, hors bundle, avec son `requirements.txt`. **Les trois défauts du pack d'origine sont corrigés**, et le premier est le plus grave : le pack calculait ses seeds avec `hash()`, randomisé à chaque exécution depuis Python 3.3, tout en vendant l'argument « même seed = même style ». Ses seeds ne l'étaient pas. Remplacé par `zlib.crc32`. Prouvé empiriquement : deux processus lancés avec des `PYTHONHASHSEED` différents produisent exactement les mêmes valeurs. `copy.deepcopy` remplace `json.loads(json.dumps(...))`. Et `rembg` reste commenté dans `requirements.txt` avec l'avertissement qui manquait : le paquet est sous MIT, **les poids du modèle ne le sont pas nécessairement**. ## Ce qui reste Le plan d'assets et les workflows ComfyUI ne sont pas écrits : ils dépendent de choix graphiques qui appartiennent au porteur, et générer du décor avant d'avoir un jeu jouable serait mettre la charrue avant les bœufs. --- ## Addendum — pipeline confronté au ComfyUI réel Le porteur a ouvert l'accès à son instance (`127.0.0.1:8188`, ComfyUI 0.27.1, deux GPU AMD). Le pipeline a donc été exécuté pour de vrai, pas simulé. ### Reproductibilité prouvée — après correction d'un test qui ne prouvait rien **Images bit-identiques**, `sha256 b7007a7a1088cb359a06ddaaff358e92…`, sur deux exécutions séparées par un **vidage du cache**. Workflow de référence : `workflows/decor-sdxl.json` (SDXL 1.0, 1024×576, 20 pas, dpmpp_2m/karras). Le mot « après vidage du cache » est tout le sujet, et il a failli manquer. Ma première vérification lançait simplement le même plan deux fois et comparait les empreintes. Le porteur ayant indiqué où ComfyUI écrit ses images, le dossier de sortie a pu être inspecté : **un seul fichier y figurait** alors que deux exécutions avaient été lancées. ComfyUI met en cache le résultat d'un graphe identique. Ma « deuxième exécution » n'avait donc rien recalculé — elle avait relu la première. Comparer deux empreintes dans ces conditions ne mesure que le bon fonctionnement du cache. Après `POST /free`, une exécution authentique a produit `decor_00002_.png`, bit-identique au premier. **La conclusion était juste ; la méthode ne l'était pas.** Le test est désormais un mode de l'outil, pas une manipulation à la main : ```bash python3 comfyui_client.py --workflow workflows/decor-sdxl.json \ --plan plan-assets.json --reproductibilite ``` Il génère, vide le cache, régénère et compare. Un test de reproductibilité qui ne vide pas le cache est un test qui se ment à lui-même. ### Deux défauts de mon propre client, révélés par le réel 1. **Le prompt négatif était concaténé au prompt positif** — travers hérité du pack. Sur SDXL, cela revient à demander au modèle de produire ce qu'on voulait exclure. Il a désormais son propre nœud. 2. **Les images n'étaient pas rapatriées.** Elles restaient dans le dossier de sortie de ComfyUI, et le manifeste référençait des chemins inexistants. Ajout de `recuperer()` via `/view`. Un pipeline qu'on n'exécute pas est un pipeline qu'on croit correct. ### Krea 2 — disponible, mais trois questions à trancher Deux choses portent ce nom sur la machine, et elles n'ont rien à voir : | | ce que c'est | état | |---|---|---| | `krea2_turbo_nvfp4.safetensors` | poids locaux, chargés par `UNETLoader` | **nvfp4 = format FP4 NVIDIA Blackwell**, sur deux GPU AMD : très probablement inexploitable | | `Krea2ImageNode` | nœud `api_node: True`, catégorie `partner/image/Krea` | **appel à un service tiers payant** | Le workflow transmis est au format *interface* (`nodes`, `links`, `widgets_values`) et non au format API que consomme `/prompt`. Sa conversion bute sur le champ `model`, de type `COMFY_DYNAMICCOMBO_V3`, dont la forme sérialisée ne se devine pas sans risque. **Trois points à trancher par le porteur** avant de câbler Krea 2 : 1. **Export au format API.** Dans ComfyUI : menu → *Save (API Format)*. C'est le seul format que `/prompt` accepte, et il lève toute incertitude sur le champ `model`. 2. **Doctrine.** `Krea2ImageNode` envoie les prompts à un serveur tiers. C'est toléré parce que la génération a lieu **au build**, jamais au runtime (playbook P2) — mais c'est un écart au « zéro service tiers » qui mérite d'être inscrit, pas subi. 3. **Licence des sorties.** Les conditions d'utilisation de Krea déterminent ce qu'on a le droit de faire des images produites. Tant qu'elles ne sont pas vérifiées, ces images ne peuvent pas être publiées sous CC BY-SA 4.0 avec le reste du contenu (ADR 0001). En attendant, SDXL 1.0 en local reste le workflow par défaut : aucun coût, aucune donnée qui sort de la machine, et une reproductibilité démontrée. ### Réserve sur le rendu Le fond produit est graphiquement juste — aplats, angles nets, aucun texte, aucun visage — mais sa palette tire vers l'orange-rouge, plus chaude que la charte OKI (noir profond, or, vert, rouge en ponctuation). À reprendre en session 6 si ces fonds sont retenus.