🇫🇷🇺🇸🇧🇷🇪🇸🇩🇪🇮🇹

J'ai écrit l'ontologie d'un produit. Trois fois, j'ai cru avoir fini.

Votre équipe reconstitue le même modèle produit à chaque question, chaque bug, chaque appel d'offres. Voici comment l'écrire une fois : 52 objets, 250 règles, moins de six heures. Et surtout comment savoir qu'on a fini — les trois critères d'arrêt qui semblent prouver la complétude et n'en prouvent rien, plus le seul qui tienne.


Une question arrive sur Slack : est-ce que le produit sait faire ceci, pour ce client, dans ce cas précis ?

Pas une question abstraite. Pas une réflexion sur la vision à cinq ans. Une question de terrain, à laquelle il faut répondre dans l'heure. Alors quelqu'un ouvre un environnement de test, reproduit le cas, vérifie. Une demi-heure. Payée deux fois : par la personne qui cherche, et par celle qu'elle interrompt.

Ce n'est pas un problème de documentation. Il y en a, et elle est à jour. Le problème est que ce dont le produit est fait — les objets qu'il manipule, les règles qui les régissent, les mots pour en parler — n'est écrit nulle part sous une forme qu'on puisse interroger. Ça existe à deux endroits : dans le code, que quelques personnes savent lire, et dans la tête de ces mêmes personnes.

Alors j'ai essayé de l'écrire. Le résultat existe : 52 objets décrits, 250 règles, 208 liens entre eux. Cet article raconte comment je l'ai obtenu — et surtout ce que j'ai raté en chemin, parce que c'est la partie qui se transfère.

Trois avertissements avant de commencer.

Le premier : ce retour d'expérience porte sur la fabrication du référentiel, pas sur son usage. Il existe, il est mesuré, il a produit ses premiers sous-produits. Mais la phase d'exploitation n'a pas commencé. Je ne peux donc rien affirmer sur le retour sur investissement. Quiconque vous vend un chiffre à ce stade invente.

Le second : les exemples sont pris sur un cas fictif — une société qui édite un SaaS de gestion, un ERP, avec ses clients, ses commandes, ses lignes et ses factures. Ce qui se transfère d'un produit à l'autre, ce ne sont pas mes trouvailles, c'est le type de problème qu'on trouve : un état recalculé partout et défini nulle part, une règle appliquée d'un seul côté, un mot que les clients emploient et que le produit ignore. Ces trois-là, vous les avez aussi. Le détail du cas, en revanche, n'intéresse personne.

Le troisième : c'est long, une demi-heure de lecture. C'est un compte rendu, pas un billet — j'ai préféré tout dire plutôt que faire court. Si vous ne devez en lire qu'une section, prenez « Trois critères d'arrêt. Trois fois faux. » : le reste est le contexte qui l'entoure. Les annexes, elles, ne servent qu'à ceux qui voudront refaire le travail.


Une ontologie n'est pas un glossaire enrichi

Le mot est piégé. Il évoque la philosophie aux uns, un domaine savant et ses outils compliqués aux autres, et rien du tout à la plupart. Autant le poser proprement.

Une ontologie, c'est la description explicite et structurée de ce dont un domaine est fait : - les types d'objets qui existent, - ce qui les caractérise, - ce qui les relie, - ce qui est vrai à leur sujet, - les mots par lesquels on les désigne.

Appliquée à un logiciel, elle répond à cinq questions. Chacune correspond à une chose qu'on écrit, et chacune a un nom savant dont vous n'aurez pas besoin ensuite :

La question Ce qu'on écrit Son nom savant
De quoi le produit est-il fait ? les objets du métier, et leurs cas particuliers concepts, hiérarchie
Qu'est-ce qui les caractérise ? leurs propriétés attributs
Comment se lient-ils ? les liens entre eux, chacun nommé par un verbe relations
Qu'est-ce qui est toujours vrai ? les règles axiomes (ou invariants)
Comment les appelle-t-on ? les mots, dans toutes les langues lexique

Dans la suite de l'article, pour éviter les termes savants, je dis « objets », « propriétés », « liens », « règles » et « mots ». C'est la même chose.

Ces cinq cases servent aussi de filtre : ce qui n'entre dans aucune n'a rien à faire dans le référentiel.

Pourquoi un document de plus

Il existait déjà un glossaire, un schéma de base de données, de la documentation. Le glossaire définit des mots un par un. Le schéma range des données selon des contraintes techniques, pas selon le métier. La documentation raconte, pour un lecteur humain.

Ce qui les distingue d'une ontologie tient en un point : les liens y comptent autant que les définitions. Un objet décrit tout seul n'apprend pas grand-chose. Le même objet relié à cinq autres par des verbes précis — passée par, contient, facturée dans — décrit un produit.

Ce qu'elle réconcilie

Un même objet porte trois noms dans une entreprise. Prenons la commande client :

Qui parle Ce qu'il dit
Le code sales_order
L'écran « commande »
Le terrain « affaire », « dossier »

Ces trois vocabulaires évoluent séparément, et l'écart entre eux est une information de valeur. Le référentiel le conserve : le mot officiel, les mots employés par les clients, et ceux qu'on a abandonnés en route. C'est ce qui permet de traduire une phrase d'utilisateur en objet du produit — et l'inverse.

Ce que je n'ai pas fait

Il existe des façons très savantes de faire tout ça : des langages dédiés, des outils qui déduisent des conclusions à partir des règles qu'on leur donne, des normes qui vont avec. C'est un vrai domaine, et je n'y suis pas allé (entre autres, par manque de compétences).

J'ai commencé par ce que je savais tenir : une fiche par objet, dans un fichier texte. Un titre, quelques champs, des liens vers les autres fiches. Rien qu'un éditeur de texte ne sache ouvrir. Tant que je ne sais pas à quoi le référentiel va servir, je ne sais pas de quelle rigueur j'ai besoin — et commencer simple pour se compliquer plus tard coûte toujours moins cher que l'inverse.


Le code est devenu la source de vérité. Le sens est resté dehors.

Autour de ce produit, la documentation, le journal des nouveautés, la documentation de support, les réponses aux questions produit et les spécifications sont régénérés à partir du code. Le raisonnement est simple : la vérité d'un produit, c'est ce qui tourne, pas ce qu'on avait prévu.

Ce basculement supprime un travail entier — celui de tenir à jour, à la main, des documents qui décrivent autre chose que la réalité. C'est un gain considérable, et je le défendrais encore.

Mais il déplace le problème.

Ce que le code ne donne pas

Le code établit comment le produit fonctionne. Le sens, lui, se construit par-dessus.

