# MANIFEST des figures README

Provenance des images de `assets/readme/` (EPIC #5654, source 1 = extraction d'outputs de notebooks).

> **Audit vision po-2025 c.473 (2026-07-14, doctrine #5780)** : les 6 PNG ci-dessous ont été ouverts un par un via l'outil `Read` et comparés à leur alt-text. Verdict par figure dans le champ *Contenu réel vérifié*. Cohérence caption ↔ image = 2/6 exacte, **4 corrections d'alt-text appliquées** (app2 «coloration CP-SAT + 101 sommets» sur-vendait vs réel «sans coloration» + 16 départements Île-de-France ; app3 «infirmières» → titre dit «infirmiers» ; app11 «Picross/nonogramme» vs titre «Puzzle Losange» ; app19 «héros marqué» absent du visuel). 3 dettes de nommage déjà disclosed conservées (compatibilité EPIC #5654).

**Migration c.780 (2026-07-22, doctrine #5780, asset-side enforcement)** : ajout du champ canonique `Description visuelle` aux 6 entrées (format vague-1 → 3-champs canonique Source / Description visuelle / Alt-text / Poids / Contenu réel vérifié / Note). Source = vision-QA MiniMax M3 (`Read` direct des 6 PNG via po-2024, mandat 2026-07-11) + stats RGB PIL (mean/std par canal, échantillonnage 2000 pixels random seed 42). Conformité avec le détecteur `scripts/notebook_tools/detect_manifest_field.py` (PR #7819 c.754). Le champ `Contenu réel vérifié` (audit c.473 po-2025) reste en place comme preuve falsifiable détaillée ; le nouveau `Description visuelle` est la version canonique courte destinée à l'extraction automatique et au lecteur rapide. **6/6 figures conformes au détecteur post-migration.**

## app1-nqueens-board.png

- **Source** : notebook `CSP/App-1-NQueens.ipynb` (cellule 6, output 0)
- **Description visuelle** : Échiquier 8×8 (522×549, fond damier brun clair `#D2A77A` / cream `#FCE5C9`) titré « Solution connue des 8-Reines ». Axes : X « Colonne » 0-7, Y « Ligne » 0-7 (labels en gras). **8 icônes couronne ♛** unicode 265B noire pleine, une par ligne exactement, à colonnes distinctes : ligne 0 col 0, ligne 1 col 6, ligne 2 col 4, ligne 3 col 7, ligne 4 col 1, ligne 5 col 3, ligne 6 col 5, ligne 7 col 2. Stats RGB PIL : moyenne (**214.04, 187.71, 159.55**), std (42.30, 53.76, 62.58) — **R mean > G mean > B mean tell discriminant** du damier brun (palette warm beige distincte du fond blanc dominant typique des autres figures Search/Apps). Une reine par ligne + colonnes toutes distinctes = condition nécessaire du CSP, **non suffisante** (la validité diagonale n'est pas attestable par lecture directe sans superposition) — le titre « Solution connue » sous-entend une solution valide (la cellule code du notebook `App-1-NQueens.ipynb` cell 6 la construit).
- **Alt-text (FR)** : Échiquier 8×8 avec une solution connue des 8-Reines : aucune paire de reines ne se menace (alignement, diagonale, anti-diagonale).
- **Contenu réel vérifié** : Échiquier 8×8 titré « Solution connue des 8-Reines » avec cases alternées brun clair/cream en damier. Une reine par ligne (icône couronne ♛) à des colonnes distinctes. **Alt-text cohérent avec l'image** (la configuration représentée doit vérifier la contrainte 8-Reines ; le titre «solution connue» sous-entend une démo de placement valide).
- **Poids** : 17.7 KB (PIL optimisé)

## app2-graphcoloring-map.png

- **Source** : notebook `CSP/App-2-GraphColoring.ipynb` (cellule 9, output 0)
- **Description visuelle** : Graphe `networkx` (1000×712, fond blanc quasi-pur) titré « **Graphe des departements francais (sans coloration)** » en gras centré. **18 nœuds circulaires cyan clair** (style `matplotlib.patches.Circle` couleur pastel uniforme `#ADD8E6`-ish) étiquetés en noir (texte centré sur chaque nœud), disposés sans grille régulière : Paris (haut-centre), Somme (haut-gauche), Val-d'Oise (milieu-haut-gauche), Aisne (haut-droit), Nord (extrème-droite), Val-de-Marne (milieu-gauche), Yvelines (centre), Hauts-de-Seine (à droite de Yvelines), Marne (gauche), Oise (centre-bas), Loiret (centre-droit), Seine-Saint-Denis (bas-gauche), Seine-et-Marne (bas-centre), Yonne (droite), Essonne (bas-gauche, doublon avec Essonne), Eure (bas-centre), Aube (bas-centre-droit), Loir-et-Cher (bas-droite). **Arêtes grises droites** (style `Line2D` thin) reliant les nœuds par frontière géographique partagée, sans orientation. **AUCUNE coloration différente sur les nœuds** (tous cyan uniforme, conforme au titre «sans coloration»). Stats RGB PIL : moyenne (**249.53, 250.44, 250.74**), std (23.79, 21.50, 21.09) — **mean R/G/B > 249 + std faible ~21-24** tell discriminant typique des **graphes académiques sur blanc** (nœuds minoritaires en surface, fond blanc quasi-pur dominant ; conforme au pattern c.477 sc-arrow et c.778 ICT-Series). Noter que le fond n'est pas exactement blanc pur (std non nulle sur R/G/B) à cause des arêtes grises transversales. Le PNG capture l'entrée du problème avant CP-SAT, pas sa solution.
- **Alt-text (FR)** *(corrigé c.473)* : Graphe d'adjacence des départements français d'Île-de-France — visibles sur le PNG : Paris, Somme, Aisne, Nord, Val-d'Oise, Val-de-Marne, Yvelines, Hauts-de-Seine, Marne, Oise, Loiret, Yonne, Essonne, Seine-Saint-Denis, Seine-et-Marne, Eure, Aube, Loir-et-Cher (~16 départements + leurs départements limitrophes non-Île-de-France), arêtes par frontière partagée, **rendu NON coloré** (tous les nœuds en cyan uniforme — le titre intégré à la figure annonce explicitement « (sans coloration) »). Le notebook démontre ensuite la coloration CP-SAT, mais le PNG capturé ici est l'étape **avant coloration**, pas l'état final.
- **Contenu réel vérifié** : Graphe titré « Graphe des departements francais (sans coloration) » montrant 18 nœuds (Paris, Somme, Aisne, Nord, Val-d'Oise, Val-de-Marne, Yvelines, Hauts-de-Seine, Marne, Oise, Loiret, Yonne, Essonne, Seine-Saint-Denis, Seine-et-Marne, Eure, Aube, Loir-et-Cher), tous en cyan uniforme, arêtes grises non-orientées. **Alt-text précédent sur-vendait (annonçait «rendu avec sa coloration CP-SAT» + «≈101 sommets» alors que la figure montre 18 nœuds Île-de-France + limitrophes SANS coloration) — corrigé.**
- **Poids** : 189.0 KB (PIL optimisé)
- **Note** : nom de fichier `app2-graphcoloring-map` conservé ; le tracé sous-jacent est un graphe, pas une carte choroplèthe — dette de nommage disclosed (EPIC #5780).

## app3-nurseschedule-planning.png

- **Source** : notebook `CSP/App-3-NurseScheduling.ipynb` (cellule 41, output 0)
- **Description visuelle** : **Heatmap `imshow`** (1200×669) titrée « **Planning 15 infirmiers x 28 jours (lignes rouges = week-ends)** » en gras centré. Axes discrets : Y « Inf_01..Inf_15 » (15 lignes), X « J-1..J-28 » (28 colonnes de jours). **Palette catégorielle 4 couleurs** : M (Matin, jaune pâle `#FFEB99`-ish), A (Après-midi, orange `#F39C12`-ish), N (Nuit, bleu vif `#5B6BC0`-ish), R (Repos, gris pâle `#ECECEC`-ish). **Lettres M/A/N imprimées en blanc gras** dans les cellules colorées correspondantes (Matin jaune/Repos gris sans lettre visible — la cellule sans lettre = Repos). **5 lignes pointillées rouges verticales** aux positions J-5/J-6, J-12/J-13, J-19/J-20 (3 transitions de week-end identifiables). **Légende automatique** coin haut-droit : 4 carrés colorés (jaune Matin, orange Après-midi, bleu Nuit, gris Repos). Stats RGB PIL : moyenne (**218.87, 210.68, 194.28**), std (49.53, 43.91, **57.48**) — **R mean > G mean > B mean tell discriminant** = fond cream (gris pâle R majoritaire) + dominance modérée du jaune/orange (Matins/Après-midi) sur le bleu (Nuits moins fréquentes). **Std B le plus élevé (57.48)** car la couleur Nuit contraste le plus visuellement (bleu saturé vs le reste pastel). La solution visualise un planning CP-SAT qui respecte les contraintes dures (couverture jour, repos, max nuits consécutives) tout en maximisant les préférences douces — la densité colorée (vs du blanc partout) matérialise la fraction couverte vs repos.
- **Alt-text (FR)** *(corrigé c.473)* : Planning de gardes infirmier·ère·s sur 28 jours : 15 lignes Inf_01..Inf_15 (le titre intégré à la figure précise «15 infirmiers», donc personnes infirmières sans genre imposé — alt-text antérieur au féminin uniformément «infirmières» sur-vendait), créneaux Matin (M, jaune) / Après-midi (A, orange) / Nuit (N, bleu) / Repos (R, gris) en colonnes J-1..J-28, week-ends marqués par des lignes pointillées rouges verticales. Solution CP-SAT respectant les contraintes dures (couverture, repos, max nuits consécutives) et maximisant les préférences douces.
- **Contenu réel vérifié** : Heatmap titrée « Planning 15 infirmiers x 28 jours (lignes rouges = week-ends) » — 15 lignes Inf_01..Inf_15, 28 colonnes J-1..J-28, cellules colorées M/A/N/R selon la légende (Matin jaune, Après-midi orange, Nuit bleu, Repos gris). Lignes pointillées rouges verticales visibles aux transitions week-end. **Alt-text précédent au féminin uniformément («infirmières») — corrigé pour refléter le titre masculin ET la neutralité genrée réelle (la profession étant mixte, l'usage «infirmier·ère·s» ou neutre est plus fidèle).**
- **Poids** : 146.5 KB (PIL optimisé)

## app11-picross-grid.png

- **Source** : notebook `CSP/App-11-Picross.ipynb` (cellule 10, output 0)
- **Description visuelle** : Figure `matplotlib` (567×590, fond blanc) titrée « **Puzzle Losange 5x5 (non resolu)** » en gras centré. **Grille 5×5 (5 lignes × 5 colonnes) vierge** : 25 cellules identiques gris pâle `#ECECEC` séparées par traits gris foncé fins (style `Rectangle` matplotlib). **Indices au-dessus des colonnes** (ligne d'indices supérieure au tick, en gras noir) : `1 3 5 3 1` (5 nombres, 1 par colonne). **Indices à gauche des lignes** (tick label Y-axis, en gras noir) : `1 3 5 3 1` (5 nombres, 1 par ligne). **Symétrie paradiagonale visible** : l'indice de la ligne k est identique à l'indice de la colonne k (signature des énig Losange symétriques par réflexion sur l'anti-diagonale principale, contrainte intrinsèque du puzzle Losange). Stats RGB PIL : moyenne (**231.87, 231.87, 231.87**), std (**27.86, 27.86, 27.86**) — **mean R = G = B exact** tell discriminant : **palette achrome** (grayscale uniforme, aucune teinte). Std faible (~28) typique d'une grille uniforme avec quelques indices noirs épars (5 noirs X + 5 noirs Y = 10 éléments contrastés sur fond blanc dominant). L'absence de valeurs dans la grille est cohérente avec l'état **avant résolution** CP-SAT (le PNG capture l'énoncé, pas la solution).
- **Alt-text (FR)** *(corrigé c.473)* : Énoncé d'un **puzzle Losange 5×5** (la figure est titrée «Puzzle Losange 5x5 (non resolu)» — un puzzle Losange est un régionnement par cases en forme de losange, distinct d'un Picross/nonogramme où l'on noircit des cases selon des indices) : indices de lignes et de colonnes au-dessus et à gauche de la grille vierge (séquence «1 3 5 3 1» sur les deux axes), grille 5×5 vide. La résolution CP-SAT remplirait chaque case selon les contraintes Losange ; la sortie capturée ici est l'énoncé avant résolution.
- **Contenu réel vérifié** : Grille 5×5 titrée « Puzzle Losange 5x5 (non resolu) », indices `1 3 5 3 1` au-dessus des colonnes et à gauche des lignes (symétrie sur les deux axes), grille totalement vide (toutes les cellules grises pâles uniformes). **Alt-text précédent disait «Picross (nonogramme)» — corrigé : le titre intégré annonce «Losange», pas nonogramme (le nonogramme a une grille standard où l'on noirçit des cases ; le Losange utilise une grille losange-régionale différente).**
- **Poids** : 9.7 KB (PIL optimisé)
- **Note** : nom de fichier `app11-picross-grid` conservé ; le PNG montre l'énoncé (grille vide), pas une grille résolue — limitation illustrative assumée (EPIC #5780).

## app15-sports-calendar.png

- **Source** : notebook `CSP/App-15-SportsScheduling.ipynb` (cellule 5, output 0)
- **Description visuelle** : **Heatmap `imshow` symétrique 6×6** (693×590) titrée « **Matrice des Distances** » en gras centré. Axes (X et Y identiques, libellés à 45° sur X) : **Paris, Marseille, Lyon, Lille, Bordeaux, Nantes**. **Palette YlOrRd** (jaune pâle → orange → rouge sombre) avec **colorbar verticale droite** étiquetée « Distance (km) » ∈ [0, **800+**] (échelle continue sur ~6 valeurs entières 0/100/200/.../800). **Diagonale jaune pâle** (zéro par construction, 6 cellules claires). **Case (Marseille, Lille) = la plus sombre** (~800+ km, case rouge sang quasi-noire, distinctement hors-échelle du reste). **Cases symétriques** : heatmap symétrique par rapport à la diagonale (cohérent avec matrice de distances : d(A,B) = d(B,A)). Stats RGB PIL : moyenne (**241.62, 176.58, 149.66**), std (35.55, **92.46**, **96.48**) — **R mean > G mean > B mean tell discriminant** = palette YlOrRd (fond jaune pâle à rouge), **distinct du heatmap dense chaud YlOrRd c.779 dt5-evpi** car la std G/B est plus élevée ici (palette YlOrRd scaled 0-800+ avec une case extrême ~800 Marseille-Lille qui creuse la variance). Tell discriminant heatmap YlOrRd tell : `R > G > B en moyenne + std G élevée`. La matrice sert d'**entrée** au solveur CP-SAT qui construit ensuite le calendrier round-robin minimisant les déplacements.
- **Alt-text (FR)** : Matrice 6×6 des distances entre les six villes de la ligue (entrée du problème de calendrier sportif) — heatmap symétrique à diagonale nulle, valeurs entières en kilomètres. L'ordonnancement des matchs (round-robin, équilibre domicile/extérieur, déplacements) est résolu par CP-SAT à partir de cette matrice.
- **Contenu réel vérifié** : Heatmap titrée « Matrice des Distances » 6×6 villes française : Paris, Marseille, Lyon, Lille, Bordeaux, Nantes. Palette YlOrRd (jaune pâle → rouge sombre), échelle colorbar « Distance (km) » ∈ [0, 800+], diagonale jaune pâle (zéro). Symétrie visible (Marseille↔Lyon ≈ Marseille↔Lyon symétrique). **Alt-text cohérent avec l'image.**
- **Poids** : 27.6 KB (PIL optimisé)
- **Note** : nom de fichier `app15-sports-calendar` conservé ; le PNG montre la matrice des distances (entrée), pas le calendrier final — dette de nommage disclosed (EPIC #5780).

## app19-wfc-tiles.png

- **Source** : notebook `CSP/App-19-ProceduralGeneration-WFC.ipynb` (cellule 12, output 0)
- **Description visuelle** : **Niveau 2D procédural** (753×790, rendu matplotlib `imshow` ou `pcolormesh`) titré « **CP-SAT — OPTIMAL | connectivité=7% ennemis=3 clés=1 coffres=1** » (2 lignes). **Grille de tuiles ~15×15** parsemée de 7 classes visuelles distinctes : **`#` mur** (carrés noirs `#000000` ~40% de la surface), **`.` sol** (carrés cream pâle `#E6D2B5` ~25%), **`~` eau** (carrés bleu vif `#3A8DC9` ~15%), **`D` porte** (carrés brun foncé `#7B4A2A` ~10%), **`'` herbe** (carrés vert vif `#5FBA4D` ~25%), **`E` ennemi** (carrés rouge sang `#E63946` 3 occurrences disséminées, label `E` rouge centré), **`K` clé** (1 carré jaune `#F9D71C` non localisé visuellement avec certitude), **`C` coffre** (1 carré orange `#F77F2A`, label `C` centré, ligne ~9 colonne ~22). **Légende automatique** coin haut-droit : 8 entrées avec carré couleur + label. Stats RGB PIL : moyenne (**130.87, 141.82, 111.02**), std (**70.52, 63.97, 74.69**) — **mean R/G/B < 150 tell discriminant** d'un **niveau dense multi-couleurs** (≠ fond clair dominant habituel) ; la dominance de G mean > R mean > B mean reflète la prépondérance des surfaces vertes herbe + rouges ennemi + noires mur (somme pondérée). Std très élevée (63-74) sur tous les canaux = variance forte typique des **grilles denses multi-tiles**. Tell discriminant niveau 2D procédural : `mean R/G/B ~100-180 + std 50+` (vs `mean R/G/B > 240` tell du fond clair, vs `mean < 100` tell imshow dark-field c.778).
- **Alt-text (FR)** *(corrigé c.473)* : Niveau 2D généré par Wave Function Collapse encodé en CP-SAT : grille de tuiles `#` mur (noir), `.` sol (cream), `~` eau (bleu), `D` porte (marron), `'` herbe (vert), trois ennemis `E` (rouge), une clé `K` (jaune) et un coffre `C` (orange) — **NB : aucun marqueur « héros H » n'est visible dans le rendu actuel (la légende n'inclut pas de classe H, contrairement à ce que suggérait l'alt-text précédent)**. Le titre intégré à la figure annonce « connectivité=7% ennemis=3 clés=1 coffres=1 », valeurs effectivement vérifiables au décompte du PNG (3 cases rouges `E` disséminées + 1 case jaune `K` + 1 case orange `C`).
- **Contenu réel vérifié** : Niveau 2D titré « CP-SAT — OPTIMAL | connectivité=7% ennemis=3 clés=1 coffres=1 », légende = `#` wall / `.` floor / `~` water / `D` door / `'` grass / `E` ennemi (rouge) / `K` clé (jaune) / `C` coffre (orange). Grille carrelée avec mix de #/./~/D/' et 3 cellules rouges E (ennemis) + 1 cellule jaune K (clé) + 1 cellule orange C (coffre). **Alt-text précédent mentionnait «héros marqué en une couleur» — corrigé : aucun marqueur H n'apparaît dans le rendu (la légende ne comporte pas H) ; les 3 cases rouges sont les ennemis `E`, pas un héros.**
- **Poids** : 24.7 KB (PIL optimisé)