Étape 0d.2 : plateau jouable en PWA hors ligne, aide intégrée #13

Merged
pierre merged 8 commits from plateau-ui into main 2026-11-03 00:02:39 +00:00
3 changed files with 26 additions and 158 deletions
Showing only changes of commit 6bc1c27bee - Show all commits
+1 -1
View File
@@ -20,7 +20,7 @@ garde-fous d'architecture (0d.1), déploiement sur https://ustagammon.sans.pub.
| Sous-étape | Contenu | État | Plan |
| --- | --- | --- | --- |
| 0d.2 | Plateau minimal jouable (PWA hors ligne) ; vérifié avec Pierre en suivant `docs/scenarios/jouer-une-partie.feature` | 🔄 | `plans/2026-11-02-plateau-pwa.md` |
| 0d.2 | Plateau minimal jouable (PWA hors ligne), publié ; reste la vérification avec Pierre sur le Fairphone 4 (`docs/guide-test-etape-0.md`, section « Étape 0d ») | 🔄 | |
**Critère de fin** : une partie complète jouée sur le Fairphone 4, moins de 2 s
par coup de l'IA en niveau standard, tous les tests au vert.
+25
View File
@@ -64,3 +64,28 @@ Une entrée datée par session : ce qui a été fait, décidé, et la suite.
- É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.
## 2026-11-02 (soir) et 2026-11-03
**Fait**
- Mesures sur le Fairphone 4 (Chrome 156) : 2 plis en 348 ms au pire, seuil
3 s ; ADR 0009 accepté (socle PWA en TypeScript), 0c abandonnée.
- Déploiement CapRover (MR !10) : app `ustagammon` créée, site publié sur
https://ustagammon.sans.pub (HTTPS forcé).
- Étape 0d.1 (MR !11) : domaine « partie » en journal d'événements, scénario
exécuté par Cucumber sur le vrai moteur, garde-fous d'architecture.
- Étape 0d.2 : plateau jouable au toucher en PWA hors ligne, aide intégrée
(glossaire et scénarios lus depuis leurs sources), CSP, `make test-browser`
(parties complètes dans Chromium et Firefox). Deux bugs trouvés et corrigés :
la pile du moteur WebAssembly débordait après quelques centaines de commandes
(plantage en cours de partie), et le service worker échouait dans Chromium en
téléchargeant les données en même temps que le moteur.
- Interruptions de quota : reprise programmée à 23h50 ; l'agent de 0d.2 arrêté a
été remplacé par un agent de reprise sur le même espace de travail.
**Reste à faire**
- Vérification finale de l'étape 0 avec Pierre : une partie complète sur le
Fairphone 4, en suivant le guide de test (section « Étape 0d »).
- Sous Firefox sur PC, un tour de l'ordinateur a pris jusqu'à 5,1 s
(Chromium : 0,4 s) ; Firefox sur le téléphone reste à mesurer.
- Validation par Pierre de Playwright (Apache-2.0), outil de `make test-browser`.
-157
View File
@@ -1,157 +0,0 @@
# Plateau minimal jouable, en PWA hors ligne
- **Date** : 2026-11-02
- **Étape** : 0d.2
- **Statut** : terminé (2026-11-03)
- **Exécutant** : sous-agent general-purpose, dans un worktree isolé
## Objectif
Sur https://ustagammon.sans.pub, un joueur joue une partie complète contre
l'ordinateur sur son téléphone, au toucher. L'application s'installe
(PWA) et fonctionne hors ligne. C'est la fin de l'étape 0 : critère
« une partie complète jouée sur le Fairphone 4, moins de 2 s par coup de l'IA
en niveau standard, tous les tests au vert ». Pas de design soigné : l'objectif
est de valider la boucle de jeu complète, proprement.
## Consignes
1. **Interface `app/src/ui/`** (TypeScript, DOM ou SVG, sans framework) :
- un plateau lisible sur un écran de téléphone en portrait (24 points,
barre, pions sortis, dés, videau) ;
- saisie au toucher : toucher une case de départ, puis une case
d'arrivée ; les cases d'arrivée possibles sont mises en évidence (le
domaine expose ce qui est possible à partir des coups légaux du moteur,
sans réimplémenter de règle) ; annuler les demi-coups en cours ;
- boutons : lancer les dés, doubler, prendre, passer, nouvelle partie ;
- pendant le tour de l'ordinateur : un indicateur discret ; le coup de
l'ordinateur s'affiche (sans animation obligatoire) ;
- fin de partie : gagnant, simple, gammon ou backgammon, points ;
- reprise automatique de la partie en cours après fermeture de la page
(le journal d'événements sérialisé dans `localStorage` suffit pour
l'étape 0 ; stockage derrière une petite interface, hors du domaine).
2. **Architecture** (ADR 0007, garde-fous existants) : l'assemblage (domaine,
adaptateur moteur dans un Web Worker, interface, stockage) se fait dans un
point d'entrée dédié (par exemple `app/src/main.ts`), seul autorisé à tout
importer ; `ui/` n'importe toujours pas `engine/`. Le moteur tourne dans un
Web Worker, jamais sur le fil d'affichage. Étendre les règles
dependency-cruiser si besoin.
3. **Textes** : en français, dans un fichier de textes séparé du code
(ADR 0007, point 5) ; les mots du jeu sont ceux du glossaire.
4. **Identité minimale** : couleurs et tailles en variables CSS, thème clair
et sombre (`prefers-color-scheme`), contrastes lisibles (pions clairs et
foncés distincts du plateau). Palette provisoire et sobre inspirée du brief
(bois, ivoire, un accent) : l'identité définitive viendra plus tard.
5. **Aide dans l'application** (ADR 0008, source unique) : le build copie
`docs/glossaire/` et `docs/scenarios/` dans le site ; une page d'aide
simple affiche le scénario « Jouer une partie contre l'ordinateur » et les
fiches du glossaire (au moins le terme et sa phrase « En bref »), lus à
l'exécution depuis ces copies, jamais recopiés à la main.
6. **PWA** : manifeste, icônes provisoires simples (pas de logo : un symbole
neutre), service worker qui met en cache tous les fichiers du site (dont
les 8,7 Mo de données du moteur) pour le hors ligne, et se met à jour
proprement à chaque publication (le commit de `version.json` peut servir de
clé de cache).
7. **Site publié** (`make site`, `docs/deploiement.md`) : l'application à la
racine ; les pages de prototype (test du moteur et mesure) restent
accessibles, par exemple sous `/moteur/` et `/moteur/bench.html`, et la doc
le dit. Ajouter une politique de sécurité du contenu (CSP) dans
`deploy/Caddyfile`, compatible WebAssembly (`'wasm-unsafe-eval'`), et la
vérifier. `tests/test_site.sh` à jour (manifeste, service worker, aide).
8. **Tests** :
- tests unitaires de ce qui est testable hors navigateur (par exemple la
transformation de l'état du domaine en ce que dessine le plateau, les
destinations possibles) ;
- vérification dans un vrai navigateur : une partie jouée par l'interface,
au moins jusqu'à plusieurs coups de chaque joueur, dans Chromium et
Firefox sans interface (image `mcr.microsoft.com/playwright:v1.48.2-noble`,
déjà présente). Cette vérification est faite et rapportée ; ne l'ajouter à
`make test` que si c'est simple et rapide, en le signalant comme nouvelle
dépendance de test (Playwright, Apache-2.0) ;
- les tests existants restent verts.
9. **Guide de test** : compléter `docs/guide-test-etape-0.md` d'une section
« Étape 0d : jouer une partie sur le téléphone » : ouvrir
https://ustagammon.sans.pub, installer l'application, jouer une partie
complète en suivant `docs/scenarios/jouer-une-partie.feature`, vérifier
le hors ligne (mode avion), et ce qu'il faut rapporter (temps des coups de
l'ordinateur ressentis, problèmes rencontrés, captures si besoin).
Contraintes :
- `CLAUDE.md`, ADR 0004, 0007, 0008, 0009 : simplicité avant tout, pas de
framework, identifiants en anglais, commentaires, docs et textes en français,
tout outil dans Docker, `-j2` ;
- aucune règle du jeu réimplémentée : tout vient du moteur, via le domaine ;
- ne pas modifier `engine/gnubg/` ni les références ;
- ne pas publier (`make deploy-prod`) : la session principale s'en charge ;
- `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.
Rapport attendu : ce qui a été fait, captures d'écran du plateau (fichiers dans
le dossier de travail temporaire, chemins dans le rapport), résultat de la
partie jouée dans les navigateurs sans interface, taille du site, difficultés,
écarts au plan.
## Critères de réussite
- Dans Chromium et Firefox sans interface, une partie se joue par l'interface
(dés, coups au toucher, coups de l'ordinateur, videau) sans erreur.
- Le site fonctionne hors ligne après un premier chargement (service worker).
- `make lint` et `make test` passent.
## Résultat
Fait en deux sessions de sous-agent (la première interrompue par la fin
d'un quota, la seconde l'a reprise), sur la branche `plateau-ui-travail`.
- **Domaine** (`app/src/domain/game/game.ts`) : reprise d'une partie depuis
son journal, plateau vu de chaque camp, demi-coups possibles à la suite de
ceux déjà saisis, droit de doubler ; tout vient du moteur.
- **Interface** (`app/src/ui/`) : plateau en SVG (24 cases, barre, pions
sortis, dés, videau), saisie au toucher avec cases d'arrivée en
surbrillance, annulation, boutons du jet, du videau et de nouvelle partie,
coup de l'ordinateur affiché avec son temps, fin de partie (simple, gammon,
backgammon, points), reprise depuis `localStorage` (`app/src/storage/`),
textes dans `texts.ts`, thème clair et sombre en variables CSS
(`web/app.css`).
- **Assemblage** : `app/src/main.ts`, seul point d'entrée autorisé à tout
importer (règles dependency-cruiser) ; moteur dans le Web Worker.
- **Aide** (`app/src/ui/help.ts`) : scénario « Jouer une partie contre
l'ordinateur » et fiches du glossaire (terme et « En bref »), lus à
l'exécution dans les copies de `docs/` faites par `make site`.
- **PWA** : manifeste, icônes provisoires, service worker qui met en cache
les 70 fichiers du site (empreinte du contenu comme version), enregistré
une fois le moteur chargé.
- **Site** : application à la racine, pages de test sous `/moteur/` ; CSP
dans `deploy/Caddyfile`, vérifiée par `tests/test_site.sh` (en-tête) et
dans les navigateurs (aucune violation, script en ligne bloqué). Site de
9,1 Mo (70 fichiers, dont 8,6 Mo pour le moteur), archive de 8,8 Mo.
- **Tests** : tests unitaires de l'interface et du domaine ; `make
test-browser` (Playwright, Apache-2.0, hors de `make test` : plusieurs
minutes et une image de 3 Go) joue une partie complète dans Chromium et
Firefox sans écran : videau proposé des deux côtés, reprise après
rechargement, aide, thème sombre, hors ligne, CSP. Les deux passent.
- **Guide de test** : section « Étape 0d » de `docs/guide-test-etape-0.md`.
Deux défauts trouvés par la vérification dans les navigateurs et corrigés :
1. **Pile du moteur WebAssembly** : `callMain` d'Emscripten laissait ses
arguments sur la pile (64 Ko) ; vers la 540e commande d'une partie, elle
débordait (moteur muet dans Firefox, onglet planté dans Chromium,
« memory access out of bounds » sous Node). La pile est remise en place
après chaque commande (`web/engine-wasm.mjs`) ; test de 3000 commandes.
2. **Installation du service worker dans Chromium** : elle échouait quand le
Worker téléchargeait les données du moteur au même moment ; le service
worker est désormais enregistré une fois le moteur chargé.
Écarts et limites :
- le hors ligne n'est vraiment simulé que dans Chromium (Firefox sous
Playwright refuse toute navigation hors ligne) : à confirmer en mode avion
sur le téléphone ;
- temps des coups de l'ordinateur en niveau standard, sur ce PC chargé :
0,6 s au plus dans Chromium, jusqu'à 4,6 s dans Firefox ; le critère de
2 s est à mesurer sur le Fairphone 4 ;
- thème sombre : les pions foncés sur les cases foncées restent lisibles
grâce à leur contour, mais le contraste est le point faible de la palette
provisoire.