Architecture Drift Score : votre documentation dit-elle la vérité ? - Archyl Blog

L'Architecture Drift Score est un chiffre de 0 à 100 qui mesure la part de votre architecture documentée qui existe encore dans votre codebase. Voici le mécanisme : la formule, ce qui entre dans le dénominateur, ce qui en est délibérément exclu, ce que la vérification ne peut pas voir, et comment l'imposer dans votre CI.

Architecture Drift Score : votre documentation dit-elle la vérité ?

Une métrique que personne ne peut auditer est une métrique sur laquelle personne ne devrait agir. Cet article porte donc sur l'arithmétique : comment l'Architecture Drift Score est produit, ce qui atterrit dans le dénominateur, ce que nous laissons délibérément de côté, et les quatre choses que la vérification ne peut pas voir.

Le score répond à une seule question. Quel pourcentage de votre architecture documentée existe encore dans votre codebase ? C'est un chiffre de 0 à 100, calculé à partir d'une seule requête à votre fournisseur Git, sans IA dans la chaîne et sans lecture du contenu des fichiers.

Si vous cherchez le problème plutôt que l'arithmétique, le guide du drift d'architecture couvre ce qu'est le drift, pourquoi il survient, et les autres façons de le détecter. Commencez par là et revenez ensuite. Cette page suppose que vous voulez déjà un chiffre et que vous voulez savoir s'il faut le croire.

Lire le chiffre

Ouvrez n'importe quel projet dans Archyl, cliquez sur l'icône de battement de cœur dans l'en-tête, puis appuyez sur "Compute Drift Score". En quelques secondes, vous obtenez un chiffre :

  • 90-100% — Excellent. Votre documentation correspond fidèlement à la codebase.
  • 70-89% — Bien. Globalement fidèle, quelques écarts à combler.
  • 50-69% — Moyen. Drift significatif détecté. Il est temps de mettre à jour.
  • En dessous de 50% — Votre documentation est de la fiction.

Ces tranches sont notre jugement sur ce qui mérite qu'on agisse, pas la mesure de quoi que ce soit. Le chiffre qui se trouve en dessous, lui, est exact.

Comment le chiffre est calculé

Chaque élément de votre modèle est classé dans un bucket, et le score est la part qui a survécu :

score = floor( (matched + 0.5 × partial) / total × 100 )

total = matched + partial + missing_in_code + new_in_code
  • matched — le modèle dit qu'il existe, le dépôt confirme.
  • missing_in_code — documenté, et introuvable. Un container dont le répertoire a disparu, un élément de code dont le fichier a été supprimé.
  • new_in_code — trouvé dans le dépôt, absent du modèle. Non documenté, ce qui est du drift dans l'autre sens et compte contre vous exactement aussi durement.

partial vaut un demi-crédit et est réservé aux éléments qui correspondent avec des différences. Les vérifications actuelles ne le produisent pas : chaque élément atterrit dans l'une des trois autres catégories, si bien qu'en pratique le score est la fraction de matched. Nous vous le disons parce qu'une formule avec un terme qui ne se déclenche jamais, c'est le genre de chose que vous devriez apprendre de nous plutôt que découvrir.

Deux détails qui comptent quand vous comparez deux exécutions. Le résultat est tronqué, pas arrondi : 89,9 est donc rapporté comme 89. Et les éléments non documentés agrandissent le dénominateur, ce qui explique qu'ajouter trois nouveaux services sans les documenter fasse baisser votre score alors même que rien de ce que vous aviez écrit n'est devenu faux.

Ce qui est réellement vérifié

L'analyse de drift est légère par conception : une seule requête d'arbre récursive à votre fournisseur Git, pas d'IA, aucun contenu de fichier récupéré. Elle valide votre architecture selon cinq dimensions :

Systems — Le nom de votre dépôt correspond-il au système documenté ? Nous utilisons la même convention de nommage PascalCase que le pipeline de découverte IA, avec une correspondance floue pour que EkoAuthz corresponde à un dépôt nommé authz.

