From 59895393fe6317e4e9158ae5396e9032b7ebc767 Mon Sep 17 00:00:00 2001 From: Pierre MARTIN Date: Mon, 2 Nov 2026 13:40:43 +0100 Subject: [PATCH] ADR 0007 : architecture et conventions de code Co-Authored-By: Claude Opus 5.5 --- .claude/worktrees/agent-a290505fc0135b4c3 | 1 + .claude/worktrees/agent-af71fe863e79bb3e8 | 1 + CLAUDE.md | 3 +- ...007-architecture-et-conventions-de-code.md | 96 +++++++++++++++++++ docs/adr/README.md | 1 + docs/etape-0.md | 2 +- docs/feuille-de-route.md | 2 +- 7 files changed, 103 insertions(+), 3 deletions(-) create mode 160000 .claude/worktrees/agent-a290505fc0135b4c3 create mode 160000 .claude/worktrees/agent-af71fe863e79bb3e8 create mode 100644 docs/adr/0007-architecture-et-conventions-de-code.md diff --git a/.claude/worktrees/agent-a290505fc0135b4c3 b/.claude/worktrees/agent-a290505fc0135b4c3 new file mode 160000 index 0000000..d0f44b6 --- /dev/null +++ b/.claude/worktrees/agent-a290505fc0135b4c3 @@ -0,0 +1 @@ +Subproject commit d0f44b689b3cbd4572691a8183d89e2492276a69 diff --git a/.claude/worktrees/agent-af71fe863e79bb3e8 b/.claude/worktrees/agent-af71fe863e79bb3e8 new file mode 160000 index 0000000..ec0f4da --- /dev/null +++ b/.claude/worktrees/agent-af71fe863e79bb3e8 @@ -0,0 +1 @@ +Subproject commit ec0f4daef3ad7ebd6efa604700705d980fa8c0ec diff --git a/CLAUDE.md b/CLAUDE.md index 205a875..b1bbcfa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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. diff --git a/docs/adr/0007-architecture-et-conventions-de-code.md b/docs/adr/0007-architecture-et-conventions-de-code.md new file mode 100644 index 0000000..44dcadb --- /dev/null +++ b/docs/adr/0007-architecture-et-conventions-de-code.md @@ -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. diff --git a/docs/adr/README.md b/docs/adr/README.md index 3e732fe..d129e34 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -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é | diff --git a/docs/etape-0.md b/docs/etape-0.md index 5e6b145..7aea3c2 100644 --- a/docs/etape-0.md +++ b/docs/etape-0.md @@ -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é ; diff --git a/docs/feuille-de-route.md b/docs/feuille-de-route.md index db7db74..331ca27 100644 --- a/docs/feuille-de-route.md +++ b/docs/feuille-de-route.md @@ -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 | ⏳ | |