Prenons la commande, et son état. Le code donne la structure : voici les champs, voici les valeurs possibles. Quatre informations la rendent réellement exploitable, et aucune ne s'y trouve :

  • la règle — une commande facturée ne reçoit plus de ligne. Le produit l'applique, mais la règle n'est écrite nulle part : le contrôle est éparpillé dans cinq fichiers et chacun n'en fait qu'un bout. Pour l'énoncer en une phrase, il faut les avoir lus tous les cinq ;
  • les cas particuliers — une commande urgente est une commande, avec des contraintes en plus ;
  • le vocabulaire — les utilisateurs disent « affaire », et un autre terme a été abandonné il y a trois ans ;
  • la portée — le produit compte deux applications, que j'appellerai A et B, et chacune met son propre sens derrière le même mot.

Rassemblées, ces quatre informations transforment une structure de données en description de produit. C'est exactement le contenu d'une fiche. Et aucune ne se trouve au même endroit : elles sont réparties entre le cœur du code, la base de données, les écrans et les traductions.

Le coût réel se paie ailleurs

La question du début n'est qu'un cas parmi d'autres. Tout ce qui décrit le produit à quelqu'un est une reconstitution, refaite à chaque fois, en parallèle, par chaque service : la documentation, les réponses aux appels d'offres, la formation des nouveaux arrivants, le discours du support. Chacun repart du code, ou de la mémoire de quelqu'un.

C'est cette dépense-là qu'il s'agit de supprimer. Elle n'apparaît dans aucun budget, ce qui explique qu'on la paie depuis des années sans la voir.

Une IA ne peut pas demander. Elle devine.

Jusqu'ici, ce que le produit est vraiment se transmettait de vive voix. On demandait à la bonne personne, on obtenait la règle, on repartait. Le modèle du produit vivait dans quelques têtes, et ça tenait parce qu'on pouvait toujours frapper à la porte.

Une IA ne frappe à aucune porte.

Quand on lui confie une évolution, on la décrit en quelques phrases. Dans notre tête, il y a un modèle complet : ce qu'est une commande, quels états elle traverse, ce qui est interdit et à partir de quand. L'agent n'a que nos quelques phrases, plus ce qu'il arrive à lire dans le code. Le reste, il le comble — de façon plausible, cohérente, et parfois fausse.

L'écart entre ce qu'on voulait et ce qu'on récupère, c'est exactement la part de notre modèle mental qu'on n'a pas écrite.

Un référentiel, c'est ce modèle mental écrit. Le donner à un agent ne le rend pas plus intelligent : ça l'empêche d'inventer là où une règle existe. Trois usages en découlent, et ce sont ceux qui m'intéressent.

Demander une évolution sans réexpliquer le produit. « Ajoute une remise sur les commandes. » Avec le référentiel en contexte, l'agent sait qu'une commande facturée ne reçoit plus de ligne, qu'une remise a un plafond, et que « commande » recouvre aussi les commandes urgentes et les commandes permanentes. Sans lui, il découvrira l'une de ces trois choses à la relecture — dans le meilleur des cas.

Analyser plus vite. Instruire un bug commence toujours par reconstituer le modèle de la zone concernée. Cette reconstitution est refaite à chaque fois, par chaque personne et par chaque agent. Écrite une fois, elle se lit en quelques secondes. Et quelques centaines de fiches tiennent dans un contexte là où des milliers de fichiers de code n'y tiennent pas : l'agent lit ce qu'il faut au lieu de fouiller au hasard.

Écrire les tests, et trancher les signalements. Une règle est une affirmation vérifiable. « Une commande facturée ne reçoit plus de ligne » est un test, tel quel, formulé en langage métier. 250 règles, ce sont 250 tests candidats que personne n'a besoin de déduire du code. Et devant un signalement client, la question devient mécanique : est-ce que ça contredit une règle écrite — alors c'est un bug ; ou est-ce une règle que personne n'avait posée — alors c'est une décision produit, pas un défaut. Aujourd'hui, ce verdict est rendu à l'expérience, par la personne la plus ancienne dans l'équipe.

Rien de tout cela n'est mesuré, conformément à l'avertissement du début. Le mécanisme me paraît solide — on supprime la part devinée — mais je n'ai pas fait le test. Celui que je ferai : prendre une trentaine de demandes, en traiter la moitié avec le référentiel en contexte et l'autre sans, comparer le temps passé et la quantité de reprises. Tant que ce n'est pas fait, cette section est une attente, pas un résultat.


La méthode : esquisser pour savoir quoi chercher

Un dilemme se pose d'emblée. Sans un modèle, même grossier, on ne sait pas quelle matière ramasser — et on passe à côté d'informations importantes sans le savoir. Sans matière, on ne sait pas quel modèle tenir.

Itérer, ne pas séquencer. On esquisse juste assez pour savoir quoi chercher, on cherche, on reprend le modèle avec ce qu'on a appris. Une contrainte traverse les allers-retours : ce qu'on ramasse est stocké sous la forme la plus simple possible, et toujours avec l'indication d'où ça vient. Un changement de modèle ne doit jamais obliger à retourner chercher ce qu'on a déjà.

Par où commencer : vingt questions qu'on nous avait déjà posées

Un produit a des dizaines de pans — la facturation, les achats, les droits d'accès, la recherche, les notifications. Par lequel commencer ? La réponse théorique est connue : on écrit d'abord les questions auxquelles le référentiel devra savoir répondre, et elles délimitent le terrain. Le problème, c'est que des questions écrites à froid, dans une salle, ressemblent toujours à ce qu'on croit important.

Je ne les ai donc pas écrites. Je suis allé les chercher.

Depuis des mois, chaque question produit qui arrive — par Slack, en réunion, d'un commercial qui prépare une réponse, du support devant un ticket — est archivée avec sa réponse. Je les ai toutes relues, puis condensées en vingt questions génériques. Aucune n'est inventée ; chacune recouvre entre cinq et vingt questions réelles.

Transposées sur l'ERP fictif, elles ressemblent à ça :

  • Quels sont les états d'une commande, et quels passages sont permis de l'un à l'autre ?
  • Qu'est-ce qu'on peut encore annuler, et à partir de quel moment on ne le peut plus ?
  • Qu'est-ce que le solde d'un client, et par quels mouvements évolue-t-il ?
  • À qui revient une commande générée automatiquement, et que devient-elle si cette personne quitte l'entreprise ?
  • Dans quels cas un utilisateur d'une filiale voit-il les commandes d'une autre filiale ?
  • Comment les utilisateurs appellent-ils la commande, et dans quelles langues ?

Ce ne sont pas des questions élégantes. Ce sont celles qui coûtent une demi-heure à quelqu'un, plusieurs fois par mois.

Ce que ça donne immédiatement : l'ordre de travail. Chaque question touche un ou plusieurs pans du produit ; il suffit de compter. Onze questions sur vingt tapaient dans le même — il est devenu le premier. Cinq dans un deuxième, quatre dans un troisième. L'ordre n'est plus une préférence, c'est un décompte.