Containers — Les répertoires de premier niveau de votre dépôt correspondent-ils aux containers documentés ? frontend/ correspond à FrontendWebApp. backend/ correspond à BackendApiServer. Les containers d'infrastructure (bases de données, files d'attente, monitoring) qui n'ont pas de répertoire source sont exclus, parce qu'ils constituent une documentation valide de services externes plutôt que du drift. La section suivante explique ce que coûte cette exclusion.

Components — Les composants sous chaque container sont-ils toujours valides ? Si le répertoire du container parent existe, ses composants sont présumés valides. Si le répertoire du container a disparu, tous ses composants sont signalés.

Code Elements — C'est la vérification la plus précise. Chaque élément de code de votre modèle C4 possède un filePath. Nous vérifions que chaque fichier existe toujours dans le dépôt. Fichier renommé ? Classe supprimée ? Module déplacé ? Le drift score le détecte instantanément.

Relationships — Une relation est valide si ses éléments source et cible ont tous deux passé la validation. Si l'une des extrémités a dérivé, la relation est signalée.

Le résultat est une ventilation par élément montrant exactement ce qui correspond, ce qui manque et ce qui est nouveau — pas un score opaque, mais un rapport exploitable.

Ce qui est exclu du dénominateur

Un score n'est honnête qu'à la hauteur de ce qu'il refuse de compter. Trois exclusions, toutes délibérées :

Les systèmes externes et les personnes. Tout ce qui est typé comme système externe ou comme personne est écarté avant la comparaison, des deux côtés. Stripe, votre fournisseur d'identité et "Client" ont leur place sur un diagramme de System Context, et aucun d'eux n'apparaîtra jamais dans votre dépôt. Les compter comme manquants vous punirait d'avoir dessiné un diagramme correct.

Les containers d'infrastructure sans répertoire source. Un container documenté qui ne correspond à aucun répertoire est retiré du décompte des containers plutôt que compté comme du drift. Votre instance PostgreSQL, votre cluster Kafka et votre compte Datadog sont des containers légitimes, et aucun d'eux n'est un dossier.

Cette règle a un coût, et vous devez le connaître : un vrai répertoire de service que vous avez supprimé est lui aussi exclu du décompte des containers, parce que la vérification ne sait pas distinguer "base de données" de "service que nous avons retiré au sprint dernier". Ses composants, eux, ne sont pas exclus. Ils continuent d'être résolus comme manquants, puisque leur container parent n'a pas correspondu, si bien qu'un service retiré apparaît bel et bien dans le score, un niveau plus bas que là où vous vous attendriez à le trouver.

Les éléments de code sans chemin de fichier enregistré. Si un élément de code de votre modèle n'a pas de filePath, il n'y a rien à vérifier : il est donc ignoré plutôt que deviné. Il ne compte ni pour vous ni contre vous. Les chemins générés et vendorisés (vendor/, node_modules/, dist/, target/, __pycache__/ et le reste de la liste habituelle) sont filtrés de l'arbre de fichiers avant que tout cela ne s'exécute.

Pourquoi la légèreté est importante

Nous avons délibérément choisi de ne pas exécuter le pipeline complet de découverte IA pour la détection de drift. Voici pourquoi :

Rapidité. L'analyse IA prend plusieurs minutes pour les gros dépôts. Le calcul du drift score prend quelques secondes. Vous pouvez l'exécuter à chaque push sans ralentir votre pipeline.

Déterminisme. L'IA peut produire des résultats différents sur la même codebase en fonction de la température du modèle, des variations de prompts et des limites de tokens. L'existence d'un chemin de fichier est binaire — soit le fichier est là, soit il ne l'est pas. Votre score est reproductible.

Coût. Aucun token d'IA consommé. Aucune limite de taux API atteinte. Exécutez-le cent fois par jour si vous le souhaitez.

Simplicité. L'algorithme est auditable. Vérifier les chemins de fichiers, faire correspondre les noms de répertoires, valider les relations. Pas de boîte noire.

Ce que le score ne peut pas voir

Chacune de ces propriétés est payée du même échange : la vérification lit la structure, pas le code. Quatre conséquences, dont aucune n'est un bug que nous comptons cacher.

