Engineering

El bug que encontramos dos veces

Para quienes ya revisan bien: los defectos que llegan a producción casi nunca son los que nadie miró.
2 de noviembre de 2026·~7 min de lectura · Read in English →

El defecto lo encontramos dos veces antes de que saliera. Una en la revisión del pull request, donde alguien lo escribió. Otra en una auditoría previa al release, que lo puso como el punto más importante de su lista.

Un hallazgo levantado en la revisión, levantado otra vez en la auditoría, y el cambio llegando a producción de todos modos.
Levantado en la revisión. Levantado otra vez por la auditoría. Mergeado de todos modos.

Salió igual. Y llegó a producción, donde alguien más lo encontró por tercera vez.

Yo llevaba un año construyendo justo lo que debía haber evitado eso.

Lo que esperaba de la auditoría

Con mi equipo armamos un merge bar: la evidencia que un cambio debe entregar antes de que una persona con nombre y apellido lo firme, graduada por el radio de impacto y no por el tamaño del diff. Lo pilotamos en cuatro aplicaciones de brokerage y funcionó — atrapó defectos críticos antes de UAT.

Después llevamos las mismas reglas a algo mucho más chico y completamente aparte: otra aplicación, nada crítico, dos de nosotros trabajándola unas tres semanas. Ochenta y un pull requests, y setenta de setenta y uno mergeados con firma humana.

Luego alguien sin ninguna relación con cómo la habíamos construido auditó el resultado de punta a punta. Yo creía saber cómo se vería la lista. Puntos ciegos. Preguntas que a nadie se le ocurrió hacer. Los huecos que surgen cuando el revisor es perfectamente competente y el proceso nunca lo ubicó en el lugar correcto.

Y traía lista mi regla favorita: convertir cada escape en un lente de revisión permanente, con nombre, para que esa clase de defecto no vuelva a escaparse. Cada falla en producción le enseña algo al proceso, algo que se queda.

La auditoría identificó nueve defectos que habían llegado a producción.

Ninguno fue por no haber mirado.

El número que rompió mi regla

Nueve defectos llegaron a producción, ordenados por la razón por la que pasaron: tres que nadie preguntó, cuatro que necesitaban maquinaria que nunca construimos, dos fuera del alcance de la revisión.

Siete de los nueve estaban al alcance de la revisión. Tres eran del tipo que mi regla sí arregla: nadie hizo la pregunta, así que nadie la respondió. Pones el lente, cierras el hueco, y ese sí queda muerto.

El grupo más grande era otra cosa. Esos defectos ya se habían encontrado. Estaban escritos. Con fecha, en una revisión o en un reporte de auditoría, antes del merge. Y salieron igual.

Un lente es una forma de memoria. Asume que la falla fue un olvido y lo arregla de maravilla. Pero no puedes ponerle un lente al “ya sabíamos”. El hallazgo ya estaba ahí, por escrito, con fecha previa al merge. Apunta un revisor nuevo a la misma pregunta y te va a dar la misma nota, y esa misma nota te va a dar el mismo resultado, porque la nota nunca fue el problema.

Ahí es donde nos equivocamos, y tuvo que venir alguien de fuera a enseñárnoslo. Habíamos construido un instrumento para la atención y dimos por hecho que también cubría la disposición. La atención y la disposición son fallas distintas y requieren maquinaria distinta. Lo que me faltaba era una regla sobre qué pasa con un hallazgo cuando alguien decide no actuar: quién decide, dónde queda registrada esa decisión y qué hace falta para reabrirla. Cuatro de esos nueve necesitaban eso, o necesitaban a su hermano: un disparador que vuelva a revisar un arreglo cuando cambia lo que está a su alrededor.

Ninguno de los dos es un lente. Habíamos construido un instrumento y yo le había llamado “sistema”.

Dos revisiones, respuestas opuestas, nadie se dio cuenta

Dos revisiones independientes llegaron a conclusiones opuestas sobre el mismo payload, y nada en el proceso las comparó.

