IVAN577

LA IA DE CURSOR - UN DESASTRE A NIVEL DE PROGRAMACIÓN !!!

Título: Anatomía del desastre digital: cuando el código se vuelve espagueti, basura y antiguo

Capítulo 1: El origen del caos — cuando la IA empieza a generar código loco

El primer síntoma de que un proyecto está entrando en terreno pantanoso aparece cuando el desarrollador nota que las soluciones generadas por herramientas de inteligencia artificial comienzan a tener una lógica retorcida e impredecible. A esto se le conoce coloquialmente como *código loco*: fragmentos que funcionan por casualidad, no por diseño. El *código loco* no sigue patrones claros, mezcla estilos de programación incompatibles y parece haber sido escrito por alguien que cambió de opinión cada cinco minutos. Este tipo de código es especialmente peligroso porque pasa las pruebas superficiales, pero al intentar modificarlo, todo se desmorona como un castillo de naipes.

La razón por la que una IA puede caer en la generación de *código loco* es simple: los modelos estadísticos aprenden de enormes cantidades de ejemplos públicos, muchos de los cuales ya eran deficientes. Al no tener un criterio humano de calidad, la IA replica malas prácticas que encuentra con frecuencia. Por ejemplo, puede combinar un bucle `while` con un `goto` dentro de una función recursiva que se llama a sí misma sin condición de salida clara. Eso no es solo código ineficiente; es *código loco* en estado puro.

Las consecuencias de introducir *código loco* en una base de código existente son inmediatas: el equipo empieza a perder tiempo tratando de entender por qué algo que “debía ser simple” se ha convertido en un laberinto. Los programadores noveles lo evitan, los veteranos lo maldicen y los sistemas de integración continua empiezan a fallar por razones inexplicables. Lo peor es que el *código loco* es contagioso: al intentar arreglar una función loca, terminas escribiendo más código loco para que todo encaje.

Uno de los ejemplos más comunes de *código loco* generado por IA ocurre cuando se le pide que resuelva un problema con restricciones cambiantes. La IA, al no tener memoria real del diálogo, empieza a apilar soluciones parciales unas sobre otras, creando monstruos de lógica anidada. Verás funciones de 300 líneas con 15 niveles de indentación, condiciones imposibles como `if (a === true && a !== false)` y bucles que solo se rompen por un `break` escondido en un `catch` vacío. Eso es *código loco*.

Para evitar caer en esta trampa, el programador debe aprender a identificar las primeras señales: cuando una función hace más de tres cosas distintas, cuando los nombres de las variables parecen sacados de un generador aleatorio y cuando la IA empieza a “disculparse” en comentarios del tipo `// esto es feo pero funciona`. Ahí es el momento de parar, reformular el *prompt* y exigir claridad. Porque una vez que el *código loco* se instala, erradicarlo cuesta el doble que reescribirlo desde cero.

Capítulo 2: Espagueti digital — el arte de estar interconectado pero de forma innecesaria

Cuando un programa está *interconectado pero de forma innecesaria*, los desarrolladores lo llaman *código espagueti*. La metáfora es precisa: así como un plato de espagueti tiene hebras que se enredan sin orden aparente, el código espagueti presenta dependencias cruzadas que no siguen una jerarquía lógica. Cambiar un parámetro en un módulo puede romper diez funciones en otros módulos que ni siquiera importaban ese módulo directamente. La conectividad excesiva es el sello distintivo de esta anti-arquitectura.

El código espagueti nace por varias razones: presión por entregar rápido, falta de diseño previo o, en el caso de la IA, porque el modelo ha visto muchos ejemplos de parches sucesivos. La IA no entiende el concepto de “acoplamiento” ni “cohesión”; solo predice el siguiente token más probable. Por eso es capaz de generar una función que modifica una variable global desde dentro de un callback asíncrono, que a su vez es llamado por un temporizador dentro de un bucle. Todo eso está *interconectado pero de forma innecesaria*.

