Files
ki-fwi/docs/plan.md
T
OKIandClaude Opus 5 945a524b44 feat(session-0): cadre juridique, porte de validation et dataset vérifié
Session 0 du plan — aucun code applicatif.

Cadre
- 5 ADR : licences, Phaser 4 hors budget initial, frontière Svelte/Phaser,
  filières A/B des assets, kréyòl langue principale (norme gwadloupéyenne).
- LICENSE (AGPL-3.0-or-later, texte canonique gnu.org), LICENSE-CONTENT
  (CC BY-SA 4.0). Le jeu est une œuvre collective : aucun compositing sur un
  média SA ou NC, contrainte vérifiée par script.
- Audit des 7 sources avec endpoints réellement appelés. TRAMIL vérifié en
  direct : « all rights reserved » et page de mentions légales en 404.
  iNaturalist mesuré à 93 % de CC BY-NC sur un échantillon de 305 photos.

Outillage (tools/data/, hors bundle, zéro appel réseau au runtime)
- verify:taxa, ingest:commons, build:dataset, validate:data, test:porte,
  build:credits, check:audio.
- validate.mjs est la porte exigée par le brief §2 : le build échoue si une
  épreuve s'appuie sur un média non validé, non photographique ou de filière B,
  sur une attribution sans auteur, sur un compositing SA/NC, ou sur une entrée
  publiée sans relecture kréyòl. test:porte prouve les 9 refus + 1 témoin.

Données
- 13 entrées (8 fruits + 5 plantes du module Pa touché) vérifiées contre
  Wikidata ET GBIF : 13/13 ACCEPTED, 0 divergence avec la graine.
- 130 candidats Commons sous licence libre, 39 pré-inscrits, 0 validé —
  aucun agent ne peut valider un média.

Écarts signalés, non corrigés en silence
- Le champ danger de la graine a deux formes (note vs resume) : normalisé.
- 3 identifiants divergent du nom kréyòl au-delà des accents : non tranchés.
- comestible:false sur akée et pomme-cajou : sous-estimation prudente assumée.
- Le mancenillier n'a aucune photographie moderne dans ses 3 premiers
  candidats — l'entrée la plus critique est la moins bien servie.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 23:47:27 -04:00

8.4 KiB

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é, cinq 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.

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
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

Dépendance humaine : aucune. La session 1 fonctionne avec 0 média validé — les fiches affichent le texte, la taxonomie et les crédits, pas encore les photos.


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

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
npm run check:audio — enregistrements manquants 0
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

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.
  2. Enregistrer les voix kréyòl. Liste prête : docs/audio-a-enregistrer.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 par un humain. Points relevés : docs/kreyol-a-relire.md.
  5. Le test en classe.

Le code est la partie facile.