Le drift comportemental est invisible. Si deux services gardent leurs noms et leurs répertoires pendant que l'appel HTTP synchrone entre eux devient un message de file d'attente, le score ne bouge pas. Rien de structurel n'a changé. C'est le plus gros angle mort, et il n'existe pas de correctif bon marché : le détecter suppose de lire du code ou de revoir le modèle avec des humains.

Un déplacement ressemble exactement à une suppression. Les éléments de code sont validés par chemin de fichier exact et sensible à la casse. Déplacez internal/auth/token.go vers internal/identity/token.go sans en toucher une ligne et l'élément est rapporté comme manquant. C'est techniquement correct, puisque le chemin documenté est faux, et cela signifie qu'un refactoring qui renomme des répertoires fait baisser votre score d'une façon qui paraît alarmante et se résout par une modification d'une ligne par élément.

La précision au niveau des composants est héritée, pas vérifiée. Si le répertoire d'un container existe, chaque composant sous celui-ci est présumé valide. La vérification ne regarde jamais à l'intérieur. Un container qui existe encore mais a été vidé et réécrit obtient donc un score propre au niveau composant, et le chiffre est plus confiant à propos de votre diagramme de niveau 3 que les preuves ne le justifient.

La correspondance des noms est généreuse. Systems et containers sont mis en correspondance par nom en trois passes : exacte sans tenir compte de la casse, puis inclusion de sous-chaîne dans un sens ou dans l'autre, puis chevauchement de tokens après découpage du PascalCase et du kebab-case. EkoAuthz correspond à un dépôt appelé authz ; BackendApiServer correspond à un répertoire appelé backend. C'est ce qui empêche des différences de nommage triviales d'être rapportées comme du drift, et cela penche du côté d'accorder à votre modèle le bénéfice du doute. Si vous voulez une lecture stricte, utilisez la ventilation par élément plutôt que le chiffre affiché en une.

Pris ensemble, le score est une bonne mesure de la question de savoir si votre modèle décrit toujours le même système, et une mauvaise mesure de la question de savoir s'il le décrit correctement. Traitez un score élevé comme "pas de surprise structurelle", pas comme "la documentation est juste".

Suivez les tendances, pas seulement les instantanés

Un score unique est utile. Une tendance est puissante.

Chaque calcul de drift est stocké avec sa ventilation complète. L'onglet Overview affiche un graphique en barres de votre score dans le temps. Cliquez sur n'importe quelle barre pour charger ce rapport historique et voir exactement ce qui a changé.

Cela transforme le drift scoring d'un audit ponctuel en une métrique de santé continue. Vous pouvez voir :

  • Le refactoring de la semaine dernière a-t-il amélioré ou dégradé la précision de la documentation ?
  • Le drift s'aggrave-t-il avec le temps, et est-ce que quelque chose que vous avez changé dans le workflow l'a ralenti ?
  • Quel sprint a introduit le plus de changements non documentés ?

Imposez-le dans la CI

Une métrique que vous n'imposez pas est une métrique que vous ignorerez. C'est pourquoi nous avons construit une GitHub Action.

on:
  push:
    branches: [main]

jobs:
  drift:
    runs-on: ubuntu-latest
    steps:
      - uses: archyl-com/actions/drift-score@v1
        with:
          api-key: ${{ secrets.ARCHYL_API_KEY }}
          organization-id: ${{ secrets.ARCHYL_ORG_ID }}
          project-id: 'your-project-uuid'
          threshold: '70'

Définissez threshold: '70' et l'action échoue si la précision de votre documentation d'architecture passe en dessous de 70%. Le résumé du job affiche un tableau formaté avec la ventilation complète — visible directement dans les checks de votre PR.

Vous pouvez également publier le score en commentaire de PR :

- uses: archyl-com/actions/drift-score@v1
  id: drift
  with:
    api-key: ${{ secrets.ARCHYL_API_KEY }}
    organization-id: ${{ secrets.ARCHYL_ORG_ID }}
    project-id: 'your-project-uuid'