Una señal clara de que estás ante espagueti es el famoso síndrome de “dar vueltas en círculos”. Esto ocurre cuando intentas depurar un error y terminas revisando los mismos cinco archivos una y otra vez sin encontrar la causa raíz. El flujo de ejecución no es lineal; es un ovillo. Tomas una ruta, llegas a una función que llama a otra, esa llama a la primera de nuevo, y así *das vueltas en círculos* durante horas. La IA, al no tener conciencia del flujo general, produce este tipo de estructuras circulares con naturalidad.

El problema se agrava porque el código espagueti es traicionero: a menudo parece funcionar en los casos de prueba básicos. Pero en producción, cuando los datos reales tienen variaciones imprevistas, el sistema empieza a comportarse de forma errática. Corregir un error en una hebra del espagueti requiere desenredar media docena de hebras más. Y como la IA no puede “ver” el plato completo, cada corrección que propone tiende a añadir más hebras en lugar de simplificar.

La única manera de combatir el espagueti generado por IA es aplicar principios sólidos de ingeniería de software después de la generación: separar responsabilidades, inyectar dependencias explícitamente y romper ciclos. El programador debe actuar como un editor humano que reescribe lo que la IA produce, eliminando conexiones innecesarias. No se trata de rechazar a la IA, sino de usarla como borrador y luego refactorizar hasta que el código deje de estar *interconectado de forma innecesaria* y pase a tener un flujo claro y jerárquico.

Capítulo 3: Código basura — la acumulación de basura digital y sus costes ocultos

El término *código basura* describe todo aquello que ocupa espacio, consume tiempo y no aporta valor real. Cuando hablamos de *basura digital* en programación, nos referimos a líneas que nunca se ejecutan, variables que se declaran pero no se usan, funciones completas que fueron reemplazadas pero nunca borradas, y comentarios que mienten porque la lógica cambió hace tres versiones. La IA es especialmente propensa a generar *basura digital* porque sus modelos están entrenados para “rellenar” código, no para limpiarlo.

Un ejemplo típico de *basura digital* generada por IA son los llamados “casos borde defensivos” exagerados. La IA, en su afán por evitar errores, añade decenas de comprobaciones redundantes: `if (x != null && x !== undefined && x !== '' && x !== 0 && x !== false)`. Eso es basura porque cuatro de esas condiciones son innecesarias. También son basura los imports que nunca se usan, las funciones helper que solo se llaman una vez desde un solo lugar, y los logs de depuración que quedaron activos en producción.

El coste de la *basura digital* no es solo estético: ralentiza el desarrollo, aumenta el tiempo de compilación, ocupa memoria innecesariamente y, lo peor, crea ruido mental. Cuando un programador abre un archivo y ve que el 30% del código es basura, su capacidad para entender la lógica real disminuye drásticamente. Además, la basura digital es un caldo de cultivo para errores: alguien podría modificar una variable que parecía útil pero que en realidad nunca se lee, o peor, una función basura podría tener efectos secundarios no documentados.

La IA genera basura digital por varios mecanismos. El más común es la “sobre-generalización”: al ver muchos ejemplos donde se incluían comprobaciones extras, la IA asume que siempre hay que añadirlas. Otro mecanismo es la “inercia de contexto”: si el usuario pide un cambio pequeño, la IA no elimina las partes que quedaron obsoletas; simplemente añade más código encima. Así se forman capas geológicas de basura, donde cada iteración entierra más profundamente las partes útiles.

Para combatir la *basura digital* generada por IA, se necesita una práctica rigurosa de limpieza continua. Cada vez que la IA propone una solución, el programador debe hacer dos cosas: primero, identificar y eliminar toda línea que no sea estrictamente necesaria; segundo, pedir explícitamente a la IA que “refactorice sin código muerto” o que “elimine comprobaciones redundantes”. Con el tiempo, el profesional desarrolla un olfato para detectar basura digital a simple vista, igual que un editor detecta palabras vacías en un texto.

