L'arête de dépendance qui vous ment
Chaque diagramme jamais dessiné d'un système en production était faux dès l'instant où quelqu'un a shippé sans le mettre à jour. Voici comment on l'attrape.
1 juillet 2026 · 7 min de lecture
Demandez à une équipe plateforme son diagramme d'architecture et vous obtiendrez l'une de ces deux choses : une page Confluence avec un tampon « dernière modification il y a 14 mois », ou un haussement d'épaules et un thread Slack où trois personnes se demandent si le service payments appelle encore inventory directement ou passe par le bus d'événements depuis la migration du T3 que personne n'a fini de documenter. Les deux réponses sont correctes, dans le sens où ce sont exactement ce qui se passe sur la plupart des équipes passé une certaine taille.
Le diagramme n'est pas faux parce que quelqu'un a été paresseux. Il est faux parce qu'un diagramme est une affirmation sur le système figée au moment où quelqu'un l'a dessiné, et le système a continué à évoluer. Chaque dépendance qu'on n'a pas retirée, chaque nouvel appel ajouté sous pression de deadline avec l'intention de le nettoyer plus tard, chaque chemin de repli qui ne se déclenche qu'en production — rien de tout ça n'apparaît dans un diagramme de boîtes et de flèches à moins que quelqu'un ne le redessine. Personne ne le redessine. Cet écart entre le système tel que documenté et le système tel qu'il tourne, c'est ce qu'on appelle le drift architectural, et ce n'est pas une hypothèse : c'est l'état par défaut de tout système assez ancien pour avoir été touché par plus d'un ingénieur.
Deux sources de vérité, et aucune des deux ne suffit seule
L'analyse statique lit ce que vous avez écrit : parsez le source, résolvez les imports, suivez les clients HTTP et les listeners Kafka, et vous obtenez un graphe de ce que le code dit devoir appeler quoi. C'est précis et bon marché à calculer, mais ça ne connaît que les chemins qui existent dans le source — un feature flag à 100% depuis huit mois dont l'ancienne branche n'a jamais été supprimée a toujours l'air « utilisé » pour une lecture purement statique, et un appel qui ne passe que par de la réflexion ou une URL construite dynamiquement peut ne pas apparaître du tout.
L'observation runtime est l'exact opposé. Regardez le trafic réel — quel port a parlé à quel conteneur, à quelle fréquence, à quelle vitesse — et vous obtenez exactement ce qui se passe en ce moment, sans interprétation nécessaire. Mais la donnée runtime n'a aucune mémoire de l'intention. Elle ne peut pas vous dire si un appel a été conçu délibérément ou s'il traîne là et que personne n'ose le retirer, et si l'échantillon de trafic rate un batch job nocturne qui tourne une fois par jour, cette dépendance lui est invisible.
Aucune des deux ne ment, à proprement parler. Elles disent toutes les deux la vérité sur une question différente.
Ce que l'étiquetage de chaque arête vous apporte vraiment
Le geste utile, ce n'est pas de choisir une source plutôt que l'autre — c'est de garder les deux sans jamais les fusionner en un seul fait sans étiquette. Chaque arête de dépendance dans le graphe d'Archynt porte son origine : static (trouvée dans le source, jamais observée en direct), runtime (observée dans le trafic, écrite nulle part), ou both. Ce troisième état, confirmed_by: both, est le seul sur lequel on peut agir avec une vraie confiance — il signifie que le code et le fil sont d'accord.
Les deux autres sont là où vivent les findings intéressants. Une arête static uniquement, sans trafic runtime depuis des semaines, est un candidat au code mort — une dépendance qu'on peut probablement supprimer, et maintenant on a une preuve au lieu d'une supposition. Une arête runtime uniquement est l'inverse et, dans notre expérience, la plus urgente des deux : une dépendance vivante que personne n'a écrite nulle part, ce qui veut dire que personne ne la possède, personne n'a d'alerte dessus, et la prochaine personne qui touche au service appelant n'a aucune idée qu'elle est critique jusqu'à ce qu'elle la casse.
Pourquoi c'est une conversation de risque, pas de documentation
C'est tentant de classer le drift dans « garder la doc à jour », ce qui explique exactement pourquoi la plupart des équipes ne le corrigent jamais — la dette de documentation perd systématiquement face à tout ce qui a un ticket et une deadline. Le cadrage le plus honnête, c'est qu'une dépendance runtime non possédée est à la fois une surface d'attaque non surveillée et un point de défaillance unique non planifié. Personne n'est d'astreinte pour une connexion dont il ne connaît pas l'existence. C'est l'argument qu'on utilise maintenant, parce que c'est celui qui survit au contact d'une réunion de roadmap.
Vous voulez voir ça sur votre propre système ?
L'URL d'un dépôt suffit pour le graphe statique. L'agent runtime ne nécessite qu'un seul fichier docker-compose.
