Forma antes que acción
Zod exige el schema versionado. Un campo extra o un tipo incorrecto devuelve feedback acotado al rol. Hasta tres retries, con backoff.
schema → validate → repairResearcher, Coder y Reviewer resuelven una tarea. El orquestador en Go decide qué puede ejecutarse; TypeScript + Zod verifica los contratos. Una persona aprueba el código y Docker lo ejecuta con límites y sin acceso a red.
Sigue los números del recorrido. Cada pieza explica qué hace, dónde vive y qué control evita que una propuesta del modelo se convierta directamente en una acción.
Controles transversales. El guard se aplica en todos los intercambios entre roles. Cada llamada de modelo pasa por el ledger USD. SQLite registra checkpoints durante todo el recorrido; el paso 8 representa esa evidencia acumulada.
El flujo real empieza en la terminal de tu Mac, con bin/lab start --agents y la configuración del modelo, las tarifas y Docker. Slack recibe las propuestas para que las apruebes; esta web solo explica y simula el recorrido.
Escribes la tarea: «Calcula la suma de los números del 1 al 10».
Revisas el código propuesto. Slack aún no tiene un comando para crear tareas.
Python corre en Colima, sin red. El ejemplo devuelve 55.
En móvil, desliza el diagrama horizontalmente para ver los participantes.
La petición real empieza en la terminal de tu Mac. La web es explicativa y Slack todavía no recibe tareas nuevas.
Ejemplo ilustrativo del flujo completo. Las llamadas al proveedor LLM salen del Mac; el código Python se ejecuta localmente en Docker. Go persiste checkpoints y controla el presupuesto durante el recorrido. TS/Zod y el guard validan los intercambios, incluido el veredicto final. No se inicia una ejecución real al recorrer este diagrama.
Prueba el recorrido con una tarea pequeña. Esta simulación vive en tu navegador: no llama a modelos, no envía mensajes y no ejecuta Python.
print(sum(range(1, 11)))print(sum(range(1, 11)))Approve permite continuar este ejemplo; Reject lo cancela. Estos botones solo cambian la simulación.
En el flujo real, Slack muestra la propuesta y su hash. Go vincula tu decisión a la operación, los argumentos exactos y su caducidad.
La prueba humana real de Slack usó print(55), con roles stub y cero llamadas pagadas. El smoke LLM de la suma fue otra prueba y utilizó aprobación automatizada. No son la misma corrida.
Los controles se aplican fuera del modelo. Una respuesta convincente no sustituye una validación, una reserva de presupuesto o una aprobación.
Zod exige el schema versionado. Un campo extra o un tipo incorrecto devuelve feedback acotado al rol. Hasta tres retries, con backoff.
schema → validate → repairLa decisión vincula actor, canal, operación, hash, schema y caducidad. Si cambia el código, hace falta una aprobación nueva.
hash + actor + expiryDocker sin red, usuario no root, raíz de solo lectura, capabilities vacías y recursos limitados. Nunca usa el host como alternativa.
128 MiB · 0,5 CPU · 32 PIDsUn efecto sin resultado confirmado exige reconciliación. Un request de modelo con uso desconocido retiene su reserva y detiene el run.
uncertain ≠ retryEl guard usa heurísticas: no detecta toda prompt injection. El sandbox confía en el kernel, el daemon y la imagen. SQLite no convierte cualquier efecto externo en exactly-once. Las pruebas muestran comportamientos concretos, no una garantía general de seguridad.
| PRUEBA | RESULTADO | QUÉ DEMUESTRA | EVIDENCIA |
|---|---|---|---|
| Aprobación humana en SlackTransporte real + Docker real | PASS 1 decisión · 1 ejecución | Callback firmado, salida 55, exit 0, cleanup confirmado y aviso de resultado entregado. | Abrir JSON ↗ |
| Researcher → Coder → ReviewerProveedor LLM real · DeepSeek Flash | PASS 464 microUSD | Roles reales, salida 55 y revisión aprobada. Aprobación de tool automatizada y sintética. | Abrir JSON ↗ |
| Trayectorias goldModelo HTTP determinístico + Docker real | 12 / 12 | Seis casos con dos repeticiones; verificadores de costo, permisos y evidencia. CI remoto pendiente. | Abrir JSON ↗ |
| Trazas OTLPCollector HTTP local real | 120 spans 23 spans de modelo | Hops correlacionados y metadata permitida. Incluye llamadas con uso incierto; sin prompts ni credenciales. | Recepción local |
| input-guard-proxyPaquete TS extraído con procedencia | 41 tests | Encuadre aleatorio, límites de entrada y cuarentena de patrones adversarios cubiertos por las pruebas. | Pruebas del paquete |
Telegram cuenta con adaptador y pruebas de callbacks sintéticos; falta su prueba humana real. Langfuse cloud, CI en GitHub, protección de PR, publicación del repositorio y los tres artículos siguen pendientes. OTLP y eval-gate sí tienen evidencia local.
Go concentra estados, permisos, presupuesto y ejecución. TypeScript conserva la validación con Zod y el guard reutilizable detrás de una API versionada.
GoTypeScriptZodSQLiteSe eligió Go para el plano de control. El costo de esa elección es mantener contratos entre dos procesos y tratar la indisponibilidad del validador como un bloqueo.
La implementación actual usa una máquina de estados propia. LangGraph se consideró como alternativa; no es una dependencia del runtime elegido.
La tool Python requiere un daemon y una imagen fijados. Si Docker no está disponible, la ejecución falla cerrada y no cambia de entorno.
Antes del request se reserva un máximo conservador. Después se liquida con el uso reportado. El umbral blando alerta y el duro bloquea nuevas reservas; el kill externo cancela llamadas en vuelo.
Contabilidad conservadora con tokens reportados. No es una factura ni una estimación del costo de cualquier tarea.
La reserva del ejemplo es ilustrativa. El cálculo real depende del prompt, el tope de salida y las tarifas configuradas.
Respuesta de modelo guardada: se recupera sin volver a pagar. Resultado de tool persistido: se recupera sin volver a ejecutarla. Envío de aviso incierto: se conserva para reconciliación, sin reenviarlo automáticamente.