Skip to content

Predice qué pull requests se van a atascar — con la baseline de tu equipo

Aliaume Caplat Fundador, DevPrism LinkedIn
pull-requests engineering-metrics dora engineering-management

Todos los equipos acaban montando la misma automatización: «avísame cuando una pull request lleve más de 48 horas abierta».

Y todos acaban desactivándola.

No porque las PR estancadas hayan dejado de importar. Porque 48 horas es el número de otra persona. En un equipo que revisa en dos horas, la alerta llega demasiado tarde para servir de algo. En un equipo que revisa dos veces por semana, salta con todo, todos los días, hasta que alguien silencia el canal.

Un umbral tiene que salir de alguna parte. El error está en elegirlo a mano.

El cambio de enfoque: comparar una PR con tu equipo, no con una constante

La pregunta «¿va tarde esta PR?» no tiene respuesta absoluta. Solo tiene una relativa: tarde respecto a lo que este equipo hace normalmente.

Ese replanteamiento convierte una opinión en un cálculo. Ya tienes el dato: cada PR fusionada es una observación de lo que tarda de verdad una revisión en tu equipo. Convierte esas observaciones en una distribución y el umbral se elige solo.

Importan dos medidas, y no son lo mismo:

Medida Definición Qué te dice
Pickup time Apertura de la PR → primera revisión Cuánto espera el código a que lo mire un humano
Cycle time Apertura de la PR → cierre / merge Todo el recorrido, trabajo del autor incluido

El pickup time es sobre el que conviene alertar. El cycle time incluye al autor respondiendo comentarios, haciendo rebase, esperando a la CI: trabajo en curso, legítimo. El pickup time mide otra cosa: nadie lo ha mirado todavía. Eso es tiempo de cola, es desperdicio puro y, a diferencia del cycle time, alguien que no es el autor puede actuar sobre él.

Paso 1 — Construir la baseline

Toma tus PR fusionadas en una ventana móvil y calcula los percentiles 50, 75 y 90 del pickup time.

Esa sola frase esconde cuatro decisiones, y cada una marca la diferencia entre una señal y ruido.

Usa percentile_disc, no percentile_cont

percentile_cont interpola entre dos observaciones. Con una muestra de doce PR, eso inventa una duración que nunca ocurrió: un P75 de «26,4 horas» cuando tu equipo jamás ha tardado 26,4 horas. percentile_disc devuelve una observación real. Cuando luego le digas a alguien «esto supera el P75 de tu equipo», más vale que ese número sea algo que de verdad pasó.

Excluye los bots de mantenimiento

Los bots de actualización de dependencias abren muchas PR y abandonan muchas. Si se quedan en la muestra, dominan la distribución y distorsionan la señal humana que intentas medir. Imagina un bot de dependencias que abre unas cuantas subidas de versión cada semana, la mayoría de las cuales se fusionan automáticamente, quedan sustituidas por la siguiente subida o se cierran sin más. Sus duraciones describen un proceso que ningún humano ejecutó — y como abre muchas más PR que cualquier persona, una sola cuenta de bot puede pesar más que todo tu equipo en la muestra. Nadie iba a revisar esas PR. No son deuda de revisión.

Niégate a responder por debajo de una muestra mínima

Por debajo de una decena de PR fusionadas en la ventana, los percentiles son ruido disfrazado de precisión. Un P90 calculado sobre cuatro observaciones es simplemente «la más lenta de cuatro». El comportamiento correcto es no emitir nada: ni baseline, ni predicción, ni alerta.

Conviene insistir, porque es lo contrario de lo que hacen la mayoría de los cuadros de mando. Una herramienta que siempre produce un número enseña a la gente que sus números no significan nada. Negarse a responder es una funcionalidad, y es la credibilidad más barata que vas a comprar nunca.

Calcula la baseline por equipo

Un equipo de plataforma y uno de móvil no comparten cultura de revisión, ni huso horario, ni definición de urgente. Un percentil global aplasta a ambos en un número que no describe a ninguno.

La consulta, si quieres reproducirla

Nada de lo anterior exige una herramienta. Si tienes tu historial de pull requests en un almacén de datos, toda la baseline cabe en una consulta — sáltatela si no es tu caso, el resto del artículo se sostiene sin ella.

SELECT
  percentile_disc(0.50) WITHIN GROUP (ORDER BY pickup_hours) AS p50,
  percentile_disc(0.75) WITHIN GROUP (ORDER BY pickup_hours) AS p75,
  percentile_disc(0.90) WITHIN GROUP (ORDER BY pickup_hours) AS p90,
  count(*)                                                   AS sample_size
