Écrire une demande qui ne se transforme pas en malentendu
Alban
Product manager & product owner

En bref
Comment rédiger une user story ou une spécification claire pour une équipe de développement ?
En décrivant le problème et les critères d'acceptation observables, jamais la solution technique. Une demande exploitable tient en une page : qui, quel problème, ce qui doit être vrai à la fin, les cas particuliers connus, et ce qui est explicitement hors périmètre. La section « hors périmètre » est celle qui évite le plus de malentendus, et c'est celle qu'on oublie systématiquement.
Un développement qui part de travers vient rarement d’une erreur technique. Il vient presque toujours d’une demande que deux personnes ont lue différemment sans le savoir.
Le pire n’est pas la demande floue — on pose des questions. Le pire est la demande qui paraît claire et ne l’est pas.
Le format que j’utilise
Une page, cinq blocs. Pas de gabarit rigide, pas de formule imposée.
Pour qui. Un rôle précis, pas « l’utilisateur ». Un gestionnaire de dossier et un responsable d’équipe n’ont pas les mêmes attentes sur le même écran.
Quel problème. Ce que la personne n’arrive pas à faire aujourd’hui, ou ce que ça lui coûte. Pas ce qu’elle voudrait qu’on construise — ce qu’elle vit.
Ce qui doit être vrai à la fin. Les critères d’acceptation, formulés de façon observable : « depuis la liste, je peux retrouver un dossier par nom de client en moins de trois secondes ». Le test se déduit de la phrase.
Les cas particuliers connus. Le client sans adresse, le dossier annulé puis rouvert, le montant à zéro. Chaque cas listé ici est un aller-retour évité en recette.
Ce qui est hors périmètre. Le bloc le plus utile, et celui qu’on saute. « L’export n’est pas inclus. » « On ne traite pas les dossiers archivés dans cette version. » Sans cette section, chacun complète mentalement avec ses propres attentes — et personne ne se rend compte qu’elles diffèrent.
Les quatre formulations qui font perdre du temps
« Comme dans l’ancien outil. » Personne ne se souvient de la même chose, et l’ancien outil comportait des comportements que tout le monde détestait sans les avoir jamais nommés. Il faut décrire, ou faire une capture d’écran commentée.
« Il faudrait que ce soit intuitif. » Ce n’est pas un critère. Ce qui est vérifiable : « un nouvel utilisateur doit pouvoir créer un dossier sans formation ». On peut le tester.
« Un bouton pour exporter. » C’est une solution, pas un problème. Pourquoi exporte-t-on ? Pour envoyer à un tiers ? Pour retravailler dans un tableur ? Pour archiver ? Les trois réponses donnent trois développements différents, dont deux ne sont pas un bouton d’export.
« Etc. » À la fin d’une liste de cas, ce mot fait porter au développeur la responsabilité de deviner les cas manquants. Soit la liste est exhaustive, soit on écrit explicitement qu’elle ne l’est pas et on prévoit un temps pour la compléter.
Photo : rawpixel — licence CC0.
Décrire le problème, pas la solution
C’est le principe qui rapporte le plus, et le plus difficile à tenir — y compris pour moi.
Quand quelqu’un demande une solution, il a déjà fait un trajet mental : il a rencontré un problème, imaginé une réponse, et il ne me transmet que la réponse. Mon travail est de remonter le trajet.
La question que je pose : « qu’est-ce qui se passe aujourd’hui qui vous amène à demander ça ? »
Elle débloque énormément de situations. Une fois sur trois, on découvre que le problème réel se résout par un chemin plus simple, plus rapide, ou déjà existant dans l’application.
Les critères d’acceptation, en pratique
Un bon critère est observable et binaire. On peut dire oui ou non sans discuter.
Mauvais : « la recherche est rapide ». Bon : « la recherche affiche un résultat en moins d’une seconde sur la base de production ».
Mauvais : « les erreurs sont gérées ». Bon : « si le service de facturation ne répond pas, l’utilisateur voit un message lui indiquant de réessayer, et le dossier n’est pas créé ».
Le second est plus long à écrire, et il supprime la conversation qu’on aurait eue en recette — celle où chacun défend sa lecture, avec le développement déjà fait.
Photo : Lukas — licence CC0.
Photo : Green Chameleon — licence CC0.
Le cas des règles de gestion
C’est la partie où les malentendus coûtent le plus cher, parce qu’elle finit dans du code difficile à corriger après coup.
Une règle exprimée en une phrase cache presque toujours des cas non dits. « Le client bénéficie d’une remise de 5 % au-delà de 1 000 € » soulève immédiatement : hors taxes ou toutes taxes ? Avant ou après les autres remises ? À 1 000 € pile, la remise s’applique-t-elle ? Sur une commande ou sur un cumul annuel ? Et si la commande est ensuite partiellement annulée ?
Ma méthode : écrire trois à cinq exemples chiffrés, avec le résultat attendu pour chacun. Un tableau de quatre lignes.
Ces exemples sont plus efficaces que n’importe quelle formulation, pour deux raisons. Ils ne laissent aucune place à l’interprétation. Et ils deviennent directement les cas de test — le développeur les reprend tels quels.
Ce que je fais quand le demandeur ne sait pas
Cela arrive, et ce n’est pas un problème en soi. Le problème serait de faire semblant.
Quand une question reste sans réponse — un cas rare, une règle jamais tranchée — j’écris explicitement dans la demande : « comportement non défini pour ce cas ; hypothèse retenue : X ; à confirmer avant la mise en production ».
Trois bénéfices. Le développement n’est pas bloqué. L’hypothèse est visible plutôt qu’implicite. Et le jour où quelqu’un découvre en recette que le comportement ne convient pas, la conversation est simple : c’était écrit, il faut arbitrer maintenant.
C’est infiniment préférable à la situation classique, où chacun avait supposé quelque chose de différent sans le dire.
Ce qui n’a pas sa place dans une story
Trois contenus s’y glissent régulièrement et devraient vivre ailleurs.
Les règles transversales. Le format des dates, la politique de droits, les messages d’erreur standard : ce sont des conventions de produit. Recopiées dans chaque story, elles divergent, et c’est la version la plus récente qui gagne au hasard.
Les détails d’implémentation. Le nom d’une table, le choix d’un composant. Cela appartient à l’équipe technique, et l’inscrire dans la story interdit une meilleure solution sans apporter de précision utile.
L’historique de la discussion. Une story qui accumule quinze commentaires contradictoires n’est plus lisible. Quand la décision est prise, elle doit être remontée dans le corps de la story, et le fil de discussion redevient ce qu’il est : une trace, pas la spécification.
Le test que je fais avant de transmettre
Je relis la demande en me posant une seule question : est-ce que quelqu’un qui ne connaît pas ce projet pourrait la lire et savoir quoi faire ?
Si je dois ajouter « je t’expliquerai de vive voix », la demande n’est pas prête. L’explication orale n’a pas de trace, et c’est elle qu’on cherchera dans six mois quand il faudra comprendre pourquoi c’est fait comme ça.
Ce n’est pas de la paperasse. La demande écrite sert trois fois : au développement, à la recette, et à celui qui reprendra le sujet plus tard. Une page bien écrite, c’est trente minutes qui en économisent plusieurs journées.