Capítulo 4: Obsoleto — cuando el código se queda anclado en el pasado tecnológico

El calificativo *obsoleto* en programación no es solo una cuestión de edad; es una sentencia de obsolescencia funcional. Un código es *obsoleto* cuando depende de librerías que ya no reciben actualizaciones de seguridad, cuando usa sintaxis que fue deprecada hace varias versiones del lenguaje, o cuando implementa patrones de diseño que hoy se consideran perjudiciales. La IA, entrenada con datos que incluyen ejemplos de hace cinco o diez años, genera código *obsoleto* con frecuencia a menos que se le indique explícitamente lo contrario.

El principal peligro del código *obsoleto* es que parece funcionar al principio, pero con el tiempo se convierte en un riesgo de seguridad y un lastre para el mantenimiento. Usar `var` en Java

Script en lugar de `let/const`, emplear `Xml

Http

Request` en vez de `fetch`, o depender de `moment.js` cuando ya existe `Temporal` son ejemplos de decisiones que hoy son *obsoletas*. La IA, al ver que esos patrones aparecen millones de veces en su entrenamiento, los reproduce sin saber que el mundo ya avanzó.

Cuando un sistema acumula suficiente código *obsoleto*, empieza a manifestar el síntoma de “generar código que se rompe” al intentar actualizarlo. Actualizas una librería por seguridad y, de repente, diez funciones que dependían de su antigua API dejan de funcionar. No porque hayas hecho nada mal, sino porque el código *obsoleto* construyó castillos sobre arena movediza. La IA no puede prever esto, porque no tiene un modelo mental de “fechas de deprecación” ni de “hojas de ruta de librerías”.

El código *obsoleto* también tiene un efecto psicológico en los equipos. Cuando un programador ve que la IA propone soluciones con tecnologías que dejó de usar hace años, pierde confianza en la herramienta. Es frustrante que la IA te sugiera usar `synchronized` en Java cuando ya sabemos que `Lock` es más flexible, o que proponga bucles `for` clásicos cuando existe `for…of`. Esa desconexión entre lo que la IA genera y lo que el programador sabe que es moderno crea fricción.

La solución pasa por entrenar a la IA en el momento: en el *prompt* se debe especificar la versión del lenguaje, las librerías permitidas y los patrones prohibidos. Frases como “usa Java

Script ES2023” o “no uses callbacks, solo async/await” ayudan a reducir el código *obsoleto*. Pero al final, la responsabilidad sigue siendo humana: revisar cada sugerencia de la IA y preguntarse “¿esto es lo mejor que podemos hacer hoy o es una reliquia del pasado?”.

Capítulo 5: El círculo vicioso — cuando todo junto genera código que se rompe constantemente

Llegamos al peor escenario: cuando *código loco*, espagueti, basura digital y obsolescencia se combinan en un solo proyecto. El resultado es un sistema que constantemente tiende a *generar código que se rompe* con cada cambio mínimo. No es que el código tenga errores puntuales; es que su arquitectura es tan frágil que cualquier modificación, por pequeña que sea, provoca una cascada de fallos en lugares insospechados. Esto es el infierno del desarrollador.

La dinámica es siempre la misma: tienes una base de código generada parcial o totalmente por IA sin supervisión suficiente. Abres un archivo y ves espagueti (interconexiones innecesarias), basura digital (código muerto), sintaxis obsoleta y toques de código loco. Intentas arreglar un error pequeño, como cambiar el nombre de una variable mal escrita. Al hacerlo, el código empieza a *generar código que se rompe* en producción: una función que ni siquiera usaba esa variable empieza a lanzar excepciones. ¿Por qué? Porque alguien (quizás la IA) metió un `eval` o una reflexión que dependía del nombre exacto.