FROM (
  SELECT EXTRACT(EPOCH FROM (first_review_at - created_at)) / 3600 AS pickup_hours
  FROM pull_requests
  WHERE merged_at BETWEEN :period_start AND :period_end
    AND first_review_at IS NOT NULL
    AND author NOT IN (SELECT login FROM maintenance_bots)
) AS observed;

Paso 2 — Puntuar las PR abiertas

Recorre ahora las PR abiertas. Para cada una, toma el tiempo transcurrido desde su apertura y sitúalo en la distribución:

transcurrido < P50            → en plazo        (no emitir nada)
P50 ≤ transcurrido < P75      → ralentizándose
P75 ≤ transcurrido < P90      → en riesgo
transcurrido ≥ P90            → bloqueo previsible

Dos reglas lo hacen utilizable en la práctica.

Ignora cualquier PR que ya tenga una primera revisión. En cuanto un humano la ha cogido, la PR ya no está en cola: está avanzando. Alertar sobre ella produce exactamente el falso positivo que hace que se silencie la integración entera. Esta única condición elimina la mayor parte del ruido.

No digas nada de las PR por debajo del P50. Aproximadamente la mitad de tus PR abiertas van en plazo por construcción. Señalarlas añade volumen y resta atención.

Y cuando emitas algo, nombra la comparación:

Sin revisión tras 31,4 h — supera el P75 del equipo (26 h). Riesgo de bloqueo.

No «esta PR está en riesgo». El número con el que se mide al lector tiene que estar en el mensaje, o la alerta es un argumento de autoridad en lugar de un argumento. Además la hace refutable: cualquiera puede ir a comprobar si 26 horas es realmente su P75, y de eso se trata.

Lo que esto no te dice

Un modelo que no se puede criticar es un modelo que no deberías desplegar. Cuatro límites honestos:

La baseline se construye sobre las supervivientes. Solo cuenta las PR que fueron revisadas y fusionadas. Las que se abandonaron tras pudrirse tres semanas no aportan nada, así que la distribución es sistemáticamente más optimista que la experiencia real del equipo. Eso hace la alerta conservadora: cuando salta, significa algo.

La baseline deriva con el equipo. Un trimestre de mala higiene de revisión sube el P75, y un P75 más alto vuelve la alerta más silenciosa. La medida se adapta al deterioro en lugar de reportarlo. Así que sigue la propia baseline a lo largo del tiempo, como métrica por derecho propio: un P90 que se duplica en dos meses es el hallazgo, y ninguna alerta por PR te lo va a mostrar.

Predice un fallo concreto. El atasco antes de la primera revisión, nada más. No dice nada sobre si el código es correcto, si la PR es demasiado grande o si la CI está a punto de fallar. Es una señal entre varias, no una puntuación de riesgo.

Los equipos pequeños tienen percentiles ruidosos. Diez observaciones son un suelo, no una comodidad. Con muestra pequeña, prefiere ampliar la ventana antes que apretar el umbral.

Por qué merece la pena

Un umbral fijo es una política: alguien decidió 48 horas. Una baseline de percentiles es una medida: lo decidió tu equipo, trabajando.

Esa distinción importa más que la ganancia de precisión. Una alerta que dice «esto supera el número con el que me configuraron» invita a discutir la configuración. Una alerta que dice «esto supera lo que tu equipo consigue tres de cada cuatro veces» invita a hablar de la cola, que es la conversación que querías tener.

Cómo lo hace DevPrism

DevPrism calcula esta baseline por equipo en cada sincronización y puntúa las PR abiertas frente a ella:

  • Percentiles de pickup time y cycle time a partir de tus PR fusionadas, con los bots de mantenimiento excluidos
  • Percentiles discretos, de modo que cada umbral es una duración que tu equipo ha registrado de verdad
  • Predicción suprimida por debajo de la muestra mínima, y en las PR ya en revisión
  • Cada PR señalada lleva su ratio respecto a la baseline y un motivo que nombra el percentil superado
Las PR abiertas puntuadas frente a la baseline del propio equipo: las señaladas llevan el percentil que han superado, no un aviso genérico.

El objetivo de todo esto no es predecir el futuro. Es dejar de pedirle a cada manager de ingeniería que se invente un número, y hacer que la alerta sea defendible ante quien la recibe.


¿Quieres esta baseline calculada por ti, por equipo, a partir de tu propio historial? Prueba DevPrism gratis — PR Intelligence y el risk scoring completo forman parte del plan Pro, incluido en la prueba de 14 días, sin tarjeta de crédito.