# Plan des sessions — KI FWI SA YÉ ? > Chaque session se termine par un build vert, un commit et une note de session dans > `docs/sessions/`. **Ne pas enchaîner deux sessions sans relire ce qui a été produit.** > > Une porte de sortie n'est franchie que si elle est **mesurée**, pas estimée. Une porte non > franchie n'autorise pas la session suivante : elle autorise à recommencer celle-ci. --- ## Session 0 — Cadre et données ✅ terminée **Livré.** Dépôt initialisé, six ADR, audit des sept sources, `fruits.schema.json`, validateur exécutable et son test, 13 entrées vérifiées contre Wikidata et GBIF, 39 médias candidats sourcés sur Commons, `CREDITS.md` généré, licences, lettres-types, points à arbitrer, inventaire mesuré des manques et guide de contribution. **Porte de sortie — franchie.** | Critère | Cible | Mesuré | |---|---|---| | Taxons vérifiés contre **deux** référentiels | 13 | 13 ✅ | | Divergences avec la graine | signalées | 0 divergence ✅ | | Médias candidats sous licence libre | ≥ 2 par entrée | 10 par entrée ✅ | | Médias validés | 0 attendu | 0 ✅ | | `npm run validate:data` | vert | vert ✅ | | `npm run test:porte` | 10/10 | 10/10 ✅ | | Manques mesurés, pas estimés | rapport daté | 3 vues sur 65 ✅ | | Code applicatif écrit | aucun | aucun ✅ | --- ## Session 1 — Socle SvelteKit 2 + Svelte 5 (runes) + TypeScript strict, `adapter-static`, prérendu intégral, `trailingSlash: 'always'`. Tokens OKI (`oki-tokens.css` + `base.css`), thème sombre par défaut et clair en opt-in AA. Polices Archivo et Inter self-hébergées en woff2. PWA légère. i18n par dossiers — `/` en kréyòl, `/fr/`, `/en/`. `/zerbaj/` : une page prérendue par entrée, avec JSON-LD, hreflang et le traitement `PRD_AI_Overview`. **Porte de sortie.** | Critère | Cible | |---|---| | Fiches en ligne | 13, une page prérendue chacune | | Lighthouse mobile (accueil **et** une fiche) | ≥ 90 / 95 / 95 / 95 | | Contenu lisible avec JavaScript désactivé | intégralement | | JS initial | ≤ 170 Ko gzip | | Requêtes vers un domaine tiers | **0**, vérifié par grep du build | | `npm run check` | 0 erreur, 0 warning | | `svelte-autofixer` sur chaque composant modifié | silencieux | | Chaque fiche affiche ce qui lui manque | vrai pour les 13 (ADR 0006) | | Les 4 questions kréyòl ouvertes sont affichées, avec un moyen de répondre | vrai (ADR 0005 amendé) | **Dépendance humaine :** aucune. La session 1 fonctionne avec 0 média validé — les fiches affichent le texte, la taxonomie, les crédits et **les manques**, pas encore les photos. Une fiche incomplète ne se masque pas : elle dit ce qui lui manque et comment le combler. --- ## Session 2 — Moteur pédagogique, en Svelte pur Modes **Rekonèt** (photo → 4 propositions, répétition espacée Leitner à 5 boîtes persistée en local), **Kaché** (indices dévoilés un à un : feuille → écorce → coupe → fruit entier, score dégressif) et **Sézon** (calendrier). Album `Lakou`, badges, audio, export de la progression en JSON. Moment de révélation : retournement de la photo, nom kréyòl prononcé, score en count-up (rAF → écriture DOM directe, span `aria-hidden` + valeur finale en `.sr-only` dans une région `aria-live`), fiche ajoutée à l'album. **Porte de sortie — la plus importante du projet.** | Critère | Cible | |---|---| | **Le jeu est amusant sans Phaser** | jugement humain, sur une partie réelle | | Navigation clavier complète sur les trois modes | vérifiée à la main | | `prefers-reduced-motion` | gate unique au provider, vérifiée à la main | | Progression conservée après rechargement | vérifiée | | Cibles tactiles | ≥ 44 px, testées par `elementFromPoint` en 390 px | | JS initial | toujours ≤ 170 Ko gzip | | Écran « Ba on koudmen » | présent, alimenté par le rapport baké au build | | Appels réseau depuis l'écran de contribution | **0** — des liens, pas des requêtes | **Si le jeu n'est pas plaisant ici, ne pas passer à la session 3.** Ajouter un moteur de jeu à un problème de game design ajoute du poids au problème. Le mode Sézon reste non publiable tant que le point 3 de `docs/a-arbitrer.md` n'est pas tranché. **Dépendance humaine :** au moins deux photos validées par entrée pour que Rekonèt fonctionne sur de vraies données. C'est le premier point de blocage réel du projet. --- ## Session 3 — Pipeline d'assets, filière B Client ComfyUI dans `tools/assets/`, hors bundle, avec son `requirements.txt`. Seeds déterministes par `zlib.crc32(clé.encode()) & 0xFFFFFFFF` — le `hash()` de Python est randomisé par exécution, les seeds du pack d'origine ne sont donc pas reproductibles malgré ce qu'il annonce. `copy.deepcopy` au lieu de `json.loads(json.dumps(...))`. Sortie AVIF/WebP, atlas de textures par écran, packs par île téléchargeables et mis en cache par le service worker. Licence des **poids** de `rembg` vérifiée, pas seulement celle du paquet. **Porte de sortie.** | Critère | Cible | |---|---| | Assets non validés dans le build | **0**, refusé par `validate:data` | | Assets de filière B dans une épreuve | **0**, refusé par `validate:data` | | Poids d'entrée du site | ≤ 2 Mo | | Reproductibilité des seeds | deux exécutions → sorties identiques, vérifié par hash | | Appels réseau au runtime | **0** | | Compositing sur un média SA ou NC | **0**, refusé par `validate:data` | --- ## Session 4 — Ranmasé (Phaser 4) et Pa touché Scène arcade en `phaser@^4`, import dynamique dans `(jeu)/ranmase`, `game.destroy(true)` au démontage, communication par événements. Rendu `AUTO`, DPR ≤ 1,5, `powerPreference: 'low-power'`. Miroir DOM sémantique. Module **Pa touché** : jamais chronométré, jamais scoré, ton sobre et factuel. **Porte de sortie.** | Critère | Cible | |---|---| | Phaser dans le bundle initial | **absent**, vérifié sur le build | | Shell JS initial, Phaser exclu | ≤ 170 Ko gzip | | Bundle Phaser mesuré et consigné dans l'ADR 0002 | fait | | fps sur Mali-G52 ou équivalent | ≥ 30 stables | | Miroir DOM de la scène | navigable au clavier et au lecteur d'écran | | Écran de chargement designé | présent, en KA | | Module Pa touché | aucun chrono, aucun score, aucune épreuve | **Réexamen :** si Phaser dépasse ~450 Ko gzip ou que les 30 fps ne tiennent pas, la scène est réécrite en DOM/CSS (ADR 0002). Les quatre autres modes n'en dépendent pas. --- ## Session 5 — Contenu Passage de 8 à 24 fruits, 5 plantes dangereuses consolidées. Enregistrement des voix kréyòl. Relecture orthographique. Arbitrage des six points de `docs/a-arbitrer.md`. **Porte de sortie.** | Critère | Cible | |---|---| | Entrées avec taxonomie vérifiée contre deux référentiels | 29 / 29 | | Entrées en `orthographe.statut: "relu"` avec relecteur nommé | 29 / 29 | | Questions kréyòl ouvertes restant sans réponse | 0, ou assumées et affichées | | `npm run check:audio` — enregistrements manquants | **0** | | Enregistrements versés à Lingua Libre plutôt que gardés localement | majorité | | Voix de synthèse | **0** | | Photos validées par entrée, avec validateur nommé | ≥ 2 | | Points de `docs/a-arbitrer.md` tranchés | 6 / 6 | | Module Pa touché relu par un humain compétent | fait, tracé | **Cette session est majoritairement du terrain, pas du code.** --- ## 🔬 Test en classe — entre la 5 et la 6 Six enfants, trente minutes, le porteur regarde **sans intervenir**. C'est la seule mesure qui compte, et elle invalidera une partie de ce plan. Tant mieux : c'est plus tôt qu'après la livraison. Note d'observation à écrire dans `docs/sessions/test-classe.md` avant la session 6. --- ## Session 6 — Finition Performance, accessibilité, DoD §8 du playbook, `.htaccess` et `_headers`, déploiement, écran de crédits, tag, push Gitea. **Porte de sortie — la DoD intégralement vraie, plus :** | Critère | Cible | |---|---| | Requêtes tierces au runtime, sur build de production | **0**, onglet réseau | | Médias sans source, auteur, licence et URL | **0**, vérifié par script | | Épreuves s'appuyant sur un asset généré | **0** | | Jeu entièrement jouable hors ligne après une visite | vérifié en mode avion | | `/zerbaj/` lisible et complet sans JavaScript | vérifié | | Bundle initial | ≤ 170 Ko gzip, Phaser mesuré à part | | Lighthouse mobile, accueil et fiche | ≥ 90 / 95 / 95 / 95 | | Navigation clavier sur les cinq modes | complète | | Écran de crédits dans le jeu | présent, généré depuis les données | | `docs/contribuer.md` publié comme page du site | fait | | Rapport de manques à jour à la date du build | fait | --- ## Ce qui ne se délègue à aucun agent Ces cinq points conditionnent la livraison et ne figurent dans aucune session parce qu'aucune session ne peut les produire : 1. **Aller voir TRAMIL à Schœlcher.** Lettre prête : `docs/courriers/tramil.md`. Si la voie privée n'aboutit pas sous deux à trois mois, l'appel public est rédigé : `docs/courriers/appel-liberation-tramil.md` — à cosigner, la décision de publier appartient au porteur. 2. **Enregistrer les voix kréyòl** — 10 sur 13, les trois autres existant déjà sur Lingua Libre en CC BY-SA. Liste prête : `docs/audio-a-enregistrer.md`. À verser de préférence sur Lingua Libre, pas dans notre dépôt : `docs/kreyol-participatif.md`. 3. **Photographier ce qui manque sur Commons** — il manquera, surtout les vues d'écorce, de feuille isolée et de coupe, celles dont le mode Kaché a besoin. 4. **Faire relire l'orthographe kréyòl.** Quatre questions sont posées publiquement dans le produit ; il reste à les porter à des locuteurs. Traduire ces questions en kréyòl est la première tâche. Points relevés : `docs/kreyol-a-relire.md`, protocole : `docs/kreyol-participatif.md`. 5. **Le test en classe.** 6. **Inscrire les noms kréyòl sur Wikidata** — 0 sur 13 aujourd'hui, contre 124 noms vernaculaires enregistrés dans d'autres langues pour les mêmes espèces. Ne demande ni appareil photo ni déplacement, mais demande une orthographe relue : à faire après le point 4, jamais avant. `docs/contribuer.md` §A. Le code est la partie facile.