Votre agent n'a pas besoin d'une meilleure spec, il a besoin d'une frontière
DDD et SDD ne sont pas deux méthodes à empiler. Ce sont deux niveaux d’une même chose : la spécification.
Le code plausible
Une équipe retail a adopté le spec-driven development pour de bon. Chaque évolution commence par une spécification structurée, un plan, des tâches atomiques. L’agent implémente.
Sur le papier, la boucle est propre.
Arrive un ticket banal : refuser la commande si le stock est insuffisant. L’agent produit ceci.
if (stock.quantite >= quantiteDemandee) {
// ...
}
Le code compile, les tests passent, la revue passe. Le développeur qui relit ce jour-là n’a pas en tête les subtilités de la promesse de stock.
Trois semaines plus tard, une vente flash génère quatre cents commandes impossibles à honorer sur une seule référence. Une centaine sont encaissées.
Personne n’a mal travaillé : l’agent a fait exactement ce qu’on lui demandait. Mais le même mot a désigné trois choses différentes.
Le ticket disait « stock ». Le métier pensait à ce qu’on peut encore promettre. L’agent a lu la colonne qui s’appelle stock.
Rien, du ticket au code, ne portait cette différence.
Ce que SDD résout, et ce qu’il ne résout pas
Le spec-driven development s’est structuré en 2025, contre le « vibe coding ». Microsoft a donné un nom à ce que SDD combat : la « translation loss ».
Du sens se perd à chaque passage de main. Du besoin métier aux exigences, puis à l’architecture, au code, à la validation.
L’IA accélère ces passages, mais, pour reprendre les mots de Microsoft, « it cannot correct ambiguity that was never resolved ».
Ce que SDD apporte, c’est la transmission de l’intention. Ce qu’on veut, sous quelles conditions, avec quels critères vérifiables.
Il laisse deux trous.
Le vocabulaire. Une spécification s’écrit en langue naturelle. Si le terme est ambigu, la spécification l’est aussi, et aucun formalisme ne rattrape ça.
Refuser si le stock est insuffisant est une phrase bien formée qui ne dit rien.
Le périmètre. SDD travaille au niveau de la fonctionnalité. Or proposer le retrait en magasin sous deux heures touche Assortiment, Disponibilité, Vente et Préparation.
Où l’agent s’arrête-t-il ? Quelles tables peut-il écrire ? Quels tests font autorité ?
Une spécification de fonctionnalité ne peut pas répondre. Ce n’est pas son niveau.
Ce sont ces deux trous que DDD comble, avec trois notions plutôt que trente. La guidance Microsoft sur SDD en entreprise arrive à la même conclusion : des specs modulaires et en couches plutôt qu’un document monolithique, découpées selon les bounded contexts.
Trois leviers
1. Le langage ubiquitaire compresse le domaine
Le mot qui a coûté quatre cents commandes :
| Contexte | « Stock » signifie |
|---|---|
| Vente | ce que je peux encore promettre, sur ce canal |
| Entrepôt | ce qui est physiquement sur les emplacements |
| Achats | physique + en transit − réservé |
Les trois définitions sont vraies, chacune chez elle.
C’est une propriété du modèle, posée par Evans en 2003 : chaque bounded context porte son propre « ubiquitous language », et un même mot y prend des sens différents. L’Azure Architecture Center la reprend, avec « account » pour exemple. Le nôtre est « stock ».
Écrivez « stock » dans une spécification sans préciser le contexte, et l’agent choisit un des trois sens. Presque toujours celui qui ressemble à une colonne de base de données, parce que c’est le signal le plus fort du repo.
Le prix de ce choix est une hallucination cohérente avec le reste du code, donc invisible en revue.
Désigner un sens officiel ne marche pas : aucun des trois ne cédera, et ils ont tous raison.
On s’en sort en deux gestes. Nommer le contexte qui porte la question, Disponibilité. Y forger un terme qui ne se prête pas à trois lectures, vendable.
Un terme bien choisi économise deux cents mots d’explication. « Vendable » porte à lui seul le retrait du réservé, du litige et du stock de sécurité.
Le retail l’a d’ailleurs déjà forgé sous son nom anglais, « available-to-promise » : ce qu’on peut promettre, pas ce qu’on possède.
Et « stock » disparaît des spécifications. Il n’y était jamais à sa place.
Un contresens à écarter au passage : les identifiants traversent les contextes ; les significations, non.
Un GTIN désigne le même produit partout, ce qui rend les intégrations possibles. Mais un identifiant partagé n’impose pas un modèle partagé. Confondre les deux, c’est fabriquer un monolithe distribué.
2. Le bounded context borne le travail de l’agent
Un « bounded context », au sens qu’Evans lui donne, est une zone du système où chaque terme a un sens unique et stable. Un contexte, pour faire court.
Sa frontière tranche trois questions qu’un agent se pose avant d’écrire une ligne :
- que charger ? les fichiers du contexte concerné, pas le repo entier ;
- que peut-il casser ? le « blast radius » d’une modification ;
- qu’est-ce qui fait foi ? l’« acceptance gate », le jeu de tests qui décide si le comportement est juste.
Un repo sans frontières explicites répond « tout », « tout » et « rien ». Empilez autant de spécifications que vous voulez par-dessus : les trois réponses ne bougeront pas.
3. Les invariants doivent être écrits noir sur blanc
Un agent produit du code. Il ne fait pas respecter les invariants du modèle : il manipule un agrégat directement, il contourne la règle qui protège sa cohérence.
Il n’a aucune mémoire des contraintes du métier, seulement ce qu’on lui donne à lire.
Les travaux sur le « Constitutional SDD » en tirent la conséquence : les contraintes non négociables vivent dans une « Constitution » versionnée et lisible par la machine, respectée « by construction rather than inspection ».
Notre invariant porte sur l’agrégat Réservation : la somme des réservations actives sur un SKU et un canal ne dépasse jamais le vendable.
Écrit une fois au bon endroit, il survit à toutes les fonctionnalités. Chaque spécification suivante en hérite.
La carte
Ce qui suit est un exemple, pas une architecture de référence. Chez un autre distributeur, les frontières et les équipes tomberaient ailleurs, et l’invariant ne s’écrirait pas tout à fait pareil.
C’est la démarche qui se transpose, pas la carte.
Trois lectures.
La fonctionnalité n’est pas une frontière. Le retrait en magasin traverse quatre contextes. Une spécification écrite à ce niveau décrit un chemin, pas un territoire.
Les zones sont des équipes, et c’est ce qui justifie les patterns. Chez Khononov, le pattern d’intégration se déduit du rapport de force entre équipes, pas de la technique.
ERP et paiement sont hors de l’organisation. Dans les deux cas l’aval subit. Et pourtant il ne tranche pas de la même façon. Disponibilité se protège derrière un « anticorruption layer », parce qu’elle porte le cœur. Facturation se contente d’un « conformist », parce qu’elle n’a rien à protéger.
Disponibilité et Préparation appartiennent à la même équipe. C’est ce qui rend leur « partnership » tenable.
Un « core » est un sous-domaine, pas un bounded context. Ce qui différencie un distributeur, ce n’est pas de prendre une commande. C’est le calcul du vendable, qui vit à l’intérieur de Disponibilité.
D’où l’absence de couleur par type de sous-domaine sur les boîtes. Le classement « core / supporting / generic » s’applique aux sous-domaines, pas aux contextes.
L’ERP le montre bien : un seul contexte qui recouvre de la compta, des achats et du stock.
Deux niveaux de spécification, et le code qu’ils gouvernent
Les deux premiers niveaux sont des spécifications. Le troisième est le code qu’elles gouvernent.
Ce qui les sépare n’est pas le degré de détail, c’est la durée de vie.
Stratégique, en années. Le vendable n’est défini que dans Disponibilité, où l’agrégat Réservation porte l’invariant.
Et surtout : Vente ne lit jamais le stock. Elle demande une réservation, et reçoit une réponse. Le contournement devient impossible, pas seulement déconseillé.
Tout cela s’est décidé avec des gens du métier, dans une pièce. Ça ne se régénère pas.
Contractuel, en itérations. Étant donné un SKU et un canal, quand la quantité demandée dépasse le vendable, alors la réservation est refusée avec le motif VENDABLE_INSUFFISANT, sans écriture partielle.
Le vocabulaire vient du niveau au-dessus, mot pour mot. Ce niveau n’invente rien.
Implémentation, jetable. L’agent travaille dans contexts/disponibilite, sans accès en écriture au schéma de Vente. Son « acceptance gate » est fixé ailleurs, et il ne peut pas le réécrire.
Microsoft pousse la même logique côté outillage : cantonner l’agent aux fichiers rattachés à un « spec ID », faire échouer le build dès que le code s’écarte du contrat.
Le if (stock.quantite >= quantiteDemandee) du début n’est plus seulement une mauvaise idée. Il n’est plus écrivable : la table qu’il interroge est hors périmètre, et le mot qu’il utilise n’existe pas dans ce contexte.
La faute classique consiste à traiter les trois niveaux à la même cadence.
Régénérer le premier à chaque ticket, c’est repartir de zéro. Figer le troisième, c’est se priver du seul gain que l’IA offre vraiment. Fusionner les deux premiers dans un document d’avant-projet, c’est refaire du cycle en V avec des outils modernes.
Un article sur la « Protocol-Driven Development » résume l’idée : « code is transient, while the protocol carries durable authority ».
Quatre pièges
Le glossaire mort. Un langage ubiquitaire écrit une fois puis oublié est pire que rien : il donne à l’agent une fausse certitude sur des termes qui ont dérivé.
S’il n’est pas versionné à côté du code, il ne survit pas six mois.
Le dictionnaire de données pris pour un langage ubiquitaire. Un référentiel impose un sens par terme sur tout le système d’information. Un langage ubiquitaire en autorise trois pour « stock », tant que les frontières sont explicites.
Beaucoup croient avoir fait le travail parce qu’ils ont un dictionnaire. Ils ont effacé la seule information qui comptait.
Le contexte calqué sur l’organigramme. Les organisations retail sont souvent découpées par canal : web, magasin, drive. Découper les contextes de la même façon produit trois modèles de stock qui se contredisent, et trois agents qui les font diverger trois fois plus vite.
L’Azure Architecture Center donne un test simple : si une équipe possède plusieurs contextes sans rapport, ou si un contexte exige la coordination de plusieurs équipes, c’est la frontière ou l’organisation qu’il faut revoir.
Croire que l’agent fera le travail à votre place. Une étude de 2026 a déroulé une analyse DDD complète par enchaînement de prompts : langage, EventStorming simulé, contextes, agrégats, architecture.
Les trois premières étapes produisent des artefacts utilisables. Les deux dernières accumulent les erreurs jusqu’à produire des artefacts impraticables.
L’agent est donc bon là où il s’agit de nommer, et faible là où vivent les invariants. Les auteurs parlent d’un « collaborative sparring partner » pour l’architecte, pas d’une automatisation.
Compression et transmission
DDD compresse le domaine : une frontière, un langage, quelques invariants.
SDD le transmet : un contrat exécutable, vérifiable, jetable.
Sans compression, la transmission sature. Des spécifications de plus en plus longues, dans un vocabulaire de plus en plus flou.
Sans transmission, la compression reste au tableau blanc. Le domaine est bien modélisé, mais personne ne l’a mis entre les mains de la machine.
Ce n’est pas une nouvelle méthode. C’est une ancienne discipline, enfin adressée à une machine qui prend tout au pied de la lettre.
Références
Fondamentaux
- Eric Evans, Domain-Driven Design, 2003 : la source du « bounded context », de l’« ubiquitous language », de l’« anticorruption layer » et du classement des sous-domaines, que les pages Microsoft ci-dessous appliquent.
- Vlad Khononov, Learning Domain-Driven Design, 2021 : chapitre 3 pour l’articulation sous-domaines / bounded contexts, chapitre 4 pour les patterns d’intégration et le rôle des équipes.
Microsoft
- Apoorv Gupta, Spec-Driven Development: A Spec-First Approach to AI-Native Engineering, Microsoft for Developers, juin 2026 : la « translation loss » et le cycle Spec Kit. https://developer.microsoft.com/blog/spec-driven-development-ai-native-engineering/
- Spec-Driven Development for AI-Enabled Enterprise Systems, Microsoft Community Hub, mai 2026 : specs modulaires, bounded contexts comme modèle mental, cantonnement de l’agent. https://techcommunity.microsoft.com/blog/educatordeveloperblog/spec-driven-development-for-ai-enabled-enterprise-systems/4520807
- Use domain analysis to model microservices, Azure Architecture Center : une mise en application du DDD d’Evans, avec un « ubiquitous language » par « bounded context », le classement « core / supporting / generic », la loi de Conway et l’« anticorruption layer ». https://learn.microsoft.com/azure/architecture/microservices/model/domain-analysis
- GitHub Spec Kit. https://github.com/github/spec-kit
Recherche
- The Productivity-Reliability Paradox: Specification-Driven Governance for AI-Augmented Software Development, arXiv, 2026 : le code généré viole les invariants DDD, faute de compréhension persistante des contraintes du domaine. https://arxiv.org/abs/2605.01160
- Srinivas Rao Marri, Constitutional Spec-Driven Development: Enforcing Security by Construction in AI-Assisted Code Generation, arXiv, janvier 2026 : une « Constitution » versionnée et lisible par la machine, respectée « by construction rather than inspection ». https://arxiv.org/abs/2602.02584
- Jun He et Deying Yu, Protocol-Driven Development: Governing Generated Software Through Invariants and Continuous Evidence, arXiv, mai 2026 : « code is transient, while the protocol carries durable authority ». https://arxiv.org/abs/2605.12981
- Tobias Eisenreich, Husein Jusic et Stefan Wagner, Automating Domain-Driven Design: Experience with a Prompting Framework, arXiv, mars 2026 : l’analyse DDD en cinq prompts, validée chez FTAPI. https://arxiv.org/abs/2603.26244
- Deepak Babu Piskala, Spec-Driven Development: From Code to Contract in the Age of AI Coding Assistants, arXiv, 2026 : trois niveaux de rigueur, « spec-first », « spec-anchored » et « spec-as-source ». https://arxiv.org/abs/2602.00180