Et elles servent une seconde fois, à l'arrivée. Une fois un pan terminé, on reprend ses questions et on vérifie que le référentiel y répond sans ouvrir le code. Le contrôle mené à mi-parcours a donné 18 réponses complètes sur 20. Les deux manquantes l'étaient de la même façon : une règle écrite en général là où la question attendait le détail — « certaines opérations exigent ceci » sans jamais dire lesquelles.

C'est le défaut le plus probable de ce genre de travail, et le plus difficile à voir. Compter les fiches ne l'aurait jamais montré.

Une fiche par objet, et des liens entre elles

Une fiche par objet du métier, dans un fichier texte portant son nom. Chaque fois qu'une fiche mentionne un autre objet, elle le fait par un lien.

Ce détail paraît cosmétique. Il ne l'est pas. Les fiches et leurs liens forment un réseau, et ce réseau se visualise : chaque fiche est un point, chaque lien un trait. Un lien qui pointe vers une fiche qui n'existe pas encore se voit immédiatement — c'est le signal qu'un objet reste à décrire.

Le réseau cesse alors d'être une jolie image pour devenir la file d'attente du travail : tant qu'il reste des liens dans le vide, il reste des fiches à écrire.

La réalité d'un côté, l'intention de l'autre

Un référentiel peut décrire deux choses très différentes : ce que le produit fait, ou ce qu'il devrait faire. Chacune seule est incomplète. La première ne permet jamais de faire apparaître un défaut. La seconde perd la trace de ce qui existe vraiment.

Je garde les deux, à deux endroits distincts de la même fiche. Le corps de la fiche décrit la réalité, telle qu'elle est dans le code. Un bloc séparé, en fin de fiche, liste les écarts : chaque endroit où cette réalité diverge de ce qu'on voudrait.

Règle absolue : un écart ne modifie jamais le corps de la fiche.

Ce qui justifie la séparation, c'est que les deux parties n'ont pas la même durée de vie :

Le corps Les écarts
D'où ça vient du code d'une décision humaine
Se réécrit quand le produit change oui jamais
Se vérifie tout seul oui non

Le corps se déduit du code : on peut le jeter et le refaire sans rien perdre. Les écarts, eux, portent du jugement — ils ne se retrouvent nulle part si on les perd. Les séparer, c'est protéger la partie qui coûte cher à produire.

Un point qu'on comprend souvent de travers : quand tout va bien, on n'écrit rien. Si le produit fait ce qu'il doit faire, la règle figure simplement dans le corps de la fiche. Le bloc des écarts ne contient que les divergences. Une fiche sans écart signale un objet conforme, et c'est une information en soi.

Cinq natures d'écart suffisent, et ce sont elles qui transforment le référentiel en matière de travail :

Nature Ce que ça veut dire Ce que ça devient
défaut le produit contredit une attente écrite quelque part un bug à instruire
manque ce qu'on attend n'existe pas un élément de backlog
incohérence deux parties du produit ne disent pas la même chose une dette à arbitrer
irritant le produit fait ce qui était prévu, mais c'est mal fichu une dette de conception
souhait une extension désirée, hors de toute attente actuelle une opportunité

Le point de départ : une photo, prise à un instant donné

On décrit le produit tel qu'il est à un instant donné. Une version du code, et tout ce qui tourne avec : la base telle qu'elle est à cette version, les écrans de cette version, les traductions de cette version. C'est la photo.

Ce qui figure dessus est l'état initial, sans date de naissance : je ne cherche pas à savoir quand chaque champ est apparu. Reconstituer l'histoire du produit demanderait de fouiller des années d'archives pour un bénéfice nul.

Plus tard, on prend une nouvelle photo, et on met à jour les fiches avec ce qui a bougé entre les deux. C'est tout le mécanisme.

La seule chose à surveiller, et je m'y suis fait prendre : une source qui ne vient pas de la photo n'est pas une source. J'y reviens plus bas.

Quatre endroits à lire, aucun facultatif

Un même objet est décrit à quatre endroits du produit, et chacun dit ce que les autres taisent :

Où on regarde Ce qu'on y trouve, et nulle part ailleurs
Le cœur du code les règles : ce qui est interdit, ce qui est obligatoire, ce qui déclenche quoi
La base de données les champs, ce qui doit être unique, ce qui ne peut pas rester vide
Les écrans les contrôles de saisie, les champs qui apparaissent sous condition, les boutons grisés, les listes de choix
Les traductions les mots réellement affichés à l'utilisateur, dans toutes les langues

Un pan du produit n'est terminé que lorsque les quatre ont été lus. Une règle peut très bien n'exister que dans un seul.

Les écrans se lisent après le cœur du code, et avant de clore le sujet. Ce n'est pas une exigence de complétude, c'est une machine à trouver des écarts :

Une règle présente uniquement dans l'écran est presque toujours un écart.

Soit c'est une vraie règle métier, mal placée — un irritant. Soit elle est contournable en passant à côté de l'écran, par un import de fichier ou par l'interface que le produit expose aux développeurs extérieurs — son API. Et c'est alors un défaut, avec un enjeu de sécurité : ce que l'écran interdit, un autre chemin l'autorise.

Le cas inverse existe et se traite pareil. Une règle appliquée par le cœur du code mais que l'écran ne reflète pas produit un message d'erreur incompréhensible : l'utilisateur se fait refuser son action sans voir ce qu'il a fait de mal.

Deux constats sur cette lecture des écrans.

D'abord, le découpage des écrans ne recouvre pas celui du code. Douze zones de l'interface n'avaient pas de zone équivalente côté serveur. Le rapprochement se fait donc objet par objet, jamais dossier par dossier.

Ensuite, une astuce qui vaut de l'or dans les parties du code les moins bien rangées : les noms des messages d'erreur techniques sont souvent la meilleure source de règles. Un développeur qui refuse une action crée un cas d'erreur, et il le nomme. Une erreur appelée CannotEditInvoicedOrder — « on ne peut pas modifier une commande facturée » — énonce une règle à elle seule. Il suffit de lire la liste de ces noms, ce qui ne demande pas de savoir programmer.

Rien de tout cela n'est original

