Étape 0b close : plan supprimé, feuille de route et journal à jour

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Pierre MARTIN
2026-11-02 19:23:43 +01:00
co-authored by Claude Opus 5.5
parent 07dd36605c
commit c411771e48
3 changed files with 25 additions and 167 deletions
+3 -3
View File
@@ -12,12 +12,12 @@ Légende : 🔄 en cours · ⏳ à venir · ⏸ conditionnel
Acquis : socle du dépôt, organisation (ADR 0001, 0003, 0006), source du moteur
(ADR 0005 : gnubg officiel, commit 14b6798), gnubg de référence et 32 positions
de référence (0a.2), moteur embarqué et `engine-cli` (0a.3), comparaison
automatique aux références, tolérance 0,002 (0a.4).
automatique aux références, tolérance 0,002 (0a.4), moteur en WebAssembly avec
page de test, page de mesure et guide de test (0b).
| Sous-étape | Contenu | État | Plan |
| --- | --- | --- | --- |
| 0b | Moteur en WebAssembly, page de test dans un Web Worker, `make deploy-web`, `make bench` | 🔄 | `plans/2026-11-02-moteur-webassembly.md` |
| Mesures | Pierre relève les mesures sur le Fairphone 4 | ⏳ | |
| Mesures | Pierre relève les mesures sur le Fairphone 4, en suivant `docs/guide-test-etape-0.md` | 🔄 | |
| Décision | Socle PWA ou Android natif, consigné dans un ADR — validation de Pierre | ⏳ | |
| 0c | Android natif (NDK, Gradle en ligne de commande, `make deploy` via adb) | ⏸ si 0b échoue | |
| 0d | Plateau minimal jouable sur le socle retenu ; vérifié avec Pierre en suivant `docs/scenarios/jouer-une-partie.feature` | ⏳ | |
+22 -7
View File
@@ -38,14 +38,29 @@ Une entrée datée par session : ce qui a été fait, décidé, et la suite.
- Les hash de commit s'écrivent sans backticks, pour les liens automatiques de
Gitea (demande de Pierre).
**Incident ouvert**
- La MR !1 a bien été fusionnée côté git (commit de fusion 6958acc sur `main`),
mais Gitea l'affiche toujours « open ». Cause non établie ; la base de
données du serveur refuse déjà les émojis (erreur MySQL 1366), piste à
vérifier dans les journaux de Gitea.
**Incident (clos)**
- Les MR fusionnées restaient « open » dans Gitea : les hooks git du serveur ne
s'exécutaient plus, sur toute l'instance (diagnostic par un sous-agent, en
lecture seule ; brief transmis à Pierre). Pierre a réparé les hooks et
marqué les MR !1 à !8 comme fusionnées. Les branches fusionnées ont été
supprimées du serveur.
**Suite de la session (après-midi)**
- ADR 0007 (architecture et conventions de code) et ADR 0008 (glossaire et
scénarios, source unique), puis amendements : scénarios en Gherkin standard
validés par l'analyseur officiel, ADR amendables (0001).
- Étape 0a terminée, par sous-agents : gnubg de référence et 32 positions
(0a.2, MR !6) ; moteur embarqué, `engine.h` et `engine-cli` (0a.3, MR !7) ;
comparaison automatique aux références, tolérance 0,002, deux défauts du
moteur corrigés (0a.4, MR !8).
- Outils de compilation et de test validés par Pierre (amendement de
l'ADR 0004).
- Étape 0b : moteur en WebAssembly, même suite de contrat (écart maximal
9,5e-4), 7,3 Mo compressés, page de test et de mesure, `make deploy-web`,
guide de test `docs/guide-test-etape-0.md`.
**Reste à faire**
- Étape 0a.2 : image Docker de gnubg de bureau compilé depuis le même commit,
et 30 positions de référence ou plus.
- Mesures sur le Fairphone 4 avec Pierre, puis décision du socle (ADR).
- Étape 0d : plateau minimal jouable sur le socle retenu.
- `adb` n'est pas installé sur le PC : `sudo apt install adb` avant les tests sur
le téléphone.
-157
View File
@@ -1,157 +0,0 @@
# Moteur en WebAssembly : page de test, contrat et mesures
- **Date** : 2026-11-02
- **Étape** : 0b
- **Statut** : en cours
- **Exécutant** : sous-agent general-purpose, dans un worktree isolé
## Objectif
Le même moteur (`engine/`, `engine.h`) compilé en WebAssembly tourne dans un
Web Worker d'une page web minimale servie sur le réseau local. Il donne les
mêmes résultats que le moteur natif sur les 32 positions de référence, et une
page de mesure produit les chiffres qui permettront de trancher entre PWA et
Android natif (`docs/etape-0.md`, section 0b).
## Consignes
1. **Compilation** : `make engine-wasm` compile le moteur avec Emscripten, dans
l'image `emscripten/emsdk:3.1.64` (déjà téléchargée ; version figée),
en C générique (pas de SIMD), sans threads, `-j2`. Sorties dans
`build/wasm/`. Les données (`gnubg.weights` ou `gnubg.wd`, bases `.bd`,
table d'équité) viennent de `build/data/` produit par `make engine`, et sont
chargées une fois (système de fichiers virtuel d'Emscripten ou équivalent
simple). Recompilation minimale si rien n'a changé. Cible visible dans
`make help`.
2. **Interface JavaScript minimale** au-dessus d'`engine.h` (par exemple
`bestMoves`, `cubeDecision`, `evaluate`, `reference`), qui renvoie les mêmes
objets JSON que `engine-cli`. Réutiliser le code de mise en JSON
d'`engine-cli` plutôt que de le réécrire, si c'est simple.
3. **Même suite de contrat** (ADR 0007, point 7) : rejouer les 32 positions de
référence aux niveaux 0 et 2 plis avec le build WebAssembly, sous Node (dans
l'image Emscripten, qui contient Node, ou une image Node figée), avec le
même comparateur `tests/reference/compare.py` et la même tolérance. Le plus
simple : un petit programme Node qui imite l'interface en ligne de commande
d'`engine-cli`, et une option du comparateur pour choisir le programme
interrogé. Test lancé par `make test` (`tests/test_wasm_reference.sh`).
4. **Page de test `web/`** (HTML, CSS et JavaScript sans framework ni étape de
build) : moteur chargé dans un Web Worker, jamais sur le fil d'affichage ;
saisie d'un Position ID, d'un Match ID et des dés ; bouton « Meilleur coup » ;
affichage du résultat et du temps de calcul. Textes en français, identifiants
en anglais.
5. **Page de mesure** (dans `web/`) : sur une série de positions de référence,
temps du meilleur coup à 0 et 2 plis et de la décision de videau à 2 plis
(médiane et maximum), temps de chargement du moteur, taille totale
téléchargée (non compressée et compressée gzip), mémoire WebAssembly
utilisée. Un bouton « Copier les résultats » met un rapport texte dans le
presse-papiers, que Pierre collera dans la conversation. La page compare
elle-même aux seuils de `docs/etape-0.md`.
6. **`make deploy-web`** sert `web/` et `build/wasm/` sur le réseau local
(serveur dans Docker, rien sur le PC ; types MIME corrects dont
`application/wasm`), et affiche l'adresse exacte à ouvrir depuis le
téléphone (IP du PC sur le réseau local). Le serveur s'arrête par Ctrl+C.
Mettre à jour la cible `deploy` si pertinent.
7. **`make bench`** : la même mesure que la page, sous Node, sur le PC, pour un
premier ordre de grandeur (le chiffre qui compte reste celui du téléphone).
8. **Guide de test** pour Pierre : `docs/guide-test-etape-0.md` (document
temporaire de l'étape 0), pas à pas : préparer le PC, lancer
`make deploy-web`, ouvrir l'adresse sur le Fairphone 4 (même Wi-Fi), faire un
essai de meilleur coup, lancer la page de mesure, copier le rapport et le
coller dans la conversation. Phrases courtes, aucune connaissance technique
supposée, que faire si la page ne s'ouvre pas (pare-feu, réseau).
Contraintes :
- respecter `CLAUDE.md` et les ADR 0004, 0005, 0007 : simplicité, pas de
framework, identifiants en anglais, commentaires et textes en français, tout
outil dans Docker ;
- ne pas modifier `engine/gnubg/` ni les références ; toute adaptation du
moteur passe par `engine/compat/` ou le code d'Ustagammon ;
- signaler chaque nouvelle dépendance et sa licence dans `CREDITS.md`
(Emscripten : MIT/NCSA) ;
- `make lint` et `make test` doivent passer ; commits petits, en français, avec
la ligne `Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>` ;
- ne pas pousser ni créer de merge request ;
- ne rien simuler : les mesures viennent d'exécutions réelles.
Rapport attendu : ce qui a été fait, commandes de vérification, taille des
fichiers téléchargés, mesures `make bench` sur le PC, résultat de la suite de
contrat en WebAssembly (écart maximal), difficultés, écarts au plan.
## Critères de réussite
- `make engine-wasm` puis `make test` : les 32 positions concordent en
WebAssembly avec la même tolérance qu'en natif.
- `make deploy-web` affiche une adresse ; la page donne le meilleur coup d'une
position de référence avec son temps de calcul (vérifié dans un navigateur
sans interface si possible, sinon par une requête HTTP sur les fichiers).
- `make bench` produit un rapport.
- `make lint` et `make test` passent.
## Résultat
**Statut : terminé** (2026-11-02, branche `wasm-travail`). Tous les critères
de réussite sont tenus ; reste la mesure sur le Fairphone 4 par Pierre
(`docs/guide-test-etape-0.md`).
Ce qui a été fait :
- `make engine-wasm` (`engine-wasm/wasm.mk`) compile dans
`emscripten/emsdk:3.1.64` les mêmes sources que le natif (liste commune
`engine/sources.mk`), plus `engine-cli/main.c`, en C générique, sans
threads, `-O3 -ffast-math`. Les données de `build/data/` sont embarquées
dans `engine.data` (`--preload-file`, système de fichiers virtuel, `/data`).
Recompilation nulle si rien n'a changé.
- Interface JavaScript (`web/engine-wasm.mjs`) : le module appelle
`engine_init` une fois, puis `main` d'engine-cli pour chaque commande
(`callMain`) ; la sortie est exactement le JSON d'engine-cli, sans code de
mise en JSON dupliqué. Seule modification du C : `main` n'appelle pas
`engine_shutdown` sous Emscripten. Fonctions `bestMove`, `cubeDecision`,
`evaluate`, `reference`.
- Suite de contrat : `tests/test_wasm_reference.sh` (lancé par `make test`)
rejoue les 32 positions à 0 et 2 plis sous Node avec
`engine-wasm/engine-cli.mjs`, qui imite engine-cli ; `compare.py --cli`
accepte désormais une commande avec arguments. Résultat : **2 598 nombres
comparés, écart maximal 9,53e-4** (le même cas `opening-64-match` qu'en
natif), tolérance 2e-3. Comparé directement au natif : mêmes classements,
mêmes décisions, écart maximal 2,3e-6.
- `web/` : page de test (`index.html`), page de mesure (`bench.html`),
Worker en module ES (`engine-worker.mjs`), client (`engine-client.mjs`),
mesure partagée avec Node (`benchmark.mjs`). Aucun framework, aucune étape
de build.
- `make deploy-web` : serveur HTTP de Python dans l'image `build-c` (aucune
nouvelle image), adresse LAN affichée (route par défaut), Ctrl+C l'arrête
(vérifié). `make deploy` renvoie vers `make deploy-web`. `make bench` :
même mesure sous Node.
Vérification de la page : Chromium 130 et Firefox 131 sans interface (image
`mcr.microsoft.com/playwright:v1.48.2-noble`, utilisée une fois, hors du
dépôt), ouverts sur l'adresse LAN `http://192.168.1.21:8080/` (contexte non
sécurisé, comme le téléphone) : meilleur coup de `middlegame-1` à 2 plis
(`24/14`, 305 ms Chromium, 2 433 ms Firefox), mesure complète, bouton de copie
fonctionnel. Types MIME vérifiés par curl : `application/wasm`,
`text/javascript` pour les `.mjs`.
Mesures sur le PC (i5-2450M, 2011) :
| Mesure (max sur les positions) | Node 18 | Chromium 130 | Firefox 131 | Seuil |
| --- | --- | --- | --- | --- |
| Meilleur coup 0 pli | 2 ms | 5 ms | 14 ms | 300 ms |
| Meilleur coup 2 plis (médiane / max) | 107 / 454 ms | 87 / 316 ms | 693 / 2 341 ms | 3 000 ms |
| Videau 2 plis (médiane / max) | 27 / 109 ms | 21 / 103 ms | 158 / 902 ms | 3 000 ms |
| Chargement du moteur | 82 ms | 178 ms | 204 ms | |
| Mémoire WebAssembly | 51,9 Mo | 51,9 Mo | 51,9 Mo | |
Taille téléchargée : 9,0 Mo non compressée, **7,3 Mo compressée gzip** (seuil
40 Mo), dont `engine.data` 8,7 Mo (7,2 Mo gzip), `engine.wasm` 180 Ko
(78 Ko gzip), `engine.mjs` 73 Ko (20 Ko gzip).
Points d'attention : Firefox sans interface est environ 7 fois plus lent que
Chromium sur le même PC, à vérifier sur le téléphone (le guide demande les
deux navigateurs). La mémoire de 52 Mo vient surtout des bases de fin de
partie copiées en mémoire et du cache d'évaluation de gnubg ; les données
existent en plus une fois côté JavaScript (système de fichiers virtuel).
Écarts au plan : aucun sur le fond. Fichiers en `.mjs` (modules ES partagés
entre navigateur et Node sans `package.json`) ; seuils jugés sur le maximum,
la médiane étant donnée en plus ; la taille compressée est calculée par la page
(CompressionStream) car le serveur de test ne compresse pas.