Diagnóstico y reconstrucción de 242 días de datos · Observed State Index
Resumen
Este documento describe un defecto que no generó ninguna excepción, ningún log de error y ningún síntoma visible durante meses de operación. El sistema funcionó, publicó datos, y pasó desapercibido — hasta que una corrida fuera de horario produjo un resultado imposible de ignorar: treinta corredores aéreos marcados como anómalos el mismo día, todos a la vez.
La causa no era una falla del sistema. Era que el sistema nunca supo, con certeza, a qué hora había medido lo que medía.
El síntoma
El sistema compara cada captura de tráfico aéreo contra el historial de esa misma franja horaria. La identidad de la franja —cuál de las cuatro capturas diarias es cada una— se derivaba del número de secuencia asignado a la carpeta de esa corrida en el almacenamiento, no de ningún dato dentro de la captura misma.
Ese número de secuencia se calculaba contando cuántas carpetas ya existían para el día en curso. Es una lógica frágil por construcción: si una corrida falla a medias, si se produce un reintento, o si alguien dispara una captura manual fuera del horario programado, el conteo se desalinea, y todas las corridas siguientes de ese día heredan un número que ya no corresponde a su hora real.
Durante meses, el sistema operó bajo el supuesto de que ese número era estable. No lo era.
El síntoma se hizo visible al correr una captura de prueba fuera de horario. Esa corrida se comparó contra el baseline de una franja que no le correspondía, con casi una hora de diferencia respecto a su hora real. El resultado: los treinta corredores monitoreados salieron clasificados como fuera de rango en la misma ejecución, incluyendo aeropuertos que, en los hechos, operaban con normalidad.
Un aeropuerto de Atlanta con más del doble de su tráfico habitual no era una anomalía real: era una comparación contra la hora equivocada del día.
Por qué es peligroso este tipo de defecto
Un error que lanza una excepción se nota de inmediato. Este no lanzaba nada. El pipeline se ejecutaba sin fallos, escribía resultados con apariencia normal, y el problema solo emergía cuando las horas se desalineaban lo suficiente como para que el efecto fuera visible a simple vista.
Eso significa que, durante meses, es probable que algunas comparaciones se hayan hecho contra la franja incorrecta sin que ningún indicador lo señalara. Cuánto, se midió después: en enero y febrero de 2026 el número de corrida acertaba la franja entre el 92% y el 100% de las veces, pero en junio y julio —con los reintentos multiplicados por el defecto de tiempo de espera— el acierto cayó al 23%. El sistema no estaba roto: estaba silenciosamente impreciso, que es un modo de falla más difícil de detectar que uno que se anuncia.
El diagnóstico
La corrección exigía dejar de depender del número de secuencia y anclar la comparación a algo que no pudiera desalinearse: la hora real en que se realizó cada captura, tal como la reportaba la fuente de datos en el momento de la consulta.
Esa hora existía en los datos crudos desde el inicio, pero nunca se había extraído durante el procesamiento hacia el formato de almacenamiento final. Estaba disponible; simplemente no se estaba usando.
La solución tenía dos partes: capturar esa hora real en las ejecuciones futuras, y reconstruir el historial completo para que los 242 días ya acumulados también contaran con ella. Sin la segunda parte, el sistema habría quedado dividido entre un pasado sin hora confiable y un futuro con ella — una inconsistencia que habría complicado cualquier análisis que cruzara ambos periodos.
La reconstrucción
Reprocesar 242 días de datos crudos implicó leer varios miles de archivos individuales pequeños y regenerar el almacenamiento completo con la nueva información incorporada.
El proceso no salió limpio al primer intento, y merece documentarse tal como ocurrió:
Un cambio de código no llegó a guardarse. Una función auxiliar del entorno de edición falló silenciosamente al intentar persistir una modificación, debido a un campo de configuración de control de versiones que había quedado a medio llenar en una sesión anterior. La reconstrucción completa se ejecutó con la versión anterior del código, sin la corrección, y hubo que repetirla por completo una vez detectado el problema, verificando esta vez, antes de lanzar el proceso, que el archivo desplegado sí contuviera el cambio esperado.
Las particiones quedaron registradas hacia una ubicación que después se eliminó. Durante la investigación se había escrito una copia de prueba en una ubicación temporal, y el catálogo de datos quedó apuntando ahí. Cuando esa ubicación se limpió, las consultas seguían siendo válidas en apariencia, no arrojaban error, pero devolvían cero resultados, porque apuntaban a una carpeta que ya no existía. La solución fue recrear por completo la definición de la tabla, apuntándola a la ubicación definitiva antes de volver a registrar las particiones.
La configuración de cómputo no hacía lo que su nombre sugería. El proceso de transformación estaba configurado para usar dos unidades de trabajo, con la expectativa de que ambas procesaran datos en paralelo. En la práctica, una de esas dos unidades se reserva siempre para coordinación y no participa en el procesamiento real, de modo que el trabajo se estaba ejecutando con una sola unidad efectiva. Esto no producía ningún error, solo un rendimiento notablemente menor al esperado, que pasó inadvertido hasta compararlo contra un progreso medido en tiempo real.
Ninguno de estos tres tropiezos fue causado por el diseño original de la corrección. Fueron fricciones del proceso de aplicarla, y cada uno se resolvió verificando directamente el estado real del sistema en lugar de asumir que un paso anterior se había completado como se esperaba.
El resultado
La reconstrucción completada dejó los 242 días de historial con la hora real de captura disponible en cada registro, permitiendo derivar la franja horaria correspondiente de forma confiable en cualquier consulta futura, sin depender de ningún número de secuencia asignado externamente.
Como efecto colateral no buscado, el proceso también reveló que aproximadamente 800.000 registros correspondientes a 43 días adicionales existían en el almacenamiento crudo pero nunca habían sido incorporados al conjunto de datos consultable, probablemente por fallas puntuales en pasos intermedios de ejecuciones anteriores que nunca se habían corregido de forma retroactiva. La reconstrucción los incorporó junto con el resto.
Lo que este caso demuestra
Que un sistema sin errores visibles no es necesariamente un sistema correcto. La ausencia de excepciones no equivale a la ausencia de defectos; algunos de los problemas más persistentes son los que nunca fallan de forma ruidosa.
Que verificar el estado real después de cada paso no es opcional cuando se opera infraestructura de datos. Dos de los tres tropiezos de la reconstrucción, el código que no se guardó y las particiones apuntando a una ubicación eliminada, se habrían evitado, o al menos detectado antes, con una verificación directa en lugar de asumir que la acción anterior había producido el efecto esperado.
Que corregir un defecto de raíz suele generar valor más allá del defecto mismo. La motivación original era resolver un problema de precisión temporal; el resultado incluyó también la recuperación de datos que se creían simplemente ausentes.
Nota metodológica
Este documento afirmaba, hasta septiembre de 2026, que la reconstrucción no alteraba ninguna conclusión de los dos análisis ya publicados, porque ambos caían sobre periodos donde la asignación por número de secuencia era correcta. Eso se midió después, cruzando el número de corrida contra la hora real que traen los datos crudos, y resultó cierto para uno de los dos y falso para el otro.
El cierre de espacio aéreo del Golfo no está afectado. En su periodo (1 de enero – 5 de marzo de 2026) el número de corrida sí correspondía a la franja real: la corrida 1 acertó 64 de 64 veces, y las corridas 2, 3 y 4 acertaron 59 de 64 cada una. Los reintentos existían, pero eran ocasionales — 28 corridas extra en 64 días.
El Mundial 2026 sí está afectado, y gravemente. Su periodo coincide con la degradación por tiempo de espera del proceso de captura, cuando llegaba a haber doce corridas diarias en tríos por franja. Bajo el supuesto de "corrida 3 = franja 3", el acierto en esa ventana fue del 23%, contra el 45% de su ventana de comparación: dos periodos mal etiquetados, con patrones de error distintos, comparados entre sí. El hallazgo publicado no sobrevivió a la revisión — la separación perfecta entre sedes y controles desaparece al recalcular con la hora real. El detalle está en la auditoría del Mundial.
La lección de esa corrección es la misma que la de este documento, aplicada al propio documento: "verificado de forma independiente" es una afirmación que también hay que verificar. Aquí se dio por buena sin una tabla detrás, y la tabla decía otra cosa.
← Volver al índice