C'est peut-être le point le plus utile de cette section. Construire des ontologies est un métier constitué, avec sa littérature, et la méthode ci-dessus ne fait que reprendre des acquis :

  • L'itératif plutôt que la cascade. Les méthodes historiques enchaînaient les étapes dans l'ordre : spécifier, concevoir, formaliser, réaliser. Elles ont été supplantées par des approches par petits morceaux recombinables. Le débat est tranché depuis une quinzaine d'années.
  • Le cadrage par questions. Écrire d'abord les questions auxquelles le référentiel devra répondre est le dispositif standard ; il porte même un nom, competency question. Aller les chercher dans le support plutôt que les écrire à froid n'est pas dans les manuels. Ça ne coûte rien, et ça change ce qu'on trouve.
  • Partir du milieu. On commence par les objets les plus centraux du métier, puis on remonte vers les catégories plus larges et on descend vers les cas particuliers. Les deux autres façons de faire échouent : partir de la base de données revient à recopier la structure technique telle quelle, avec ses tables qui ne veulent rien dire pour le métier ; partir d'une théorie générale de ce qui existe donne un édifice hors de proportion avec le besoin.
  • La rigueur proportionnée à l'usage. On se complique la vie quand on en a besoin, pas par principe.
  • Ne pas réinventer ce qui est normalisé. Dans la plupart des métiers, des classifications existent et font référence. Il faut les regarder — et traiter tout écart entre son propre modèle et elles comme une question à instruire, pas comme un détail.

Trois critères d'arrêt. Trois fois faux.

Voilà la partie pour laquelle cet article existe.

D'abord, deux stratégies écartées

Savoir quoi chercher ne dit pas dans quel ordre parcourir le produit. Deux approches se présentent naturellement, et toutes deux échouent.

Tout lire, dans l'ordre des fichiers. Sans priorité, il n'y a ni ordre d'arrivée ni structure qui émerge. L'organisation des dossiers n'a aucun rapport avec l'importance métier, et ce qui n'est là que pour des raisons techniques est décrit au même rang que les vrais objets du métier. On obtient une masse de fiches sans savoir lesquelles comptent.

Partir de la base de données et faire une fiche par table. Utile, mais insuffisant, et fondé sur une confusion : une table n'est pas un objet du métier. Beaucoup de tables ne servent qu'à relier deux autres tables, à garder une trace technique, à stocker des jetons de connexion ou des résultats temporaires. Elles n'ont aucun sens pour qui parle du produit.

J'ai donc retenu une troisième voie : un pan du produit à la fois, en partant du cœur du métier vers la périphérie, en m'appuyant sur le découpage que le code porte déjà. Un logiciel un peu gros est découpé en modules — des zones de code qui correspondent grossièrement à des pans du métier : la facturation, les achats, les droits d'accès. Ce découpage a été fait par des développeurs, mais il constitue déjà une description partielle du métier, gratuite et validée par l'usage.

C'était la bonne décision. Elle n'a pas empêché la suite.

Premier critère : « le réseau de fiches est refermé »

Toutes les fiches citées existent, plus aucun lien ne pointe dans le vide. Donc c'est fini.

C'est faux, et la raison est mécanique. Un ensemble de fiches qui ne se citent qu'entre elles referme son réseau bien avant d'avoir couvert le produit. Le réseau s'est refermé chez moi alors que douze modules sur trente-deux seulement avaient donné lieu à une fiche.

Ce que ce contrôle prouvait réellement : que l'ensemble se tient. Rien d'autre. C'est un bon contrôle, il faut le garder — mais il ne répond pas à la question posée.

Le contrôle de couverture mené ensuite a fait apparaître deux objets centraux du métier que rien, dans le réseau, ne réclamait.

Deuxième critère : « j'ai parcouru toutes mes sources »

Le code des deux applications, la base de données, l'API, le glossaire, les comptes rendus d'entretiens, les tickets de support. Plus rien à ouvrir.

C'est vrai, et ça ne prouve rien. C'est une affirmation sur ce que j'ai ouvert, pas sur ce qui existe. « J'ai lu toute ma pile » ne dit rien de la bibliothèque : tant que le produit n'est pas énuméré, « tout » n'a pas de dénominateur. Un module qui n'a jamais figuré sur ma liste ne figure pas davantage dans mon « tout ».

Troisième critère : « chaque pan a été lu aux quatre endroits »

Le cœur du code, la base de données, les écrans, les traductions.

Vrai aussi, et insuffisant pour la même raison : ça ne vaut que pour les pans que j'avais identifiés. Le critère mesure la profondeur, il ne dit rien de la largeur. On peut lire quatre endroits sur douze modules et en ignorer vingt — c'est exactement ce qui s'est passé.

Le diagnostic

Reprenons les trois, et ce que chacun prouvait vraiment.

Ce que je disais Ce que ça voulait dire Ce que ça prouvait
« Le réseau de fiches est refermé » toutes les fiches que je cite existent que mes fiches se tiennent entre elles. Pas qu'il n'en manque pas.
« J'ai parcouru toutes mes sources » je n'ai plus rien à ouvrir que ma pile est finie. Pas que le produit est couvert.
« Chaque pan a été lu partout » j'ai lu les quatre endroits, pan par pan que j'ai bien travaillé sur les pans que je connaissais. Pas que je les connaissais tous.

Les trois disent la même chose : j'ai fini ce que j'avais commencé. Aucun ne dit : il ne reste rien.

On choisit un critère qu'on peut satisfaire, plutôt qu'un critère qui prouve le travail fait.

C'est la différence entre « j'ai rangé tout ce qui traînait sur mon bureau » et « voici la liste de ce que je devais ranger, tout est coché ». La première phrase est vraie, et elle n'engage à rien. La seconde suppose d'avoir fait la liste avant de commencer.

Ce n'est pas de la malhonnêteté, c'est une affaire de coût.

Un critère qu'on peut satisfaire est déjà sous la main : il suffit de regarder ce qu'on vient de faire et de constater que c'est fait. Un critère qui prouve, lui, demande de fabriquer quelque chose en plus — la liste de ce qui existe, une façon de la compter, un chiffre qu'un autre pourrait recalculer. C'est du travail supplémentaire, réclamé au moment précis où l'on croit avoir terminé.

D'où la seule parade que je connaisse : choisir le critère d'arrêt au début, pas à la fin. Le chercher à la fin, c'est le choisir parmi ceux qu'on est déjà certain de satisfaire.

Le seul critère qui tienne

Énumérer le produit sous plusieurs angles indépendants, et mesurer pour chacun la part qui correspond à une fiche.

Chaque angle voit ce que les autres ne peuvent pas voir :

L'angle Ce qu'il ramène et que les autres ne voient pas
Les modules du code des pans fonctionnels entiers, purement et simplement oubliés
Les tables de la base des objets qu'on stocke sans qu'aucune description les mentionne
Les événements émis par le logiciel les faits marquants du métier — « commande confirmée », « facture émise », « règlement encaissé » — et surtout les verbes, que rien d'autre ne donne
L'API les objets qu'on s'est engagé à exposer à l'extérieur, souvent éparpillés sur plusieurs modules et donc invisibles quand on navigue pan par pan
La seconde application les objets qu'elle manipule et que le découpage de la première ignore
Les écrans ce que l'utilisateur manipule tous les jours sans que ça existe nulle part comme objet

