Fusion de la MR !3 : ADR 0007, architecture et conventions de code

This commit was merged in pull request #3.
This commit is contained in:
2026-11-02 12:41:37 +00:00
6 changed files with 104 additions and 3 deletions
+3
View File
@@ -16,3 +16,6 @@ local.properties
# Web (pour plus tard)
node_modules/
# Espaces de travail de Claude Code (worktrees des sous-agents)
/.claude/
+2 -1
View File
@@ -14,7 +14,8 @@ est la feuille de route.
- **Cibles** : Android (téléphone de test : Fairphone 4, arm64) et, si le prototype le valide, une PWA avec le moteur compilé en WebAssembly. Pas d'iOS.
- **IA générative** : en V1, uniquement des boutons qui copient un prompt contextualisé. Aucun appel réseau.
- **Licence** : tout le code sous GPLv3. Les contenus pédagogiques (leçons, textes) sous CC BY-SA 4.0.
- **Langue** : interface, contenus, commentaires de code et messages de commit en français.
- **Langue** : interface, contenus, commentaires de code et messages de commit en français ; identifiants du code en anglais.
- **Architecture et code** : simplicité d'abord, pas de sur-ingénierie ; domaine pur, moteur derrière `engine.h`, parties en journal d'événements ; règles complètes dans l'ADR 0007, à transmettre à chaque sous-agent.
- **Communauté de départ** : l'app sera d'abord diffusée auprès des joueurs de l'Atelier du Huit, café associatif à Cugnaux. Elle doit être accessible à de vrais débutants.
- **Identité visuelle** : définie par le brief créatif (https://claude.ai/artifact/36WMwZWqvMxXvSSVBJTgwd). Les choix de produit, de ton et d'identité appartiennent au porteur du projet ; le rôle de Claude Code est technique : les mettre en œuvre et signaler leurs conséquences techniques.
@@ -0,0 +1,96 @@
# 0007. Architecture et conventions de code
- **Statut** : accepté
- **Date** : 2026-11-02
- **Décideurs** : Pierre (stockage des parties, nommage, garde-fous), sur
proposition de Claude Code
## Contexte
Le code va être écrit par des agents et Pierre ne le relit pas en détail. Il
doit donc rester simple, lisible par un humain, et protégé par des tests contre
les dérives. Le cadrage impose déjà que le moteur soit caché derrière une
interface, et demande l'annulation et les branches de partie (« Rejouer
d'ici »).
## Décision
**1. La simplicité d'abord.** Le code se lit sans connaître de patron de
conception. Pas d'abstraction sans un deuxième usage réel, pas de framework sans
besoin avéré, pas de couche « au cas où ». Dans le doute, la solution la plus
directe.
**2. Trois parties, une seule règle de dépendance.**
- **Le domaine** : les règles de l'application (partie, match, branches,
coach, analyse, parcours). Du code pur : ni écran, ni stockage, ni appel
direct au moteur. Il décrit l'interface `Engine` dont il a besoin (coups
légaux, classement, videau, évaluation).
- **Le moteur** : gnubg en C derrière `engine/include/engine.h`, et un
adaptateur par plateforme (WebAssembly dans un Web Worker, ou JNI sur
Android) qui implémente l'interface `Engine` du domaine.
- **L'application** : écrans, stockage, presse-papiers, assemblage.
Les dépendances vont vers le domaine, jamais l'inverse. Aucun écran n'appelle le
moteur directement. Ces règles sont vérifiées par des tests ; l'outil qui les
vérifie sera choisi avec le socle (PWA ou Android) et signalé avec sa licence.
**3. Une partie est un journal d'événements.** Une partie est enregistrée comme
la suite de ce qui s'est passé (`GameStarted`, `DiceRolled`, `MovePlayed`,
`CubeOffered`, `CubeTaken`, `CubeDropped`, `GameEnded`…), sans jamais modifier
un événement passé. Chaque événement pointe vers le précédent : une branche
n'est qu'un nouvel événement accroché à un ancien. L'état de la partie se
recalcule en rejouant les événements ; annuler revient à repartir de
l'événement précédent ; l'export SGF est un parcours de l'arbre. Chaque
événement porte un numéro de version de format. Le reste de l'application
(réglages, progression, leçons) est stocké simplement, sans journal.
**4. Le hasard est injecté.** Le domaine reçoit sa source de dés : les tests
sont reproductibles, et l'historique des dés d'une partie est consultable.
**5. Nommage.** Tous les identifiants du code sont en anglais (fichiers, types,
fonctions, variables, clés JSON). Commentaires, documentation et messages de
commit sont en français. Les textes de l'interface sont en français, dans des
fichiers de textes séparés du code. En conséquence, l'interface C prévue sous le
nom `moteur.h` (ADR 0005) s'appelle `engine.h`, avec le préfixe `engine_`.
**6. Le vocabulaire du jeu, pas la cérémonie.** On reprend du DDD le langage
commun (un glossaire des termes du jeu, les mêmes dans le code, la doc et
l'interface) et le découpage par sous-domaines en dossiers (`game`,
`analysis`, `learning`, `prompts`). On n'en reprend pas les patrons tactiques
(dépôts, fabriques, objets-valeurs systématiques) tant qu'un besoin concret ne
les justifie pas.
**7. Tests.**
- Domaine : tests unitaires rapides, avec un faux moteur.
- Moteur : une même suite de tests de contrat, rejouée sur chaque adaptateur
(ligne de commande, WebAssembly, Android), contre les positions de référence
de gnubg de bureau.
- Bout en bout : quelques scénarios seulement.
**8. Notre code C** (hors copie de gnubg) : C11, compilé avec
`-Wall -Wextra -Werror`, sans état global ajouté par nous.
## Alternatives écartées
- **Event sourcing pour toute l'application, avec projections (CQRS)** : très
traçable, mais lourd pour une application hors ligne à un seul utilisateur.
- **État classique pour les parties** (position courante et historique à
côté) : plus simple au départ, mais les branches et l'annulation deviennent du
code au cas par cas.
- **Identifiants en français** : cohérents avec la doc, mais écart avec les
conventions habituelles du code et des bibliothèques.
- **Architecture hexagonale formelle, DDD complet** : beaucoup d'interfaces et
de vocabulaire pour une application de cette taille.
- **Règles d'architecture seulement documentées** : sans relecture humaine du
code, rien ne garantirait qu'elles sont respectées.
## Conséquences
- Le format des événements de partie est un contrat durable : le changer
demande une migration et un ADR.
- La structure des dossiers du domaine et l'outil de vérification des
dépendances seront fixés avec le socle, à la fin de l'étape 0.
- Les sous-agents reçoivent ces règles dans leurs consignes ; `CLAUDE.md` y
renvoie.
+1
View File
@@ -12,3 +12,4 @@ passe au statut « remplacé par NNNN ». Voir l'ADR 0001.
| [0004](0004-outils-de-developpement-dans-docker.md) | Outils de développement dans Docker | accepté |
| [0005](0005-moteur-gnubg-officiel.md) | Source du moteur : GNU Backgammon officiel, commit 14b6798 | accepté |
| [0006](0006-merge-requests-systematiques.md) | Merge requests systématiques, fusionnées par Claude Code | accepté |
| [0007](0007-architecture-et-conventions-de-code.md) | Architecture et conventions de code | accepté |
+1 -1
View File
@@ -12,7 +12,7 @@
À faire :
1. Récupérer les sources du moteur (choisir entre gnubg, gnubg-nn ou le moteur extrait par CBG ; justifier le choix dans un ADR, `docs/adr/`).
2. Définir une **interface C minimale** du moteur (`engine/include/moteur.h`), indépendante de toute interface graphique :
2. Définir une **interface C minimale** du moteur (`engine/include/engine.h`, identifiants en anglais : ADR 0007), indépendante de toute interface graphique :
- initialiser le moteur (charger réseaux, base de fin de partie, table d'équité de match) ;
- lister les coups légaux pour une position et des dés ;
- donner le meilleur coup et le classement des coups avec leur équité, pour un niveau d'évaluation donné ;
+1 -1
View File
@@ -15,7 +15,7 @@ Acquis : socle du dépôt, organisation (ADR 0001, 0003, 0006), source du moteur
| Sous-étape | Contenu | État | Plan |
| --- | --- | --- | --- |
| 0a.2 | Image Docker GNU Backgammon de bureau (compilé depuis le commit 14b6798), 30+ positions de référence dans `tests/reference/` | ⏳ | |
| 0a.3 | Interface C `engine/include/moteur.h` et `engine-cli` (JSON) | ⏳ | |
| 0a.3 | Interface C `engine/include/engine.h` et `engine-cli` (JSON) | ⏳ | |
| 0a.4 | `make test` compare `engine-cli` aux références | ⏳ | |
| 0b | Moteur en WebAssembly, page de test dans un Web Worker, `make deploy-web`, `make bench` | ⏳ | |
| Mesures | Pierre relève les mesures sur le Fairphone 4 | ⏳ | |