El Número del que Nadie Quiere Hablar
La revisión informal de código detecta entre el 15 y el 30 por ciento de los defectos presentes en el código que se revisa. Esa no es una opinión. Es un hallazgo que se ha replicado a lo largo de cuatro décadas, múltiples empresas y docenas de estudios.
Michael Fagan lo documentó en IBM en 1976. Un estudio de 1987 en AT&T Bell Labs encontró un 20 por ciento. Un estudio de HP de 1996 encontró un 25 por ciento. Un paper de Microsoft Research de 2013 sobre code review moderno encontró aproximadamente el mismo rango. Las herramientas cambiaron de tarjetas perforadas a GitHub, pero la curva de rendimiento humano no se movió.
Si su equipo cree que el pull request review es su salvaguarda de calidad, los datos dicen que está detectando aproximadamente un bug de cada cuatro. Los otros tres se van a producción.
De Dónde Vienen los Números
La metodología original de Fagan era simple y brutal. Inyectaba defectos conocidos en el código, ejecutaba el proceso de revisión y contaba cuántos encontraban los revisores. Luego comparaba eso con el total de defectos que el equipo eventualmente encontraba mediante pruebas, incidents en producción y reportes de clientes. La proporción de encontrados-en-revisión respecto a defectos-totales se convirtió en la removal rate.
La idea clave es que el denominador importa. Una revisión que encuentra diez defectos suena bien hasta que se sabe que había cincuenta en el archivo. Fagan midió el denominador completo. La mayoría de los equipos hoy no lo hacen.
Los estudios posteriores usaron diseños similares. Los investigadores sembraron defectos, compararon tipos de revisión, o rastrearon defectos hacia atrás desde producción para ver dónde podrían haberse detectado. Los resultados se agrupan estrechamente:
| Tipo de revisión | Defect removal rate | Estudios clave |
|---|---|---|
| Sin revisión | 0% | Baseline |
| Informal / PR review | 15-30% | Fagan 1976, Porter 1995, Microsoft 2013 |
| Walkthrough estructurado | 30-50% | Yourdon 1979, Weller 1993 |
| Fagan inspection | 60-90% | Fagan 1976, Russell 1991, NASA 2002 |
La brecha entre la revisión informal y la estructurada no es pequeña. Es una diferencia de 3x en la defect escape rate.
Por qué el PR Review Rinde Tan Mal
El problema no es que los revisores sean malos en su trabajo. El problema es que el pull request review no está diseñado para encontrar defectos. Está diseñado para que dos personas acuerden que el código puede hacer merge.
Esto es lo que realmente sucede en un PR review típico. El revisor abre el diff. Lee el resumen, escanea las adiciones, verifica que las pruebas pasen y busca algo obviamente incorrecto. Esto toma de cinco a quince minutos. Luego aprueba.
El proceso está optimizado para la velocidad, no para la exhaustividad. No hay tiempo de preparación. El revisor no ha leído el código circundante, no ha rastreado el flujo de datos ni ha construido un modelo mental del cambio. Está reaccionando a un diff en una pantalla, y los cerebros humanos son terribles para encontrar bugs en ese formato.
Un estudio de 2015 de Bacchelli y Bird en Microsoft encontró que las categorías de comentarios de revisión más comunes no estaban relacionadas con defectos en absoluto. Las principales categorías eran preguntas sobre la intención, solicitudes de aclaración y sugerencias de mejora. Los hallazgos reales de defectos eran una minoría de los comentarios. La herramienta funcionaba como un canal de comunicación, no como una quality gate.
Esto está bien si sabe lo que hace la herramienta. Es peligroso si cree que hace algo más.
Qué Hace la Revisión Estructurada de Manera Diferente
Las Fagan inspections y otros métodos de revisión estructurada logran removal rates más altos cambiando el diseño del proceso, no a las personas.
La palanca más grande es la preparación individual. En una Fagan inspection, cada revisor pasa tiempo enfocado con el material antes de cualquier discusión en grupo. Fagan descubrió que los inspectores preparados encontraban aproximadamente el doble de defectos que aquellos que llegaban en frío. El modelo de PR es el modelo de llegada en frío por defecto.
La segunda palanca es el ritmo. Fagan recomendó de 100 a 125 líneas de código por hora de revisión. La mayoría de los revisores de PR procesan diez veces esa velocidad. La velocidad mata la detección. Su cerebro completa patrones esperados en lugar de leer lo que realmente está ahí.
La tercera palanca es el enfoque. Las reuniones de Fagan tienen un único propósito: registrar defectos. Sin debates de diseño. Sin propuestas de solución. Sin discusiones de estilo. Los threads de PR habitualmente derivan hacia opiniones de arquitectura, lo que consume el mismo presupuesto cognitivo que podría haber encontrado un null dereference.
La cuarta palanca es el rol del lector. Tener a alguien que no escribió el código parafrasearlo en voz alta obliga al grupo a procesar a velocidad de comprensión en lugar de velocidad de lectura superficial. Un diff en una pantalla permite que sus ojos se salten las partes aburridas. Una persona hablando no se salta.
El Argumento de Costo Está al Revés
La objeción usual a la revisión estructurada es el costo. Una Fagan inspection consume de cuatro a seis horas-persona por unas pocas centenas de líneas de código. Un PR review consume quince minutos del tiempo de una persona. La cuenta parece obvia.
Es obvia, y es incorrecta.
Fagan también midió el costo de encontrar defectos en diferentes etapas. Un defecto encontrado durante la inspection costaba aproximadamente una décima parte de lo que costaba encontrarlo durante las pruebas. Cuando escapaba a producción, la proporción crecía a veinte o treinta a uno. El estudio de la NASA de 2002 encontró que cada hora dedicada a inspection prevenía un promedio de 33 horas de trabajo de mantenimiento posterior.
Los ahorros son invisibles. No puede medir el bug que previno. El costo de la reunión es inmediato y obvio. Por eso las organizaciones optimizan la velocidad visible sobre la calidad invisible, incluso cuando los datos dicen que les cuesta más al final.
Un Término Medio Basado en Datos
No necesita la cultura de reuniones de IBM para obtener la mayor parte del beneficio. Necesita tomar prestadas las características del proceso que realmente mueven el número, y descartar las que no.
Esto es lo que dicen los datos que importa:
-
Tiempo de preparación. Exija que los revisores pasen tiempo con el código antes de comentar. Incluso diez minutos de lectura enfocada superan un vistazo rápido.
-
Límites de ritmo. Para archivos críticos, imponga una velocidad máxima de revisión. Si un revisor aprueba un cambio de 500 líneas en cinco minutos, eso son datos, no diligencia.
-
Enfoque solo en defectos. Separe el feedback de estilo y arquitectura de la búsqueda de defectos. Use formateadores automáticos para lo primero. Reserve la attention humana para lo segundo.
-
Checklists. Fagan descubrió que los revisores guiados por checklist encontraban defectos que los revisores guiados por intuición pasaban por alto. La checklist existe porque la expertise crea puntos ciegos.
Aquí hay un script ligero que mide la profundidad de revisión desde el historial de Git. Estima si una revisión tuvo suficiente tiempo para ser exhaustiva:
#!/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']}")
Guárdelo como review_depth.py y ejecútelo:
python review_depth.py abc1234
La salida le dirá si un commit tuvo suficiente tiempo de revisión para ser exhaustivo según el estándar de Fagan. La mayoría de los commits dirán insufficient. Ese es el punto. Los datos nos han estado diciendo esto durante décadas, y seguimos construyendo pipelines más rápidos en lugar de mejores.
Qué Significa Esto para Su Equipo
El pull request review no es inútil. Construye contexto compartido, difunde conocimiento y atrapa errores obvios. Pero los datos son claros sobre lo que no hace. No atrapa la mayoría de los defectos.
Si su estrategia de calidad depende del PR review como filtro principal, está filtrando con un tamiz. La removal rate del 15-30% no es un fallo de sus revisores. Es una propiedad del proceso.
Los equipos que superan este número no contratan gente más inteligente. Cambian el proceso. Agregan tiempo de preparación, imponen límites de ritmo, separan la búsqueda de defectos de la discusión de diseño, y usan checklists para dirigir la attention donde la intuición falla.
No necesita una Fagan inspection completa para cada diff. Sí necesita saber lo que su proceso actual realmente logra, y dejar de pretender que logra más.
FAQ
¿Qué dicen los datos sobre la efectividad del pull request review?
Múltiples estudios en IBM, AT&T, HP y Microsoft encuentran consistentemente que la revisión informal de código detecta el 15-30% de los defectos presentes en el código. Este rango se ha mantenido estable desde los años 70 hasta la investigación moderna sobre workflows basados en GitHub.
¿Por qué los pull request reviews detectan tan pocos defectos?
El PR review está optimizado para la velocidad y la aprobación de merge, no para la detección sistemática de defectos. Los revisores típicamente dedican 5-15 minutos por revisión, no tienen tiempo de preparación, procesan el código a 10x la velocidad que recomienda la investigación, y el formato fomenta el vistazo rápido en lugar del análisis profundo.
¿Cuánto mejores son las revisiones estructuradas como las Fagan inspections?
Las Fagan inspections reportan consistentemente removal rates de defectos del 60-90%, aproximadamente 3-4x mejor que la revisión informal. La diferencia proviene de la preparación individual, los límites de ritmo impuestos, la separación de roles, el enfoque guiado por checklist, y las reuniones que registran defectos en lugar de debatir soluciones.
¿Cuál es la forma más barata de mejorar la efectividad del PR review?
Exija preparación individual antes de comentar, use checklists adaptadas a los tipos de defectos comunes de su equipo, separe el feedback de estilo de la búsqueda de defectos, y limite la velocidad de revisión para archivos críticos. Incluso pequeños cambios en la preparación y el enfoque pueden mover la aguja significativamente sin agregar overhead de reuniones.
¿Cómo mido la removal rate real de defectos de mi equipo?
Rastree los defectos encontrados en revisión versus los defectos encontrados posteriormente en pruebas o producción. La proporción de detectados-temprano respecto a total-encontrados es su removal rate. La mayoría de los equipos no rastrean esto, por eso sobrestiman la efectividad de la revisión. Comience a registrar dónde se encontró cada defecto, luego calcule la proporción mensualmente.