Et surtout : le signal utile est le désaccord entre deux angles. Un objet présent dans l'un et absent des autres est soit un objet du métier qu'on a raté, soit de la plomberie. La question se tranche en une ligne — mais elle se tranche explicitement, jamais en passant à côté.

Les autres erreurs

Quatre, plus petites, toutes coûteuses.

Lire une source qui n'était pas sur la photo. L'export de la base de données dont je disposais avait été produit cinq mois avant la version de code que je décrivais. Je l'ai lu comme s'il décrivait le même produit. Il décrivait un produit plus ancien : sur un pan entier, les objets étaient là dans le code sans aucune table correspondante dans l'export, et j'en ai conclu qu'ils n'existaient pas.

La règle est plus simple que ce que je croyais sur le moment. Ce n'est pas « vérifier la date avant de conclure » — c'est qu'une source qui ne vient pas de la photo n'est pas une source. On la remplace par une version à jour, ou on s'en passe.

Et la précision qui compte, parce que je l'avais d'abord ratée : quand deux parties de la même photo se contredisent — le code d'un côté, la base ou l'écran de l'autre, au même instant, en production —, ce n'est pas un décalage. C'est une incohérence du produit. C'est exactement ce qu'on cherche.

Prendre une recherche pour un inventaire. J'avais indexé tout le code dans un moteur de recherche par le sens — le principe du RAG : on pose sa question en langage courant, l'outil remonte les passages qui s'en approchent le plus. C'est redoutablement efficace pour retrouver une règle enfouie au milieu d'un fichier, que rien dans son nom ne signalait.

Mais un moteur de ce genre répond toujours, et il répond toujours par un classement : voici les dix passages les plus proches de votre question. Il ne dit jamais « il n'y en a pas ». Une recherche qui ne ramène rien d'intéressant peut donc vouloir dire deux choses — la chose n'existe pas, ou j'ai mal posé la question. Impossible de trancher.

D'où la règle : énumérer d'abord, chercher ensuite. Dans l'autre sens, on obtient un référentiel fait de ce que le moteur a bien voulu remonter.

Deux détails qui coûtent cher. Le moteur avait sa propre date, une version de retard sur le code. Et il faut poser la question dans la langue du code : une requête en français sur un code écrit en anglais donne des résultats médiocres, même quand la réponse s'y trouve.

Écrire la même règle à trois endroits. En cours de route, trois documents se sont constitués : - le modèle de fiche à remplir, - le document de méthode, - les consignes de travail que je donnais à l'agent.

Une même règle — par exemple « un écart ne modifie jamais le corps de la fiche » — a fini écrite dans les trois, chaque fois avec des mots un peu différents.

Tant qu'on ne change rien, ça ne gêne personne. Le jour où la règle évolue, on en corrige un, on oublie les deux autres, et trois documents se contredisent sans que personne sache lequel fait foi. Une IA moins que les autres : elle lit les trois sans voir qu'ils divergent, et fonde son analyse sur celui qu'elle a ouvert en premier.

Chaque règle vit désormais à un seul endroit. Le modèle de fiche décrit uniquement la forme — quels champs, quelles valeurs autorisées — et renvoie à la méthode pour tout le reste. Une seule source par règle.

L'ironie ne m'a pas frappé sur le moment : je construisais un référentiel destiné à supprimer les définitions dupliquées, en dupliquant ses propres règles dans trois fichiers.

Compter faux. Je voulais savoir quels mots les clients emploient vraiment, et à quelle fréquence. J'ai donc compté les occurrences de chaque terme métier dans 261 comptes rendus d'entretiens.

Premier résultat : un sigle de deux lettres apparaissait 3 525 fois. En réalité, il y en avait 2. La recherche comptait toutes les fois où ces deux lettres se trouvaient à l'intérieur d'un autre mot. Cherchez « CA » de cette façon et vous récoltez « cadre », « cas », « scanner », « application ».

Il faut donc compter des mots entiers, et tenir compte des majuscules quand le terme est un sigle. Un compteur faux est pire que pas de compteur du tout : il a l'air d'une donnée.

L'erreur inverse existe aussi, et elle est plus sournoise. Un terme que je croyais absent du produit s'y trouvait, mais employé dans un tout autre sens, dans un coin technique sans rapport avec le métier. Vérifier une absence avant d'en conclure à un manque.

Et un écart qui n'en était pas un

J'avais enregistré un écart affirmant qu'un certain type de lien entre objets n'était pas correctement décrit dans le produit. Vérification faite, il l'était.

L'écart reste dans la fiche, marqué comme rejeté, avec le motif du rejet. Se tromper fait partie du travail, à condition que l'erreur laisse une trace exploitable — sinon la même sera refaite dans six mois par quelqu'un d'autre.


L'agent capte. L'humain rouvre.

Le travail a été mené par un agent — une IA à qui l'on confie une tâche longue — sous ma direction. C'est sans doute la partie la plus transférable de ce retour d'expérience, parce qu'elle ne parle pas que d'ontologie.

Précision de méthode : cette section ne repose sur le souvenir de personne. Le registre des décisions du chantier est le journal de mes interventions — chaque entrée porte son motif, c'est-à-dire ce que j'ai corrigé et pourquoi. Le journal d'avancement montre ce que l'agent a produit entre deux arbitrages. Tout ce qui suit se lit dans ces deux traces.

Ce qu'un agent fait remarquablement bien : énumérer, croiser, compter, tenir un suivi ligne à ligne, et lire les traductions du douzième pan avec la même application que celles du premier. Ce travail est massivement répétitif, et c'est exactement ce qui le rendait inabordable jusqu'ici.

Ce qu'il fait mal : déclarer le travail terminé. Les trois faux critères d'arrêt ne sont pas venus de nulle part — ils ont chacun été proposés comme preuve d'achèvement, et il a fallu chaque fois les refuser. Le biais est le même que chez un humain fatigué en fin de projet, sauf qu'il n'a pas la fatigue pour excuse : confondre rapporter et livrer.

Mes interventions, telles qu'elles se lisent dans les motifs des décisions, se rangent en trois catégories :

  • Élargir un périmètre qu'il avait implicitement réduit. L'agent lisait le cœur du code et s'arrêtait là. La règle des quatre endroits, dont les écrans, vient de là — et c'est justement dans les écrans que se trouvent les écarts les plus intéressants.
  • Corriger une structure qui allait diverger. La même règle écrite à trois endroits : il l'avait recopiée par souci de bien faire, ce qui était exactement ce qu'il ne fallait pas faire.
  • Refuser un critère d'arrêt trop commode. Trois fois.

