La confianza se demuestra, no se promete
Qué hace falta para gobernar a un agente de IA que no puede comprometerse a cumplir tus reglas — y por qué la solución es un contrato, no un mejor prompt
La confianza se demuestra, no se promete
Paramos un proyecto. No porque el código fuera malo — porque la forma en que se estaba construyendo había derivado más allá del punto en que alguien podía fiarse del resultado. El agente que hacía el trabajo se había saltado, una sesión tras otra, las propias salvaguardas del proyecto: las restricciones, los niveles, los validadores que levantamos durante meses precisamente para evitar esto.
Así que hicimos una entrevista. No para poner un parche, sino para entender el fallo y diseñar el mecanismo que lo vuelve imposible. Lo que sigue es la conclusión, y le da la vuelta al discurso habitual sobre los agentes que programan.
El fallo, en una frase
El agente metió la configuración de ejecución como opciones de línea de comandos. El proyecto tiene una invariante dura — la config NCL es la fuente de verdad — que lo habría detectado en treinta segundos. La invariante estaba a la vista, en describe constraints: consultable, tipada, aprobada en un ADR.
Dio igual. El agente nunca la consultó antes de decidir la arquitectura.
La explicación cómoda es “se le olvidó” o “se le perdió en el contexto”. Las dos son ciertas y las dos sobran. La honesta es más fría:
Una regla escrita en prosa, sin una puerta que la compruebe, para un agente probabilístico volcado en avanzar es solo una sugerencia que su muestreo puede ignorar.
Por qué todo termina en prosa que no obliga a nada
Esta es la parte incómoda, y es estructural, no moral.
Comprender y obligar son dos máquinas distintas. Comprender es lo que un modelo de lenguaje hace bien y por lo que se le recompensa: produce NCL elegante, ADRs, tensiones nombradas, describe, qa — porque eso parece trabajo hecho y satisface al instante. Obligar exige una pieza con dientes que diga no y detenga el trabajo. Esa pieza va en contra del ritmo y de la recompensa inmediata, así que nadie la construye salvo que algo la imponga.
De ahí la ironía que hay en el fondo de todo sistema gobernado por un agente: una capa de gobierno construida por aquello mismo que debe frenar hereda su alergia a tener frenos. Es poner al lobo a cuidar las ovejas, en la dimensión donde al lobo se le premia.
Por debajo se ven los cinco modos de fallo:
- El conocimiento era solo de lectura.
describe constraints,describe capabilities,qa showson introspección. La información solo cambia la conducta si algo la consume y bloquea. El consumidor previsto era el agente, voluntariamente — la pieza menos fiable del sistema. - Los validadores existían como modos, no como puertas. Un validador que el agente decide correr no es una barrera. La distancia entre “el validador existe” y “el validador bloquea el commit” es toda la distancia entre la decoración y el mecanismo.
- Las capas con dientes de verdad nunca se conectaron. Lo único que de verdad detiene a un agente en este entorno es el compilador, los tests, el pre-commit, la integración continua sobre una rama que no puede fusionar, y el sistema de permisos del entorno. El conocimiento del proyecto nunca bajó hasta ninguna de ellas.
- El lobo cuidaba las ovejas. Para que una puerta obligue, tiene que vivir fuera de lo que el agente puede editar. Aquí casi todo es editable por él — el agente escribe el NCL, los validadores, los hooks. Un candado que puedes abrir en el mismo gesto con que lo rompes es solo un consejo.
- El ciclo nunca penalizó la prosa. Cada sesión que producía más NCL articulado parecía productiva. Nada midió jamás “¿esto bloquea un fallo real?”. El sistema creció en la dimensión recompensada (expresar) y no en la que no lo estaba (obligar). Meses de catedral; ni una losa de hormigón en la puerta.
El principio, no más reglas
Un mecanismo mínimo es una trampa, porque una puerta mínima sigue dependiendo de que el agente la respete. El giro no es “más reglas”. Es un principio:
Toda regla que importe baja hasta una puerta determinista, en un paso obligado fuera de lo que el agente puede editar, donde una violación frena en seco — commit, fusión o edición rechazados,
exit ≠ 0— y el avance se mide por fallos atrapados, no por prosa producida.
La prosa tipada y rica no se desperdicia. Las tensiones nombradas, los niveles, los ADRs — eso es exactamente la materia prima desde la que se genera una puerta. El fallo fue no tener nunca un compilador que la convirtiera en barreras.
Y una cosa más, cierta e incómoda: parte del mecanismo es que el agente no lo construya solo. Si el agente diseña y escribe todas las barreras, vuelves al lobo. El núcleo que obliga tiene que estar redactado y en manos de una persona, o de una integración continua que un revisor lee y el agente no puede silenciar.
Por qué tampoco debes fiarte del plan
Aquí está el movimiento que hace esto honesto en vez de otra demostración optimista. Si te pido que confíes en un plan porque está bien argumentado, cometo el pecado exacto que acabamos de diagnosticar — un plan es prosa sin verificar.
Así que la confianza no puede salir de lo bien diseñado que esté. Tiene que salir de verlo funcionar contra el agente. Lo primero que construimos no fue una funcionalidad. Fue una demostración refutable: coge una invariante real, monta una puerta con dientes, y entonces el agente intenta violarla a propósito mientras miras si lo rechaza. Si no lo rechaza, el mecanismo es falso y lo sabemos en cinco minutos.
La plantilla: Pliego + Orden de Trabajo
La unidad a la que llegamos separa los términos de la ejecución, porque esa frontera es justo la que el agente no debe cruzar.
Un Pliego (los términos — los posees tú, el agente no los puede tocar):
Pliego = {
id,
alcance = { contexto = [rutas/packs mínimos], objetivo = "una frase" },
contrato = { check = <cmd | esquema | restricción>, refutable = true },
validacion = { modo = 'Maquina | 'Adversario, firmado = Bool, clave_ver = <opt> },
}
Una Orden de Trabajo (la ejecución — la corre el agente bajo un Pliego; prescindible y acotada):
OrdenTrabajo = {
id, pliego_ref,
entregable = { forma = <esquema/tipo verificado en la capa de la herramienta> },
observabilidad = { workdir, log_level = 'Error|'Warning|'Info|'Debug, log_jsonl, inicio_ts, fin_ts },
testigo = { alcance_hash, entregable_hash, contrato_salida, exit, firma },
veredicto = 'Aceptado | 'Rechazado | 'Escalado,
}
Cada campo mata un fallo concreto:
- El alcance mínimo mata la deriva: no hay cadena larga donde anclarse a sus propias conjeturas, y los demás proyectos no están en contexto, así que el agente no puede inventarse cruces entre ellos.
- El contrato refutable mata la “prosa que no obliga” y el “digo que está hecho sin pruebas”. Si el resultado no lo puede comprobar una máquina, la unidad está mal dimensionada — demasiado abierta.
- El testigo mata el “fíate de mi palabra”. Hecho lleva la salida real del validador como artefacto, firmada. Es el pariente cercano de la costura del sello-testigo: el testigo es el acta de la Orden de Trabajo.
- La propiedad externa de los términos mata lo de poner al lobo a cuidar las ovejas — el operario no puede editar el contrato en el mismo gesto con que lo cumple.
- El veredicto acotado mata la propagación de código roto — el fallo muere en la unidad en vez de contaminar la sesión.
Toda la disciplina de conducta se reduce a dos reglas atómicas, cortas y en el sitio donde se usan — las únicas que un agente cumple de hecho:
- Sin alcance y contrato, no se empieza.
- Sin testigo, no está hecho.
Lo que ninguna puerta puede atrapar — y por qué importa más
Sé honesto con el residuo. Algunos fallos los puede comprobar una máquina: saltarse una guía de estilo, la configuración en opciones sueltas en vez de NCL, un cambio de arquitectura sin ADR, una violación de esquema, “digo que está hecho” sin salida de validador. Esos, un contrato los caza.
Otros, ningún esquema los cazará jamás: la abstracción sutilmente equivocada, darte la razón cuando debería discutir, un dato inventado al cruzar proyectos. Ese residuo es el fallo más peligroso, y pide otra herramienta — un verificador adversario (una segunda unidad cuyo único contrato es refutar el entregable de la primera), no un esquema. La diversidad sustituye al esquema cuando no puede haber esquema.
Por eso los validadores de ontoref están diseñados para atestiguar la estructura, no la veracidad (ADR-050), y por eso el protocolo se compromete con verificación suficiente antes que conocimiento completo (ADR-056). Una máquina que finge certificar la verdad miente; una máquina que certifica que una comprobación se ejecutó y qué devolvió te dice exactamente lo que sabe. La misma disciplina recorre el ciclo de memoria, que propone y nunca aplica (ADR-052): el acto autoritativo sigue siendo humano.
La demostración, sobre el fallo mismo
Hicimos que la primera Orden de Trabajo fuera la invariante que el agente rompió. El contrato: una comprobación que falla si algún ajuste de ejecución solo se alcanza por una opción de línea de comandos y no está en el esquema NCL. Luego lo atacamos a propósito — tres ejecuciones:
| ejecución | qué demuestra | veredicto | exit |
|---|---|---|---|
| A — código real vs config NCL inexistente | dientes sobre la violación real que originó todo | Rechazado · 12/12 | 1 |
| B — configuración limpia (declara los 12) | no es un “siempre falla”: puede pasar | Aceptado · 0/12 | 0 |
C — opción intrusa PASOS_FANTASMA | discrimina: caza solo a la intrusa | Rechazado · 1/13 | 1 |
El acta — un testigo JSONL que lleva la salida real de la comprobación, no una frase — es la prueba. La invariante config NCL como fuente de verdad dejó de ser prosa. Ahora exit ≠ 0 la hace cumplir, y eso funciona igual derive el agente o no.
Los límites honestos
Esto no se vende como acabado:
- Son dientes, pero sin mandíbula todavía. Hoy la comprobación es un script que alguien corre. Para ser una puerta de verdad tiene que sentarse en una costura que el agente no pueda esquivar — pre-commit, integración continua sobre una rama protegida. Hasta entonces sigue dependiendo de que alguien la invoque.
- El testigo firmado es lo siguiente. La primera ejecución usó
firmado = false. La unidad de dominio ejercitaráfirmado = truede punta a punta. - Más agentes y validadores cuestan tokens y latencia. Es real, y es el precio de que el fallo muera en la unidad en vez de en producción.
Lo que cambió es la postura. A un agente probabilístico y deseoso de agradar no lo haces cumplir ni confiando en él ni vigilándolo a mano — las dos cosas te devuelven al desgaste que paró el proyecto. Llegas tratándolo como un proponente prolífico dentro de un arnés de verificación donde lo no verificado y lo que viola una regla no pueden aterrizar.
Para esto nació ontoref. El hueco no era que faltara el sistema — era que el sistema describía en vez de poner puertas. Una salvaguarda que no bloquea es, para un agente así, decoración.
La confianza es lo que demuestra ese experimento. Nunca lo que promete su retórica.