anexo de la demo de Impacto · software
El mismo mapa, dos preguntas, respuestas opuestas
La demo de Impacto pregunta qué ficheros tocará un arreglo que todavía no existe. Este anexo pregunta otra cosa que suena parecida y no lo es: quién se rompe si cambio una pieza compartida hoy.
Medimos las dos, con el mismo mapa de dependencias. Y salieron respuestas opuestas: para saber quién se rompe, el mapa gana de calle. Para predecir qué tocará el arreglo, no aporta nada. Las dos mediciones están aquí, con sus números y sus límites.
de dónde sale esto
Esta página no estaba planeada. El 7 de agosto de 2026, Francisco Borja Escalona abrió un debate en LinkedIn sobre cómo hacer que la inteligencia artificial entienda el código de una empresa, y se juntaron ahí varias personas que llevan tiempo peleándose con el problema. Nos faltaba un número para opinar, así que fuimos a medirlo. Gracias a él por abrir la conversación, y a quienes discutieron en ella: buena parte de los límites que aparecen más abajo salen de objeciones suyas. Ninguno avala lo que hay en esta página.
La pregunta, sin tecnicismos
Un programa grande tiene piezas que usan muchas otras partes. Cambiar una de esas piezas es como cambiar una tubería en un edificio: antes de tocarla conviene saber a qué pisos llega el agua. A esa lista de sitios afectados la llamamos el radio de explosión.
Hay dos maneras de averiguarlo. La primera, y la que usa casi todo el mundo, es buscar el nombre de la pieza por todo el texto del programa, como quien busca una palabra en un documento. La segunda es preguntarle a un mapa de dependencias: un plano, hecho por una máquina, de qué parte llama a qué parte.
Suele darse por hecho que la segunda es más fiable y que la primera es el apaño. Fuimos a comprobarlo aplicando las dos al mismo código.
Por qué esto le cuesta dinero a una empresa
Cuando alguien cambia una pieza compartida y no ve una parte del programa que dependía de ella, no pasa nada ese día. Pasa dos semanas después, en producción, en una parte del sistema que nadie relacionaba con aquel cambio. Es la clase de avería que se paga cara justamente porque nadie la vio venir.
Y ahora ese cálculo lo hace cada vez más una máquina. Un asistente de programación que calcula mal el alcance de un cambio puede escribir código que compila, pasa las pruebas y rompe una parte que nadie estaba mirando. La pregunta de qué se rompe deja de ser una comprobación manual y pasa a ser el dato que hay que darle a la máquina antes de dejarla trabajar.
De ahí el interés de saber cuál de las dos lentes se equivoca, cuánto, y en qué dirección.
Lo que salió
Cuatro repositorios, seis piezas de cada uno, elegidas por ser las más usadas y no a dedo. Las reglas se fijaron por escrito antes de mirar ningún resultado. Se comparan tres formas de buscar por texto contra el mapa de dependencias.
| Aplicación | Por el nombre | Solo quien lo importa | Mapa | Solo lo ve el mapa | Solo lo ve el texto |
|---|---|---|---|---|---|
| Aplicación A | 241 | 198 | 293 | 106 | 11 |
| Aplicación B | 605 | 357 | 333 | 205 | 229 |
| Aplicación C | 703 | 521 | 474 | 97 | 144 |
| Aplicación D (la mayor) | 1.430 | 668 | 2.018 | 1.578 | 228 |
| Total | 2.979 | 1.744 | 3.118 | 1.986 | 612 |
Seis piezas por aplicación, 24 en total. De las 2.979 apariciones que encuentra buscar el nombre, 1.378 son ruido: comentarios o texto donde la palabra sale por otra razón.
- Afinar la búsqueda por texto quita ruido y no cierra el hueco. Al exigir que el fichero importe la pieza y no solo la nombre, el recuento baja de 2.979 a 1.744: 1.235 sitios que parecían afectados no lo estaban. Son más que las 1.378 menciones que la tabla marca como ruido, porque el ruido solo recoge las que están en comentarios o dentro de un texto; el resto son usos del nombre que no son una dependencia. Y aun así, los que solo ve el mapa siguen siendo 1.986: afinar la búsqueda reduce los falsos positivos, pero no recupera lo que se deja fuera.
- El mapa también se deja 612 casos. Ocurre sobre todo cuando una pieza se vuelve a ofrecer desde otro fichero, o se llega a ella por un camino indirecto. Por eso la conclusión no es cambiar de lente: es que hacen falta las dos.
- Los dos casos extremos. En uno, el mapa encuentra 365 sitios afectados y buscar el nombre encuentra uno. En otro, el mapa encuentra 561 y la búsqueda encuentra dos. Son los ejemplos más concluyentes porque no hay nada que clasificar: o importas la pieza o no.
En qué coinciden y qué se deja cada uno
Si una de las dos lentes bastara, una de las bandas de los extremos no existiría. Existen las dos, en las cuatro aplicaciones.
Las barras están a la misma escala entre aplicaciones, así que también se ve el tamaño relativo: el programa más grande no solo tiene más piezas, tiene la banda ámbar más ancha en proporción. Cuanto mayor es el código, más se pierde quien busca por texto.
Por qué falla la búsqueda por texto
No es que busque mal. Es que las piezas viajan acompañadas. Un fichero exporta varias cosas, y quien usa cualquiera de ellas se rompe igual cuando tocas el fichero, aunque no mencione nunca el nombre que estás buscando. Esos son la mayoría de los 1.986 que solo ve el mapa, y por definición no hay búsqueda de texto que los encuentre.
El segundo motivo es el nombre. Una pieza llamada user aparece
por todas partes por razones que no tienen nada que ver: en nuestro caso, 759 apariciones de
las que 737 eran ruido. Con nombres así, el censo por texto no es impreciso. Es inservible.
El fallo que descubrimos midiéndonos a nosotros mismos
La primera vez que ejecutamos esto, la aplicación más grande daba 827 apariciones de una pieza. Al repetirlo sobre una copia limpia, daban 417. La mitad eran el mismo fichero contado varias veces: el directorio de trabajo tenía dentro copias del propio repositorio, 3.770 ficheros duplicados que nadie había puesto ahí para engañar a nadie.
El mapa de dependencias, en las dos pasadas, dio 427. Exactamente lo mismo.
Esto no es una curiosidad de nuestra máquina. Le pasa a cualquiera que tenga copias de trabajo, librerías de terceros en el árbol o carpetas de compilación con fuentes dentro. Y lo peligroso es que no deja rastro: no falla, no avisa. Simplemente devuelve un número más grande, que es justo lo que uno espera de un censo.
El caso de los 365, dibujado
Una sola pieza de la aplicación mayor. Cada punto es un fichero que dejaría de funcionar si se cambia, coloreado por la capa a la que pertenece. El punto ámbar es el único que encuentra buscar el nombre por el código. Los otros 364 no mencionan esa pieza en ninguna parte, y se rompen igual.
El reparto por capas dice algo que el número solo no dice: el radio no está concentrado en un rincón. Hay 162 servicios, 100 pruebas, 37 utilidades, 23 procesos de fondo y 9 rutas de entrada. Atraviesa la aplicación entera.
La otra pregunta: aquí el mapa no sirve
Con lo de arriba en la mano, lo natural era pensar que el mapa mejoraría también las predicciones de la demo de Impacto. Fuimos a comprobarlo sobre los mismos quince años de historia pública de pandas que usa aquella, con su mismo examen y sus mismos parámetros congelados.
El sistema de Impacto puntúa con dos señales: el texto del fallo reportado y la memoria de qué ficheros cambian juntos. Añadimos una tercera, la estructura: quién importa a quién, leída del código tal y como estaba en cada fecha de corte, para no darle al sistema información del futuro.
El peso de la señal nueva se eligió mirando solo los años de calibración, nunca los del examen. Y esa calibración eligió sola no usarla: el peso ganador fue cero.
forzando la señal en los años del examen (1.125 casos)
| Acierto a la 1ª | En 3 | En 5 | |
|---|---|---|---|
| Sistema de Impacto | 0,276 | 0,483 | 0,581 |
| Con la estructura añadida | 0,254 | 0,473 | 0,572 |
Peor en las tres medidas, y peor en los cuatro años por separado. No es ruido.
Tiene sentido cuando se piensa: la memoria de qué cambia junto ya recoge las dependencias que importan en la práctica, y además recoge las que no están escritas en el código, como dos ficheros que siempre se tocan a la vez aunque ninguno mencione al otro.
De paso, esta prueba sirvió para volver a correr el experimento original desde cero, con un mes más de datos: dio 0,276 frente al 0,277 publicado en julio. Reproduce.
Y ese es el resultado que nos interesaba: el mismo mapa que encuentra 365 sitios donde buscar el nombre encuentra 1, no aporta nada cuando la pregunta es qué tocará un arreglo futuro. Sirve para el presente estructural, no para el futuro probable. Es una distinción que casi nadie hace, y decidir mal cuál de las dos preguntas tienes delante es lo que hace que una herramienta buena parezca inútil, o al revés.
Por qué el grafo lo construimos nosotros
Para esta prueba hacía falta un mapa de dependencias de pandas congelado en cada fecha de corte. Lo primero que probamos fue graphify, la herramienta de la que hablaba el hilo que originó todo esto y que tiene más de cien mil estrellas. Antes de construir nada encima, medimos cuánto veía.
Sobre pandas congelado a 1 de enero de 2021, con 1.227 ficheros de Python: el analizador que trae el propio lenguaje encuentra 1.088 ficheros con dependencias internas, y la herramienta ve 569. Se deja unos 530, la mitad.
Si hubiéramos construido la señal sobre esa extracción, el experimento habría medido los huecos de una herramienta en Python en lugar del valor del mapa, y la conclusión habría sido falsa sin que se notara. Así que el grafo lo construimos con el analizador del propio lenguaje: exacto, sin depender de nada y reproducible por cualquiera.
Dos avisos que nos debemos a nosotros mismos: la ejecutamos en su modo local, y la propia herramienta avisa de que sin una clave de API no hace extracción semántica; y podría estar atribuyendo dependencias a módulos en vez de a ficheros, con lo que nuestra cuenta la subestimaría. No hemos descartado ninguna de las dos, así que esto no es un veredicto sobre la herramienta: es el motivo por el que aquí no la usamos.
Los peros
- Una pieza por módulo, la primera que encuentra el guion. No es necesariamente la más representativa.
- Solo se mide el alcance visible en el código escrito. Lo que se decide mientras el programa corre no lo ve ninguna de las dos lentes, y es una limitación real.
- 24 módulos de cuatro aplicaciones nuestras. Es una medición, no una evaluación: sirve para mostrar un efecto y su tamaño, no para dar una tasa general.
- El código es privado, así que estas cifras exactas no las puede reproducir nadie de fuera. Por eso publicamos el guion: lo reproducible es el método, sobre el código de quien lo ejecute.
- La tabla anterior de esta misma medición, con 17 módulos, no es comparable con esta: cambiaron el instrumento y la muestra a la vez.
pruébalo en tu código
No hace falta que te creas nuestros números. Este es el guion que hizo la medición, tal cual: censo.py. Se ejecuta sobre cualquier repositorio con su grafo de dependencias y te dice cuántos sitios se te escapan a ti. Lleva dentro el protocolo de clasificación, escrito antes de mirar los resultados, para que puedas discutirlo. Si te sale distinto, nos interesa.
Hecho con Python. El mapa de dependencias lo genera graphify, un proyecto abierto que extrae símbolos y relaciones en local. Las reglas de clasificación se fijaron por escrito antes de mirar los resultados. Ningún modelo de lenguaje interviene en la medición.
Sobre esta demo
Medición interna sobre código propio, publicada con su método y sus límites. No evalúa herramientas de terceros ni afirma que una sustituya a la otra: la conclusión es la contraria, que hacen falta las dos. Las cifras corresponden a la medición del 8 de agosto de 2026 y no se recalculan solas.