Aprender AI-DLC creando un juego, parte 12: guardas y hooks
Esta es la parte 12 de una serie sobre aprender AI-DLC creando un juego, World Rift Conflict, en Godot con un backend en AWS. La parte 1 lo configuró, y la parte 11 repasó la primera ejecución completa. Esta es un análisis a fondo: las guardas, la parte de AI-DLC que puede decir que no.
Partes hasta ahora:
- Parte 1: configuración
- Parte 2: prueba de concepto
- Parte 3: pruebas E2E automatizadas
- Parte 4: lo que hallaron las revisiones
- Parte 5: dentro de una etapa
- Parte 6: un bugfix
- Parte 7: ideación
- Parte 8: incepción
- Parte 9: un error de AppSync
- Parte 10: esqueleto funcional
- Parte 11: retrospectiva
- Parte 12: guardas y hooks (este artículo)
TL;DR
- AI-DLC funciona como hooks de Claude Code: 16, en 8 eventos. La mayoría solo registra. Uno revisa cada llamada a una herramienta contra las guardas.
- Hay dos tipos de guardas. Cuatro son vallas que la Guard Policy puede bajar. Dos siguen activas diga lo que diga la política: la comprobación de presencia humana en las aprobaciones y la comprobación de integridad de los registros de AI-DLC.
- Todo el trabajo de este proyecto corrió con Guard Policy
off, el valor por defecto de cada scope que usé. Las vallas se apartaron 984 veces, y la auditoría tiene una fila por cada una. - Los rechazos que sí sufrí vinieron de lo que sigue activo: ocho en mi diario de construcción. La comprobación de integridad lee palabras, así que rechazó un comentario de GitHub que decía "audit".
- Ningún agente esquivó un rechazo. Dos veces el propio mensaje de rechazo indicaba la salida.
Hooks: donde corre AI-DLC
AI-DLC no tiene un proceso propio. Es un conjunto de hooks de Claude Code, comandos que Claude Code ejecuta en momentos fijos. En el .claude/settings.json de este proyecto hay 16, en 8 eventos:
| Evento | Qué hace AI-DLC ahí |
|---|---|
| Antes de usar una herramienta | revisa las guardas, entrega las reglas de la etapa a un agente ayudante, suma el uso |
| Después de usar una herramienta | escribe la fila de auditoría, lanza los sensores, sincroniza el estado, reconstruye el grafo de etapas |
| Cuando envío un mensaje | registra que un humano tomó un turno |
| Inicio y fin de sesión | carga dónde está el trabajo; cierra el registro de la sesión |
| Antes de compactar | revisa el archivo de estado y deja una nota de recuperación |
| Cuando un agente ayudante termina | registra el agente |
| Cuando termina un turno | mantiene el flujo en marcha hasta que el motor dice que acabó |
La mayoría solo observa. En las seis piezas de trabajo de este proyecto, la auditoría tiene 2.035 filas de artefactos escritos, 419 disparos de sensores y 675 turnos humanos. Las guardas son los hooks que pueden detener algo, y corren antes de la llamada, así que una acción rechazada nunca ocurre.
Dos tipos de no
El primer tipo son las vallas. Cada una impone una regla de orden que las instrucciones de la etapa también dicen con palabras. El código del hook explica por qué se añadió cada una: la prosa perdió. Un comentario dice: "a conductor generated the code first and backfilled the plan".
| Valla | Qué detiene |
|---|---|
| Aprobación del plan | código escrito antes de que yo apruebe el plan en Code Generation |
| Congelación tras la revisión | cambios a un documento revisado después del recibo de revisión, que anularían la revisión |
| Alcance de lectura del revisor | un revisor de una unidad que lee archivos de otras unidades |
| Transición de estado | un agente ayudante que ejecuta los comandos de ciclo de vida y de ruta del flujo |
El segundo tipo sigue activo. La comprobación de presencia humana rechaza una aprobación si no envié un mensaje desde que se mostró la pregunta. Para eso son los 675 turnos humanos: un agente no puede aprobar su propia puerta. La comprobación de integridad protege los registros de AI-DLC: la auditoría, el registro de aprobación del plan, los hooks y el runtime. Su código lo dice claro: "no Guard Policy word, lowered fence, or presence bypass turns it off."
Guard Policy off: 984 veces apartadas
Cada scope fija una Guard Policy por defecto. poc, bugfix, mvp y classic, los cuatro scopes que usó este proyecto, dicen guard_policy: off, y nunca lo cambié. El archivo del scope mvp explica qué significa: "plan approval, review freeze, state transition, and reviewer read scope are lowered for undirected work. Human presence stays up."
Una valla bajada no se calla. Cuando su regla encuentra una acción que habría detenido, se aparta: la acción sigue, la persona recibe una línea y la auditoría una fila GUARD_STOOD_ASIDE. La tabla de decisión del motor lo dice así: "Never 'are you sure': the switch is already off."
Contadas en la auditoría de las seis piezas de trabajo:
| Valla | Se apartó |
|---|---|
| Aprobación del plan | 709 |
| Congelación tras la revisión | 165 |
| Alcance de lectura del revisor | 108 |
| Transición de estado | 2 |
| Total | 984 |
- 778 fueron en Code Generation. El resto, en las etapas de diseño, donde aplican la congelación y el alcance del revisor.
- 640 fueron acciones de agentes ayudantes, sobre todo el agente desarrollador editando código y los revisores leyendo. Esas líneas fueron a la sesión principal, no a mí, así que vi muy pocas.
- Solo la ejecución
mvptuvo 712.
No revisé las 984 filas una por una, así que no puedo decir cuántas eran inofensivas. Lo que sí puedo decir es qué significan. Con la política en off, las vallas se volvieron un registro, no un freno. Si quiero que una valla detenga, lo pido, para una pieza de trabajo o para el proyecto. Por ejemplo, "turn the review freeze check back on".
Lo que aún dijo que no
No encontré en la auditoría ninguna fila de rechazo, así que esta lista sale de mi diario de construcción y puede estar incompleta. Cada uno vino de una comprobación que sigue activa, o de una valla cuya regla no tenía nada que apartar porque aún no existía ninguna aprobación.
- Borrar
.claudetras la instalación (2026-10-25). "AIDLC runtime records and hooks belong to the harness … use the official updater or an external terminal." - El borrador de la parte 1 (2026-10-26). Se rechazó la escritura del archivo entero. El texto describía los hooks y registros de AI-DLC, la coincidencia probable, pero no se identificó la regla exacta. El borrador de la parte 2, escrito cuando ese flujo había terminado, pasó.
- Dos comandos de shell que decían "audit" (2026-10-27): un comentario en un issue de GitHub y un añadido al diario, ambos en un heredoc. "The audit trail under
aidlc/spaces/<space>/intents/<intent>/audit/is written only by the framework's own tools…" Ninguno tocaba la auditoría. - Un revisor que no pudo correr las pruebas (2026-10-28). Un hook bloqueó su shell tras el primer comando, "because the recovery question is open". El mensaje actual para este caso dice: "Code changes wait while AI-DLC's recovery question is open."
- Leer código antes de que existiera el plan (2026-10-30). En Code Generation, hasta que se escribió el archivo del plan, se rechazaban incluso
catygrep: "Code generation cannot run mutation-capable shell commands for unit u2-accounts-profile because … code-generation-plan.md is missing or empty". La guarda no distingue un comando inofensivo de uno que escribe, así que los rechaza todos. La herramienta de archivos seguía funcionando. - Una aprobación borrada (2026-10-31). El agente reescribió entero el archivo de preguntas y se llevó con él la sección Plan Approval del motor. Después se rechazó cada comando de shell: "code-generation-questions.md has no Plan Approval section". El mensaje indicaba la vuelta: imprimir la misma huella de aprobación, reescribir la sección y volver a hacerme la pregunta del plan. La aprobé de nuevo.
- Un log con nombre de auditoría (2026-11-05). El agente no pudo correr el script pre-push porque un log nuevo se llamaba
pre-push-check-audit.log. Ese mismo día se rechazó la descripción de un PR pasada en un heredoc, porque decía "audits". - Tres cambios a
scripts/pre-push.sh(2026-11-06). Rechazados con el mensaje de registros del harness. No se identificó la regla que coincidió. El agente me preguntó, y yo hice el cambio a mano.
Una comprobación que lee palabras
Los números 3 y 7 tienen la misma causa, y quizá también el 8: scripts/pre-push.sh menciona "audit" tres veces, aunque su rechazo mostró otro mensaje. La comprobación de integridad lee el texto del comando, no lo que el comando hará. Para ella, un comentario de GitHub sobre una auditoría parece una escritura en la auditoría.
El propio código lo dice:
Defense in depth for harness-owned runtime records and hooks, not a sandbox. Hooks and tool calls run as the same user, so an agent with unrestricted execution can always find a path around a lexical check. The outer boundary is the harness's permission model and the person's review of what the agent runs.
Así que la comprobación es un cable de alarma, no un muro, y salta con texto inocente. El arreglo siempre fue simple: escribir el texto en un archivo y pasar el archivo, como en gh pr create --body-file, o usar la herramienta de edición en vez de un heredoc. Lo que más importó es que ningún agente buscó un rodeo. En el número 8, el agente se detuvo y me preguntó, que es para lo que sirve un cable de alarma.
Lo que me diría a mí mismo
- Conoce tu Guard Policy. Viene del scope. Con
off, las cuatro vallas solo registran. Eso encajó en un proyecto en solitario donde leo cada puerta. Un proyecto en equipo quizá quierastrict. - Los rechazos útiles traían el remedio. El mensaje de la guarda del plan nombraba los comandos exactos para recuperar la aprobación. Un rechazo que dice qué hacer cuesta minutos. Los que solo dicen que no cuestan una búsqueda.
- Deja la palabra "audit" fuera de los comandos de shell. Pon el texto largo en un archivo. Ese solo hábito habría evitado dos de los ocho rechazos.
- Lee la auditoría, no tu memoria. Yo habría calculado unas docenas de veces apartadas, no 984.
Qué sigue
El trabajo de interfaz de la parte 11 sigue en marcha: hay seis unidades construidas, entre ellas un diseño que cabe en la ventana, un mapa del mundo, banderas y un panel nuevo de propuestas, pero nada está publicado todavía. El próximo artículo de hito llega cuando cierre ese trabajo. Hasta entonces, más análisis como este, a partir de los mismos registros.