ADR

Un ADR — Architecture Decision Record — est un fichier qui consigne une décision d’architecture : le contexte dans lequel elle a été prise, ce qui a été décidé, et ce qu’on accepte en échange. Le format a été proposé par Michael Nygard en 2011, et il tient en cinq titres de section.

Il répond à un manque précis. Le code dit ce que fait le système. Un diagramme C4 dit comment il est structuré. Rien, dans un dépôt ordinaire, ne dit pourquoi. Six mois plus tard, personne ne se souvient pourquoi PostgreSQL plutôt que MongoDB, pourquoi deux services plutôt qu’un, pourquoi cette bibliothèque a été écartée. Et le raisonnement perdu produit toujours l’un de ces deux comportements, aussi mauvais l’un que l’autre :

  • le respect aveugle — « on ne touche pas à ça, il doit y avoir une raison » ;
  • le renversement aveugle — on défait la décision sans savoir quelle contrainte elle réglait, et l’on redécouvre le problème quelques mois plus tard.

Ce n’est pas de la documentation

Le point qui rend la pratique viable, et qu’on manque presque toujours au départ : un ADR ne documente pas le système, il journalise une décision. La différence a trois conséquences directes.

Un ADR n’est jamais mis à jour. Il décrit ce qui a été décidé à une date, dans un contexte donné. Changer d’avis n’autorise pas à le réécrire : on en écrit un nouveau qui remplace l’ancien.

Il ne se périme donc pas. C’est ce qui distingue radicalement les ADR de tout le reste de la documentation d’architecture. Un diagramme faux est nuisible ; un ADR ancien reste vrai, puisqu’il ne prétend décrire que le passé.

Le coût de maintenance est nul. On n’entretient pas un journal. C’est la raison pour laquelle c’est la pratique d’architecture au meilleur rapport valeur/effort — et pourquoi je l’avais mise en tête de liste des manques de cette section.

Quelles décisions méritent un ADR

Le critère de Nygard est qu’une décision soit architecturalement significative. Formulé de manière utilisable : elle est coûteuse à défaire, et quelqu’un la remettra en question.

Mérite un ADRNe mérite pas d’ADR
Le choix d’un moteur de stockageLe choix d’une bibliothèque de formatage de dates
Communication synchrone ou asynchrone entre deux servicesLe nom d’une variable, un refactoring local
Une frontière entre deux contextesL’ajout d’un champ à une table
L’adoption d’un style — hexagonal, 3-tierUne convention de nommage — sauf si elle est contestée
Le mécanisme d’authentificationLe choix d’un formateur de code
Une dérogation assumée à une règle interneCe qui se défait en une après-midi
Le refus d’une option qui reviendra sur la tableUne décision que personne ne discutera jamais

Le test le plus fiable, et il est presque infaillible : un nouvel arrivant dirait-il « mais pourquoi diable… » ? Si oui, il fallait un ADR. Le corollaire vaut aussi : consigner une option rejetée est souvent plus utile que consigner celle qui a été retenue, parce que c’est celle qui reviendra.

Le format de Nygard

Cinq sections, et pas une de plus.

# 2. Séparer la billetterie et la fidélité en deux contextes

Date : 2026-03-14

## Statut

Accepté

## Contexte

<La situation, les forces en présence, les contraintes réelles du moment.>

## Décision

<Ce qui est décidé, à la voix active : « nous séparons… ».>

## Conséquences

<Ce qui devient plus facile ET ce qui devient plus difficile.>

La section décisive est la dernière, et c’est celle qu’on abîme le plus souvent : les conséquences incluent les négatives. Un ADR qui n’énumère que des bénéfices n’est pas un enregistrement, c’est un plaidoyer — et il est sans valeur pour le lecteur futur, qui a besoin de savoir ce qu’on avait accepté de payer.

La section Contexte est la plus précieuse à long terme, pour une raison qui n’apparaît qu’après coup : c’est la seule que le lecteur futur ne peut pas reconstituer. Le code, il l’a sous les yeux ; l’échéance de l’époque, la composition de l’équipe, le progiciel qu’il fallait supporter, le budget — non. Ce sont ces contraintes qui rendent une décision compréhensible, et souvent qui autorisent à la défaire : « cette contrainte n’existe plus ».

Un exemple complet

# 2. Séparer la billetterie et la fidélité en deux contextes

Date : 2026-03-14

## Statut

Accepté

## Contexte

Le module de fidélité partage aujourd'hui les tables `clients` et `commandes`
avec la billetterie. Trois faits nous y font revenir :

- Depuis janvier, six incidents de production sur huit venaient d'un changement
  de schéma fait pour la billetterie et qui a cassé le calcul de points.
- Le mot « client » ne désigne pas la même chose des deux côtés : un profil de
  réservation d'un côté, un porteur de points cumulés de l'autre, avec des
  règles de fusion distinctes.
- Les deux domaines évoluent à des rythmes très différents : la billetterie
  change à chaque saison, la fidélité a été modifiée deux fois en trois ans.