Ce qui rend cet arbitrage possible tient en quatre dispositifs, et ils valent pour tout travail délégué — à une machine comme à quelqu'un d'autre :

  1. Un critère d'arrêt vérifiable par un tiers. Pas « j'ai tout lu », mais une liste et un taux.
  2. Une mesure qu'on peut relancer, plutôt qu'une affirmation. Entre « c'est couvert » et « voici la commande qui le vérifie », il y a tout l'écart entre une promesse et un fait.
  3. Un suivi écrit, à la bonne maille. Une ligne par pan et par endroit à lire, mise à jour au fur et à mesure. Il survit à l'interruption du travail, et c'est lui qui évite de refaire deux fois la même chose.
  4. L'énumération avant la recherche. Ce qui est certain d'abord, ce qui est probable ensuite et en complément.

52 objets, et sept façons de vérifier qu'il n'en manque pas

Ce que ça a donné, une fois le bon critère appliqué.

52 objets du métier décrits. 250 règles. 208 liens entre eux. 124 écarts relevés. Plus aucun lien pointant dans le vide.

Les vingt questions de départ trouvent leur réponse sans ouvrir le code.

La couverture, mesurée

Le principe tient en trois opérations. Je liste les objets d'un angle — les modules, les tables, les événements, les écrans, les ressources exposées par l'API. Je regarde, pour chacun, s'il correspond à une fiche. Je compte.

Ce que j'énumère Part
Les modules de l'application A 81 %
Les tables de la base de données 81 %
Les événements émis par le logiciel 93 %
Les écrans de l'application A 77 %
Les modules de l'application B 94 %
Les objets de l'application B 69 %
Les ressources exposées par l'API 81 %

La mesure se rejoue par un petit programme. C'est le point important : ce n'est pas une affirmation, c'est un contrôle que quelqu'un d'autre peut relancer.

Et c'est une mesure faible, ce qu'il faut dire dans la même phrase. Le rapprochement se fait sur les noms : une table sales_order est reconnue comme la fiche « Sales Order », majuscules, tirets et pluriels mis de côté.

Ça marche à peu près une fois sur deux. Pour le reste, les noms ne se ressemblent pas du tout — une table peut s'appeler so_header là où la fiche s'appelle « Sales Order ». J'ai donc tenu à côté une liste de correspondances, écrite ligne par ligne au fur et à mesure que je tombais dessus : cette table-là, c'est cet objet-là.

Cette liste est un jugement, pas une règle. Si j'oublie une ligne, l'objet ressort comme non couvert alors qu'il l'est. Si j'en ajoute une douteuse — « allez, cette table doit bien correspondre à cette fiche » —, je gonfle mon propre score. Et même quand les noms coïncident, ça peut être un hasard : deux choses différentes portant le même mot.

La mesure ne prouve donc rien. Elle désigne où aller regarder.

Pourquoi je ne cherche pas à atteindre 100 %

C'est l'objection immédiate : si je sais qu'il me manque 19 % des modules, je sais lesquels — il n'y a qu'à les décrire.

Sauf que la case manquante n'est pas une tâche, c'est une question. Chaque objet sans fiche est soit un objet du métier que j'ai raté, soit de la plomberie sans aucun sens métier : une file d'attente technique, un redimensionneur d'images, une table de jetons de connexion, un écran de navigation. Atteindre 100 % supposerait de créer une fiche « File d'attente » et une fiche « Jeton » — c'est-à-dire de polluer le référentiel pour faire monter un chiffre.

Le compteur a donc trois états, et non deux :

État Ce qu'il faut en faire
Correspond à une fiche rien
Examiné, tranché comme purement technique rien, mais la décision est écrite
Pas encore regardé c'est le seul qui compte

Ce qui doit atteindre 100 %, c'est la troisième ligne à zéro — plus rien qui n'ait été examiné. Le pourcentage affiché, lui, ne monte pas jusqu'à 100 et n'a pas à le faire.

Ici, le reste a été passé en revue à la main : de la technique, des mécanismes internes, des écrans sans objet métier propre. Aucun objet du métier ne s'y cachait. Mais c'est une vérification manuelle, à refaire à chaque évolution — et c'est la faiblesse qui subsiste.

Le chiffre sert donc à autre chose qu'à mesurer un avancement. Il sert à comparer les angles entre eux. 69 % sur les objets de l'application B contre 93 % sur les événements, ça ne veut pas dire « il reste 31 % de travail » : ça veut dire « l'application B manipule des choses que le reste du produit ignore, allez voir de ce côté ». C'est ce désaccord qui a fait remonter les quatre trouvailles suivantes.

Ce que les angles ont rapporté

Quatre objets qu'aucune autre voie n'aurait trouvés :

  • Par les tables de la base. Un objet que le produit affiche mais qui n'appartient à aucun pan du code — dans l'ERP fictif, ce serait l'échéance de facturation à venir : le client la voit dans son échéancier, mais elle n'existe pour de bon qu'au moment où la facture est émise. Cette ambiguïté explique une famille entière de réclamations clients.
  • Par les événements. Un sous-ensemble entier d'un pan qu'on croyait couvert, révélé par les événements qu'il émettait et que personne n'avait rattachés à quoi que ce soit.
  • Par l'API. Deux objets répartis sur cinq modules différents — donc invisibles tant qu'on avance pan par pan, et pourtant exposés contractuellement à l'extérieur.
  • Par l'application B. Deux objets qu'elle manipule et que l'application A ne connaît pas.

Les problèmes qui reviennent partout

Voici les trouvailles, transposées sur l'ERP fictif. Ce sont des types de problème, pas des cas isolés — et je parierais qu'aucun n'est absent de votre produit.

Un état recalculé partout, défini nulle part. Le statut d'une commande déduit de quelques dates et de l'état de ses lignes, recalculé dans chaque écran, sans règle centrale. Deux écrans finissent par ne plus dire la même chose, et personne ne sait lequel a raison.

Un objet que l'utilisateur voit et ne peut pas retrouver. L'échéance de facturation dont je parlais : affichée dans l'échéancier, absente des résultats de recherche, parce qu'elle n'existe pas encore comme document. L'utilisateur, lui, l'a vue à l'écran — il la cherche donc, ne la trouve pas, et ouvre un ticket. Le support répond au cas par cas depuis des années sans que la cause soit écrite nulle part.

Une valeur qui n'en est pas une. Le solde d'un client n'est pas un nombre rangé quelque part : c'est le résultat d'un calcul sur toutes ses factures, ses règlements, ses avoirs et ses écritures d'ajustement. Tant que ça reste implicite, chaque nouvelle fonctionnalité qui « lit le solde » se trompe d'objet et donne un chiffre légèrement différent, selon les mouvements qu'elle a pensé à inclure. Trois écrans, trois soldes.