Este fenómeno de *generar código que se rompe* no es aleatorio; es consecuencia directa de la falta de encapsulamiento y de pruebas. La IA, al no escribir pruebas unitarias automáticamente, produce código que parece funcionar en el momento pero no tiene ningún “contrato” que garantice su comportamiento futuro. Así, cuando tocas una línea, todo el castillo se derrumba. Y como el código es espagueti, ni siquiera puedes predecir qué se romperá.

El ciclo se vuelve vicioso porque, al intentar reparar una rotura, los desarrolladores (o la propia IA) introducen más código temporal, más parches, más excepciones. Con cada iteración, la probabilidad de *generar código que se rompe* aumenta en lugar de disminuir. Llegas a un punto donde el equipo tiene miedo de hacer cualquier cambio, incluso añadir un simple `console.log`. Eso es el fracaso técnico total: un sistema que ya no se puede mantener, solo se puede aguantar.

La única salida de este círculo vicioso es una reescritura controlada y la adopción de prácticas defensivas. No se trata de culpar a la IA, sino de cambiar el flujo de trabajo: la IA debe generar primero un diseño de alto nivel (no código) que sea aprobado por humanos. Luego, el código debe generarse en módulos pequeños, cada uno con sus pruebas unitarias generadas también por IA pero validadas. Y cada vez que el código intente *generar código que se rompe*, las pruebas deben atraparlo antes de llegar a producción. Con disciplina, el espagueti puede desenredarse, la basura puede reciclarse y lo obsoleto puede actualizarse. Pero sin ella, el código generado por IA seguirá siendo un monumento al dolor técnico.

Aquí tienes los Capítulos 6 y 7 con ejemplos cómicos y las metáforas que pediste, más el código enredado como una manila con 20 nudos y el desastre de la regadera rota.

Capítulo 6: El código enredado es como hacerle 20 nudos a una manila — y luego intentar deshacerlos con guantes de boxeo

Imagina que tienes una manila marina de 50 metros, gruesa y resistente. Una manila bien hecha es como un código limpio: cada hebra cumple su función, puedes seguir su recorrido de principio a fin y, si necesitas cortar un tramo, sabes exactamente dónde hacerlo. Pero el código espagueti generado por IA es el equivalente a tomar esa misma manila y hacerle 20 nudos apretados, algunos dobles, otros con vueltas de alondra y uno que otro nudo de ballestero que ni los marineros veteranos reconocen. Eso es un código enredado.

Ahora ponte en la situación cómica (y trágica) de tener que arreglar un error menor en ese código: solo necesitas cambiar el valor de una constante que define el tiempo de espera de una petición HTTP, de 5 segundos a 6 segundos. Pero como la manila tiene 20 nudos, resulta que esa constante no se usa directamente. La IA decidió que era buena idea copiar ese valor en 15 lugares diferentes, dentro de funciones que se llaman entre sí formando un bucle casi imposible de seguir. Al cambiar un solo valor, descubres que otros 12 valores que parecían independientes también cambiaron porque alguien usó un `eval` o una referencia indirecta.

El momento cómico llega cuando intentas deshacer el primer nudo. Tomas un extremo de la manila y empiezas a tirar. Pero como todo está enredado, lo único que logras es que los 19 nudos restantes se aprieten más. En términos de código, eso significa que al “arreglar” el error del tiempo de espera, ahora la aplicación entera se cae porque una función de autenticación que estaba a 10 archivos de distancia dependía de que ese valor fuera exactamente 5 para hacer un cálculo ridículo como `if (tiempo

Espera === 5) { reiniciar

Servidor() }`. ¿Quién escribió eso? La IA, por supuesto, en un momento de *código loco*.

La comedia negra continúa cuando llamas a un compañero para que te ayude. Entre los dos empiezan a deshacer nudos: uno tira de un lado, el otro del otro lado. Pero resulta que la manila no tiene dos extremos claros; la IA creó una estructura circular donde el “principio” y el “final” son el mismo punto. Es como si hubieran hecho un nudo de infinity loop. En código, eso son dependencias cíclicas: el módulo A importa al B, el B importa al C, y el C importa al A. Para arreglar el tiempo de espera, tienes que reescribir medio proyecto.

