Ingeniería14 min lectura

De Ticket a Código Testeado: Automatizando el Desarrollo Enterprise con AI Agents

Construimos un sistema donde un AI agent lee un ticket, planifica, implementa código en 6 capas, compila, testea con browser automation, y reporta resultados.

Santiago Valdovinos

Santiago Valdovinos

CEO & Co-founder·

De ticket a código testeado — automatización enterprise con AI agents / Agentify

De ticket a código testeado — automatización enterprise con AI agents / Agentify

Este artículo fue escrito en colaboración con Renzo Horacio Coronel.

TL;DR: Construimos un sistema donde un AI agent lee un ticket de Azure DevOps, planifica cambios en 6 capas de una app .NET legacy, implementa el código, compila, testea con browser automation, y reporta resultados al developer para revisión. La arquitectura separa el orquestador (agnóstico) de los skills (específicos al proyecto), lo que la hace reutilizable. Después de varias semanas de iteración: 21 planes generados, 12 suites de tests ejecutadas, y capacidad para correr hasta 99 workflows en paralelo.


El problema: desarrollar en un monolito enterprise es repetitivo

Si alguna vez trabajaste en una aplicación enterprise legacy, conocés la rutina. Un ticket nuevo llega al board. Lo leés. Creás un branch. Abrís el proyecto y empezás a rastrear cuáles capas necesitás tocar.

En nuestro caso, la aplicación es un sistema de gestión corporativa en .NET con más de 10 años de evolución. Cada feature nueva — por simple que parezca — implica tocar entre 5 y 6 capas:

Stored Procedure → Data Access → Business Logic → WebApp → API → Tests

Un campo nuevo en un formulario? Hay que crear o modificar el SP, actualizar el DataSet tipado, agregar la lógica en el DAO, exponer el campo en la capa de negocio, agregarlo al formulario WebForms, y eventualmente exponerlo en la API REST. Cada capa tiene sus convenciones, naming, patrones. Y todo tiene que compilar junto.

No es difícil. Es tedioso. Y es exactamente el tipo de trabajo que un AI agent debería poder hacer.


La pregunta que nos hicimos

¿Qué pasa si un AI agent pudiera ejecutar el workflow completo de un developer?

No hablamos de autocompletar una línea de código. Hablamos de que un agent, de forma autónoma, pueda:

  1. Leer un ticket del board de trabajo
  2. Crear un branch aislado
  3. Analizar qué capas se ven afectadas y planificar los cambios
  4. Implementar el código en cada capa siguiendo las convenciones del proyecto
  5. Compilar la aplicación y levantarla en un servidor local
  6. Testear generando test cases y ejecutándolos con browser automation
  7. Reportar los resultados al developer para revisión

Lo construimos. Lo llamamos Agentify. Y funciona.


La arquitectura: 4 componentes, 1 principio

El principio de diseño más importante que definimos fue separación estricta entre plumbing y domain logic:

1. Dispatcher (Python FastAPI) — ~1,836 líneas de código

El dispatcher es completamente agnóstico. No sabe que existe .NET, ni stored procedures, ni WebForms. Solo sabe de:

  • State machine: cada workflow tiene un estado (detected → running → testing → completed/failed/paused) con transiciones validadas
  • PID tracking: registra los procesos que cada workflow lanza (compilador, servidor web, browser) y los monitorea cada 30 segundos. Si todos los procesos mueren, marca el workflow como failed
  • Port pool: asigna puertos únicos (57001-57099) para que múltiples workflows corran en paralelo sin conflictos
  • PTY manager: spawna sesiones de Claude Code vía pseudo-terminal (pywinpty), inyecta prompts vía stdin, y bufferiza el output para streaming a la UI
  • Audit log: cada cambio de estado queda registrado con timestamp

El storage es SQLite. No necesita más.

2. Skills (Claude Code) — ~1,453 líneas de instrucciones

Los skills son documentos declarativos (Markdown) que definen el comportamiento del AI agent. No son código ejecutable — son instrucciones que Claude Code interpreta y ejecuta autónomamente.

Construimos 4 skills especializados:

  • agentify-workflow: El orquestador. Ejecuta los 6 pasos del workflow. Soporta dos modos: tickets de ADO y prompts custom (sin ticket real).
  • agentify-developer: El "senior developer virtual". Contiene los patrones, convenciones, templates, y naming conventions de cada capa del proyecto.
  • agentify-testing: El QA automatizado. Parsea test cases en Markdown, los ejecuta con browser automation, verifica datos con SQL, y reporta resultados.
  • worktree-runner: Abstrae el build y ejecución de la app. Delega a un script PowerShell self-contained (build-and-run.ps1) que maneja NuGet, MSBuild, IIS Express, y auto-repara problemas de compilación (.targets stubs faltantes).