Contraintes du moment : l'équipe compte cinq personnes et ne peut pas exploiter
un second cluster de bases de données avant le T4. La saison ouvre en mai, aucun
arrêt de service n'est acceptable d'ici là.

## Décision

Nous séparons les deux domaines en deux contextes délimités, dans le **même
déploiement** : deux modules, deux schémas PostgreSQL distincts dans la même
instance, aucune jointure entre les deux.

La fidélité s'abonne aux événements `ReservationConfirmee` publiés par la
billetterie et tient sa propre notion de client, reliée par le seul identifiant.

La séparation en deux déploiements distincts est explicitement **remise à plus
tard**, et n'est pas un objectif en soi.

## Conséquences

Ce que cela améliore :

- Un changement de schéma de la billetterie ne peut plus casser la fidélité :
  la CI interdit les références croisées entre schémas.
- Chaque domaine retrouve un vocabulaire non ambigu.
- Le module de fidélité devient testable sans jeu de données de billetterie.

Ce que cela dégrade, et que nous acceptons :

- Le total de points n'est plus cohérent immédiatement après une réservation,
  mais à quelques secondes près. Le service client a validé ce délai.
- Le client est dupliqué dans les deux schémas. C'est voulu — deux notions
  différentes — mais cela déroute à la lecture, et il faudra l'expliquer.
- Deux écrans d'administration affichaient une jointure directe entre points et
  réservations : ils sont à réécrire pour appeler deux sources.
- Nous ajoutons un bus d'événements interne, donc un mécanisme de reprise et de
  supervision qui n'existait pas.

Cet exemple tient en une page, et il contient les trois choses qui feront sa valeur dans deux ans : des faits datés et chiffrés dans le contexte, une décision qui énonce aussi ce qu’elle ne fait pas, et quatre conséquences négatives assumées.

Bon ADR, mauvais ADR

Le même sujet, traité comme il ne faut pas :

## Contexte

Notre architecture actuelle est monolithique et ne passe pas à l'échelle.
Les microservices sont l'état de l'art.

## Décision

Nous passons aux microservices.

## Conséquences

Meilleure scalabilité, déploiements indépendants, équipes autonomes.

Trois défauts, tous typiques. Le contexte n’énonce aucun fait — ni incident, ni mesure, ni contrainte —, seulement un jugement et un argument d’autorité. La décision n’est pas actionnable : on ne sait pas ce qui est découpé ni comment. Et les conséquences sont une liste d’arguments de vente, sans une seule contrepartie — ce qui rend l’ADR inutilisable pour décider, plus tard, s’il faut revenir en arrière.

Le statut et le cycle de vie

StatutSignification
ProposéÉcrit, en discussion
AcceptéEn vigueur
RejetéExaminé puis écarté — on garde l’ADR, c’est même souvent le plus utile
DépréciéPlus pertinent, sans remplacement
Remplacé par ADR-0007Une décision postérieure prend le relais
   Proposé ──► Accepté ──► Remplacé par ADR-0007
      │                            │
      │                            ▼
      └──► Rejeté          ADR-0007 : « Remplace ADR-0002 »

La seule modification autorisée sur un ADR accepté est le changement de son statut, plus un lien vers celui qui le remplace. Tout le reste est immuable.

Warning

La faute la plus commune est de rouvrir un ancien ADR pour le « mettre à jour ». Cela détruit exactement ce qu’on venait y chercher : l’état du raisonnement à une date. Un lecteur qui voit un ADR de 2024 modifié en 2026 ne sait plus quelle partie était vraie quand la décision a été prise, et le journal perd toute valeur de preuve. Un changement de décision est toujours un nouveau fichier.

Les variantes de format

FormatCe qu’il ajouteQuand le choisir
NygardRien — cinq sectionsPar défaut, dans 90 % des cas
MADROptions envisagées, avec avantages et inconvénients de chacune ; critères de décision explicitesQuand il faut prouver que les options ont été pesées : audit, équipe nombreuse, décision contestée
Y-statementUne seule phrase structuréeComme résumé en tête d’un ADR Nygard
Tyree & AkermanUne douzaine de rubriques — hypothèses, contraintes, positions, implications, notesEnvironnements réglementés. Lourd, souvent abandonné

Le Y-statement d’Olaf Zimmermann mérite d’être connu pour sa densité :

Dans le contexte de <cas d'usage ou composant>,
face à <préoccupation ou contrainte>,
nous avons décidé <option retenue>,
et écarté <options rejetées>,
pour obtenir <bénéfice attendu>,
en acceptant <contrepartie>.

Soit, appliqué à l’exemple ci-dessus :

Dans le contexte du module de fidélité, face à des changements de schéma de la billetterie qui le cassent régulièrement, nous avons décidé de le séparer en un contexte distinct avec son propre schéma, et écarté à la fois le statu quo et la séparation en deux déploiements, pour obtenir l’indépendance des évolutions, en acceptant une cohérence différée des points et la duplication de la notion de client.

Une phrase qui contient contexte, décision, options rejetées, bénéfice et contrepartie : c’est un excellent exercice de discipline, et un bon résumé à placer juste sous le titre.

Où les ranger