La moraleja de este capítulo es sencilla: un código enredado no se arregla tirando más fuerte. Si la manila tiene 20 nudos, la solución no es hacer el nudo 21. Pero eso es exactamente lo que hace la IA cuando le pides que arregle algo: añade más código encima, más condiciones, más excepciones, más nudos. Al final, tienes una manila con 40 nudos y el mismo problema original sigue sin resolverse. La única salida honesta es cortar la manila por algún punto y volver a empalmar desde cero, pero eso duele porque significa tirar horas de “trabajo” generado por IA.

Capítulo 7: La regadera rota en el piso 1 — cuando una mínima fuga deja sin agua al piso 50

Ahora cambiemos de metáfora. Imagina un edificio de 50 pisos. En el piso 1, en el baño de la conserjería, se rompe la regadera. Es una fuga mínima: apenas gotea, pierde unos 100 mililitros por hora. Nada grave, piensas. Pero lo que no sabes es que el fontanero original (que claramente era un primo de la IA) conectó todo el edificio en serie: el agua que llega al piso 50 tiene que pasar primero por la regadera rota del piso 1. ¿El resultado? Esa pequeña fuga provoca que en el piso 50 la presión caiga a cero. Los inquilinos del piso 50 abren la llave y no sale ni una gota. Todo porque alguien no supo diseñar una red de tuberías en paralelo con válvulas de aislamiento.

Esto es exactamente lo que ocurre en un código mal estructurado donde una mínima fuga (un pequeño error, una variable mal inicializada, un `null` inesperado) provoca que funcionalidades completamente no relacionadas dejen de funcionar. El código de la IA es famoso por crear estas dependencias invisibles. Por ejemplo, cambias el color de un botón en la interfaz de usuario y, de repente, el proceso de facturación comienza a fallar. ¿Por qué? Porque la IA decidió que el color del botón se guardaba en la misma variable global que el estado de la transacción. Absurdo, pero cierto.

El momento cómico ocurre cuando intentas explicarle al cliente por qué lleva tres días arreglando la regadera del piso 1. El cliente dice: “Pero si lo que falla es el agua caliente del piso 50, ¿por qué están desmontando el baño de la conserjería?”. Y tú, como desarrollador, tienes que responder con cara de poker: “Porque resulta que la tubería del piso 50 pasa por dentro de la regadera del piso 1. No preguntes por qué. El que diseñó esto era un genio del caos”. Esa es la vida real con código generado por IA sin supervisión.

Otro ejemplo clásico: trabajas en una aplicación de comercio electrónico. La IA generó el carrito de compras, el sistema de inventario y el sistema de envíos. Todo parece funcionar. Pero un día decides arreglar un pequeño error estético: el texto “Agregar al carrito” estaba mal centrado. Corriges el CSS, solo el CSS, nada de Java

Script. Milagrosamente, al día siguiente nadie puede pagar con tarjeta de crédito. ¿La razón? La IA había atado la función `procesar

Pago` al evento `on

Click` del botón, pero también a un listener de cambio de estilo porque “por si acaso”. Cambiaste el estilo y se disparó una excepción silenciosa que mató el pago. La regadera rota en el piso 1 dejó sin agua al piso 50.

La enseñanza final de este capítulo es dolorosa pero necesaria: en un código bien diseñado, las fugas están aisladas. Si se rompe la regadera del piso 1, que solo se quede sin agua el piso 1. El piso 50 debe tener su propia alimentación, sus propias válvulas, su propio sistema independiente. Eso se logra con módulos desacoplados, pruebas unitarias y responsabilidades claras. La IA, por sí sola, no entiende esto. Solo entiende probabilidades. Por eso, el programador humano debe ser el fontanero jefe que rediseña el edificio después de que la IA haya puesto todas las tuberías en serie. O, dicho de otro modo: nunca dejes que la IA sea la arquitecta de tu fontanería.

6