- uses: actions/github-script@v7
  if: github.event_name == 'pull_request'
  with:
    script: |
      github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: '## Architecture Drift: ' +
              '${{ steps.drift.outputs.score }}%\n' +
              'Matched: ${{ steps.drift.outputs.matched-count }}' +
              ' / ${{ steps.drift.outputs.total-elements }}'
      })

Chaque développeur voit l'impact de ses changements sur le drift avant le merge. La documentation d'architecture devient un citoyen de première classe dans votre pipeline CI — aux côtés des tests, du linting et des analyses de sécurité.

MCP : des agents IA qui connaissent leur précision

Si vous utilisez Claude Code, Cursor ou tout agent IA compatible MCP avec le serveur MCP d'Archyl, le drift scoring est disponible en tant qu'outil :

compute_drift_score({ projectId: "..." })
get_drift_score({ projectId: "..." })
get_drift_history({ projectId: "..." })
get_drift_details({ scoreId: "..." })

Cela signifie qu'un agent IA peut vérifier la précision de la documentation avant de commencer à travailler. L'outil get_agent_context fournit déjà le modèle C4 complet, les ADRs et les règles de conformité. Désormais, il peut aussi vérifier la fiabilité de cette documentation.

Un agent qui voit un drift score de 45% sait qu'il doit être prudent avec le contexte architectural reçu. Un agent qui voit 95% peut s'appuyer en confiance sur la structure documentée. C'est la base d'agents IA auto-conscients qui adaptent leur comportement en fonction de la qualité de la documentation.

Alertes webhook : soyez informé quand le drift survient

Deux nouveaux événements webhook vous permettent de rester informé sans consulter les tableaux de bord :

  • drift.score_computed — Se déclenche à chaque fois qu'un drift score termine son calcul. Envoyez-le dans un canal Slack pour plus de visibilité.
  • drift.score_degraded — Se déclenche lorsque le score baisse de 10 points ou plus par rapport au calcul précédent. C'est votre système d'alerte précoce — l'architecture dérive rapidement.

Configurez ces événements dans les paramètres webhook d'Archyl. Ils fonctionnent avec Slack, Microsoft Teams, Discord et tout endpoint HTTP générique.

L'API REST

Pour les équipes qui souhaitent un contrôle programmatique complet :

# Déclencher le calcul
curl -X POST https://api.archyl.com/api/v1/drift/compute \
  -H "X-API-Key: $API_KEY" \
  -H "X-Organization-ID: $ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{"projectId": "your-project-uuid"}'

# Obtenir le dernier score
curl https://api.archyl.com/api/v1/drift/latest?projectId=...

# Obtenir l'historique des scores
curl https://api.archyl.com/api/v1/drift/history?projectId=...&limit=20

Le calcul est asynchrone — le POST retourne immédiatement avec un ID de score, et vous interrogez jusqu'à ce que le status devienne completed. La GitHub Action gère cela automatiquement.

Où cela se place dans la boucle

Un score est une étape dans un cycle : les agents et les humains lisent le modèle, le code change, le score mesure l'écart, la CI tient un seuil, l'équipe réconcilie. Sans l'étape de mesure, le cycle n'a pas de retour et la documentation dérive sans que rien ne la conteste. Cet argument, et le reste du dossier en faveur de la détection du drift, se trouvent dans le guide.

Ce dont cet article est responsable, c'est que l'étape de mesure soit digne de confiance. D'où la formule, les exclusions, et les quatre choses qu'elle ne peut pas voir.

Pour commencer

  1. Ouvrez n'importe quel projet dans Archyl
  2. Cliquez sur l'icône de battement de cœur dans la barre d'outils de l'en-tête
  3. Cliquez sur "Compute Drift Score"
  4. Configurez la GitHub Action pour un suivi continu
  5. Configurez un webhook Slack pour les alertes drift.score_degraded

Votre documentation d'architecture reflète la réalité ou non. Désormais, vous avez un chiffre qui vous dit laquelle des deux options correspond à votre situation — et assez de son arithmétique pour le contester.


Le reste du cluster : la détection du drift d'architecture pour le problème et les autres méthodes de détection, la documentation d'architecture vivante pour les pratiques qui empêchent un score de redescendre. Définitions : drift d'architecture. Page produit : détection de drift.