Une règle appliquée d'un seul côté. Le plafond de remise contrôlé dans le formulaire de saisie, et nulle part ailleurs — donc contournable par un import de fichier ou par l'API. C'est la machine à écarts dont je parlais plus haut, et son rendement est remarquable.

Un droit calculé à partir de six sources sans endroit qui les rassemble. Le rôle de la personne, la formule souscrite, les options activées, la restriction de période d'essai, le périmètre de sa filiale, une liste d'exceptions. Aucun endroit du produit ne dit « voici comment se calcule un droit ». Chaque évolution le redécouvre à ses frais.

Un même objet nommé différemment à chaque étage. « Commande » à l'écran, un mot dans le code, un autre dans la seconde application, « affaire » sur le terrain. Quatre vocabulaires pour l'objet le plus central du produit.

Un mot que les clients emploient sans arrêt et que le produit ignore. Sur 261 comptes rendus d'entretiens, une notion revient 79 fois, une autre 29. Ni l'une ni l'autre n'existe dans le produit, sous aucun nom. Ce ne sont pas des écarts de vocabulaire, ce sont des manques de conception — et ils n'apparaissent qu'en comparant ce que disent les clients à ce que fait le produit.

Les sous-produits

Aucun n'était l'objectif. Tous sont tombés du travail.

Des bugs candidats. Le produit contredit une attente écrite quelque part. Chacun arrive avec sa preuve et sa conséquence, pas avec une intuition.

Un vocabulaire client, avec ses fréquences. En comptant les mots sur 261 comptes rendus d'entretiens et 365 tickets de support, on obtient pour chaque objet du produit les termes réellement employés et leur poids. Celui qui parle au client sait alors quel mot utiliser. Un terme revient 168 fois pour désigner un périmètre que le produit nomme autrement ; un autre 141 fois pour l'objet central.

Et ces deux corpus ne disent pas la même chose. Les entretiens disent ce que les clients veulent construire. Les tickets disent ce qui casse. Un même mot peut dominer l'un et être absent de l'autre. Les compter ensemble, c'est prioriser de travers.

Un état des lieux des traductions. Le glossaire multilingue ne couvre que 15 des 52 objets. Parmi les absents, deux sont pourtant affichés à l'utilisateur dans toutes les langues : aucune traduction de référence n'existe pour eux. Et sur les dix-neuf langues du glossaire, deux seulement ont été relues.


Ce que ça coûte, et ce que la méthode ne dit toujours pas

Le coût

Moins de six heures. C'est le temps qu'a pris l'ensemble : les 52 fiches, les 250 règles, les mesures de couverture. Une session, d'un bout à l'autre.

Avant de commencer, j'avais estimé quelques dizaines d'heures, étalables pan par pan. Je me suis trompé d'un ordre de grandeur — et cette erreur d'estimation est peut-être la vraie raison pour laquelle personne n'avait fait ce travail avant : on le croit hors de portée, alors on ne le commence pas.

Trois réserves sur ce chiffre, pour qu'il reste honnête. C'est une mesure sur un produit, une fois, pas une moyenne. Les sources étaient déjà rassemblées et indexées localement ; le temps de mise en place n'est pas dedans. Et il en dit autant sur l'outillage que sur la méthode : le même travail à la main aurait pris des semaines, ce qui est précisément pourquoi il n'avait jamais été fait.

La condition de rentabilité, elle, est claire : finir un pan avant d'en ouvrir un autre. Un référentiel complet sur un périmètre sert immédiatement tous les métiers de ce périmètre. Un référentiel à moitié fait sur cinq périmètres ne sert personne.

L'entretien

C'est la question qu'on pose toujours en second, et elle est légitime : un référentiel dont on ne dit pas comment il reste vivant n'intéresse personne.

La version de référence sert de curseur : elle donne, par une simple commande, la liste exacte de ce qui a bougé dans le produit depuis la dernière mise à jour — donc la liste de ce qu'il reste à consigner.

Chaque fiche porte un journal où l'on ajoute des entrées sans jamais corriger les précédentes. Une entrée qui cite une version du code signale que le produit a changé. Une entrée qui n'en cite pas signale autre chose : c'est notre compréhension qui a changé, pas le produit. La distinction paraît mineure ; c'est elle qui permet, six mois plus tard, de savoir si on a corrigé une fiche ou si le logiciel a évolué.

Deux mouvements méritent une mention parce qu'aucun outil ne les raconte : la fusion de deux objets qu'on croyait distincts, et la division d'un objet qui en cachait deux. Ce sont les mouvements les plus fréquents quand un référentiel mûrit.

Enfin, quand un objet est repensé de fond en comble, on ne modifie pas sa fiche : on en crée une nouvelle, et l'ancienne reste. Elle décrit ce que le produit a été, et elle reste nécessaire pour interpréter les données et les échanges antérieurs au changement.

Ce que j'ai décidé de ne pas faire

  • Pas de reconstitution de l'histoire passée du produit.
  • Périmètre fermé sur les exports de données, qui sont des vues dérivées du produit et non le produit lui-même.
  • Pas d'outillage savant tant qu'aucun usage ne le réclame.

Ce que la méthode ne dit pas encore

  • Jusqu'où pousser la rigueur du format. Ça dépend de l'usage, et l'usage n'a pas commencé.
  • Comment rattacher une donnée ancienne au bon état d'un objet, quand cet objet a été repensé entre-temps.
  • Qui relit une fiche, et selon quels critères, avant qu'elle entre dans le référentiel.
  • À quel rythme remettre le point de départ à jour, et donc rattraper ce qui a bougé depuis.

Un document de méthode qui se prétend complet ment. Celui-ci porte une section « ce qu'il ne dit pas encore », et elle rétrécit à mesure que les questions se tranchent.


Conclusion : le critère d'arrêt est le vrai livrable

Si je devais ne garder qu'une chose de ce chantier, ce serait la phrase qui explique les trois faux départs :

On choisit un critère qu'on peut satisfaire, plutôt qu'un critère qui prouve le travail fait.

Elle ne concerne pas que les ontologies. Elle vaut pour un audit, une migration, une revue de sécurité, une reprise de dette technique. Chaque fois qu'un travail se termine sur « j'ai tout regardé », la question à poser est : tout, c'est-à-dire ? En avez-vous la liste ?

Deux contrôles, jamais un seul. Que l'ensemble se tienne se vérifie en regardant les fiches entre elles. Qu'il soit complet se vérifie en énumérant le produit. Les confondre a coûté, ici, un tiers du produit.

Reste le plus intéressant, et il n'est pas fait : les écarts. Ils attendent tous d'être instruits — les bugs candidats d'abord, puis ceux qu'une demande client appuie déjà, puis les manques, puis la dette de conception. Ce n'est plus de la description, c'est de la décision produit.