Uno de los nueve merece contarse aparte, porque es la falla que ahora busco primero.

Una revisión del control de acceso recorrió el payload, campo por campo. Enumeró lo que había y luego concluyó, en una sola frase, que el payload era seguro — una conclusión que su propia enumeración contradice. Lee la lista, lee el veredicto y no coinciden.

Esa misma semana, una auditoría distinta marcó el mismo campo por su cuenta.

Dos artefactos de revisión llegaron a conclusiones opuestas sobre lo mismo, y ganó el permisivo. No porque alguien los hubiera pesado. Porque nada en el proceso estaba viendo el desacuerdo. Teníamos una regla para la disidencia dentro de una revisión: basta con que un revisor objete para detener un merge. No teníamos absolutamente nada para la disidencia entre dos revisiones. El que dijo “va” fue simplemente el que alguien leyó.

Y esto se pone más difícil conforme agregas revisores, no más fácil. Cada pasada independiente es otra oportunidad de generar una contradicción que nadie busca.

La parte que tengo que decir en voz alta

La auditoría encontró los nueve. Nosotros los ordenamos en categorías. Y la frontera que más importa — entre “a ningún revisor lo apuntaron a esta pregunta” y “alguien la vio de frente y se le fue” — es un juicio hecho por quienes diseñamos el proceso de revisión.

No somos imparciales. Un hueco de lente es un problema de arquitectura. Un descuido simple es un problema de personas, y es el menos halagador de los dos. Lee ese “ninguno fue por no haber mirado” sabiendo quién hizo la clasificación.

Lo que no es cuestión de juicio es el grupo donde de verdad se sostiene el argumento. Para esos, el hallazgo existe por escrito, con fecha anterior al merge. Cualquiera puede ir a verlo. Ese conteo lo comprueba quien quiera, y es el que rompió mi regla.

Qué haría el lunes

Si tienes un proceso de revisión del que estás orgulloso, el ejercicio útil no consiste en contar lo que atrapa. Es conseguir que alguien sin nada en juego audite algo que ya sacaste, y luego ordenar lo que encuentre por por qué se pasó.

Después construye para lo que realmente veas:

  • Un lente, para la pregunta que nadie hizo. Este es el instrumento que casi todos los equipos ya tienen, y del que trata casi todo lo que se escribe.
  • Una regla de disposición, para el hallazgo que se levantó y se soltó. ¿Quién puede cerrar un hallazgo sin arreglarlo, dónde reside esa decisión y qué la reabre? Un hallazgo sin disposición registrada no está cerrado; está perdido.
  • Un disparador de re-revisión, para el arreglo que se echó a perder cuando algo a su alrededor se movió.

Y una cosa barata que no cuesta nada: cuando dos revisiones del mismo cambio llegan a conclusiones distintas, haz que el proceso se dé cuenta. Hoy la mayoría no lo hace, y la respuesta permisiva gana por defecto.

Lo que aprendí: esto fue una auditoría de un sistema, y no voy a hacer una ley con nueve defectos. Pero apuntó a algo que yo no había considerado: un proceso maduro de revisión quizá no falla por no mirar. Falla en el momento en que alguien ya miró, ya lo escribió, y el equipo decide — casi siempre sin decidir — sacarlo. Esa regla del lente que tanto me gustaba cubría una tercera parte de nuestros escapes. Había confundido un instrumento con un sistema, y solo una auditoría que yo no corrí pudo enseñármelo.

Cada equipo que adopta la ingeniería asistida por IA generará muchísimos más hallazgos que antes. El cuello de botella nunca se iba a quedar en encontrar cosas. Se mueve a qué haces con un hallazgo una vez que lo tienes.

Así que ve a ver lo último que sacó tu equipo y cuenta los hallazgos que se levantaron antes del merge. Luego averigua qué pasó con cada uno. Si no puedes distinguir un riesgo asumido de uno que simplemente se soltó — y casi ninguno de nosotros puede, porque nadie escribió la decisión — acabas de encontrar lo que hay que construir a continuación. Y no es otro revisor.