3. Build Script (PowerShell) — 159 líneas

Script self-contained que se copia al worktree antes de ejecutar y se elimina después. Maneja todo el ciclo de build sin que el agent tenga que descubrir paths o lidiar con quoting entre bash y PowerShell:

build-and-run.ps1 -Action start   -Port 57001   # NuGet + MSBuild + IIS Express
build-and-run.ps1 -Action restart -Port 57001   # Kill + rebuild + relaunch
build-and-run.ps1 -Action stop                   # Kill IIS Express

4. Dashboard (HTML + xterm.js) — Monitoring en tiempo real

Una interfaz web que muestra:

  • Estado de cada workflow con badges de color
  • Barra de progreso de 5 pasos (Read, Branch, Plan, Implement, Test)
  • Terminal embebida con xterm.js que renderiza la sesión PTY del agent en tiempo real — ves exactamente lo que Claude está haciendo, carácter por carácter
  • Panel de logs con audit trail completo
  • Controles: pausar, resumir, completar, matar procesos individuales
┌──────────────────────────────────────────────────────────┐
│  Agentify - Workflow Monitor                             │
├─────────────────────┬────────────────────┬───────────────┤
│                     │                    │               │
│  Workflow Cards     │   Terminal         │   Logs        │
│  - State badge      │   (xterm.js)       │   (audit)     │
│  - Progress [████░░]│   Real-time agent  │               │
│  - Branch, port     │   output           │   Step 1: ✓   │
│  - PIDs [kill]      │                    │   Step 2: ✓   │
│  - Last action      │                    │   Step 3: →   │
│                     │                    │               │
└─────────────────────┴────────────────────┴───────────────┘

Cómo funciona en la práctica

El developer escribe una sola línea:

ejecuta workflow 581

O con un prompt custom (sin ticket real de ADO):

POST /api/workflows/create
{
  "ticket_id": 9999,
  "title": "Add dialog after login",
  "prompt": "Add a dialog that shows when the user logs in displaying Are you ok today"
}

Y esto es lo que pasa:

Paso 1 — Lectura del ticket: El agent lee el work item del board (Azure DevOps) vía CLI. Extrae título, descripción, criterios de aceptación, tipo (feature, bug, task). Evalúa si la descripción es clara o ambigua.

Paso 2 — Branch y worktree: Crea un branch con naming convention (user/581.descripcion.en.dots) y un git worktree aislado. Esto permite que el developer siga trabajando en main mientras el agent trabaja en su copia.

Paso 3 — Planificación: El agent analiza qué capas se ven afectadas. Identifica stored procedures a modificar (y hace backup antes de tocarlos), clases de Data Access, entidades de negocio, páginas web, endpoints de API. Genera un documento de plan formal en docs/plans/.

Paso 4 — Implementación: Siguiendo el plan y las convenciones del skill agentify-developer, implementa los cambios en cada capa. Respeta naming conventions (UsuarioDA, dsUsuario, oUsuario), usa los patrones de Enterprise Library Data Block, actualiza cache-busting en imports de JS/CSS.

Paso 4.1 — Build y Run: Copia el script build-and-run.ps1 al worktree y lo ejecuta. El script auto-repara .targets faltantes, hace NuGet restore, compila la solución completa, y levanta IIS Express en un puerto dedicado del pool (ej: localhost:57001). Si el agent hace cambios de código después, ejecuta restart para recompilar sin intervención manual.

Paso 5 — Testing: Genera test cases en formato Markdown estructurado (TC-581-*.md) con pasos, datos de prueba, queries SQL de verificación. Luego ejecuta cada test case usando browser-use (CLI de browser automation): navega páginas, llena formularios, hace clicks, toma screenshots, y verifica datos en la base de datos con sqlcmd.

Paso 6 — Reporte: Presenta un resumen al developer con resultados de tests (8/10 PASS, 2 FAIL), archivos modificados, y el estado del worktree. El developer revisa, hace commit y push manualmente. El agent nunca pushea código sin supervisión humana.


Decisiones de diseño que hicieron la diferencia

