Files
ki-fwi/docs/plan.md
T

219 lines
10 KiB
Markdown
Raw Normal View History

# 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` | tous les cas interdits refusés | 14/14 ✅ |
| 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 six 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.