diff --git a/README.md b/README.md index 385e952..6a79734 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,17 @@ l'inventaire ; [`docs/contribuer.md`](docs/contribuer.md) explique les six geste de l'ajout d'un nom sur Wikidata — cinq minutes, aucun matériel — jusqu'à l'enregistrement d'une voix kréyòl. -Contribuer se fait sur Wikimedia Commons, Wikidata, iNaturalist ou Pl@ntNet, **jamais dans le -jeu** : les contributions doivent servir à tout le monde, pas seulement à ce projet. Le jeu -se contente de liens ordinaires — il ne contacte aucun service pendant qu'on y joue. +Contribuer se fait sur Wikimedia Commons, Wikidata, iNaturalist, Pl@ntNet ou Lingua Libre, +**jamais dans le jeu** : les contributions doivent servir à tout le monde, pas seulement à ce +projet. Le jeu se contente de liens ordinaires — il ne contacte aucun service pendant qu'on y +joue. + +**La langue aussi se demande.** Le projet écrit des noms en kréyòl sans avoir autorité pour +le faire. Quatre questions sont donc posées publiquement dans les fiches — `aki` ou `ake` ? +qu'appelez-vous `pòm-dlo` ? — et le validateur refuse qu'une entrée soit publiée sans qu'un +locuteur nommé ait tranché. Les variantes proposées sont conservées avec leur source : une +variante est un usage, pas une erreur. Voir +[`docs/kreyol-participatif.md`](docs/kreyol-participatif.md). ## Commandes @@ -63,6 +71,7 @@ runtime du jeu** : tout est cuit au build. | Fichier | Contenu | |---|---| | [`docs/contribuer.md`](docs/contribuer.md) | **comment enrichir la connaissance** — six gestes, du plus rapide au plus engageant | +| [`docs/kreyol-participatif.md`](docs/kreyol-participatif.md) | **corriger notre kréyòl** — les questions ouvertes, et comment y répondre | | [`docs/manques.md`](docs/manques.md) | ce qui manque, mesuré et daté — régénéré par script | | [`docs/plan.md`](docs/plan.md) | les 7 sessions et leurs portes de sortie mesurables | | [`docs/adr/`](docs/adr/) | les six décisions d'architecture et leurs motifs | diff --git a/docs/adr/0005-kreyol-langue-principale.md b/docs/adr/0005-kreyol-langue-principale.md index 7ec0dfb..0a71294 100644 --- a/docs/adr/0005-kreyol-langue-principale.md +++ b/docs/adr/0005-kreyol-langue-principale.md @@ -72,7 +72,66 @@ corrigées. l'orthographe leur est peu familière — un jeu qui enseigne les noms kréyòl sans les faire entendre rate sa cible. `npm run check:audio` tient la liste de ce qui manque. +## Amendement du 2026-07-27 — la relecture est ouverte, pas confiée à une seule personne + +La rédaction initiale supposait **un** relecteur qui tranche. C'est une mauvaise façon de +traiter une langue vivante : elle transforme un usage collectif en décision individuelle, et +elle bloque tout le projet sur la disponibilité d'une personne. + +Décision du porteur : la relecture devient **participative**, sans que la porte ne s'abaisse. + +### Trois états, pas deux + +`orthographe.statut` accepte désormais : + +- `a_relire` — personne ne s'est prononcé ; +- `en_discussion` — un doute est identifié **et posé publiquement**, avec sa question ; +- `relu` — un locuteur humain nommé a tranché. + +Le validateur refuse un statut `en_discussion` sans `question_ouverte` renseignée : **on ne +signale pas un doute sans dire lequel**. Un doute sans question décourage le lecteur au lieu +de l'appeler. Quatre entrées sont aujourd'hui dans cet état — `ake`, `medisinye`, +`lorye-jonn`, `pom-dlo`. + +### Les variantes sont conservées, pas arbitrées + +Le champ `noms.variantes_gcf` recueille les formes proposées par des locuteurs, chacune avec +sa source et son île. Une variante n'est pas une erreur en attente de correction : c'est un +usage attesté. La norme gwadloupéyenne détermine ce qui s'affiche en premier ; elle n'efface +pas ce que les gens disent. + +Le validateur refuse en revanche qu'une graphie identique au nom principal soit enregistrée +comme variante : une confirmation est une corroboration, et gonfler la liste des doutes +découragerait ceux qui la lisent. + +### La prononciation passe par les communs + +`audio` porte désormais `source`, `licence`, `url_description` et `valide`, et le validateur +exige un locuteur crédité, une licence, et une page d'origine pour toute source externe. + +**Lingua Libre est le canal recommandé**, avant l'enregistrement maison : les prises y sont +versées sur Commons sous licence libre et servent au Wiktionnaire et aux lexiques, pas +seulement à ce jeu. `npm run check:audio` interroge Lingua Libre automatiquement. + +### Ce que la mesure a montré + +Cet amendement n'est pas théorique. Lingua Libre compte **456 enregistrements en kréyòl +gwadloupéyen**, et **trois de nos treize noms y figurent déjà** — `gouyav`, `kénèt`, `zikak` — +en CC BY-SA 4.0, avec exactement notre graphie. Trois entrées sortent du doute par +corroboration externe, sans que le projet ait rien décidé. + +Autrement dit : la communauté existait avant nous. La question n'était pas de savoir qui +trancherait, mais d'aller regarder. + +### Ce qui ne change pas + +La porte. Une entrée n'est publiable que `relu`, avec un relecteur nommé. L'ouverture porte +sur **qui peut proposer**, jamais sur qui peut valider. + ## Point ouvert -Le relecteur n'est pas encore désigné. Tant qu'il ne l'est pas, aucune entrée ne peut être -publiée : c'est le validateur qui l'impose, pas une note de bas de page. +Le relecteur de référence n'est pas encore désigné, et les quatre questions ouvertes sont +rédigées **en français** — pis-aller assumé, puisque les rédiger en kréyòl reviendrait à +produire du kréyòl non relu au moment même où l'on reconnaît ne pas savoir le faire. Leur +traduction est la première contribution demandée dans +[`kreyol-participatif.md`](../kreyol-participatif.md). diff --git a/docs/audio-a-enregistrer.md b/docs/audio-a-enregistrer.md index 30df326..b670991 100644 --- a/docs/audio-a-enregistrer.md +++ b/docs/audio-a-enregistrer.md @@ -1,22 +1,53 @@ -# Enregistrements kréyòl à réaliser +# Prononciations kréyòl — état et travail à faire -> Généré par `npm run check:audio`. Aucune synthèse vocale : ces noms doivent être -> prononcés par une voix humaine locale (brief §6). +> Généré par `npm run check:audio`. **Aucune synthèse vocale** : ces noms doivent être +> prononcés par une voix humaine locale (brief §6). Le locuteur conserve ses droits +> voisins et est crédité nominativement. -Format attendu : `.opus` — un fichier par entrée, déposé dans `static/audio/.opus`. +Format embarqué : `.opus`, un fichier par entrée dans `static/audio/.opus`. -## À enregistrer (13) +## Il existe déjà une communauté + +**456 enregistrements en kréyòl gwadloupéyen** sont déjà publiés sur +[Lingua Libre](https://lingualibre.org), l'atelier d'enregistrement de Wikimedia, et versés +sur Commons sous licence libre (langue `gcf`, [Q3006280](https://www.wikidata.org/wiki/Q3006280)). + +Enregistrer là-bas plutôt que dans notre coin, c’est faire servir sa voix au +Wiktionnaire, aux lexiques et à tous les projets à venir — pas seulement à ce jeu. + +## ✔ Déjà enregistrés par la communauté (3) + +Ces noms n’ont pas besoin d’être réenregistrés : la prise existe, sous licence libre. +Il reste à vérifier qu’il s’agit bien du fruit, puis à renseigner le bloc `audio`. + +**C’est aussi une corroboration de notre graphie** : le nom enregistré porte +l’orthographe employée par le locuteur. + +| entrée | notre graphie | enregistrement | licence | locuteur | +|---|---|---|---|---| +| `gouyav` | gouyav | [LL-Q3006280 (gcf)-Palé Kréyol-Gouyav.wav](https://commons.wikimedia.org/wiki/File:LL-Q3006280_(gcf)-Pal%C3%A9_Kr%C3%A9yol-Gouyav.wav) | CC BY-SA 4.0 | Speaker: Palé Kréyol Recorder: Palé Kréy | +| `kenet` | kénèt | [LL-Q3006280 (gcf)-Palé Kréyol-Kénèt.wav](https://commons.wikimedia.org/wiki/File:LL-Q3006280_(gcf)-Pal%C3%A9_Kr%C3%A9yol-K%C3%A9n%C3%A8t.wav) | CC BY-SA 4.0 | Speaker: Palé Kréyol Recorder: Palé Kréy | +| `zikak` | zikak | [LL-Q3006280 (gcf)-Palé Kréyol-Zikak.wav](https://commons.wikimedia.org/wiki/File:LL-Q3006280_(gcf)-Pal%C3%A9_Kr%C3%A9yol-Zikak.wav) | CC BY-SA 4.0 | Speaker: Palé Kréyol Recorder: Palé Kréy | + +## 🎙️ À enregistrer (10) - [ ] **aki** — `static/audio/ake.opus` _(akée)_ + ⚠ Orthographe en discussion : Nous écrivons « aki », mais l'identifiant du fruit dit « ake ». Laquelle des deux graphies est la bonne en Guadeloupe ? Et comment le prononcez-vous chez vous ? - [ ] **fwiyapen** — `static/audio/fwiyapen.opus` _(fruit à pain)_ -- [ ] **gouyav** — `static/audio/gouyav.opus` _(goyave)_ -- [ ] **kénèt** — `static/audio/kenet.opus` _(quenette)_ - [ ] **kowosòl** — `static/audio/kowosol.opus` _(corossol)_ - [ ] **lorié-jòn** — `static/audio/lorye-jonn.opus` _(laurier jaune)_ + ⚠ Orthographe en discussion : « lorié-jòn » ou « lorye-jonn » ? Nous ne savons pas trancher. Comment l'écrivez-vous ? - [ ] **mansiniyé** — `static/audio/mansiniye.opus` _(mancenillier)_ - [ ] **medsinyé** — `static/audio/medisinye.opus` _(médicinier)_ + ⚠ Orthographe en discussion : « medsinyé » ou « medisinyé » ? Nous rencontrons les deux. Laquelle employez-vous ? - [ ] **pòm-dlo** — `static/audio/pom-dlo.opus` _(pomme d'eau)_ + ⚠ Orthographe en discussion : Selon les îles, « pòm-dlo », « pòm-malaka » et « pòm-rose » ne désignent pas le même fruit. Lequel appelez-vous « pòm-dlo » ? - [ ] **pòm-kajou** — `static/audio/pom-kajou.opus` _(pomme-cajou)_ - [ ] **pòm-kannèl** — `static/audio/pom-kannel.opus` _(pomme-cannelle)_ - [ ] **pòm-sitè** — `static/audio/pom-site.opus` _(prune de Cythère)_ -- [ ] **zikak** — `static/audio/zikak.opus` _(icaque)_ + +## Comment enregistrer + +Marche à suivre détaillée dans [`kreyol-participatif.md`](kreyol-participatif.md). +En deux lignes : une pièce calme, un téléphone, le mot dit deux fois, naturellement. +Une voix locale vaut mieux qu’un studio. diff --git a/docs/contribuer.md b/docs/contribuer.md index 71398cb..5e1b39a 100644 --- a/docs/contribuer.md +++ b/docs/contribuer.md @@ -162,18 +162,33 @@ Deux conseils qui découlent de cette mesure : --- -### E. Enregistrer une voix kréyòl +### E. Corriger le kréyòl, ou enregistrer une voix -Chaque nom doit être **entendu**, pas seulement lu : les enfants visés lisent mal le kréyòl -écrit, dont l'orthographe leur est peu familière. **Aucune synthèse vocale** n'est utilisée -dans ce projet. +**Le projet écrit des noms en kréyòl sans avoir autorité pour le faire.** Quatre questions +sont posées publiquement dans les données et affichées dans le jeu : `aki` ou `ake` ? +`medsinyé` ou `medisinyé` ? `lorié-jòn` ou `lorye-jonn` ? Et surtout : qu'appelez-vous +`pòm-dlo` ? -La liste de ce qui manque : [`audio-a-enregistrer.md`](audio-a-enregistrer.md) — **13 noms à -ce jour, soit la totalité.** +**Vous n'avez pas à être sûr, ni linguiste.** « Chez nous on dit plutôt comme ça, mais je ne +sais pas l'écrire » est une réponse utile — probablement la plus utile de toutes. Les +variantes sont conservées avec leur source et leur commune, jamais écrasées : une variante +est un usage, pas une erreur. -Un téléphone dans une pièce calme suffit. Une voix locale vaut mieux qu'un studio. Le -locuteur est crédité nominativement, conserve ses droits, et doit donner une autorisation -écrite avant embarquement. +**Pour la prononciation, préférez [Lingua Libre](https://lingualibre.org)** à un envoi +direct. C'est l'atelier d'enregistrement de Wikimedia : on choisit le kréyòl gwadloupéyen, +on lit une liste de mots, et chaque prise part sur Commons sous licence libre — utile au +Wiktionnaire et aux lexiques, pas seulement à ce jeu. **456 enregistrements en kréyòl +gwadloupéyen y existent déjà**, et trois de nos noms — `gouyav`, `kénèt`, `zikak` — s'y +trouvaient avant que nous les cherchions. + +Sinon, un téléphone dans une pièce calme suffit : le mot dit deux fois, naturellement, sans +articuler exagérément « pour les enfants » — ils apprennent la langue telle qu'elle se parle. + +**Aucune synthèse vocale ne sera jamais utilisée**, même provisoirement. Le locuteur conserve +ses droits, est crédité nominativement, et peut demander le retrait à tout moment. + +Reste à enregistrer : [`audio-a-enregistrer.md`](audio-a-enregistrer.md) — **10 noms sur 13**. +Protocole complet : [`kreyol-participatif.md`](kreyol-participatif.md). Une après-midi d'enregistrement vaut dix heures de développement. diff --git a/docs/kreyol-a-relire.md b/docs/kreyol-a-relire.md index 70912d4..6cbe407 100644 --- a/docs/kreyol-a-relire.md +++ b/docs/kreyol-a-relire.md @@ -11,11 +11,31 @@ ## Statut -**13 entrées sur 13 sont en `statut: "a_relire"`.** Aucune n'est publiable tant qu'un -locuteur nommé n'a pas tranché : `npm run validate:data` refuse toute entrée déclarée -valide dont l'orthographe n'est pas relue, et toute entrée relue sans nom de relecteur. +**9 entrées en `a_relire`, 4 en `en_discussion`** — ces dernières portant une question posée +publiquement, affichée dans le jeu et dans l'encyclopédie. Aucune n'est publiable tant qu'un +locuteur nommé n'a pas tranché : `npm run validate:data` refuse toute entrée déclarée valide +dont l'orthographe n'est pas relue, toute entrée relue sans nom de relecteur, et tout doute +signalé sans question. -Relecteur désigné : **aucun à ce jour.** +Relecteur de référence désigné : **aucun à ce jour** — mais la relecture est ouverte à tous, +voir [`kreyol-participatif.md`](kreyol-participatif.md). + +## 0. Trois graphies corroborées de l'extérieur + +Découvert le 2026-07-27 en interrogeant [Lingua Libre](https://lingualibre.org), l'atelier +d'enregistrement de Wikimedia : **456 enregistrements en kréyòl gwadloupéyen** y sont publiés, +et trois de nos noms s'y trouvaient déjà, **avec exactement notre graphie** : + +| notre graphie | enregistrement Lingua Libre | licence | +|---|---|---| +| **gouyav** | `LL-Q3006280 (gcf)-Palé Kréyol-Gouyav.wav` | CC BY-SA 4.0 | +| **kénèt** | `LL-Q3006280 (gcf)-Palé Kréyol-Kénèt.wav` | CC BY-SA 4.0 | +| **zikak** | `LL-Q3006280 (gcf)-Palé Kréyol-Zikak.wav` | CC BY-SA 4.0 | + +Ce n'est **pas une validation** — le statut de ces trois entrées reste `a_relire`, et seul un +relecteur nommé peut le changer. Mais c'est une corroboration par un locuteur extérieur au +projet, et elle vaut mieux que notre propre certitude : trois graphies sur treize cessent +d'être une supposition. ## 1. Incohérences internes relevées dans la graine @@ -34,6 +54,10 @@ graphie, pas une simple translittération : (`noms.gcf`) sera corrigé en conséquence. **L'identifiant, lui, ne bougera pas** — il est déjà dans les URLs et dans la progression stockée localement. +Ces trois entrées sont désormais en `statut: "en_discussion"` : la question est **posée dans +le produit**, pas seulement consignée ici. Elle est visible par toute personne qui ouvre la +fiche. + ## 2. Graphies à confirmer Toutes issues de `fruits.seed.json`, qui déclare lui-même l'ensemble comme non vérifié. @@ -83,6 +107,10 @@ L'entrée actuelle associe `pòm-dlo` à *Syzygium samarangense*, sur la seule f graine. **Non vérifié.** Trois voies possibles, à trancher par le relecteur : garder, corriger, ou scinder en plusieurs entrées distinctes. +Cette entrée est en `statut: "en_discussion"` avec la question suivante, affichée dans le +produit : « Selon les îles, "pòm-dlo", "pòm-malaka" et "pòm-rose" ne désignent pas le même +fruit. Lequel appelez-vous "pòm-dlo" ? » + ## 4. Ce qui reste à faire hors relecture - **Les enregistrements.** Chaque nom doit être prononcé par une voix humaine locale ; pas diff --git a/docs/kreyol-participatif.md b/docs/kreyol-participatif.md new file mode 100644 index 0000000..90fb05f --- /dev/null +++ b/docs/kreyol-participatif.md @@ -0,0 +1,178 @@ +# Le kréyòl se demande, il ne se décrète pas + +Ce projet écrit des noms de fruits en kréyòl. Il n'a aucune autorité pour le faire. + +Ce n'est pas une formule de modestie : c'est une contrainte inscrite dans le code. Le schéma +de données refuse qu'une entrée soit publiée si son orthographe n'a pas été relue par un +locuteur humain **nommé**, et il refuse qu'un doute soit signalé sans que la question soit +posée. Un agent de code ne peut pas franchir cette porte, et le porteur du projet ne le peut +pas seul non plus. + +Ce document explique comment répondre. + +--- + +## Ce qu'on sait déjà — mesuré le 2026-07-27 + +**Il existe une communauté, et elle est en avance sur nous.** Lingua Libre — l'atelier +d'enregistrement de Wikimedia — compte **456 enregistrements en kréyòl gwadloupéyen**, versés +sur Wikimedia Commons sous licence libre. Un contributeur, « Palé Kréyol », en a déposé +l'essentiel. + +**Trois de nos treize noms y sont déjà**, avec exactement notre graphie : + +| notre graphie | enregistrement | licence | +|---|---|---| +| **gouyav** | `LL-Q3006280 (gcf)-Palé Kréyol-Gouyav.wav` | CC BY-SA 4.0 | +| **kénèt** | `LL-Q3006280 (gcf)-Palé Kréyol-Kénèt.wav` | CC BY-SA 4.0 | +| **zikak** | `LL-Q3006280 (gcf)-Palé Kréyol-Zikak.wav` | CC BY-SA 4.0 | + +C'est doublement précieux : la prononciation est disponible **et** la graphie est corroborée +par un locuteur qui n'a rien à voir avec ce projet. Trois entrées sur treize sortent du +doute sans que nous ayons rien décidé. + +Les dix autres restent à enregistrer. La liste vivante : +[`audio-a-enregistrer.md`](audio-a-enregistrer.md), régénérée par `npm run check:audio`. + +**En revanche, le kréyòl reste absent des données structurées.** Zéro lexème Wikidata en +kréyòl gwadloupéyen. Zéro étiquette `gcf` sur les treize espèces. Zéro nom vernaculaire +kréyòl, quand ces mêmes espèces en totalisent 124 en chinois, anglais, portugais et slovène. + +--- + +## Les quatre questions posées aujourd'hui + +Elles sont dans les données, affichées dans l'encyclopédie et dans le jeu — pas cachées dans +un fichier de développeur. + +### 1. `aki` ou `ake` ? — l'akée + +Nous écrivons « aki », mais l'identifiant technique du fruit dit « ake ». Laquelle des deux +graphies est la bonne en Guadeloupe ? Et comment le prononcez-vous chez vous ? + +### 2. `medsinyé` ou `medisinyé` ? — le médicinier + +Nous rencontrons les deux formes. Laquelle employez-vous ? + +### 3. `lorié-jòn` ou `lorye-jonn` ? — le laurier-jaune + +Nous ne savons pas trancher. + +### 4. Qu'appelez-vous `pòm-dlo` ? + +Celle-ci n'est pas une question d'orthographe mais de **sens**, et c'est la plus importante. +Selon les îles, « pòm-dlo », « pòm-malaka » et « pòm-rose » ne désignent pas le même fruit — +trois *Syzygium* différents. Un jeu qui enseigne un nom que l'enfant entend appliqué à un +autre fruit chez lui produit exactement la confusion qu'il prétend dissiper. + +> **Ces quatre questions sont rédigées en français, et c'est un pis-aller.** Demander en +> français à des locuteurs kréyòl de corriger du kréyòl est un contresens. Mais les rédiger +> en kréyòl reviendrait à produire du kréyòl non relu au moment même où l'on reconnaît ne pas +> savoir le faire. +> +> **Leur traduction est donc la première contribution demandée.** + +--- + +## Répondre : trois façons, aucune ne demande de compétence technique + +### 1. Dire ce que vous employez — deux minutes + +Ouvrir une issue, écrire un courriel, le dire de vive voix au porteur. Ce qui aide : + +- **la graphie que vous employez**, telle que vous l'écririez ; +- **d'où vous êtes** — commune ou région : les usages varient d'un bout de l'île à l'autre, + et c'est une information, pas un bruit ; +- **votre âge approximatif ou celui de qui vous l'a appris**, si vous le voulez bien : une + forme transmise par une grand-mère et une forme apprise à l'école ne disent pas la même + chose. + +**Vous n'avez pas à être sûr.** « Chez nous on dit plutôt comme ça, mais je ne sais pas +l'écrire » est une réponse utile — probablement la plus utile de toutes. + +### 2. Proposer une autre forme — et elle sera gardée + +Les données prévoient un champ `variantes_gcf`. Une variante **n'est pas une erreur en +attente de correction** : c'est un usage attesté, conservé avec sa source et son île. + +Le validateur refuse d'ailleurs d'enregistrer comme « variante » une graphie identique au nom +principal : une confirmation est une corroboration, pas un désaccord, et gonfler +artificiellement la liste des doutes découragerait ceux qui la lisent. + +Ce que le projet **ne fera pas** : choisir une forme et effacer les autres. La norme +gwadloupéyenne est celle retenue pour l'affichage principal (ADR 0005) ; elle n'efface pas ce +que les gens disent. + +### 3. Enregistrer votre voix + +Chaque nom doit être **entendu**. Les enfants visés lisent mal le kréyòl écrit, dont +l'orthographe leur est peu familière — un jeu qui enseigne des noms kréyòl sans les faire +entendre rate sa cible. + +**Aucune synthèse vocale ne sera jamais utilisée.** Le schéma de données n'en accepte pas, et +ce n'est pas un détail technique : une voix de synthèse enseignerait une prononciation qui +n'est celle de personne. + +#### Où enregistrer — deux voies, la première est meilleure + +**Sur Lingua Libre — recommandé.** [lingualibre.org](https://lingualibre.org) est fait pour +ça : on choisit la langue (kréyòl gwadloupéyen, `gcf`), on lit une liste de mots, et chaque +prise part sur Wikimedia Commons sous licence libre. L'enregistrement sert alors au +Wiktionnaire, aux lexiques, aux projets à venir — **pas seulement à ce jeu**. C'est la même +logique que pour les photographies : contribuer aux communs plutôt qu'à un silo. + +Notre script `npm run check:audio` va chercher automatiquement si un nom y a été enregistré. +Vous n'avez rien à nous signaler : nous le trouverons. + +**Avec un téléphone, sinon.** Une pièce calme, pas de ventilateur, le mot dit **deux fois**, +naturellement, à vitesse normale — pas d'articulation exagérée « pour les enfants », ils +apprennent la langue telle qu'elle se parle. Envoyer le fichier brut, sans traitement. + +Dans les deux cas : le locuteur **conserve ses droits**, est **crédité nominativement**, et +donne une autorisation écrite avant embarquement. Il peut demander le retrait à tout moment. + +--- + +## Ce qui arrive à votre réponse + +``` + vous répondez, ou vous enregistrez + ↓ + la variante est ajoutée aux données, avec votre nom et votre commune + — rien n'est écrasé, rien n'est arbitré à la volée + ↓ + quand un relecteur nommé tranche : + orthographe.statut → "relu", orthographe.relu_par → son nom + ↓ + npm run validate:data autorise alors la publication de l'entrée + ↓ + le nom kréyòl part sur Wikidata (étiquette gcf + P1843) + — il cesse d'appartenir à ce seul projet +``` + +La dernière étape est le but réel. Un nom qui n'existe que dans ce jeu reste un nom perdu +partout ailleurs. + +--- + +## Ce que le projet s'interdit + +- **Trancher à la place des locuteurs.** Aucun agent, aucun script, aucun développeur. +- **Corriger en silence.** Tout écart constaté est signalé dans + [`kreyol-a-relire.md`](kreyol-a-relire.md), jamais réparé discrètement. +- **Mélanger les normes.** Le gwadloupéyen et le matinitjé diffèrent ; le schéma n'accepte + qu'une valeur de norme, si bien qu'en changer suppose de rouvrir la décision. +- **Confondre les créoles.** Le créole haïtien (`ht`) est une **autre langue**. L'employer + faute de mieux serait une erreur, pas un pis-aller. +- **Utiliser une voix de synthèse**, même provisoirement, même « en attendant ». +- **Publier une graphie douteuse sans le dire.** Le doute s'affiche, avec sa question. + +--- + +## Contact + +Issues du dépôt, ou le contact d'ORGANISATION KA INTERNATIONALE sur +[o-k-i.net](https://o-k-i.net). + +**Une réponse approximative vaut mieux qu'une erreur qui reste.** Si vous hésitez à écrire +parce que vous n'êtes pas linguiste : c'est précisément à vous que ce document s'adresse. diff --git a/docs/plan.md b/docs/plan.md index 2dc7545..d952e87 100644 --- a/docs/plan.md +++ b/docs/plan.md @@ -50,6 +50,7 @@ entrée, avec JSON-LD, hreflang et le traitement `PRD_AI_Overview`. | `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. @@ -145,7 +146,9 @@ kréyòl. Relecture orthographique. Arbitrage des six points de `docs/a-arbitrer |---|---| | 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 | @@ -197,11 +200,15 @@ qu'aucune session ne peut les produire : 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.** Liste prête : `docs/audio-a-enregistrer.md`. +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** par un humain. Points relevés : - `docs/kreyol-a-relire.md`. +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 diff --git a/docs/sessions/00-cadre-et-donnees.md b/docs/sessions/00-cadre-et-donnees.md index 9cf7084..53968bf 100644 --- a/docs/sessions/00-cadre-et-donnees.md +++ b/docs/sessions/00-cadre-et-donnees.md @@ -121,6 +121,38 @@ en CC BY-SA (jeu de données GBIF sous CC BY 4.0). À effort égal pour le contr seconde voie produit des images pleinement réutilisables. D'où le conseil mis en avant dans le guide : régler sa licence par défaut sur iNaturalist une fois pour toutes. +### La langue devient participative — et la communauté existait déjà + +Second ajout du porteur : demander aux locuteurs, sur l'orthographe comme sur la +prononciation, plutôt que d'attendre un relecteur unique. ADR 0005 amendé, protocole dans +[`kreyol-participatif.md`](../kreyol-participatif.md). + +**Découverte en interrogeant Lingua Libre**, l'atelier d'enregistrement de Wikimedia : +**456 enregistrements en kréyòl gwadloupéyen** y sont déjà publiés sous licence libre, versés +pour l'essentiel par un contributeur nommé « Palé Kréyol ». Et **trois de nos treize noms s'y +trouvaient déjà** — `gouyav`, `kénèt`, `zikak` — en CC BY-SA 4.0, **avec exactement notre +graphie**. + +Trois entrées sortent donc du doute par corroboration externe, sans que le projet ait rien +décidé, et trois enregistrements sont immédiatement utilisables. La leçon dépasse le cas : +la question n'était pas de savoir qui trancherait, mais d'aller regarder si quelqu'un +l'avait déjà fait. + +En regard, le kréyòl reste absent des données structurées : **0 lexème Wikidata** en kréyòl +gwadloupéyen, 0 étiquette `gcf` sur les treize items. + +**Ce que le modèle de données gagne.** Trois états d'orthographe au lieu de deux — +`a_relire`, `en_discussion`, `relu` — avec obligation de poser la question quand un doute est +signalé ; un champ `variantes_gcf` qui conserve les usages proposés avec leur source et leur +île, sans en effacer aucun ; un bloc `audio` qui porte source, licence, page d'origine et +locuteur crédité. Quatre entrées passent en `en_discussion` : `ake`, `medisinye`, +`lorye-jonn`, `pom-dlo`. + +**Un pis-aller assumé.** Les quatre questions sont rédigées en français. Demander en français +à des locuteurs kréyòl de corriger du kréyòl est un contresens — mais les rédiger en kréyòl +reviendrait à produire du kréyòl non relu au moment même où l'on reconnaît ne pas savoir le +faire. Leur traduction est la première contribution demandée. + ### Une mesure fausse, attrapée avant publication Le premier rapport annonçait **28 vues manquantes sur 65**. C'était faux. Le groupement `OR` diff --git a/fruits.schema.json b/fruits.schema.json index a330d7b..6550c87 100644 --- a/fruits.schema.json +++ b/fruits.schema.json @@ -42,26 +42,45 @@ "gcf": { "type": "string", "minLength": 1, "description": "Nom kréyòl — nom principal de l'entrée." }, "fr": { "type": "string" }, "en": { "type": "string" }, - "es": { "type": "string" } + "es": { "type": "string" }, + "variantes_gcf": { + "type": "array", + "description": "Autres graphies ou autres noms proposés par des locuteurs. On les garde toutes : une variante n'est pas une erreur, c'est un usage. C'est le matériau de la relecture, pas son résultat.", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["graphie", "source"], + "properties": { + "graphie": { "type": "string", "minLength": 1 }, + "source": { "type": "string", "minLength": 2, "description": "Qui la propose : personne, commune, enregistrement, publication." }, + "ile": { "enum": ["gp", "mq", "gf", "re", null] }, + "note": { "type": ["string", "null"] } + } + } + } } }, "orthographe": { "type": "object", "additionalProperties": false, - "required": ["norme", "statut", "relu_par"], + "required": ["norme", "statut", "relu_par", "question_ouverte"], "properties": { "norme": { "enum": ["gwadloupeyen"], "description": "Norme unique du projet (ADR 0005). Ne jamais mélanger avec le matinitjé." }, "statut": { - "enum": ["a_relire", "relu"], - "description": "Passe à 'relu' uniquement quand un locuteur humain a tranché. Aucun agent ne peut le faire." + "enum": ["a_relire", "en_discussion", "relu"], + "description": "'a_relire' : personne ne s'est prononcé. 'en_discussion' : un doute est identifié et posé publiquement. 'relu' : un locuteur humain nommé a tranché — aucun agent ne peut le faire." }, "relu_par": { "type": ["string", "null"], "description": "Nom du relecteur humain. Obligatoirement non nul quand statut = relu." + }, + "question_ouverte": { + "type": ["string", "null"], + "description": "La question posée aux locuteurs, affichée telle quelle dans le jeu et l'encyclopédie. Obligatoire quand statut = en_discussion : on ne signale pas un doute sans dire lequel." } } }, @@ -145,14 +164,31 @@ "audio": { "type": "object", "additionalProperties": false, - "required": ["gcf", "locuteur"], + "required": ["gcf", "locuteur", "source", "licence", "url_description", "valide"], + "description": "La prononciation du nom kréyòl. Aucune synthèse vocale (brief §6) : une voix humaine, toujours.", "properties": { "gcf": { "type": ["string", "null"], "pattern": "^/audio/[a-z0-9-]+\\.opus$", - "description": "Prononciation kréyòl par une voix humaine. Aucune synthèse vocale (brief §6). Null tant que l'enregistrement manque ; le jeu doit se replier en silence." + "description": "Fichier embarqué dans le jeu. Null tant que l'enregistrement manque ; le jeu se replie alors en silence, jamais sur une voix de synthèse." }, - "locuteur": { "type": ["string", "null"] } + "locuteur": { + "type": ["string", "null"], + "description": "Nom ou pseudonyme du locuteur, crédité nominativement. Il conserve ses droits voisins." + }, + "source": { + "enum": ["porteur", "lingualibre", "contributeur", null], + "description": "'lingualibre' désigne un enregistrement déjà versé aux communs — à préférer, il sert au-delà de ce jeu." + }, + "licence": { + "enum": ["CC0-1.0", "CC-BY-4.0", "CC-BY-SA-4.0", "OKI-CC-BY-SA-4.0", null] + }, + "url_description": { + "type": ["string", "null"], + "description": "Page d'origine de l'enregistrement. Obligatoire quand la source n'est pas le porteur." + }, + "valide": { "type": "boolean" }, + "note": { "type": ["string", "null"] } } }, diff --git a/src/lib/data/fruits/ake.json b/src/lib/data/fruits/ake.json index 30aeb09..14685d4 100644 --- a/src/lib/data/fruits/ake.json +++ b/src/lib/data/fruits/ake.json @@ -6,12 +6,14 @@ "gcf": "aki", "fr": "akée", "en": "ackee", - "es": "seso vegetal" + "es": "seso vegetal", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", - "statut": "a_relire", - "relu_par": null + "statut": "en_discussion", + "relu_par": null, + "question_ouverte": "Nous écrivons « aki », mais l'identifiant du fruit dit « ake ». Laquelle des deux graphies est la bonne en Guadeloupe ? Et comment le prononcez-vous chez vous ?" }, "taxon": { "scientifique": "Blighia sapida", @@ -120,7 +122,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/fwiyapen.json b/src/lib/data/fruits/fwiyapen.json index fbe301b..0a02843 100644 --- a/src/lib/data/fruits/fwiyapen.json +++ b/src/lib/data/fruits/fwiyapen.json @@ -6,12 +6,14 @@ "gcf": "fwiyapen", "fr": "fruit à pain", "en": "breadfruit", - "es": "fruta del pan" + "es": "fruta del pan", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Artocarpus altilis", @@ -128,7 +130,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/gouyav.json b/src/lib/data/fruits/gouyav.json index 3c32463..9916614 100644 --- a/src/lib/data/fruits/gouyav.json +++ b/src/lib/data/fruits/gouyav.json @@ -6,12 +6,14 @@ "gcf": "gouyav", "fr": "goyave", "en": "guava", - "es": "guayaba" + "es": "guayaba", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Psidium guajava", @@ -127,7 +129,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/kenet.json b/src/lib/data/fruits/kenet.json index 1e2df02..5954d62 100644 --- a/src/lib/data/fruits/kenet.json +++ b/src/lib/data/fruits/kenet.json @@ -6,12 +6,14 @@ "gcf": "kénèt", "fr": "quenette", "en": "Spanish lime", - "es": "mamoncillo" + "es": "mamoncillo", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Melicoccus bijugatus", @@ -127,7 +129,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/kowosol.json b/src/lib/data/fruits/kowosol.json index 3075215..e84cec8 100644 --- a/src/lib/data/fruits/kowosol.json +++ b/src/lib/data/fruits/kowosol.json @@ -6,12 +6,14 @@ "gcf": "kowosòl", "fr": "corossol", "en": "soursop", - "es": "guanábana" + "es": "guanábana", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Annona muricata", @@ -126,7 +128,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/lorye-jonn.json b/src/lib/data/fruits/lorye-jonn.json index 29c45bb..783fc09 100644 --- a/src/lib/data/fruits/lorye-jonn.json +++ b/src/lib/data/fruits/lorye-jonn.json @@ -6,12 +6,14 @@ "gcf": "lorié-jòn", "fr": "laurier jaune", "en": "yellow oleander", - "es": "cabalonga" + "es": "cabalonga", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", - "statut": "a_relire", - "relu_par": null + "statut": "en_discussion", + "relu_par": null, + "question_ouverte": "« lorié-jòn » ou « lorye-jonn » ? Nous ne savons pas trancher. Comment l'écrivez-vous ?" }, "taxon": { "scientifique": "Cascabela thevetia", @@ -122,7 +124,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/mansiniye.json b/src/lib/data/fruits/mansiniye.json index 83b2622..111817f 100644 --- a/src/lib/data/fruits/mansiniye.json +++ b/src/lib/data/fruits/mansiniye.json @@ -6,12 +6,14 @@ "gcf": "mansiniyé", "fr": "mancenillier", "en": "manchineel", - "es": "manzanillo" + "es": "manzanillo", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Hippomane mancinella", @@ -122,7 +124,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/medisinye.json b/src/lib/data/fruits/medisinye.json index d85af31..a5dc96e 100644 --- a/src/lib/data/fruits/medisinye.json +++ b/src/lib/data/fruits/medisinye.json @@ -6,12 +6,14 @@ "gcf": "medsinyé", "fr": "médicinier", "en": "physic nut", - "es": "piñón" + "es": "piñón", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", - "statut": "a_relire", - "relu_par": null + "statut": "en_discussion", + "relu_par": null, + "question_ouverte": "« medsinyé » ou « medisinyé » ? Nous rencontrons les deux. Laquelle employez-vous ?" }, "taxon": { "scientifique": "Jatropha curcas", @@ -120,7 +122,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/pom-dlo.json b/src/lib/data/fruits/pom-dlo.json index 81364c6..847b673 100644 --- a/src/lib/data/fruits/pom-dlo.json +++ b/src/lib/data/fruits/pom-dlo.json @@ -6,12 +6,14 @@ "gcf": "pòm-dlo", "fr": "pomme d'eau", "en": "water apple", - "es": "manzana de agua" + "es": "manzana de agua", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", - "statut": "a_relire", - "relu_par": null + "statut": "en_discussion", + "relu_par": null, + "question_ouverte": "Selon les îles, « pòm-dlo », « pòm-malaka » et « pòm-rose » ne désignent pas le même fruit. Lequel appelez-vous « pòm-dlo » ?" }, "taxon": { "scientifique": "Syzygium samarangense", @@ -126,7 +128,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false, diff --git a/src/lib/data/fruits/pom-kajou.json b/src/lib/data/fruits/pom-kajou.json index 2191442..b7248ca 100644 --- a/src/lib/data/fruits/pom-kajou.json +++ b/src/lib/data/fruits/pom-kajou.json @@ -6,12 +6,14 @@ "gcf": "pòm-kajou", "fr": "pomme-cajou", "en": "cashew apple", - "es": "marañón" + "es": "marañón", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Anacardium occidentale", @@ -119,7 +121,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/pom-kannel.json b/src/lib/data/fruits/pom-kannel.json index f4c7bcc..27e5221 100644 --- a/src/lib/data/fruits/pom-kannel.json +++ b/src/lib/data/fruits/pom-kannel.json @@ -6,12 +6,14 @@ "gcf": "pòm-kannèl", "fr": "pomme-cannelle", "en": "sugar apple", - "es": "anón" + "es": "anón", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Annona squamosa", @@ -127,7 +129,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/pom-site.json b/src/lib/data/fruits/pom-site.json index 7199180..0c4725e 100644 --- a/src/lib/data/fruits/pom-site.json +++ b/src/lib/data/fruits/pom-site.json @@ -6,12 +6,14 @@ "gcf": "pòm-sitè", "fr": "prune de Cythère", "en": "ambarella", - "es": "jobo indio" + "es": "jobo indio", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Spondias dulcis", @@ -126,7 +128,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/src/lib/data/fruits/zikak.json b/src/lib/data/fruits/zikak.json index 5473054..65b8fa8 100644 --- a/src/lib/data/fruits/zikak.json +++ b/src/lib/data/fruits/zikak.json @@ -6,12 +6,14 @@ "gcf": "zikak", "fr": "icaque", "en": "cocoplum", - "es": "icaco" + "es": "icaco", + "variantes_gcf": [] }, "orthographe": { "norme": "gwadloupeyen", "statut": "a_relire", - "relu_par": null + "relu_par": null, + "question_ouverte": null }, "taxon": { "scientifique": "Chrysobalanus icaco", @@ -125,7 +127,12 @@ ], "audio": { "gcf": null, - "locuteur": null + "locuteur": null, + "source": null, + "licence": null, + "url_description": null, + "valide": false, + "note": null }, "sources_factuelles": [], "valide": false diff --git a/tools/data/build-dataset.mjs b/tools/data/build-dataset.mjs index fc6d9e2..e99b6cf 100644 --- a/tools/data/build-dataset.mjs +++ b/tools/data/build-dataset.mjs @@ -74,6 +74,34 @@ function normaliserDanger(d) { return { ...reste, resume: resume ?? note }; } +/** + * Les questions posées aux locuteurs, affichées telles quelles dans le jeu. + * + * Ce sont des QUESTIONS, pas des corrections : le projet n'a pas à trancher l'orthographe + * kréyòl (ADR 0005), mais il a le devoir de dire où il doute plutôt que d'afficher une + * graphie douteuse avec l'aplomb d'une certitude. + * + * Une entrée qui figure ici sort en `statut: "en_discussion"`, ce qui déclenche l'affichage + * de la question dans l'encyclopédie et dans le jeu. + */ +const QUESTIONS_KREYOL = { + ake: "Nous écrivons « aki », mais l'identifiant du fruit dit « ake ». Laquelle des deux graphies est la bonne en Guadeloupe ? Et comment le prononcez-vous chez vous ?", + medisinye: "« medsinyé » ou « medisinyé » ? Nous rencontrons les deux. Laquelle employez-vous ?", + 'lorye-jonn': "« lorié-jòn » ou « lorye-jonn » ? Nous ne savons pas trancher. Comment l'écrivez-vous ?", + 'pom-dlo': + "Selon les îles, « pòm-dlo », « pòm-malaka » et « pòm-rose » ne désignent pas le même fruit. Lequel appelez-vous « pòm-dlo » ?" +}; + +/** + * Ces questions sont rédigées en français, et c'est un pis-aller assumé : demander en + * français à des locuteurs kréyòl de corriger du kréyòl est un contresens. Mais rédiger + * la question en kréyòl reviendrait à produire du kréyòl non relu au moment même où l'on + * reconnaît ne pas savoir le faire (ADR 0005). + * + * Leur traduction en kréyòl fait donc partie des contributions demandées — c'est la + * première tâche listée dans docs/kreyol-participatif.md. + */ + /** Deux planches Blanco tronquées au même slug : on désambiguïse plutôt que de perdre un média. */ function idsUniques(medias) { const vus = new Map(); @@ -159,8 +187,13 @@ async function main() { $schema: '../../../../fruits.schema.json', id: e.id, categorie: e.categorie, - noms: e.noms, - orthographe: { norme: 'gwadloupeyen', statut: 'a_relire', relu_par: null }, + noms: { ...e.noms, variantes_gcf: [] }, + orthographe: { + norme: 'gwadloupeyen', + statut: QUESTIONS_KREYOL[e.id] ? 'en_discussion' : 'a_relire', + relu_par: null, + question_ouverte: QUESTIONS_KREYOL[e.id] ?? null + }, taxon: { scientifique: t.gbif.canonicalName ?? e.taxon.scientifique, famille: t.gbif.famille ?? e.taxon.famille, @@ -179,7 +212,15 @@ async function main() { danger: normaliserDanger(e.danger), indices: e.indices ?? {}, medias: candidats, - audio: { gcf: null, locuteur: null }, + audio: { + gcf: null, + locuteur: null, + source: null, + licence: null, + url_description: null, + valide: false, + note: null + }, sources_factuelles: [], valide: false }; diff --git a/tools/data/check-audio.mjs b/tools/data/check-audio.mjs index 86a8e15..1fbec4d 100644 --- a/tools/data/check-audio.mjs +++ b/tools/data/check-audio.mjs @@ -1,16 +1,23 @@ #!/usr/bin/env node /** - * check-audio.mjs — liste les enregistrements kréyòl manquants. + * check-audio.mjs — état des prononciations kréyòl. * - * Le brief §6 le demande explicitement : « prévois le contrat (audio.gcf, format .opus, - * repli silencieux si le fichier manque) et un script de vérification listant les - * enregistrements manquants. » + * Le brief §6 le demande : « prévois le contrat (audio.gcf, format .opus, repli silencieux + * si le fichier manque) et un script de vérification listant les enregistrements manquants ». * - * Pas de synthèse vocale : ce script n'en fabrique aucune. Il produit une liste de courses - * pour la séance d'enregistrement — une après-midi de terrain vaut dix heures de code. + * Ce script fait deux choses : + * 1. il liste ce qui manque localement ; + * 2. il cherche sur **Lingua Libre** si quelqu'un a déjà enregistré le mot. * - * Ce script n'échoue jamais : un enregistrement manquant est un travail à faire, - * pas un défaut de build. Le jeu doit se replier en silence. + * Le second point est le cœur de la démarche : Lingua Libre est l'atelier d'enregistrement + * de Wikimedia, et ses prises sont versées sur Commons sous licence libre. Un nom enregistré + * là-bas sert à ce jeu, mais aussi au Wiktionnaire, aux lexiques, aux synthèses vocales + * futures — bref, à la langue, pas seulement à nous. + * + * Pas de synthèse vocale : ce script n'en fabrique aucune, et le schéma n'en accepte pas. + * Ce script n'échoue jamais : un enregistrement manquant est un travail à faire. + * + * Sortie : docs/audio-a-enregistrer.md */ import { readFile, readdir, writeFile, access } from 'node:fs/promises'; @@ -20,6 +27,13 @@ import { dirname, join } from 'node:path'; const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..'); const DATA = join(ROOT, 'src', 'lib', 'data', 'fruits'); const STATIC = join(ROOT, 'static'); +const UA = 'ki-fwi-dataset/0.1 (https://o-k-i.net ; projet educatif ORGANISATION KA INTERNATIONALE)'; + +/** Élément Wikidata du kréyòl gwadloupéyen — sert de code de langue à Lingua Libre. */ +const Q_GWADLOUPEYEN = 'Q3006280'; +const CATEGORIE_LL = 'Lingua Libre pronunciation-gcf'; + +const pause = (ms) => new Promise((r) => setTimeout(r, ms)); async function existe(p) { try { @@ -30,54 +44,185 @@ async function existe(p) { } } +async function commons(params) { + const u = new URL('https://commons.wikimedia.org/w/api.php'); + for (const [k, v] of Object.entries({ format: 'json', formatversion: '2', ...params })) u.searchParams.set(k, v); + const res = await fetch(u, { headers: { 'User-Agent': UA, Accept: 'application/json' } }); + if (!res.ok) throw new Error(`Commons ${res.status}`); + return res.json(); +} + +const sansBalises = (s) => + s + ? String(s) + .replace(/<[^>]+>/g, ' ') + .replace(/\s+/g, ' ') + .trim() + : null; + +/** Cherche un enregistrement du mot dans la catégorie Lingua Libre du kréyòl gwadloupéyen. */ +async function chercherLinguaLibre(mot) { + const j = await commons({ + action: 'query', + list: 'search', + srnamespace: '6', + srlimit: '3', + srsearch: `incategory:"${CATEGORIE_LL}" ${mot}` + }); + const trouves = j.query?.search ?? []; + if (!trouves.length) return null; + + const detail = await commons({ + action: 'query', + prop: 'imageinfo', + iiprop: 'url|mime|extmetadata', + iiextmetadatafilter: 'LicenseShortName|Artist', + titles: trouves[0].title + }); + const p = detail.query?.pages?.[0]; + const i = p?.imageinfo?.[0]; + return { + titre: p?.title ?? trouves[0].title, + licence: sansBalises(i?.extmetadata?.LicenseShortName?.value), + auteur: sansBalises(i?.extmetadata?.Artist?.value), + url_fichier: i?.url ?? null, + url_description: i?.descriptionurl ?? null, + autres: trouves.length - 1 + }; +} + +/** Combien d'enregistrements existent en tout dans cette langue ? Mesure l'état de la communauté. */ +async function tailleCategorie() { + const j = await commons({ action: 'query', prop: 'categoryinfo', titles: `Category:${CATEGORIE_LL}` }); + return j.query?.pages?.[0]?.categoryinfo?.files ?? 0; +} + async function main() { + const horsLigne = process.argv.includes('--hors-ligne'); const fichiers = (await readdir(DATA)).filter((f) => f.endsWith('.json')).sort(); + const manquants = []; const absents = []; const presents = []; + const dejaEnregistres = []; + + let totalLL = 0; + if (!horsLigne) { + try { + totalLL = await tailleCategorie(); + } catch { + console.warn('⚠ Lingua Libre injoignable — rapport local uniquement.'); + } + } for (const f of fichiers) { const e = JSON.parse(await readFile(join(DATA, f), 'utf8')); - if (!e.audio.gcf) { + + if (e.audio.gcf) { + if (await existe(join(STATIC, e.audio.gcf))) presents.push(e); + else absents.push(e); + } else { manquants.push(e); - continue; } - // Le chemin est absolu depuis la racine du site : /audio/.opus → static/audio/.opus - if (await existe(join(STATIC, e.audio.gcf))) presents.push(e); - else absents.push(e); + + if (!horsLigne && !e.audio.gcf) { + try { + process.stdout.write(`→ Lingua Libre : ${e.noms.gcf}… `); + const trouve = await chercherLinguaLibre(e.noms.gcf); + console.log(trouve ? '✔ déjà enregistré' : '—'); + if (trouve) dejaEnregistres.push({ e, trouve }); + await pause(400); + } catch { + console.log('(échec de la requête)'); + } + } } const l = [ - '# Enregistrements kréyòl à réaliser', + '# Prononciations kréyòl — état et travail à faire', '', - '> Généré par `npm run check:audio`. Aucune synthèse vocale : ces noms doivent être', - '> prononcés par une voix humaine locale (brief §6).', + '> Généré par `npm run check:audio`. **Aucune synthèse vocale** : ces noms doivent être', + '> prononcés par une voix humaine locale (brief §6). Le locuteur conserve ses droits', + '> voisins et est crédité nominativement.', '', - "Format attendu : `.opus` — un fichier par entrée, déposé dans `static/audio/.opus`.", - '', - `## À enregistrer (${manquants.length})`, + 'Format embarqué : `.opus`, un fichier par entrée dans `static/audio/.opus`.', '' ]; - for (const e of manquants) l.push(`- [ ] **${e.noms.gcf}** — \`static/audio/${e.id}.opus\` _(${e.noms.fr ?? ''})_`); + + if (totalLL) { + l.push( + '## Il existe déjà une communauté', + '', + `**${totalLL} enregistrements en kréyòl gwadloupéyen** sont déjà publiés sur`, + `[Lingua Libre](https://lingualibre.org), l'atelier d'enregistrement de Wikimedia, et versés`, + `sur Commons sous licence libre (langue \`gcf\`, [${Q_GWADLOUPEYEN}](https://www.wikidata.org/wiki/${Q_GWADLOUPEYEN})).`, + '', + 'Enregistrer là-bas plutôt que dans notre coin, c’est faire servir sa voix au', + 'Wiktionnaire, aux lexiques et à tous les projets à venir — pas seulement à ce jeu.', + '' + ); + } + + if (dejaEnregistres.length) { + l.push( + `## ✔ Déjà enregistrés par la communauté (${dejaEnregistres.length})`, + '', + 'Ces noms n’ont pas besoin d’être réenregistrés : la prise existe, sous licence libre.', + 'Il reste à vérifier qu’il s’agit bien du fruit, puis à renseigner le bloc `audio`.', + '', + '**C’est aussi une corroboration de notre graphie** : le nom enregistré porte', + 'l’orthographe employée par le locuteur.', + '', + '| entrée | notre graphie | enregistrement | licence | locuteur |', + '|---|---|---|---|---|' + ); + for (const { e, trouve } of dejaEnregistres) { + const t = trouve.titre.replace('File:', '').replace(/\|/g, '\\|'); + l.push( + `| \`${e.id}\` | ${e.noms.gcf} | [${t.slice(0, 52)}](${trouve.url_description}) | ${trouve.licence ?? '?'} | ${(trouve.auteur ?? '?').slice(0, 40)} |` + ); + } + l.push(''); + } + + const restants = manquants.filter((e) => !dejaEnregistres.some((d) => d.e.id === e.id)); + l.push(`## 🎙️ À enregistrer (${restants.length})`, ''); + if (!restants.length) l.push('_Rien à enregistrer._', ''); + for (const e of restants) { + const q = e.orthographe.question_ouverte; + l.push(`- [ ] **${e.noms.gcf}** — \`static/audio/${e.id}.opus\` _(${e.noms.fr ?? ''})_`); + if (q) l.push(` ⚠ Orthographe en discussion : ${q}`); + } l.push(''); + if (absents.length) { - l.push(`## Déclarés mais fichier introuvable (${absents.length})`, ''); - for (const e of absents) l.push(`- ⚠ \`${e.id}\` → \`${e.audio.gcf}\` absent de \`static/\``); + l.push(`## ⚠ Déclarés mais fichier introuvable (${absents.length})`, ''); + for (const e of absents) l.push(`- \`${e.id}\` → \`${e.audio.gcf}\` absent de \`static/\``); l.push(''); } if (presents.length) { l.push(`## En place (${presents.length})`, ''); - for (const e of presents) l.push(`- ✔ \`${e.id}\` — ${e.audio.locuteur ?? 'locuteur non renseigné'}`); + for (const e of presents) + l.push(`- \`${e.id}\` — ${e.audio.locuteur ?? 'locuteur non renseigné'} (${e.audio.licence ?? 'licence ?'})`); l.push(''); } + l.push( + '## Comment enregistrer', + '', + 'Marche à suivre détaillée dans [`kreyol-participatif.md`](kreyol-participatif.md).', + 'En deux lignes : une pièce calme, un téléphone, le mot dit deux fois, naturellement.', + 'Une voix locale vaut mieux qu’un studio.', + '' + ); + await writeFile(join(ROOT, 'docs', 'audio-a-enregistrer.md'), l.join('\n')); - console.log(`À enregistrer : ${manquants.length}`); - console.log(`Introuvables : ${absents.length}`); - console.log(`En place : ${presents.length}`); + console.log(`\nDéjà enregistrés par la communauté : ${dejaEnregistres.length}`); + console.log(`À enregistrer : ${restants.length}`); + console.log(`Introuvables : ${absents.length}`); + console.log(`En place : ${presents.length}`); console.log('\n docs/audio-a-enregistrer.md'); - if (absents.length) console.log("\n⚠ Des chemins audio sont déclarés sans fichier : le jeu se repliera en silence."); } main().catch((e) => { diff --git a/tools/data/test-porte.mjs b/tools/data/test-porte.mjs index 6736207..5d1ec5c 100644 --- a/tools/data/test-porte.mjs +++ b/tools/data/test-porte.mjs @@ -112,7 +112,7 @@ const CAS = [ regle: 'brief §8 — « ≥ 2 photos Commons par fruit avec auteur, licence et URL. »', muter: (e) => { e.medias = [mediaValide()]; - e.orthographe = { norme: 'gwadloupeyen', statut: 'relu', relu_par: 'relecteur' }; + e.orthographe = { norme: 'gwadloupeyen', statut: 'relu', relu_par: 'relecteur', question_ouverte: null }; e.valide = true; } }, @@ -131,6 +131,50 @@ const CAS = [ e.medias = [mediaValide()]; e.medias[0].valide_par = null; } + }, + { + nom: 'doute orthographique signalé sans question posée', + regle: 'ADR 0005 — on ne signale pas un doute sans dire lequel, sinon on décourage au lieu d’appeler.', + muter: (e) => { + e.orthographe = { norme: 'gwadloupeyen', statut: 'en_discussion', relu_par: null, question_ouverte: null }; + } + }, + { + nom: 'enregistrement sans locuteur crédité', + regle: 'brief §6 et LICENSE-CONTENT §4 — le locuteur conserve ses droits voisins et est crédité nominativement.', + muter: (e) => { + e.audio = { + gcf: '/audio/kowosol.opus', + locuteur: null, + source: 'contributeur', + licence: 'CC-BY-SA-4.0', + url_description: null, + valide: false, + note: null + }; + } + }, + { + nom: 'enregistrement externe sans page d’origine', + regle: 'brief §3 — toute ressource tierce porte sa source vérifiable.', + muter: (e) => { + e.audio = { + gcf: '/audio/kowosol.opus', + locuteur: 'Palé Kréyol', + source: 'lingualibre', + licence: 'CC-BY-SA-4.0', + url_description: null, + valide: false, + note: null + }; + } + }, + { + nom: 'variante orthographique identique au nom principal', + regle: 'ADR 0005 — une graphie confirmée est une corroboration, pas une variante : ne pas gonfler le doute.', + muter: (e) => { + e.noms.variantes_gcf = [{ graphie: e.noms.gcf, source: 'un locuteur', ile: 'gp', note: null }]; + } } ]; @@ -140,7 +184,7 @@ const TEMOIN = { attendu: 0, muter: (e) => { e.medias = [mediaValide(), muter(mediaValide(), (m) => (m.id = 'photo-temoin-2'))]; - e.orthographe = { norme: 'gwadloupeyen', statut: 'relu', relu_par: 'relecteur' }; + e.orthographe = { norme: 'gwadloupeyen', statut: 'relu', relu_par: 'relecteur', question_ouverte: null }; e.valide = true; } }; diff --git a/tools/data/validate.mjs b/tools/data/validate.mjs index 94e5f7e..e0651cb 100644 --- a/tools/data/validate.mjs +++ b/tools/data/validate.mjs @@ -132,8 +132,28 @@ async function main() { warn(f, 'entrée non encore validée pour publication'); } - if (!e.audio.gcf) warn(f, 'aucun enregistrement kréyòl — le jeu devra se replier en silence'); + // Langue — ADR 0005. On ne tranche pas l'orthographe, mais on ne bâcle pas la question. + if (e.orthographe.statut === 'en_discussion' && !e.orthographe.question_ouverte) + err(f, "orthographe « en discussion » sans question posée — on ne signale pas un doute sans dire lequel"); + if (e.orthographe.statut === 'relu' && !e.orthographe.relu_par) + err(f, 'orthographe déclarée relue sans nom de relecteur'); + for (const v of e.noms.variantes_gcf ?? []) + if (v.graphie === e.noms.gcf) + err(f, `variante « ${v.graphie} » identique au nom principal — c'est une corroboration, pas une variante`); + + // Prononciation — brief §6 : voix humaine, jamais de synthèse. + if (e.audio.gcf) { + if (!e.audio.locuteur) err(f, 'enregistrement sans locuteur crédité — il conserve ses droits voisins'); + if (!e.audio.licence) err(f, 'enregistrement sans licence déclarée'); + if (e.audio.source && e.audio.source !== 'porteur' && !e.audio.url_description) + err(f, `enregistrement de source « ${e.audio.source} » sans page d'origine`); + if (!e.audio.valide) warn(f, 'enregistrement présent mais non validé — le jeu se repliera en silence'); + } else { + warn(f, 'aucun enregistrement kréyòl — le jeu devra se replier en silence'); + } + if (e.orthographe.statut === 'a_relire') warn(f, 'orthographe kréyòl à relire'); + if (e.orthographe.statut === 'en_discussion') warn(f, 'orthographe kréyòl en discussion — question posée aux locuteurs'); entrees.push(e); }