Décisions en ADR ; plans et feuille de route temporaires

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Pierre MARTIN
2026-11-02 13:23:18 +01:00
co-authored by Claude Opus 5.5
parent 6958accec2
commit d017f3338b
17 changed files with 446 additions and 266 deletions
@@ -0,0 +1,42 @@
# 0001. Consigner les décisions dans des ADR
- **Statut** : accepté
- **Date** : 2026-11-02
- **Décideurs** : Pierre
## Contexte
Les premières décisions du projet étaient consignées dans un fichier unique,
`docs/decisions.md`, à côté des plans et de la feuille de route. Or ces
documents n'ont pas la même durée de vie : un plan ou une ligne de feuille de
route est temporaire et disparaît une fois réalisé, alors qu'une décision doit
rester lisible tant qu'elle s'applique, et même après, pour comprendre
l'historique. Les mélanger rend les choix plus difficiles à retrouver et à
remettre en cause proprement.
## Décision
Chaque décision structurante fait l'objet d'un ADR (Architecture Decision
Record) : un fichier `docs/adr/NNNN-titre-court.md`, numéroté dans l'ordre, au
format de `docs/adr/modele.md`. Un ADR accepté n'est plus réécrit : une
décision qui change donne un nouvel ADR, et l'ancien passe au statut
« remplacé par NNNN ». L'index `docs/adr/README.md` liste tous les ADR.
Les plans (`docs/plans/`) et la feuille de route ne contiennent que le travail
à faire ; un plan réalisé est supprimé, et ce qu'il contenait de durable passe
dans un ADR, dans la description de la merge request ou dans le journal.
`docs/decisions.md` est supprimé ; ses entrées deviennent les ADR 0002 à 0006.
## Alternatives écartées
- **Garder `docs/decisions.md`** : un seul fichier qui grossit, où l'on ne
distingue pas une décision en vigueur d'une décision remplacée.
- **Ne garder la trace que dans les merge requests** : elle existe déjà là,
mais hors du dépôt, sur un serveur qui peut changer.
## Conséquences
- `make test` vérifie la forme des ADR (numérotation, statut, sections, index).
- Les ADR 0002 à 0006 reprennent des décisions antérieures à celui-ci, avec
leur date d'origine.
+27
View File
@@ -0,0 +1,27 @@
# 0002. Nom de l'application : Ustagammon
- **Statut** : accepté
- **Date** : 2026-11-01
- **Décideurs** : Pierre
## Contexte
Le nom de l'application était une question ouverte du cadrage. Il conditionne
l'identifiant de l'application, le nom du dépôt et l'identité visuelle.
## Décision
L'application s'appelle **Ustagammon** : « usta », en turc le maître artisan
qui transmet son savoir à l'apprenti, et « gammon », de backgammon. Le sens du
nom et l'identité visuelle sont décrits dans le brief créatif :
https://claude.ai/artifact/36WMwZWqvMxXvSSVBJTgwd
## Alternatives écartées
Non documentées : le choix a été fait par Pierre avant le démarrage technique.
## Conséquences
- Le dépôt s'appelle `pierre/Ustagammon` sur git.sans.pub.
- Reste à vérifier, avant publication, qu'aucune application du même nom
n'existe sur F-Droid et le Play Store.
@@ -0,0 +1,34 @@
# 0003. Pilotage par Claude Code et des sous-agents
- **Statut** : accepté
- **Date** : 2026-11-02
- **Décideurs** : Pierre
## Contexte
Le kit de démarrage prévoyait un fichier `PROMPTS.md` : des messages que Pierre
collait dans Claude Code à chaque étape. Pierre ne relit pas le code en détail
et souhaite que le suivi du projet ne repose pas sur lui ni sur la mémoire
d'une session.
## Décision
La session principale de Claude Code est chef de projet technique : elle tient
la feuille de route, découpe le travail, délègue l'exécution à des sous-agents
et vérifie leurs résultats. Toute tâche déléguée a un plan écrit dans
`docs/plans/` avant la délégation. Rien d'important ne vit seulement dans la
mémoire d'une session : tout est écrit dans `docs/` et commité. Le
fonctionnement détaillé est dans `docs/organisation.md`.
## Alternatives écartées
- **Prompts collés par Pierre** (`PROMPTS.md`) : fait reposer l'enchaînement
des étapes sur Pierre, et ne laisse pas de trace de ce qui a été demandé à
chaque agent.
## Conséquences
- `PROMPTS.md` est supprimé ; l'enchaînement des étapes est dans
`docs/feuille-de-route.md`.
- Pierre garde la main sur le produit, l'identité et les décisions soumises à
validation (liste dans `docs/organisation.md`).
@@ -0,0 +1,30 @@
# 0004. Outils de développement dans Docker
- **Statut** : accepté
- **Date** : 2026-11-02
- **Décideurs** : Claude Code
## Contexte
La machine de développement est ancienne et doit rester légère. Le cadrage
prévoit déjà que les chaînes d'outils lourdes (NDK, Emscripten, gnubg de
référence) tournent dans Docker. La question s'est posée dès le premier outil
de vérification, ShellCheck, absent du PC.
## Décision
Rien n'est installé sur le PC en dehors de git, make, Docker et adb. Chaque
outil tourne dans une image Docker de version figée, récupérée ou construite
par `make setup`. Premier cas : ShellCheck (GPLv3), image
`koalaman/shellcheck-alpine:v0.10.0`.
## Alternatives écartées
- **Installer les outils avec apt** : versions qui varient d'une machine à
l'autre, et pollution du système.
## Conséquences
- `make lint` demande d'avoir lancé `make setup` une fois ; il le dit
explicitement sinon.
- Chaque nouvelle image est signalée avec sa licence dans `CREDITS.md`.
+100
View File
@@ -0,0 +1,100 @@
# 0005. Source du moteur : GNU Backgammon officiel, commit 14b6798
- **Statut** : accepté
- **Date** : 2026-11-02
- **Décideurs** : Pierre, sur recommandation de Claude Code
## Contexte
L'étape 0a commence par choisir le code source à partir duquel embarquer le
moteur, derrière une interface C `moteur.h` qui doit offrir cinq fonctions :
initialisation, coups légaux, classement des coups par niveau, décision de
videau en match, évaluation. Positions au format GNU Position ID et Match ID.
Les résultats doivent concorder avec le GNU Backgammon de bureau, qui sert de
référence aux tests.
Trois candidats ont été étudiés par un sous-agent, sur clones superficiels lus
sans rien compiler ni exécuter (MR !1 sur git.sans.pub) :
| Source | Commit étudié | Date |
| --- | --- | --- |
| gnubg officiel | 14b67984737ded0f6de43d63dcb789f729d9b06b (1.08.003) | 2026-10-23 |
| gnubg-nn | 595a9e8f1fe094ee22db5a736bc05027643756df | 2025-09-07 |
| CBG (`github.com/clavierhaus/gnubg-android`) | 62028573d7564275a7c9363f0ef5d4b63d8d0f26 (moteur gnubg b1b2772c) | 2026-10-26 |
| Critère | gnubg | gnubg-nn | CBG |
| --- | --- | --- | --- |
| Activité | Active (corrections régulières) | Quasi arrêtée (outil d'entraînement des réseaux) | Très active ; un mainteneur, code très majoritairement écrit par IA |
| Licence | GPLv3 ou ultérieure | **48 fichiers en GPLv2 seule** : incompatible | GPLv3 ou ultérieure ; noms « CBG » et « Clavierhaus » revendiqués comme marques |
| Fonctions | Les cinq, avec tables d'équité, Crawford, Jacoby, Position ID et Match ID | Partiel : pas de Match ID, videau réimplémenté en C++ | Les cinq, mais interface pensée pour une partie en cours |
| Dépendances | GLib dans tout le cœur, remplaçable par un shim d'environ 30 fonctions, sauf GMarkup (tables d'équité) et `g_mapped_file` ; SSE, AVX, **NEON** et repli en C générique ; threads désactivables | C++14, Python 2, SSE seul | GLib, GObject et libintl compilés en entier pour Android |
| Isolement | Faisable : environ 24 400 lignes ; état global partout ; `backgammon.h` à réduire | Évaluation isolée, le reste à réécrire | 41 fichiers et 681 lignes de bouchons : pas une bibliothèque minimale |
| Données | `gnubg.weights` (1 097 796 octets) ; `gnubg.wd`, `gnubg_os0.bd`, `gnubg_ts0.bd` générés au build ; tables d'équité XML (`Kazaross-XG2.xml` par défaut) | Pas de poids fournis | Mêmes poids, identiques octet pour octet ; aucune base `.bd` fournie |
| Portabilité | NEON présent ; pas de SIMD WebAssembly (C générique) ; un portage Emscripten tiers existe (`hwatheod/gnubg-web`, 2019) | Mauvais point de départ | Build CMake/NDK fonctionnel, pas de WebAssembly |
| Concordance | Mêmes sources et poids que le bureau ; écart flottant car `configure.ac` force `-ffast-math` | Non, pour le videau | Écarts de 1e-4 à 3e-3 selon leur documentation, non vérifié |
Points recoupés directement dans les sources par la session principale : les
48 en-têtes GPLv2 de gnubg-nn (ex. `gnubg-nn/gnubg/eval.c` l. 7) ; la licence
GPLv3+ de `gnubg/eval.c` ; `-ffast-math` ajouté par `gnubg/configure.ac:595` ;
le code NEON dans `lib/simd.h` et `lib/neuralnetsse.c` ; l'identité des poids
entre gnubg et CBG ; trois usages de `g_markup` dans `matchequity.c` ;
`makebearoff` dans `Makefile.am`.
## Décision
Le moteur d'Ustagammon est construit à partir de **GNU Backgammon officiel,
figé au commit 14b67984737ded0f6de43d63dcb789f729d9b06b**, dont on n'extrait
que le cœur, derrière `moteur.h`.
Fichiers à reprendre (liste issue des `#include` et des symboles, à confirmer à
la première édition des liens) :
- Évaluation : `eval.c/h`, `movefilters.inc`, `lib/neuralnet.c/h`,
`lib/neuralnetsse.c`, `lib/inputs.c`, `lib/simd.h`, `lib/sigmoid.h`,
`lib/cache.c/h`, `lib/gnubg-types.h`, `lib/isaac.c/h`, `lib/isaacs.h`,
`lib/md5.c/h`.
- Fin de partie : `bearoff.c/h`, `bearoffgammon.c/h`.
- Identifiants : `positionid.c/h`, `matchid.c/h`.
- Équité de match : `matchequity.c/h`, `mec.c/h`, `lib/list.c/h`.
- En-têtes à réduire : `backgammon.h`, `common.h`, `multithread.h`, `util.h`.
- Données : `gnubg.weights`, `met/*.xml` ; outils hôte `makeweights.c` et
`makebearoff.c`.
Plan d'isolement :
1. Copie figée dans `engine/`, `config.h` écrit à la main (sans threads ; NEON
sur arm64 ; rien en WebAssembly).
2. Shim `glib.h` minimal ; `mmap` ou `fread` à la place de `g_mapped_file`.
3. Tables d'équité converties en tableaux C au build, ou table Zadeh intégrée
pour commencer.
4. En-tête réduit à la place de `backgammon.h`, variables globales aux valeurs
par défaut de `gnubg.c`, en s'inspirant de `jni-bridge/src/stubs.c` de CBG.
5. Façade `moteur.h` sur `GenerateMoves`, `FindnSaveBestMoves`,
`GeneralCubeDecisionE` et `FindCubeDecision`, `PositionFromID`,
`MatchFromID`.
6. `gnubg.wd` et bases `.bd` générées sur l'hôte avec les outils officiels.
7. Tests de concordance avec tolérance, en mesurant l'écart avec et sans
`-ffast-math`.
## Alternatives écartées
- **gnubg-nn** : 48 fichiers sous GPLv2 seule, incompatibles avec la GPLv3 du
projet ; videau réimplémenté, donc sans concordance possible avec gnubg de
bureau.
- **CBG** : même moteur, mais avec GLib complète et toute la logique de partie ;
interface orientée partie en cours ; pas de bases de fin de partie. Gardé
comme référence de lecture, sans reprise de code ni de ses noms.
## Conséquences
- Le gnubg de bureau de référence est compilé dans Docker depuis le même
commit, et non pris dans un paquet Debian d'une autre version.
- Concordance au bit près impossible entre x86 avec `-ffast-math` et ARM ou
WebAssembly : les tests ont une tolérance, et prévoient le cas où le meilleur
coup change entre deux coups presque équivalents.
- L'état global de gnubg impose une seule instance du moteur et des appels
sérialisés.
- Les mises à jour de gnubg sont reportées à la main sur la copie figée.
- Les tailles des bases `.bd` restent à mesurer.
- Attention aux noms de niveaux : gnubg compte les plis à partir de 0 (0-ply =
évaluation statique).
@@ -0,0 +1,35 @@
# 0006. Merge requests systématiques, fusionnées par Claude Code
- **Statut** : accepté
- **Date** : 2026-11-02
- **Décideurs** : Pierre
## Contexte
Pierre veut comprendre chaque changement sans suivre le travail au fil de
l'eau. Les premiers commits ont été poussés directement sur `main`, ce qui a
laissé passer un `README.md` contenant des marqueurs de conflit.
## Décision
Aucun commit direct sur `main`. Chaque changement passe par une branche et une
merge request sur git.sans.pub, dont la description explique le pourquoi, le
quoi, le comment, les choix, les risques, la vérification et ce qui est hors
périmètre. Claude Code la fusionne lui-même, par commit de fusion, dès que
`make lint` et `make test` passent. Une MR qui touche un point soumis à
validation attend l'accord de Pierre.
## Alternatives écartées
- **Pousser directement sur `main`** : aucune explication attachée au
changement, aucune étape de vérification avant publication.
- **Fusion par squash** : plus lisible, mais perd le détail des étapes de la
branche.
- **Fusion par Pierre** : contraire au fonctionnement voulu (ADR 0003).
## Conséquences
- Le déroulé est décrit dans `docs/organisation.md`.
- La base de données du Gitea refuse les caractères hors du plan multilingue de
base (émojis) dans les descriptions : les descriptions de MR n'en contiennent
pas.
+14
View File
@@ -0,0 +1,14 @@
# Décisions d'architecture (ADR)
Un fichier par décision structurante, au format de `modele.md`. Un ADR accepté
n'est plus réécrit : une décision qui change donne un nouvel ADR, et l'ancien
passe au statut « remplacé par NNNN ». Voir l'ADR 0001.
| N° | Décision | Statut |
| --- | --- | --- |
| [0001](0001-consigner-les-decisions-dans-des-adr.md) | Consigner les décisions dans des ADR | accepté |
| [0002](0002-nom-ustagammon.md) | Nom de l'application : Ustagammon | accepté |
| [0003](0003-pilotage-par-claude-code-et-sous-agents.md) | Pilotage par Claude Code et des sous-agents | accepté |
| [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é |
+23
View File
@@ -0,0 +1,23 @@
# NNNN. Titre de la décision
- **Statut** : proposé | accepté | remplacé par NNNN | obsolète
- **Date** : AAAA-MM-JJ
- **Décideurs** : qui a tranché
## Contexte
La situation, le problème, les contraintes et les faits (avec preuves) qui
rendent une décision nécessaire.
## Décision
Ce qui est décidé, formulé de façon à pouvoir être appliqué et vérifié.
## Alternatives écartées
Chaque option envisagée et la raison de l'écarter.
## Conséquences
Ce que la décision implique : effets positifs, limites assumées, risques,
travail induit.