ADR 0007 : architecture et conventions de code
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
aa4f504123
commit
59895393fe
@@ -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.
|
||||
@@ -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
@@ -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é ;
|
||||
|
||||
@@ -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 | ⏳ | |
|
||||
|
||||
Reference in New Issue
Block a user