1. El dispatcher no sabe nada del dominio

Esta fue la decisión más importante. El dispatcher solo entiende de procesos, puertos y estados. Toda la lógica de "cómo se desarrolla en este proyecto" vive en los skills.

Resultado: el dispatcher es reutilizable para cualquier proyecto. Los skills son los que se adaptan.

2. Los skills son documentos, no código

Los skills son archivos Markdown con instrucciones declarativas. No tienen loops, no tienen condicionales, no importan librerías. Son como un manual de procedimientos que el AI agent interpreta.

Esto los hace extremadamente fáciles de iterar. Cuando una convención cambia o encontramos un edge case, editamos un párrafo en el skill. No hay CI/CD, no hay tests del skill, no hay deploys.

3. Graceful degradation

Los skills funcionan sin el dispatcher. Si el dispatcher no está corriendo, los callbacks fallan silenciosamente y el agent usa un puerto default. Esto fue crítico durante el desarrollo: podíamos testear los skills sin tener el dispatcher listo.

4. Developer-in-the-loop con Pause/Resume

Cuando el agent encuentra ambigüedad (ticket mal definido, decisión arquitectónica necesaria), pausa el workflow y le pregunta al developer. Guarda un checkpoint JSON con el estado exacto — cuando el developer responde, el workflow continúa desde ese punto preciso.

El agent nunca adivina decisiones de arquitectura. Siempre escala.

5. Zombie killer

Cada 30 segundos, un health monitor verifica que los procesos registrados sigan vivos. Si un proceso muere inesperadamente (crash del compilador, cierre del servidor), el sistema lo detecta y actualiza el estado. Si TODOS los procesos mueren, marca el workflow como failed.

Cuando el dispatcher arranca, lo primero que hace es matar todos los procesos huérfanos de sesiones anteriores. Cero zombies.

6. Terminal embebida = confianza

La terminal xterm.js embebida en el dashboard fue inicialmente un "nice to have". Resultó ser crítica para la adopción. Ver en tiempo real lo que el agent está haciendo — qué archivos lee, qué código escribe, qué comandos ejecuta — genera la confianza necesaria para dejarlo trabajar autónomamente.

7. Build script self-contained

Intentamos que el agent ejecutara NuGet, MSBuild e IIS Express paso a paso vía instrucciones en el skill. Fallaba constantemente: paths con espacios, quoting entre bash y PowerShell, variables que no persisten entre llamadas al Bash tool. La solución fue un script PowerShell self-contained que se copia al worktree, se ejecuta con un solo comando, y se elimina al final. El agent solo dice powershell -File build-and-run.ps1 -Action start -Port 57001. Cero ambigüedad.

8. Modo prompt-custom

Originalmente, todo workflow requería un ticket real en Azure DevOps. Agregamos un modo prompt-custom donde el dispatcher recibe una descripción directa en el payload de creación. El skill detecta si el prompt incluye "con la siguiente descripción:" y usa ese texto como fuente, salteando el fetch de ADO. Esto permite demos rápidos y tareas ad-hoc sin crear tickets.


Resultados

Después de varias semanas de iteración, estos son los números del sistema en producción:

Output del agent

  • 21 planes de implementación generados autónomamente a partir de tickets
  • 12 suites de tests generadas y ejecutadas con browser automation
  • Hasta 99 workflows en paralelo, cada uno con su worktree, puerto y proceso aislado

Cuánto código fue necesario para construirlo

El sistema completo tiene menos de 4,400 líneas. El dispatcher (Python) es el componente más grande con ~1,836 líneas, seguido por los 4 skills (~1,453 líneas de instrucciones en Markdown), el dashboard (~947 líneas de HTML/JS), y el build script (159 líneas de PowerShell). Fueron 13 commits desde el primer prototipo hasta producción.

Lo que funcionó bien

  • Separación dispatcher/skills: permitió iterar cada parte independientemente. Cambiar cómo el agent desarrolla no requiere tocar el orquestador, y viceversa.
  • Skills declarativos sobre código procedural: un párrafo nuevo en el skill cambia el comportamiento del agent sin builds ni deploys.
  • Port pool para paralelismo: cada workflow tiene su instancia aislada de la app. Cero conflictos.

