Un ejemplo inventado, pero verosímil: se le pide a un agente que añada un campo a un módulo de facturación de hace quince años. El agente lee el código, ve que el redondeo se hace en un orden poco habitual, lo «arregla» de paso y deja los tests en verde. Tres semanas después, el informe que un cliente concilia cada mes con su contabilidad descuadra en unos céntimos por línea. El redondeo raro no era un error: era el comportamiento del que dependía ese cliente.
Nadie hizo nada mal, en apariencia. El agente encontró algo que parecía un fallo y lo corrigió. El problema es que nadie le había dicho qué comportamiento no podía cambiar, porque nadie lo había escrito nunca. En un sistema legacy, la documentación más fiable es el propio código, con sus casualidades incluidas. Y un agente que trabaja sin saber cuáles de esas casualidades son contrato es un riesgo, por bueno que sea el modelo.
Lo que la IA ya hace bien con el legacy
Conviene empezar por lo que funciona, porque funciona mucho. En noviembre de 2025, el Technology Radar de Thoughtworks colocó en «Adopt», su categoría más alta, el uso de IA generativa para entender código legacy: según su experiencia con varios clientes, ha pasado a ser «una opción práctica por defecto, no un experimento». Herramientas como Claude Code, Cursor o Copilot sacan a la luz reglas de negocio, resumen la lógica e identifican dependencias en sistemas que nadie del equipo actual escribió. Lo contamos con más detalle en GenAI para comprender código legacy.
El caso más citado es el de Morgan Stanley. Según publicó The Wall Street Journal en junio de 2025, recogido por Entrepreneur, la herramienta interna DevGen.AI había revisado nueve millones de líneas de código antiguo en cinco meses, con un ahorro estimado de 280.000 horas de desarrollo. Lo interesante es qué hace exactamente: traduce código en lenguajes antiguos a especificaciones en inglés llano, que los desarrolladores usan después como referencia para reescribirlo. No escribe el código nuevo; eso sigue siendo trabajo de personas.
Es decir, el valor no está en que la IA reescriba el sistema, sino en que produzca un texto que diga qué hace. Ese texto es el punto de partida correcto. Lo que hay que entender es qué tipo de texto es.
Una descripción no es una especificación
Cuando una IA lee código legacy y explica lo que hace, produce una descripción. Dice lo que el código hace, no lo que debería hacer. Incluye el redondeo raro, el campo que se rellena con ceros cuando viene vacío y el caso límite que se resuelve de forma inesperada porque en 2011 alguien tenía prisa. Una especificación es otra cosa: dice lo que el sistema debe hacer y alguien la firma.
La diferencia importa porque en un sistema con usuarios reales, buena parte de lo que parece un error es, en la práctica, un contrato. Lo formuló Hyrum Wright, y hoy se conoce como la ley de Hyrum: con suficientes usuarios de una API, da igual lo que prometa el contrato, alguien dependerá de cualquier comportamiento observable del sistema. Un sistema legacy lleva años acumulando usuarios de comportamientos que nadie prometió.
El propio Radar de Thoughtworks lo apunta en otra de sus entradas de noviembre de 2025, en la que propone usar descripciones generadas por IA como paso intermedio para reescribir sistemas: el objetivo no es ocultar los detalles de implementación, sino introducir «una abstracción temporal» que permita razonar sobre qué hace el sistema antes de decidir cómo rehacerlo. Temporal es la palabra clave. La descripción es una herramienta para pensar, no un requisito.
Dos documentos, no uno
De ahí sale la idea central de esta pieza. Antes de que un agente modifique un módulo heredado, hacen falta dos documentos distintos, con reglas distintas:
| Acta del comportamiento actual | Especificación del cambio | |
|---|---|---|
| Qué afirma | Lo que el código hace hoy, errores incluidos | Lo que va a ser distinto después del cambio, y nada más |
| Quién la produce | La IA lee el código; una persona revisa y marca lo sospechoso | Una persona, con quien conoce el negocio |
| Cómo se verifica | Con tests de caracterización que fijan cada comportamiento | Con tests nuevos que fallan antes del cambio y pasan después |
| Quién la firma | Nadie: es un acta, no un requisito | Quien responde del cambio |
| Qué puede hacer el agente | Nada que la contradiga, salvo lo que diga la especificación del cambio | Implementar exactamente eso |
| Cuánto vive | Mientras exista el módulo; se actualiza con cada cambio aprobado | Hasta que el cambio se integra; después pasa al acta |
Propuesta de onext. Los nombres son lo de menos; lo que importa es no mezclar los dos documentos
La regla que hace funcionar el par es simple: el agente sólo puede cambiar un comportamiento del acta si la especificación del cambio lo nombra. Todo lo demás se queda como está, aunque parezca un error. Si el agente encuentra algo sospechoso, lo apunta; no lo arregla. Arreglarlo es una decisión de negocio, y entra en la siguiente especificación del cambio con su firma y su test.
En el ejemplo del redondeo, el acta habría dicho «el importe se redondea por línea antes de sumar, no sobre el total», con un test que lo fija y una marca de «sospechoso, preguntar a finanzas». El agente habría añadido el campo sin tocar el redondeo. Y alguien habría preguntado, en lugar de enterarse por el cliente.
Es la misma lógica que defendemos para código nuevo en la especificación es donde se firma, con una diferencia: en legacy hay un documento previo que nadie firma, porque nadie lo decidió. Sólo se constata.
La red: tests de caracterización
Un acta en texto es una hipótesis. La IA puede haber entendido mal una rama, y el texto no lo va a decir. Lo que convierte el acta en algo fiable es fijar cada afirmación con un test que se ejecuta.
Para eso existe desde hace veinte años una técnica con nombre propio. Michael Feathers acuñó el término test de caracterización en 2004, en Working Effectively with Legacy Code: un test que describe el comportamiento real de un código existente para protegerlo de cambios no intencionados. No dice si el código es correcto; dice si ha cambiado. Cuando uno falla, alguien decide si el cambio era el buscado.
Aquí hay un giro que conviene señalar, porque contradice algo que hemos escrito. En tests generados por IA explicamos que un test escrito a partir del código no lo prueba: sólo lo describe, y por eso no detecta errores. En código nuevo es un problema. En legacy es justo lo que se busca. Un test de caracterización es, por definición, una descripción del código. Que la IA los genere deprisa y en cantidad es una ventaja real, con una condición: alguien revisa qué comportamientos se han fijado y marca los que son errores conocidos, para que dentro de un año nadie los lea como requisitos.
Especificar la costura, no el sistema
La objeción obvia es el coste. Especificar un sistema legacy entero antes de tocarlo es un proyecto de meses que se queda obsoleto antes de terminar. Y las herramientas de Spec-Driven Development no ayudan tanto como cabría esperar: en su análisis de Kiro, Spec Kit y Tessl de octubre de 2025, Birgitta Böckeler apuntó que introducir dos de ellas en un código existente parecía costar todavía más trabajo, y al probar Kiro con un error pequeño el flujo completo le pareció como usar un mazo para cascar una nuez.
La salida es la que usa la modernización gradual desde hace veinte años. Martin Fowler la llama strangler fig: en lugar de reescribir de golpe, se identifican costuras por las que dividir el sistema y se va moviendo funcionalidad poco a poco, de forma que la inversión y el retorno llegan también poco a poco. Aplicado a las especificaciones, significa especificar sólo la costura por la que entra el cambio: el módulo que se va a tocar, sus entradas y salidas, y los comportamientos que sus vecinos esperan de él. El acta crece al ritmo de los cambios, no antes.
En la práctica, el orden es este. Primero, la IA lee el módulo y redacta el acta. Segundo, se generan los tests de caracterización y una persona marca lo sospechoso. Tercero, se escribe la especificación del cambio, corta, nombrando cada comportamiento del acta que va a cambiar. Y sólo entonces actúa el agente, con la instrucción explícita de no cambiar nada más. El review del resultado ya no pregunta «¿esto está bien?», que en legacy casi nadie puede responder, sino «¿ha cambiado algo que no estuviera en la especificación?», que los tests contestan solos. Es la pregunta que propusimos en el review que sigue esperando a un autor.
Lo que se gana, además del cambio
Hay un efecto secundario que suele valer más que el propio cambio: después de unas cuantas iteraciones, el equipo tiene por primera vez un documento fiable de lo que hace el sistema, respaldado por tests que lo demuestran. Es lo que casi ningún sistema legacy tiene, y lo que hace posible todo lo demás, desde la siguiente modificación hasta una migración completa. Y es exactamente el tipo de artefacto que Spec-Driven Development pone en el centro: no el código, sino la descripción verificable de lo que debe hacer.
Lo que no se gana es velocidad en el primer cambio. El primero cuesta más que pedirle al agente que lo haga directamente. El segundo, en el mismo módulo, cuesta menos. Y el tercero es el que se puede delegar con tranquilidad, porque la red ya está ahí. Es también una buena forma de ver qué sabe hacer un desarrollador: quien encuentra un comportamiento raro y lo apunta en lugar de arreglarlo está demostrando el criterio que describimos en qué medir al contratar desarrolladores.
Preguntas frecuentes
¿Se puede aplicar Spec-Driven Development a un sistema legacy?
Sí, pero no empezando por especificar el sistema entero. Las herramientas de SDD se pensaron sobre todo para código nuevo, y Birgitta Böckeler, de Thoughtworks, apuntó en octubre de 2025 que introducir dos de las tres que analizó en un código existente parecía costar todavía más trabajo. Lo que funciona es especificar sólo la parte que se va a tocar, con dos documentos distintos: uno que describe lo que el código hace hoy y otro que dice qué va a cambiar.
¿Qué diferencia hay entre una descripción del código y una especificación?
Una descripción dice lo que el código hace, incluidos sus errores y sus casualidades. Una especificación dice lo que debe hacer, y alguien la firma. Cuando una IA analiza código legacy produce descripciones, y son muy útiles. El problema aparece cuando se tratan como especificaciones y un agente «corrige» un comportamiento que alguien en producción necesita tal como está.
¿Qué es un test de caracterización?
Es un test que fija el comportamiento real de un código existente, no el que debería tener. El término lo acuñó Michael Feathers en 2004, en «Working Effectively with Legacy Code». No sirve para saber si el código es correcto, sino para saber si ha cambiado: si un test de caracterización falla después de una modificación, alguien tiene que decidir si ese cambio era el buscado o un efecto secundario.
¿Puede la IA generar los tests de caracterización?
Sí, y es uno de los pocos casos en los que un test generado a partir del código es exactamente lo que se necesita. En código nuevo, un test escrito desde la implementación sólo la describe. En legacy, describir el comportamiento actual es el objetivo. La condición es que una persona revise qué comportamientos se han fijado y marque los que son errores conocidos, para que nadie los confunda con requisitos.
¿Qué hago con los bugs que encuentra la IA al analizar el código legacy?
Apuntarlos, no arreglarlos en la misma pasada. Un comportamiento extraño puede ser un error o algo de lo que depende un cliente, un informe o una integración que nadie recuerda. Se fija con un test de caracterización marcado como sospechoso, se pregunta a quien conoce el negocio y, si se decide corregirlo, entra en la especificación del cambio como una modificación explícita, firmada y con su propio test.
¿Cuánto del sistema hay que especificar antes de empezar?
Lo mínimo para el cambio que se va a hacer: el módulo o la costura por la que entra la modificación, sus entradas y salidas y los comportamientos que no pueden cambiar. Especificar un sistema legacy entero antes de tocarlo es un proyecto de meses que se queda obsoleto antes de acabar. Se especifica por trozos, al ritmo de los cambios, como en una migración gradual.
Fuentes
- Thoughtworks Technology Radar (noviembre de 2025), «Using GenAI to understand legacy codebases» (Adopt) y «GenAI for forward engineering» (Assess).
- Birgitta Böckeler, «Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl», martinfowler.com, 15 de octubre de 2025.
- Entrepreneur, sobre DevGen.AI de Morgan Stanley, 3 de junio de 2025, a partir de la información de The Wall Street Journal.
- Hyrum Wright, Hyrum's Law.
- Michael Feathers, Working Effectively with Legacy Code (Prentice Hall, 2004); definición de test de caracterización.
- Martin Fowler, «Strangler Fig», martinfowler.com, 22 de agosto de 2024.

Jordi García es Tech Lead en onext. Trabaja en llevar la IA a producción gobernada en equipos de desarrollo y de producto —con Spec-Driven Development, ingeniería de contexto y verificación humana en cada paso— y firma los insights técnicos de onext sobre método, calidad y coste de la IA aplicada.
LinkedIn →