Qué pasa cuando una metodología de desarrollo asistido por IA se aplica completa —de la idea al merge— sobre un sistema legacy en producción. Sin recortes, con los números reales: tiempo, tokens, hallazgos, y lo que salió mal.
«Quiero comprimir los bytes que se envían al servidor, porque el vínculo es 4G y se paga por MByte.»
Cliente Java 8 corriendo en Raspberry Pi dentro de locales comerciales, que recolecta datos de impresoras fiscales y los sube a un servidor central. Código legacy de 2019 en adelante, sin una sola prueba automática, 12 modos de operación distintos, y un servidor separado que persiste los datos para un tercer proceso río abajo.
Son datos fiscales. Si el cliente borra su copia local creyendo que el envío salió bien, y el servidor guardó basura, ese dato no existe más en ningún lado. No hay "lo reprocesamos mañana".
| Salida (lo que el modelo escribió) | 1,04 M |
| Entrada nueva + escritura de caché | 9,27 M |
| Lecturas de caché | 177 M |
| Entrada bruta total | 186 M |
El 95% del volumen de entrada son lecturas de caché —el contexto se relee en cada turno pero se cobra a fracción del precio—. La cifra que refleja trabajo real del modelo es el 1,04 M de salida.
| Orquestador principal | 443 k salida |
| Subagentes (20) | 486 k salida |
| Tramos puntuales (modelo cambiado a mano) | 110 k salida |
Casi la mitad del trabajo lo hicieron subagentes: contextos frescos y aislados, que es justamente lo que da valor a las revisiones adversariales.
Método: el tiempo activo se calculó sumando los intervalos entre mensajes menores a 5 minutos; los 10,5 h restantes son pausas del humano (la más larga, 6,2 h). Tokens y tiempos salen del transcript de la sesión, no de una estimación.
| Rol | Modelo | Salida |
|---|---|---|
| Orquestador · fases 1 a 6 | claude-fable-5 | 443.601 |
| 20 subagentes | claude-sonnet-5 | 486.111 |
| Tramos finales (tablero, documentos) | sonnet-5 · opus-4-8 | 110.330 |
| Total salida | 1.040.042 |
El orquestador mantiene el hilo y las decisiones; los subagentes hacen el trabajo pesado en contextos frescos. Casi la mitad de los tokens de salida se produjo fuera del hilo principal.
| Fase | Tier | Effort |
|---|---|---|
| idea | human | none |
| discovery | deep | high |
| spec | deep | high |
| adr | deep | high |
| build | standard | medium |
| qa | checker · no correlacionado | high |
| verify | standard | medium |
| prod | human | none |
| Exploradores de código (solo lectura) | 3 |
| Constructores y verificadores | 11 |
| Jueces adversariales ciegos | 4 |
| Agentes de arreglo quirúrgico | 2 |
El registro de la sesión no guarda una etiqueta de esfuerzo por turno. Lo que ves arriba es lo que la metodología declara para cada fase y el entorno aplica: alto para descubrir, decidir y auditar; medio para construir y verificar. Es configuración real y auditable, no una medición del consumo.
Marcar la diferencia entre "lo declarado" y "lo medido" es la misma disciplina que atraviesa toda la metodología.
Cada fase tiene una salida concreta, y ninguna arranca hasta que la anterior cerró. Lo que sigue pasó en este orden, con estas herramientas.
Las herramientas son comandos: /uscha-reverse-discovery, /uscha-characterize, /uscha-adr-refine, /uscha-devloop, más /uscha-rubric y /uscha-mirador para calidad no testeable y tablero de estado.
Los tiempos son minutos desde el primer mensaje, tomados del registro de la sesión. Las flechas doradas son las dos compuertas que el agente no puede cruzar; la roja, el hallazgo que frenó el avance hasta corregirse. Entre la fase 5 y la 6 pasaron además dos verificaciones extremo a extremo que el diagrama omite por espacio.
La regla de la fase: el sistema ya existe, así que su comportamiento es la verdad. El agente mapea lo verificable y tiene prohibido escribir un "spec" de lo que cree que el sistema hace.
Antes de tocar una línea, se corre el sistema original con datos reales y se captura byte por byte lo que hace. Eso queda como verdad de campo contra la que se compara todo lo que venga después.
5 casos: 2 archivos de producción reales (48 KB y 25 KB) y 3 casos borde (vacío, 1 byte, binario 0–255), enviados por el ejecutable viejo sin modificar.
Longitud, MD5 y SHA-256 de cada captura contra el archivo origen. Coincidencia exacta en los 5.
El agente emite archivos .received y para. Renombrarlos a .approved lo hace la persona. Un hook del sistema bloquea al agente si lo intenta.
No es una convención de buena voluntad: es un bloqueo mecánico. Se disparó de verdad durante la sesión cuando el agente intentó agregar una regla de .gitattributes mencionando esa ruta.
La fase de decisiones no arranca escribiendo documentos: arranca haciendo preguntas de a una, y se niega a emitir artefactos hasta que los huecos estén cerrados.
La propuesta inicial era elegante: el servidor no se toca, y el proceso río abajo descomprime. La entrevista destapó el agujero — durante la transición, un terminal que se actualiza a mitad del día deja el archivo diario mezclado: mitad plano, mitad comprimido. Ilegible para ambos lados.
Resultado: la descompresión se movió al servidor. Más código tocado, pero convivencia de versiones sin fecha de corte ni coordinación.
Cada criterio de aceptación se convirtió en una prueba que primero falló. El registro de la sesión conserva la evidencia del rojo: por ejemplo, el criterio que exige rechazar un archivo comprimido corrupto devolvía "OK" antes de implementar la validación.
El nombre de la prueba lleva el identificador del criterio. Eso permite que la herramienta de medición diga después "7 de 7 criterios cerrados por prueba verde" en lugar de contar checkboxes tildados a mano.
Cada vuelta pasa por revisión de código, dos jueces independientes que no ven los hallazgos del otro, y una pasada final de calidad. Se corrige solo lo que supera el umbral de gravedad; el resto se documenta.
| Herramienta | Hallazgos | Sobre umbral | Corregidos | Diferidos |
|---|---|---|---|---|
| code-review | 8 | 1 | 2 | 6 |
| judgment-day (2 jueces ciegos) | 9 | 4 | 6 | 3 |
| improve | 1 | 1 | 1 | 0 |
| Total | 18 | 6 | 9 | 9 |
Un juez detectó que los archivos temporales del servidor se nombraban solo por terminal. Dos conexiones simultáneas del mismo terminal —escenario real, porque el cliente reintenta a los 5 segundos y el servidor tiene 25 hilos— podían pisarse los datos y responder "OK" igual. Pérdida de dato fiscal silenciosa.
Prueba del hallazgo: al revertir el arreglo, la prueba de concurrencia falla exactamente como el juez predijo.
Un patrón de Java donde el constructor de un flujo comprimido hace entrada/salida: si falla, el archivo subyacente queda abierto. Apareció en el servidor, en la descompresión del cliente y —lo encontró la última pasada— en la compresión del cliente. Las tres veces se probó en rojo antes de arreglar.
10/10 idéntico. El ejecutable viejo contra el arnés de captura reproduce exactamente lo aprobado: el camino sin comprimir quedó intacto.
5/5 por SHA-256. Cliente nuevo contra servidor nuevo: el archivo persistido es idéntico al original en los cinco casos del corpus.
Verificado. El ejecutable viejo contra el servidor nuevo sigue funcionando — la actualización puede hacerse en cualquier orden.
La herramienta calcula si el estado permite abrir un PR a partir de hechos registrados —convergencia, pruebas verdes, cero bloqueantes abiertos— y no de una declaración del agente. Después de abrir los PRs, se detiene.
Sacá cualquiera de los tres y la metodología se vuelve teatro: mucho proceso, misma confianza que antes.
Todo lo que la metodología afirma tiene que salir de un artefacto verificable. Si el agente dice "listo" pero no hay una prueba verde que lo respalde, el sistema lo marca como narrado y no lo cuenta.
Eso apareció de verdad en esta sesión: los 7 criterios estaban tildados y el índice igual marcaba 0% medido, porque los reportes de prueba no estaban donde la herramienta los busca. Dos criterios —configuración y compatibilidad de versión de Java— ni siquiera tenían prueba: se escribieron ahí, y recién entonces el número subió a 100%.
Es la definición de "cómo se comportaba el sistema antes". Si el agente la escribe, está certificando su propia lectura del código viejo — exactamente el error que el golden existe para atrapar.
La entrevista propone y muestra los costos de cada opción, pero la elección queda registrada como decisión de una persona, con su fundamento escrito.
El agente abre el PR con la evidencia reunida. Integrar a la rama principal es el acto que no delega.
En esta sesión el humano además rechazó una propuesta del agente —eliminar los 6 campos de telemetría que nadie lee— porque conocía un valor de diagnóstico futuro que el código no muestra. Esa decisión negativa quedó escrita como ADR, con su razón, para que dentro de un año nadie la "arregle" por ignorancia.
Durante el ensayo manual, el envío falló: el servidor no podía crear un archivo porque el identificador del terminal no estaba configurado y llegaba como ?, carácter ilegal en Windows. El cliente reintentó y conservó el dato. El invariante de no perder datos fiscales funcionando en vivo, sobre un error de configuración que nadie había previsto.
La metodología bloquea solo en gravedad alta o superior. Todo lo demás va a un archivo de deuda visible, versionado junto al código. Sin esa regla, el ciclo de revisión no termina nunca.
1 bloqueante de concurrencia · 1 crítico de escritura parcial · 3 fugas de recursos · 1 cobertura ausente del código que protege el invariante fiscal · 1 tope contra bombas de descompresión · 2 arreglos de infraestructura de pruebas.
Consumo de memoria sin tope en el camino sin comprimir (riesgo bajo con archivos de 48 KB) · un caso compuesto teórico empíricamente inalcanzable · huérfanos preexistentes de archivos temporales · cuatro observaciones menores de registro y pruebas.
Dos vueltas completas hicieron falta para converger: en la segunda, las tres herramientas reportaron cero hallazgos sobre el umbral en ambos repositorios. El indicador de "salió bien a la primera" quedó en 0% — y así está registrado, sin maquillaje.
Ninguna demo es útil si esconde los tropiezos. Estos son los de esta sesión, todos registrados en el propio ledger.
| Qué pasó | Cómo se resolvió |
|---|---|
| La versión de Java del sistema rompía una biblioteca nativa del proyecto | Se detectó al primer intento de ejecución y se fijó la JDK correcta por ruta absoluta en todos los scripts |
| Una de las herramientas de medición se colgó con un error de rutas en Windows | Quedó registrada como NO EJECUTADA, no como "limpia" — el ledger distingue una cosa de la otra |
| Un comando mal escrito del agente vació el archivo de criterios de aceptación | Se detectó al leerlo de nuevo y se reconstruyó completo en el mismo turno |
| El archivo de criterios no tenía el formato exacto que el validador espera | El validador lo rechazó explícitamente; se reformateó sin tocar el contenido acordado |
| Dos paneles del tablero de estado aparecen vacíos | Es correcto: el motor no calcula esas métricas todavía y prefiere el vacío antes que un número inventado |
La metodología no es un prompt largo: es una secuencia de compuertas donde cada una produce algo verificable, y donde el humano conserva las tres decisiones que importan.
Si el sistema ya existe, mapealo y capturá su comportamiento actual antes de decidir nada. Ese golden es lo que después te deja refactorizar sin miedo.
Que cada criterio tenga una prueba con su identificador en el nombre. "Está listo" no es un estado; "hay una prueba verde que lo demuestra" sí.
Definí qué gravedad bloquea y qué se documenta. Sin ese corte, la revisión adversarial no converge: encuentra cosas para siempre.