Sistema interno · resumen técnico

El orquestador

Un sistema que convierte issues de un repositorio en pull requests revisados por una persona, ejecutando cada tarea en un espacio aislado, con límites de concurrencia, turnos y presupuesto, y con la decisión de fusionar siempre en manos de un humano.

01Qué problema resuelve

Un agente de programación suelto es un becario con mucha confianza: escribe rápido, no sabe cuándo parar, y no tiene idea de lo que cuesta. El orquestador resuelve eso. No es "un bot que programa"; es una fábrica con estaciones, guardarraíles y contabilidad.

La tesis de diseño, copiada de la metodología Symphony y adaptada: gestionar trabajo, no agentes.

02El recorrido completo

Del issue al PR revisado issue claim + relectura workspace worktree runner agente validación del repo PR gate humano etiqueta + checks verdes merge orquestador (un tick cada 5 minutos) reconcilia antes de despachar ¿issue cerrado? ¿perdió la etiqueta? ¿se estancó? ¿excedió presupuesto? ¿murió el proceso? → código de salida
Siete estaciones y un bucle de reconciliación. El orquestador nunca escribe código: despacha, vigila y decide cuándo parar.
  1. Entrada. Un issue con campos obligatorios: contexto, cambio, criterios comprobables, pruebas y comando de validación. Si falta algo, no se crea.
  2. Despacho humano. Una persona pulsa "Despachar". La etiqueta es el interruptor de seguridad: sin ella, ningún agente toca el issue.
  3. Claim. El tick cambia la etiqueta y vuelve a leer por la API para verificar. No hay compare-and-swap en la API de issues, así que la ventana de carrera se mitiga, no se elimina.
  4. Workspace. Un git worktree por issue, con hooks de creación y preparación. El clon principal nunca se ensucia.
  5. Runner. El agente corre con timeout de 900 s, detección de estancamiento a los 300 s y máximo de 12 turnos.
  6. Validación. El agente ejecuta la comprobación del repositorio y abre un PR con prueba de trabajo.
  7. Reconciliación. El tick compara estado real y esperado: si el issue se cerró, perdió la etiqueta o el proceso murió, actúa. Si falla la escritura en el tracker, el resultado no se pierde: se reintenta.
  8. Gate humano. El merge exige etiqueta de aprobación y todos los checks verdes. Sin checks, no se fusiona.

03Arquitectura

PiezaImplementación
Lenguaje del orquestadorBash + Python
Planificadorsystemd timer, cada 5 min
Estadoficheros por issue + CSV append-only + SQLite derivado
Colaissues con etiqueta; la etiqueta es el lock
Concurrenciatope por repo y global; locks con flock
Notificaciónbot de Telegram con botones
Interfaz de agenteMCP con 13 herramientas
ObservabilidadGrafana sobre el SQLite derivado

No hay demonio. El tick arranca, hace su trabajo y termina. Eso hace cada ejecución idempotente y un crash no deja nada a medias. El precio es la latencia: hasta cinco minutos entre despachar y arrancar.

04Las decisiones que definen el sistema

DecisiónPor qué
Un worktree por issueDos agentes en el mismo checkout se pisan el índice de git
Reconciliar antes de despacharEl estado remoto es la verdad, no la memoria del orquestador
Claim con relecturaNo hay CAS en la API de issues; se mitiga la carrera en vez de ignorarla
Credenciales fuera del agenteEl token del tracker se elimina del entorno del runner; solo el orquestador habla con la API
Enrutar por verificabilidadSi el repo tiene tests y un comando único, un fallo se detecta; si no, el fallo es silencioso y merece un modelo más caro
Escalar solo si falló el modeloEscalar porque faltaba un .env es quemar dinero por un error de entorno
Presupuesto como ciudadano de primeraCuota del motor leída del log, saldo en vivo y horario punta: si el motor lo eligió un humano, espera; si era la ruta por defecto, reencamina

05El clasificador de fallos — la pieza más senior

Antes de decidir si subir de modelo, el sistema clasifica el fallo en modelo, infraestructura o infraestructura fija (un .env que falta, un workspace que no arranca, un timeout de red).

Clasificar antes de escalar fallo del run ¿el entorno estaba sano? infraestructura reintenta igual, luego para modelo sube un peldaño de la escalera infra-fija → no escala: avisa y pide intervención escalera: deepseek → … → opus
Reintentar sin clasificar es la forma más rápida de quemar presupuesto sin mejorar el resultado.
"El valor no está en que el agente escriba código. Está en que el sistema sepa cuándo no debe seguir."

06Números reales

MétricaValor
Ejecuciones259
Periodo1 – 23 de octubre
Completadas86
Fallidas100
Continuaciones38
Timeout18
Canceladas13
Coste total46,89 USD
Coste por ejecución0,32 USD
Duración media463 s
Tiempo total de agente33,3 h
Repos atendidos3

259 ejecuciones por 47 dólares y un operador. Ese es el titular.

07Qué quedó frágil

Dicho antes de que lo pregunten

08Cómo contarlo

En 60 segundos

"Construí un sistema que convierte el backlog de un repositorio en pull requests revisables por agentes, sin conducirlos. El humano decide qué se hace y qué se fusiona; el sistema reclama el issue, aísla el trabajo, elige el motor según coste y cuota, valida, abre el PR y avisa por Telegram con botones. En tres semanas: 259 ejecuciones por 47 dólares, un solo operador. Lo importante no es que sea autónomo: es que mide lo que cuesta y distingue cuándo falló el modelo de cuándo falló el entorno."

Si preguntan "¿y si empezaras de cero?"

La respuesta que demuestra seniority: no empezaría por el agente, sino por el registro de estado.

  1. Estado transaccional con compare-and-swap real, no etiquetas del tracker.
  2. Workers en contenedores efímeros: un worktree de git no es aislamiento de proceso.
  3. Gateway de modelos que resuelva motor, presupuesto y coste por tarea, fuera del prompt.
  4. Evaluaciones con casos conocidos antes de subir la concurrencia. Sin eso, la escalera optimiza coste, no calidad.

Lo que no cambiaría: el gate humano, la separación de credenciales y el clasificador de fallos.