204 lines
13 KiB
Markdown
204 lines
13 KiB
Markdown
# MISSION : créer « KI FWI SA YÉ ? » selon le PLAYBOOK UNIFIÉ OKI × SVELTEKIT
|
||||
|
|
|
|||
|
|
> **Mode d'emploi.** Colle ce fichier entier dans Claude Code, en joignant :
|
|||
|
|
> `playbook-oki-sveltekit.md` (méthode + marque, **fait autorité**), `AGENTS.md`,
|
|||
|
|
> `svelte_core_bestpractices.md`, `PRD_AI_Overview_SEO_Recommandations.md`,
|
|||
|
|
> `pack_complet_game_fruit.txt` (matière première, **à corriger, pas à appliquer tel quel**),
|
|||
|
|
> `fruits.seed.json` (données d'amorçage), `GITEA.md` (déploiement).
|
|||
|
|
> Ajuste « Périmètre de cette session » (§6) à chaque nouvelle session.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
Tu es un agent de code senior. Tu construis un **jeu éducatif libre** qui apprend aux enfants des
|
|||
|
|
Antilles à reconnaître les fruits, les arbres et les plantes de leurs îles.
|
|||
|
|
|
|||
|
|
Le `playbook-oki-sveltekit.md` fait autorité : la marque (§1) prime pour couleurs, typographie, voix
|
|||
|
|
et iconographie ; la méthode (§2) prime pour la technique ; les budgets (§2.7) et l'accessibilité
|
|||
|
|
(§2.8) ne se négocient jamais. Les conventions Svelte 5 du §3 sont obligatoires. Ce brief ne
|
|||
|
|
remplace le playbook nulle part : il le spécialise.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. Contexte
|
|||
|
|
|
|||
|
|
- **Projet :** `ki-fwi` — nouveau dépôt, création *ex nihilo* (type de mission **B** du playbook §0).
|
|||
|
|
- **Porteur :** ORGANISATION KA INTERNATIONALE (o-k-i.net), Martinique/Guadeloupe.
|
|||
|
|
- **Problème :** une partie des enfants antillais ne sait plus nommer ni reconnaître les fruits de
|
|||
|
|
leur île, ni les arbres qui les portent. Le jeu vise à restituer cette connaissance.
|
|||
|
|
- **Public :** 7–12 ans, lecture parfois fragile, téléphone Android d'entrée de gamme, 4G ou wifi
|
|||
|
|
d'école instable. Le jeu doit être **jouable hors ligne** et **installable**.
|
|||
|
|
- **Positionnement :** logiciel libre, aucun compte, aucune publicité, aucun tracker, aucune requête
|
|||
|
|
vers un domaine tiers au runtime.
|
|||
|
|
|
|||
|
|
## 2. Règle n°1 du projet — la vérité visuelle
|
|||
|
|
|
|||
|
|
Le jeu enseigne la reconnaissance du réel. **Deux filières d'assets, régimes séparés, jamais
|
|||
|
|
mélangés :**
|
|||
|
|
|
|||
|
|
- **Filière A — Vérité.** Photographies réelles (Wikimedia Commons, iNaturalist, herbiers,
|
|||
|
|
photos du porteur). **Seule** filière autorisée pour tout ce qui sert à identifier : épreuves de
|
|||
|
|
reconnaissance, indices (feuille, écorce, coupe, port de l'arbre), fiches encyclopédiques.
|
|||
|
|
- **Filière B — Décor.** Images générées par IA (ComfyUI/Krea2/FLUX) : fonds, personnages, sprites
|
|||
|
|
du mode arcade, badges, écrans de titre, iconographie. **Jamais** une épreuve d'identification.
|
|||
|
|
|
|||
|
|
Tout média porte un champ `valide` (booléen, `false` par défaut) et un champ `source`. **Le build
|
|||
|
|
échoue si un média non validé est référencé par une épreuve.** Écris ce contrôle comme un script de
|
|||
|
|
build, pas comme une consigne.
|
|||
|
|
|
|||
|
|
Justification, à ne pas oublier : les modèles de diffusion connaissent mal le corossol, à peine la
|
|||
|
|
quenette, presque pas le zikak ou le cachiman. Ils produisent des fruits plausibles et faux. Un jeu
|
|||
|
|
d'identification bâti sur des assets IA apprend l'erreur.
|
|||
|
|
|
|||
|
|
## 3. Règle n°2 — les licences
|
|||
|
|
|
|||
|
|
Rien n'est « libre de droit ». Avant d'embarquer le moindre média :
|
|||
|
|
|
|||
|
|
- **Wikimedia Commons** : majoritairement CC BY-SA 4.0 → attribution nominative **et** partage à
|
|||
|
|
l'identique, qui contamine les dérivés. Récupérer auteur, licence, URL du fichier, URL de la page
|
|||
|
|
de description, et les stocker par média dans les données.
|
|||
|
|
- **iNaturalist** : souvent CC BY-**NC**. Acceptable pour un jeu non commercial ; à signaler
|
|||
|
|
explicitement dans `CREDITS.md` et dans l'ADR de licence.
|
|||
|
|
- **TRAMIL** (tramil.net) : **aucune licence accordée** dans ses mentions légales → tous droits
|
|||
|
|
réservés. Utilisable comme **source de vérification factuelle** citée en référence, **jamais**
|
|||
|
|
comme source de fichiers. Rédige une lettre-type de demande d'autorisation que le porteur enverra.
|
|||
|
|
- **CIRAD / INRAE** : régimes mixtes. Même traitement : vérification et demande, pas présomption.
|
|||
|
|
- **Wikidata / GBIF** : à utiliser pour la taxonomie (Q-id, clé GBIF, nom scientifique accepté,
|
|||
|
|
famille) — c'est la colonne vertébrale factuelle du dataset.
|
|||
|
|
|
|||
|
|
Livrables associés : `LICENSE` (code : **AGPL-3.0-or-later**), `LICENSE-CONTENT` (contenu :
|
|||
|
|
**CC BY-SA 4.0**), `CREDITS.md` généré depuis les données, et un écran de crédits dans le jeu.
|
|||
|
|
Si un conflit de licence apparaît (NC vs commercial, SA vs compositing), **arrête-toi et demande**.
|
|||
|
|
|
|||
|
|
## 4. Stack
|
|||
|
|
|
|||
|
|
Défaut = §2.3 du playbook, avec ces précisions et ces écarts explicites :
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
SvelteKit 2 + Svelte 5 (runes) + TypeScript strict
|
|||
|
|
@sveltejs/adapter-static, prerender intégral, trailingSlash 'always'
|
|||
|
|
CSS vanilla : oki-tokens.css + base.css (pas de Tailwind)
|
|||
|
|
vite-imagetools (AVIF/WebP responsive), vite-plugin-pwa (shell + packs hors ligne)
|
|||
|
|
@fontsource → woff2 self-hébergés dans static/fonts/
|
|||
|
|
phaser@^4 ← ÉCART DOCUMENTÉ, voir ci-dessous
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Phaser 5 n'existe pas.** La branche courante est **Phaser 4** (4.0 « Caladan », avril 2026 ;
|
|||
|
|
4.1 « Salusa » ; 4.2 « Giedi »), moteur WebGL réécrit en *render nodes*. Vérifie la dernière version
|
|||
|
|
publiée (`npm view phaser version`) avant d'installer. Ne pars pas de Phaser 3.
|
|||
|
|
|
|||
|
|
**Frontière stricte Svelte / Phaser :**
|
|||
|
|
|
|||
|
|
- Svelte porte la coquille : routes, i18n, SEO, menus, HUD, album, fiches, données, progression,
|
|||
|
|
audio, réglages, et **trois des cinq modes de jeu** (Rekonèt, Kaché, Sézon) en DOM/CSS pur.
|
|||
|
|
- Phaser porte **une seule scène** : le mode arcade « Ranmasé ». Montée par import dynamique dans
|
|||
|
|
`(jeu)/ranmase`, jamais au layout racine, détruite au démontage (`game.destroy(true)`),
|
|||
|
|
communication par événements — pas d'état Svelte partagé par frame.
|
|||
|
|
- Rendu `AUTO` (WebGL, repli canvas), DPR plafonné à **1.5**, `powerPreference: 'low-power'`,
|
|||
|
|
cible 30 fps stables sur Mali-G52.
|
|||
|
|
- **Miroir DOM sémantique** obligatoire pour la scène (playbook §2.8, point 4).
|
|||
|
|
|
|||
|
|
**Budgets :** le shell reste **≤ 170 Ko JS gzip** (non négociable). Phaser n'est téléchargé qu'à
|
|||
|
|
l'entrée dans la scène arcade, derrière un écran de chargement designé (P5). Consigne cet écart dans
|
|||
|
|
`docs/adr/0002-phaser-hors-budget-initial.md` : mesure réelle, justification, condition de
|
|||
|
|
réexamen. Entrée du site ≤ 2 Mo, LCP < 2,5 s, INP < 200 ms, CLS < 0,05.
|
|||
|
|
|
|||
|
|
## 5. Architecture produit — deux faces, un dataset
|
|||
|
|
|
|||
|
|
- **`/zerbaj/`** — l'encyclopédie. Une page prérendue par fruit et par plante, **lisible sans
|
|||
|
|
JavaScript**, JSON-LD, hreflang, traitement conforme à `PRD_AI_Overview_SEO_Recommandations.md`.
|
|||
|
|
C'est la face indexable et citable du projet.
|
|||
|
|
- **`/je/`** — le jeu. PWA, hors ligne, sans compte, progression locale (`localStorage` +
|
|||
|
|
Cache-Storage), export/import de la progression en JSON.
|
|||
|
|
|
|||
|
|
Le jeu déverrouille les fiches ; les fiches renvoient au jeu. **Un seul jeu de données** alimente les
|
|||
|
|
deux : `src/lib/data/fruits/*.json` validés par `fruits.schema.json` à chaque build.
|
|||
|
|
|
|||
|
|
**Langues :** le **kréyòl est la langue principale** — le nom kréyòl est le nom du fruit, le français
|
|||
|
|
est sa traduction (choix assumé, à ne pas inverser). Routes `/` (GCF), `/fr/`, `/en/`. Routeur par
|
|||
|
|
dossiers + catalogues JSON, pas de middleware (playbook §5b.7). Attribut `lang` correct partout.
|
|||
|
|
L'orthographe kréyòl **n'est pas de ton ressort** : signale toute incertitude dans un fichier
|
|||
|
|
`docs/kreyol-a-relire.md` au lieu de trancher.
|
|||
|
|
|
|||
|
|
## 6. Les cinq modes
|
|||
|
|
|
|||
|
|
1. **Rekonèt** — photo réelle → 4 propositions. Répétition espacée (Leitner, 5 boîtes) persistée en
|
|||
|
|
local. C'est le mode qui fait apprendre : soigne-le en premier.
|
|||
|
|
2. **Kaché** — indices dévoilés un à un : feuille → écorce → coupe → fruit entier, score dégressif.
|
|||
|
|
3. **Ranmasé** — arcade Phaser : récolter le fruit demandé, éviter les plantes dangereuses.
|
|||
|
|
4. **Sézon** — placer les fruits sur le calendrier annuel de l'île sélectionnée.
|
|||
|
|
5. **Pa touché** — module sécurité : mancenillier, akée non mûr, coque de pomme-cajou, médicinier,
|
|||
|
|
laurier-jaune. **Jamais chronométré, jamais scoré, jamais transformé en épreuve d'adresse.** Ton
|
|||
|
|
sobre et factuel : on n'apprend pas le danger sous pression. Aucun visuel anxiogène.
|
|||
|
|
|
|||
|
|
**Moment de révélation** à la bonne réponse (leçon JWE du playbook §5b.12) : retournement de la
|
|||
|
|
photo, **nom kréyòl prononcé**, score en count-up (rAF → écriture DOM directe, span animé
|
|||
|
|
`aria-hidden` + valeur finale en `.sr-only` dans une région `aria-live`), fiche ajoutée à l'album.
|
|||
|
|
|
|||
|
|
**Audio :** chaque fruit a un fichier de prononciation kréyòl. **Pas de synthèse vocale.** Les
|
|||
|
|
enregistrements seront fournis par le porteur ; prévois le contrat (`audio.gcf`, format `.opus`,
|
|||
|
|
repli silencieux si le fichier manque) et un script de vérification listant les enregistrements
|
|||
|
|
manquants.
|
|||
|
|
|
|||
|
|
**Accessibilité :** cibles tactiles ≥ 44 px, navigation clavier complète, aucun mode chronométré en
|
|||
|
|
découverte, contraste AA sur le thème sombre, `prefers-reduced-motion` en gate unique au provider.
|
|||
|
|
|
|||
|
|
## 7. Pipeline d'assets IA (filière B uniquement)
|
|||
|
|
|
|||
|
|
Reprends le pack `pack_complet_game_fruit.txt` en corrigeant ses défauts :
|
|||
|
|
|
|||
|
|
- **Seeds déterministes** : `hash()` de Python est randomisé par exécution (`PYTHONHASHSEED`) — les
|
|||
|
|
seeds du script fourni ne sont pas reproductibles, contrairement à ce qu'il annonce. Utilise
|
|||
|
|
`zlib.crc32(clé.encode()) & 0xFFFFFFFF`. `copy.deepcopy` au lieu de `json.loads(json.dumps(...))`.
|
|||
|
|
- **Sortie** : AVIF/WebP + atlas de textures par écran, jamais 80 PNG 512×512 en vrac. Packs par île.
|
|||
|
|
- **Porte de validation** : chaque asset généré est comparé à ≥ 2 photos réelles ; `valide: false`
|
|||
|
|
tant qu'un humain n'a pas tranché ; le build refuse tout asset non validé.
|
|||
|
|
- **Licence du modèle `rembg`** : vérifie la licence des **poids**, pas seulement du paquet.
|
|||
|
|
- ComfyUI est piloté **hors ligne, au build** (P2). Aucun appel réseau ne subsiste au runtime.
|
|||
|
|
- Le script vit dans `tools/assets/`, hors du bundle, avec son propre `requirements.txt`.
|
|||
|
|
|
|||
|
|
## 8. Périmètre de CETTE session
|
|||
|
|
|
|||
|
|
> **Session 0 — Cadre et données. Aucun code applicatif.**
|
|||
|
|
|
|||
|
|
- [ ] `git init` + premier commit **avant toute autre action** (playbook §5b.1).
|
|||
|
|
- [ ] Audit des sources : pour chacune (Commons, Wikidata, GBIF, iNaturalist, TRAMIL, CIRAD, INRAE),
|
|||
|
|
une fiche courte : ce qu'on y prend, sous quelle licence, avec quelle contrainte, comment on
|
|||
|
|
l'interroge. Rapport dans `docs/audit-sources.md`.
|
|||
|
|
- [ ] ADR dans `docs/adr/` : 0001 licences · 0002 Phaser 4 hors budget initial · 0003 frontière
|
|||
|
|
Svelte/Phaser · 0004 filières A/B des assets · 0005 kréyòl langue principale.
|
|||
|
|
- [ ] `fruits.schema.json` (JSON Schema) + validateur exécutable en `npm run validate:data`.
|
|||
|
|
- [ ] Dataset de **8 fruits**, chaque champ taxonomique **vérifié contre Wikidata et GBIF** (pas
|
|||
|
|
contre ta mémoire) : nom scientifique accepté, famille, Q-id, clé GBIF, plus ≥ 2 photos
|
|||
|
|
Commons par fruit avec auteur, licence et URL. Point de départ : `fruits.seed.json`, dont
|
|||
|
|
**tout est à vérifier**, y compris l'orthographe kréyòl.
|
|||
|
|
- [ ] `SOURCES.md`, `CREDITS.md` (généré), `LICENSE`, `LICENSE-CONTENT`.
|
|||
|
|
- [ ] Lettre-type de demande d'autorisation TRAMIL et CIRAD (`docs/courriers/`).
|
|||
|
|
- [ ] `docs/plan.md` : le plan des sessions 1 à 6 avec, pour chacune, sa porte de sortie mesurable.
|
|||
|
|
|
|||
|
|
**Ne commence à coder l'application qu'après validation explicite du plan par le porteur.**
|
|||
|
|
|
|||
|
|
## 9. Méthode de travail
|
|||
|
|
|
|||
|
|
- Vérifie `git` en premier, toujours (playbook §5b.1).
|
|||
|
|
- Présente le plan **avant** d'écrire quoi que ce soit d'autre, et attends la validation.
|
|||
|
|
- Après tout composant Svelte modifié : `npx @sveltejs/mcp svelte-autofixer <fichier>` jusqu'à
|
|||
|
|
silence, puis `npm run check` à **0 erreur / 0 warning** avant tout commit (playbook §3).
|
|||
|
|
- Aucune dépendance installée sans être importée et utilisée.
|
|||
|
|
- Les données priment sur ce brief. Si `fruits.seed.json` ou Wikidata contredisent une affirmation
|
|||
|
|
écrite ici, **les données gagnent** — signale l'écart, ne le corrige pas en silence.
|
|||
|
|
- Si une décision engage le juridique, la pédagogie ou la sécurité des enfants : **arrête-toi et
|
|||
|
|
demande**. Ce sont les trois domaines où une erreur ne se rattrape pas par un correctif.
|
|||
|
|
|
|||
|
|
## 10. Critères d'acceptation
|
|||
|
|
|
|||
|
|
- La DoD §8 du playbook est intégralement vraie, **plus** :
|
|||
|
|
- [ ] Zéro requête tierce au runtime (onglet réseau, sur build de production).
|
|||
|
|
- [ ] Chaque média porte source, auteur, licence, URL — vérifié par script.
|
|||
|
|
- [ ] Aucune épreuve d'identification ne s'appuie sur un asset IA.
|
|||
|
|
- [ ] Le jeu est entièrement jouable hors ligne après une première visite.
|
|||
|
|
- [ ] `/zerbaj/` est lisible et complet avec JavaScript désactivé.
|
|||
|
|
- [ ] Bundle initial ≤ 170 Ko gzip, Phaser exclu du chemin critique et mesuré à part.
|
|||
|
|
- [ ] Lighthouse mobile ≥ 90/95/95/95 sur l'accueil et sur une fiche.
|
|||
|
|
- [ ] Navigation clavier complète sur les cinq modes, `prefers-reduced-motion` vérifié à la main.
|
|||
|
|
- [ ] Le module « Pa touché » a été relu par un humain avant livraison.
|