Lo que fue más difícil de lo esperado

  • Build de .NET en worktrees: requirió junctions de Windows para packages/ y referencias/, .targets stubs faltantes, y pre-seed de bin/ desde el repo principal. La solución fue encapsular todo en un script PowerShell que se auto-repara.
  • Inyección de prompts vía PTY: detectar cuando Claude está "listo" para recibir input fue frágil — buscar caracteres específicos en el buffer no funcionaba. La solución fue un wait fijo de 8 segundos mínimo.
  • BASH_ENV rompía el PATH: la configuración de Claude Code dejaba al agent spawneado vía PTY sin acceso a curl, git, y otras herramientas básicas. Descubrir esto llevó horas de debugging.
  • Browser automation frágil: los índices de elementos cambian entre páginas, requiriendo state antes de cada interacción.
  • Skills genéricos no alcanzan: la primera versión del skill de developer era demasiado genérica; las versiones posteriores incluyen templates específicos por capa.

Lo que viene

La arquitectura ya soporta features que estamos construyendo:

  • Polling automático del board: El dispatcher detecta tickets nuevos asignados al developer y los presenta en el dashboard, listos para ejecutar con un click.
  • Notificaciones móviles: Alertas vía Telegram cuando un workflow completa o falla — el developer no necesita estar mirando el dashboard.
  • Workflows en paralelo reales: La infraestructura (port pool, worktrees aislados, PID tracking) ya está lista. El siguiente paso es un UI optimizado para monitorear múltiples agents trabajando simultáneamente.
  • Iteración autónoma: El agent ya puede recompilar con restart después de cambios de código. El siguiente paso es que detecte errores de compilación, los diagnostique, y haga fix + rebuild sin intervención humana.

Trade-offs y limitaciones

Este approach no es gratis. Algunas cosas que hay que tener en cuenta:

  • Setup inicial alto: Escribir los 4 skills con el nivel de detalle necesario llevó semanas de iteración. La primera versión del skill de developer era demasiado genérica y producía código que no compilaba. Cada capa del proyecto necesitó templates específicos.
  • Dependencia del modelo: La calidad del output depende directamente de las capacidades de Claude Code. Un cambio en el modelo puede romper comportamientos que funcionaban. No tenemos control sobre eso.
  • Browser automation frágil: Los tests con browser automation fallan más de lo esperado. Los índices de elementos cambian entre páginas, los tiempos de carga varían, y un popup inesperado rompe toda la suite.
  • Costo de compute: Cada workflow consume tokens de API. Un ticket complejo puede requerir múltiples iteraciones del agent, y el costo se acumula. Para tickets triviales, un developer experimentado puede ser más rápido y barato.
  • No reemplaza code review: El agent genera código funcional, pero no toma decisiones de arquitectura. Un developer senior todavía necesita revisar cada PR. Esto es una feature, no un bug — pero significa que el cuello de botella se mueve, no desaparece.

Reflexión final

No construimos Agentify para reemplazar developers. Lo construimos porque el 70% del trabajo de implementar una feature en un sistema enterprise es mecánico: seguir convenciones, tocar las mismas capas, compilar, verificar.

Un AI agent bien instruido puede hacer ese 70% de forma autónoma. El developer se queda con el 30% que realmente requiere criterio: revisar el plan, validar decisiones de arquitectura, aprobar el código final.

La clave no es que el agent sea "inteligente". La clave es que la orquestación sea sólida: state machine predecible, procesos trackeados, degradación elegante, y un developer que siempre puede intervenir.

Un developer + AI agents bien orquestados pueden producir más que un equipo grande sin automatización. No porque el agent sea mejor que un developer, sino porque libera al developer para hacer lo que mejor sabe hacer: pensar.



Stack técnico

Python (FastAPI), Claude Code (AI agent), pywinpty (PTY), xterm.js (terminal), SQLite, PowerShell (build script), browser-use (browser automation), Azure DevOps CLI.

Tiempo de desarrollo del sistema: ~4 semanas de iteración (dispatcher + 4 skills + dashboard + build script).


Lecturas relacionadas

Siguiente paso

¿Tu organización está evaluando cómo adoptar IA de manera práctica?

En Agentify ayudamos a empresas y gobiernos de Latinoamérica a implementar IA que realmente llega a producción. Hablemos.

Agendar Auditoría
Santiago Valdovinos

Sobre el autor

Santiago Valdovinos

CEO & Co-founder

Arranqué como developer, pasé por Project Management y terminé liderando operaciones comerciales en startups de San Francisco como Waterplan (YC) y Alto (adquirida por Revelo). Esa combinación — técnica + negocio — es lo que llevé a Agentify.