feat(session-3): pipelines d'assets, un par filière

Filière A — fetch:medias rapatrie les photographies VALIDÉES depuis
Commons et les encode en AVIF/WebP à 480, 800 et 1200 px. Aujourd'hui :
0 traité, 39 ignorés — le pipeline respecte la porte de validation au
lieu de la contourner. Vérifié sur une copie : source de 256 Ko → 106 Ko
en AVIF 1200 px, 36 Ko en 480 px, budget de 200 Ko tenu.
ImageMagick est une dépendance système, pas un paquet npm.

Filière B — client ComfyUI en bibliothèque standard seule, hors bundle.
Les trois défauts du pack d'origine sont corrigés :
- hash() est randomisé par exécution depuis Python 3.3, donc les seeds
  du pack n'étaient PAS reproductibles malgré son argumentaire. Remplacé
  par zlib.crc32 et prouvé empiriquement — deux processus avec des
  PYTHONHASHSEED différents donnent les mêmes valeurs.
- copy.deepcopy au lieu de json.loads(json.dumps(...)).
- rembg reste commenté avec l'avertissement qui manquait : le paquet est
  MIT, les poids du modèle ne le sont pas nécessairement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
OKI
2026-07-27 11:56:25 -04:00
co-authored by Claude Opus 5
parent dadcbdbcbb
commit ebb05796c9
6 changed files with 509 additions and 1 deletions
+82
View File
@@ -0,0 +1,82 @@
# Pipeline d'assets — filière B (décor)
> **Filière B uniquement.** Rien de ce qui sort d'ici ne peut servir à identifier une
> espèce. Fonds, sprites du mode arcade, badges, écrans de titre, iconographie — jamais
> une épreuve, jamais un indice (ADR 0004).
>
> La séparation n'est pas une consigne : `npm run validate:data` fait échouer le build si
> un média de filière B porte un usage identifiant, et `npm run test:porte` le prouve.
## Pourquoi cette séparation existe
Les modèles de diffusion connaissent mal le corossol, à peine la quenette, presque pas le
zikak. Sur ces espèces, ils ne refusent pas : ils produisent un fruit **plausible et faux**.
Un enfant qui apprend dessus apprend l'hallucination d'un modèle.
Le décor, lui, n'a rien à enseigner. C'est là que la génération a sa place.
## Utilisation
```bash
# Vérifier que les seeds sont bien déterministes (aucun serveur requis)
python3 comfyui_client.py --verifier
# Calculer les seeds d'un plan sans rien générer
python3 comfyui_client.py --workflow workflows/decor.json --plan plan-assets.json --sec
# Générer, ComfyUI devant tourner en local
python3 comfyui_client.py --workflow workflows/decor.json --plan plan-assets.json
```
Aucune dépendance n'est nécessaire : le client n'utilise que la bibliothèque standard.
## Les trois défauts du pack d'origine, corrigés
### 1. Les seeds n'étaient pas reproductibles
Le pack faisait `hash(fruit["id"] + asset_type) % 2**32` en vendant l'argument « même seed
= même style ». Or `hash()` sur une chaîne est **randomisé à chaque exécution** depuis
Python 3.3 (`PYTHONHASHSEED`) : les seeds changeaient d'un lancement à l'autre, exactement
l'inverse de ce qui était annoncé.
Remplacé par `zlib.crc32(clé.encode()) & 0xFFFFFFFF`. Vérifié empiriquement — deux
processus avec des `PYTHONHASHSEED` différents produisent les mêmes valeurs :
```
kowosol:fond 1368899280
zikak:sprite 4184016363
mansiniye:badge 1009059342
lakou:titre 4201979101
```
### 2. `json.loads(json.dumps(x))` pour copier
Remplacé par `copy.deepcopy(x)` : même effet, sans aller-retour par une sérialisation qui
écrase les types non JSON.
### 3. La licence de `rembg` n'était pas vérifiée
Le paquet est sous MIT, mais **les poids** du modèle qu'il télécharge ne suivent pas
nécessairement cette licence. `requirements.txt` porte l'avertissement, et `rembg` reste
commenté : à n'installer qu'après vérification des poids, pas du paquet.
## Format du plan
```json
{
"noeud_seed": "4",
"noeud_prompt": "6",
"assets": [
{ "id": "lakou", "type": "fond", "prompt": "jaden créole au petit matin, …" }
]
}
```
La clé de seed est `<id>:<type>`. Elle ne doit jamais changer une fois un asset retenu :
c'est elle qui garantit qu'une régénération donne la même image.
## Ce que le pipeline ne fait pas
Il ne valide rien. Tout asset sort en `valide: false` et le reste jusqu'à ce qu'un humain
tranche — comme pour les photographies. La différence est qu'un asset de filière B, même
validé, ne pourra jamais porter une épreuve.