C'est un autre article, et il ne pourra s'écrire qu'après.


Annexe A — À quoi ressemble une fiche

Cette annexe est la plus technique de l'article ; on peut s'arrêter avant sans rien perdre du propos.

La fiche ci-dessous est transposée sur l'ERP fictif. Elle décrit la forme — les règles qui la gouvernent vivent dans le document de méthode, à un seul endroit.

Ce qu'une fiche contient

Ce qu'on écrit À quoi ça sert Exemple
L'objet un type d'objet du métier Sales Order, Customer, Invoice
Ses cas particuliers « est un cas particulier de » une commande urgente est une commande
Ses propriétés ce qui le caractérise, et sous quelle forme le numéro de TVA d'un client : du texte
Ses liens vers quels autres objets, par quel verbe, et combien de chaque côté une commande est passée par un client (un seul)
Ses règles ce qui est toujours vrai une commande facturée ne peut plus recevoir de ligne
Ses mots comment on l'appelle, dans chaque langue et sur le terrain commande (fr), pedido (es), « affaire » chez les clients

La fiche elle-même

Le fichier porte le nom de l'objet — c'est ce qui permet aux liens entre fiches de se résoudre tout seuls.

---
concept: Sales Order
definition: Engagement de livraison pris envers un client, suivi de son enregistrement à sa facturation.
parent:
enfants: ["[[Rush Order]]", "[[Standing Order]]"]
attributs:
  - nom: status
    type: enum
    valeurs: [draft, confirmed, shipped, invoiced]
relations:
  - verbe: placed-by
    cible: "[[Customer]]"
    cardinalite: 1..1
  - verbe: contains
    cible: "[[Order Line]]"
    cardinalite: 1..n
axiomes:
  - Une commande facturée ne peut plus recevoir de ligne
lexique:
  fr: [commande, commande client]
  en: [sales order]
  es: [pedido]
  synonymes_terrain: [affaire, dossier]
  deprecies: [bon de commande client]
sources:
  - erp.sql:table `sales_order`
  - fr.json:order.status.draft
ecarts:
  - id: E1
    nature: manque
    portee: relations
    attendu: un lien vers "[[Attachment]]", comme en a "[[Customer]]"
    consequence: impossible de joindre un bon de commande signé
    statut: confirme
    date: 2026-08-10
historique:
  - date: 2026-08-10
    action: creation
    motif: description initiale, sur la version de référence
---

# Sales Order

Engagement de livraison pris envers un client, suivi de son enregistrement à sa facturation.

## Liens

- *placed-by* → [[Customer]] (un seul)
- *contains* → [[Order Line]] (au moins une)
- cas particuliers → [[Rush Order]], [[Standing Order]]

## Historique

| Date | Ce qui s'est passé | Version du code | Motif |
|---|---|---|---|
| 2026-08-10 | création | — | description initiale |

Une seule chose est écrite deux fois : les liens. Une fois dans l'en-tête, pour que les outils puissent les lire ; une fois dans le corps, pour qu'ils apparaissent dans la vue en réseau. Tout le reste n'existe qu'à un seul endroit.

Trois critères de qualité, opposables à n'importe quelle fiche : la définition tient en une phrase et ne se mord pas la queue ; chaque lien est nommé par un verbe précis, jamais par « est lié à » ; le vocabulaire est multilingue et porte les mots employés par les clients.


Annexe B — La grille des écarts

Ce qu'on note pour chaque écart :

Ce qu'on écrit Obligatoire À quoi ça sert
Un identifiant oui pour pouvoir en parler
Sa nature oui voir les cinq natures ci-dessous
Ce qu'il concerne oui quelle partie de la fiche, ou la fiche entière
Ce que fait le produit si ça existe l'état actuel
Ce qu'il devrait faire oui l'attente
Ce que ça produit oui la conséquence concrète, pour quelqu'un
Son statut oui à instruire, confirmé, accepté, résolu, rejeté
Sa source non un ticket, une phrase de client, une décision
Sa date oui quand ça a été constaté

Les cinq natures :

Nature Ce que ça veut dire Ce que ça devient
défaut le produit contredit une attente écrite quelque part un bug à instruire
manque ce qu'on attend n'existe pas un élément de backlog
incohérence deux parties du produit ne disent pas la même chose une dette à arbitrer
irritant le produit fait ce qui était prévu, mais c'est mal fichu une dette de conception
souhait une extension désirée, hors de toute attente actuelle une opportunité

Ce qui se passe quand l'écart disparaît. On le marque comme résolu, et il reste dans la fiche. Le corps de la fiche est mis à jour pour décrire la nouvelle réalité, et une ligne s'ajoute au journal. Les deux se répondent : les écarts portent l'intention, le journal porte le mouvement.

Un garde-fou. Un écart décrit une divergence structurelle, pas un incident. Une ligne, un lien vers le ticket. Les captures d'écran, les étapes de reproduction et le détail restent dans l'outil de suivi. Une fiche n'est pas un outil de gestion de bugs.


Annexe C — Les angles d'énumération

À passer tous, et à confronter deux à deux.

L'angle Ce qu'il ramène et que les autres ne voient pas
Les modules du code des pans fonctionnels entiers, oubliés
Les tables de la base des objets stockés qu'aucune description ne mentionne
Les événements émis par le logiciel les faits marquants du métier, et les verbes qui vont avec
L'API les objets exposés par contrat à l'extérieur, éparpillés sur plusieurs modules
Une seconde application les objets absents du découpage principal
Les écrans ce que l'utilisateur manipule sans que ça existe comme objet
Ce que disent les clients les notions qu'ils emploient et que le produit ignore

Trois règles d'emploi :

  1. Le signal est le désaccord entre deux angles, pas le score d'un angle pris tout seul.
  2. Chaque objet non rattaché se tranche explicitement — objet du métier, ou plomberie. Jamais par omission.
  3. Deux corpus clients, comptés séparément : les entretiens disent ce que les clients veulent construire, les tickets ce qui casse. Porter les deux fréquences dans le vocabulaire — l'une oriente la roadmap, l'autre la documentation et la formation.

Où se trouvent les règles, par ordre de rendement décroissant :

  1. Les noms des messages d'erreur techniques. Dans les parties du code les moins bien rangées, c'est souvent la seule source — et elle se lit sans savoir programmer.
  2. Les vérifications faites en début d'opération, avant que quoi que ce soit ne soit modifié.
  3. Les contraintes de la base de données — ce qui doit être unique, ce qui ne peut pas rester vide. Elles contredisent parfois le métier, et cet écart est un défaut.
  4. Les contrôles de saisie dans les écrans — la part la plus souvent oubliée, et celle qui produit les écarts les plus intéressants.

Un objet décrit sans aucune règle signale une description superficielle, jamais un métier sans règles.