Dans le dépôt du code, à côté de ce qu’ils décrivent.

docs/
  adr/
    README.md                             l'index
    0001-choix-de-postgresql.md
    0002-separation-billetterie-fidelite.md
    0003-abandon-du-bus-maison.md

La numérotation est séquentielle, sur quatre chiffres, et jamais réutilisée — même pour un ADR rejeté. Le titre en kebab-case rend le dossier lisible sans l’ouvrir.

Le dépôt plutôt qu’un wiki, pour trois raisons concrètes : l’ADR suit le même cycle de vie que le code qu’il justifie ; il passe en revue avec le changement qui l’accompagne, ce qui est le seul moment où la décision est réellement discutée ; et il survit aux migrations d’outils, qui emportent les wikis avec une régularité remarquable.

Tip

Structurizr rend ce dossier directement avec les statuts et le graphe de remplacement, via la directive !adrs — voir Mise en œuvre. Les diagrammes montrent alors la structure, les ADR disent pourquoi elle est ainsi, et les deux sont dans le même dépôt.

L’outillage

Facultatif, et c’est important de le dire : un dossier et un fichier de gabarit suffisent pour commencer, aujourd’hui.

adr-tools — les scripts shell de Nygard lui-même. Numérotation, gabarit et gestion des remplacements automatisés :

adr new "Choix de PostgreSQL"              # crée 0001-choix-de-postgresql.md
adr new -s 2 "Abandon du bus maison"       # crée un ADR qui remplace le n° 2,
                                           # et marque le n° 2 comme remplacé
adr generate toc                           # génère l'index
adr generate graph | dot -Tsvg > adr.svg   # le graphe des remplacements

L’option -s est le seul vrai apport de l’outil : elle met à jour les deux fichiers de façon cohérente, ce qu’on oublie systématiquement à la main.

log4brains produit en plus un site statique consultable et une interface d’édition — utile quand les lecteurs ne sont pas tous à l’aise avec un dépôt Git.

Structurizr intègre les ADR aux diagrammes, comme indiqué plus haut.

Comment on écrit un bon ADR

Huit règles, tirées de ce qui distingue les ADR qu’on relit avec profit de ceux qu’on ignore.

Écrire au moment de la décision. Un ADR rédigé trois mois après est une rationalisation : on y retrouve les arguments qui ont survécu, pas ceux qui ont compté. C’est la règle qui a le plus d’effet sur la qualité du résultat.

Soigner le contexte, avec des faits. Des dates, des chiffres, des incidents, des contraintes nommées. « Ne passe pas à l’échelle » ne veut rien dire ; « six incidents sur huit en janvier » se vérifie.

Nommer les options rejetées et pourquoi. C’est la deuxième partie la plus utile, et celle qui empêche de rejouer le débat.

Écrire les conséquences négatives. Sans elles, l’ADR est une plaidoirie.

Une décision par fichier. Un ADR qui décide trois choses ne pourra être remplacé pour aucune des trois proprement.

Une page. S’il en faut cinq, ce sont plusieurs décisions — ou du contexte qui appartient à une documentation, pas à un journal.

Écrire à la voix active et au présent : « nous séparons », pas « il serait souhaitable de séparer ». Un ADR consigne un acte, pas une intention.

Ne pas s’en servir pour se couvrir. Un ADR n’est pas un document de dédouanement. Dès qu’il devient un moyen de reporter la responsabilité, plus personne n’y écrit les conséquences négatives — et la pratique meurt.

Les pièges

Le processus lourd. Un comité de validation, un gabarit de douze rubriques, une réunion hebdomadaire : la pratique s’arrête en trois mois. Un ADR doit s’écrire en vingt minutes et se relire dans la revue du changement.

L’ADR modifié au lieu d’être remplacé. Traité plus haut ; c’est la faute qui détruit le plus de valeur.

Le silence puis la rafale. Zéro ADR pendant six mois, puis vingt écrits en une semaine pour « rattraper ». Les vingt sont des reconstitutions, et le contexte authentique est déjà perdu.

L’ADR pour tout. Consigner des choix non structurants noie le signal : un dossier de deux cents fichiers dont dix comptent n’est pas plus lisible qu’un dossier vide.

L’absence d’index. Un dossier de trente fichiers sans table des matières n’est pas consulté. adr generate toc, ou un README.md tenu à la main.

Ce que ça change

Quatre effets, dont deux inattendus.

Les débats se ferment. Une décision consignée cesse d’être rejouée tous les trimestres. C’est l’effet le plus immédiat, et il suffit à rentabiliser la pratique.

L’arrivée d’un nouveau change de nature. C’est le bénéfice le plus grand et le moins anticipé : la lecture du dossier adr/ dans l’ordre raconte l’histoire du système et de ses contraintes, ce qu’aucune documentation de structure ne fait.

La révision devient possible. On peut défaire une décision en connaissance de cause, parce que le contexte est écrit. « Cette contrainte n’existe plus » est un argument que seul un ADR autorise.

Le refus devient un actif. Un ADR « Rejeté » économise, chaque fois que l’option revient, la totalité de l’analyse déjà faite.

Références