Le Chiffre Dont Personne Ne Veut Parler
La revue de code informelle détecte entre 15 et 30 pour cent des défauts présents dans le code en cours de révision. Ce n’est pas une opinion. C’est une constatation qui a été répliquée sur quatre décennies, plusieurs entreprises et des dizaines d’études.
Michael Fagan l’a documenté chez IBM en 1976. Une étude de 1987 chez AT&T Bell Labs a trouvé 20 pour cent. Une étude HP de 1996 a trouvé 25 pour cent. Un article de Microsoft Research de 2013 sur le code review moderne a trouvé à peu près la même fourchette. Les outils sont passés des cartes perforées à GitHub, mais la courbe de performance humaine n’a pas bougé.
Si votre équipe pense que la revue de pull request est votre filet de sécurité qualité, les données vous disent que vous détectez environ un bug sur quatre. Les trois autres partent en production.
D’où Vienment les Chiffres
La méthodologie originale de Fagan était simple et brutale. Il injectait des défauts connus dans le code, exécutait le processus de révision et comptait combien les revieweurs en trouvaient. Puis il comparait cela au total des défauts que l’équipe finissait par trouver via les tests, les incidents de production et les rapports clients. Le ratio de trouvé-en-révision par rapport à défauts-totaux est devenu le removal rate.
L’idée clé est que le dénominateur compte. Une révision qui trouve dix défauts semble bonne jusqu’à ce que l’on apprenne qu’il y en avait cinquante dans le fichier. Fagan mesurait le dénominateur complet. La plupart des équipes aujourd’hui ne le font pas.
Les études ultérieures ont utilisé des conceptions similaires. Les chercheurs injectaient des défauts, comparaient les types de révision, ou traçaient les défauts à rebours depuis la production pour voir où ils auraient pu être détectés. Les résultats se regroupent étroitement :
| Type de révision | Defect removal rate | Études clés |
|---|---|---|
| Aucune révision | 0% | Baseline |
| Informelle / PR review | 15-30% | Fagan 1976, Porter 1995, Microsoft 2013 |
| Walkthrough structuré | 30-50% | Yourdon 1979, Weller 1993 |
| Fagan inspection | 60-90% | Fagan 1976, Russell 1991, NASA 2002 |
L’écart entre la révision informelle et la révision structurée n’est pas petit. C’est une différence de 3x dans le defect escape rate.
Pourquoi le PR Review Performe Si Mal
Le problème n’est pas que les revieweurs sont mauvais dans leur travail. Le problème est que la revue de pull request n’est pas conçue pour trouver des défauts. Elle est conçue pour que deux personnes acceptent qu’un code puisse être mergé.
Voici ce qui se passe réellement dans un PR review typique. Le revieweur ouvre le diff. Il lit le résumé, scanne les ajouts, vérifie que les tests passent, et cherche tout ce qui est visiblement incorrect. Cela prend de cinq à quinze minutes. Puis il approuve.
Le processus est optimisé pour la vitesse, pas pour l’exhaustivité. Il n’y a pas de temps de préparation. Le revieweur n’a pas lu le code environnant, n’a pas tracé le flux de données, ni construit un modèle mental du changement. Il réagit à un diff sur un écran, et les cerveaux humains sont terribles pour trouver des bugs dans ce format.
Une étude de 2015 de Bacchelli et Bird chez Microsoft a trouvé que les catégories de commentaires de révision les plus courantes n’étaient pas liées aux défauts du tout. Les principales catégories étaient des questions sur l’intention, des demandes de clarification et des suggestions d’amélioration. Les détections réelles de défauts étaient une minorité de commentaires. L’outil fonctionnait comme un canal de communication, pas comme une quality gate.
C’est bien si vous savez ce que l’outil fait. C’est dangereux si vous pensez qu’il fait autre chose.
Ce Que la Révision Structurée Fait Différemment
Les Fagan inspections et autres méthodes de révision structurée atteignent des removal rates plus élevés en changeant la conception du processus, pas les personnes.
Le plus grand levier est la préparation individuelle. Dans une Fagan inspection, chaque revieweur passe du temps concentré avec le matériel avant toute discussion de groupe. Fagan a découvert que les inspecteurs préparés trouvaient environ deux fois plus de défauts que ceux qui entraient à froid. Le modèle PR est le modèle d’entrée à froid par défaut.
Le deuxième levier est le rythme. Fagan recommandait 100 à 125 lignes de code par heure de révision. La plupart des revieweurs de PR traitent dix fois ce rythme. La vitesse tue la détection. Votre cerveau remplit des motifs attendus au lieu de lire ce qui est réellement là.
Le troisième levier est le focus. Les réunions Fagan ont un seul but : enregistrer les défauts. Pas de débats de conception. Pas de propositions de solution. Pas de discussions de style. Les threads de PR dérivent routinièrement vers des opinions d’architecture, ce qui consomme le même budget cognitif qui aurait pu trouver un null dereference.
Le quatrième levier est le rôle du lecteur. Faire paraphraser le code à voix haute par quelqu’un qui ne l’a pas écrit force le groupe à traiter à la vitesse de compréhension plutôt qu’à la vitesse de scan. Un diff sur un écran permet à vos yeux de sauter les parties ennuyeuses. Une personne qui parle ne saute pas.
L’Argument de Coût Est à l’Envers
L’objection habituelle à la révision structurée est le coût. Une Fagan inspection consomme quatre à six heures-personne pour quelques centaines de lignes de code. Un PR review consomme quinze minutes du temps d’une personne. Le calcul semble évident.
Il est évident, et il est faux.
Fagan a aussi mesuré le coût de trouver des défauts à différentes étapes. Un défaut trouvé pendant l’inspection coûtait environ un dixième de ce qu’il coûtait de le trouver pendant les tests. Quand il échappait à la production, le ratio passait à vingt ou trente pour un. L’étude NASA de 2002 a trouvé que chaque heure passée en inspection prévenait en moyenne 33 heures de travail de maintenance plus tard.
Les économies sont invisibles. Vous ne pouvez pas mesurer le bug que vous avez prévenu. Le coût de la réunion est immédiat et évident. C’est pourquoi les organisations optimisent la vitesse visible plutôt que la qualité invisible, même quand les données disent que cela leur coûte plus cher à la fin.
Un Juste Milieu Guidé par les Données
Vous n’avez pas besoin de la culture de réunion d’IBM pour obtenir la majeure partie du bénéfice. Vous devez emprunter les caractéristiques du processus qui font réellement bouger le chiffre, et abandonner celles qui ne le font pas.
Voici ce que les données disent qui compte :
-
Temps de préparation. Exigez que les revieweurs passent du temps avec le code avant de commenter. Même dix minutes de lecture concentrée battent un survol.
-
Limites de rythme. Pour les fichiers critiques, imposez une vitesse de révision maximale. Si un revieweur approuve un changement de 500 lignes en cinq minutes, ce sont des données, pas de la diligence.
-
Focus uniquement sur les défauts. Séparez le feedback de style et d’architecture de la chasse aux défauts. Utilisez des formateurs automatiques pour le premier. Réservez l’attention humaine pour le second.
-
Checklists. Fagan a découvert que les revieweurs guidés par checklist trouvaient des défauts que les revieweurs guidés par intuition passaient. La checklist existe parce que l’expertise crée des angles morts.
Voici un script léger qui mesure la profondeur de révision depuis l’historique Git. Il estime si une révision a eu assez de temps pour être exhaustive :
#!/usr/bin/env python3
"""Estimate review depth from git history."""
import subprocess
import sys
from datetime import datetime, timezone
def get_commit_info(commit_hash: str) -> dict:
"""Return author, committer, and timestamps for a commit."""
fmt = "%H|%an|%cn|%ad|%cd"
result = subprocess.run(
["git", "log", "-1", f"--format={fmt}", commit_hash],
capture_output=True,
text=True,
check=True,
)
parts = result.stdout.strip().split("|")
return {
"hash": parts[0],
"author": parts[1],
"committer": parts[2],
"author_date": datetime.strptime(parts[3], "%a %b %d %H:%M:%S %Y %z"),
"commit_date": datetime.strptime(parts[4], "%a %b %d %H:%M:%S %Y %z"),
}
def get_lines_changed(commit_hash: str) -> int:
"""Count total lines added + deleted in a commit."""
result = subprocess.run(
["git", "diff", f"{commit_hash}^", commit_hash, "--stat"],
capture_output=True,
text=True,
check=True,
)
# Last line of --stat contains totals like "3 files changed, 42 insertions(+), 7 deletions(-)"
for line in reversed(result.stdout.strip().splitlines()):
line = line.strip()
if "insertions" in line or "deletions" in line:
# Extract numbers roughly
parts = line.split(",")
total = 0
for part in parts:
digits = "".join(ch for ch in part if ch.isdigit())
if digits:
total += int(digits)
return total
return 0
def estimate_review_depth(commit_hash: str) -> dict:
"""Estimate whether a commit had time for thorough review.
Returns lines changed, time between author and commit dates
(a rough proxy for review duration), and a verdict.
"""
info = get_commit_info(commit_hash)
lines = get_lines_changed(commit_hash)
# Time between author date and commit date is a proxy for review time
# In many workflows, commit date reflects when the merge happened
review_seconds = (info["commit_date"] - info["author_date"]).total_seconds()
review_hours = review_seconds / 3600
# Fagan recommended 100-125 lines/hour for thorough review
fagan_rate = 125
needed_hours = lines / fagan_rate if lines else 0
verdict = "insufficient"
if review_hours >= needed_hours:
verdict = "adequate"
if review_hours >= needed_hours * 2:
verdict = "thorough"
return {
"hash": commit_hash[:8],
"lines": lines,
"review_hours": round(review_hours, 2),
"needed_hours": round(needed_hours, 2),
"verdict": verdict,
}
if __name__ == "__main__":
commit = sys.argv[1] if len(sys.argv) > 1 else "HEAD"
result = estimate_review_depth(commit)
print(f"Commit: {result['hash']}")
print(f"Lines: {result['lines']}")
print(f"Review time: {result['review_hours']} hours")
print(f"Fagan time: {result['needed_hours']} hours")
print(f"Verdict: {result['verdict']}")
Enregistrez-le sous review_depth.py et exécutez :
python review_depth.py abc1234
La sortie vous dira si un commit a eu assez de temps de révision pour être exhaustif selon le standard de Fagan. La plupart des commits diront insufficient. C’est le point. Les données nous disent cela depuis des décennies, et nous continuons à construire des pipelines plus rapides au lieu de meilleurs.
Ce Que Cela Signifie pour Votre Équipe
La revue de pull request n’est pas inutile. Elle construit un contexte partagé, diffuse les connaissances et attrape les erreurs évidentes. Mais les données sont claires sur ce qu’elle ne fait pas. Elle n’attrape pas la majorité des défauts.
Si votre stratégie qualité dépend du PR review comme filtre principal, vous filtrez avec un tamis. Le removal rate de 15-30% n’est pas un échec de vos revieweurs. C’est une propriété du processus.
Les équipes qui battent ce nombre n’embauchent pas des gens plus intelligents. Elles changent le processus. Elles ajoutent du temps de préparation, imposent des limites de rythme, séparent la détection de défauts de la discussion de conception, et utilisent des checklists pour diriger l’attention là où l’intuition manque.
Vous n’avez pas besoin d’une Fagan inspection complète pour chaque diff. Vous devez savoir ce que votre processus actuel atteint réellement, et cesser de prétendre qu’il atteint plus.
FAQ
Que disent les données sur l’efficacité du pull request review ?
De multiples études chez IBM, AT&T, HP et Microsoft trouvent de manière cohérente que la revue de code informelle détecte 15-30% des défauts présents dans le code. Cette fourchette est restée stable des années 1970 jusqu’à la recherche moderne sur les workflows basés sur GitHub.
Pourquoi les pull request reviews détectent-elles si peu de défauts ?
Le PR review est optimisé pour la vitesse et l’approbation de merge, pas pour la détection systématique de défauts. Les revieweurs consacrent typiquement 5-15 minutes par révision, n’ont pas de temps de préparation, traitent le code à 10x le rythme recommandé par la recherche, et le format encourage le survol plutôt que l’analyse approfondie.
Combien de fois meilleures sont les révisions structurées comme les Fagan inspections ?
Les Fagan inspections rapportent de manière cohérente des defect removal rates de 60-90%, environ 3-4x meilleurs que la révision informelle. La différence vient de la préparation individuelle, des limites de rythme imposées, de la séparation des rôles, du focus guidé par checklist, et des réunions qui enregistrent les défauts au lieu de débattre des solutions.
Quelle est la manière la moins chère d’améliorer l’efficacité du PR review ?
Exigez une préparation individuelle avant de commenter, utilisez des checklists adaptées aux types de défauts courants de votre équipe, séparez le feedback de style de la chasse aux défauts, et limitez la vitesse de révision pour les fichiers critiques. Même de petits changements dans la préparation et le focus peuvent faire bouger l’aiguille significativement sans ajouter de overhead de réunions.
Comment mesure-je le removal rate réel de défauts de mon équipe ?
Suivez les défauts trouvés en révision par rapport aux défauts trouvés plus tard en tests ou en production. Le ratio de détectés-tôt par rapport à total-trouvés est votre removal rate. La plupart des équipes ne suivent pas cela, c’est pourquoi elles surestiment l’efficacité de la révision. Commencez à enregistrer où chaque défaut a été trouvé, puis calculez le ratio mensuellement.