Phase 14 - Lesson 38
Compuertas de Verificación
El agente no define su propio trabajo como completado. Una compuerta de verificación lee el contrato de alcance, el registro de retroalimentación, el informe de reglas y el diff, y responde a una sola pregunta: ¿esta tarea está realmente completada? Si la compuerta dice no, la tarea no está hecha, no importa lo que diga el chat.
Tipo: Build Idiomas: Python (stdlib) Prerrequisitos: Phase 14 · 33 (Rules), Phase 14 · 36 (Scope), Phase 14 · 37 (Feedback) Tiempo: ~55 minutos
Objetivos de Aprendizaje
- Definir una compuerta de verificación como una función determinista sobre los artefactos del workbench.
- Combinar el informe de reglas, el informe de alcance, los registros de retroalimentación y el diff en un solo veredicto.
- Emitir un
verification_report.jsonque tanto el agente revisor como la CI puedan leer. - Rechazar el avance de una tarea ante cualquier falla de severidad de bloqueo (block-severity), sin excepciones.
El Problema
Los agentes declaran el éxito con demasiada facilidad. Predominan tres formas de falla:
- "Se ve bien." El modelo leyó su propio diff y decidió que era correcto.
- "Pruebas superadas." Dicho con confianza. No hay registro de que la prueba se haya ejecutado realmente.
- "Aceptación cumplida." Criterios de aceptación interpretados de manera tan laxa que significan "cualquier cosa parecida a terminado".
La solución del workbench es una sola compuerta de verificación que lee los artefactos que el agente ya ha producido y toma la decisión. La compuerta es determinista. La compuerta está bajo control de versiones. La compuerta está conectada a la CI. El agente no puede sobornarla.
El Concepto
flowchart TD
Diff[Diff] --> Gate[verify_agent.py]
Scope[scope_report.json] --> Gate
Rules[rule_report.json] --> Gate
Feedback[feedback_record.jsonl] --> Gate
Gate --> Verdict[verification_report.json]
Verdict --> Pass{¿aprobó?}
Pass -- yes --> Review[Agente Revisor]
Pass -- no --> Refuse[rechazar terminado + exponer al humano]
Qué verifica la compuerta
| Check | Source artifact | Severity |
|---|---|---|
| Todos los comandos de aceptación se ejecutaron | feedback_record.jsonl |
block |
| Todos los comandos de aceptación finalizaron con código cero | feedback_record.jsonl |
block |
| La verificación de alcance no tiene escrituras prohibidas | scope_report.json |
block |
| La verificación de alcance no tiene escrituras fuera de alcance | scope_report.json |
block or warn |
| Todas las reglas de severidad de bloqueo se cumplen | rule_report.json |
block |
Sin códigos de salida null en la retroalimentación |
feedback_record.jsonl |
block |
Los archivos modificados coinciden con scope.allowed_files |
both | warn |
Un hallazgo warn anota el veredicto; un hallazgo block impide passed: true.
Determinista, no probabilística
La compuerta debe producir el mismo veredicto para el mismo conjunto de artefactos cada vez. Sin jueces LLM. Los jueces LLM pertenecen al lado del revisor (Phase 14 · 39) donde el objetivo es la evaluación cualitativa, no el estado.
Un informe, una ruta
La compuerta emite un verification_report.json por cierre de tarea, escrito en outputs/verification/<task_id>.json. La CI consume la misma ruta. Múltiples compuertas con diferentes rutas bifurcan la fuente de la verdad.
Rechazar sin excepciones
Los hallazgos de severidade de bloqueo (block-severity) no pueden ser anulados por el agente. Solo pueden ser anulados por un humano, con un override_reason registrado y un ID de usuario overridden_by. La anulación (override) es un cambio firmado, no una decisión del agente.
Constrúyelo
code/main.py implementa:
- Un cargador para cada artefacto de entrada, todos creados con stubs locales para que la lección sea autónoma.
- Una función pura
verify(task_id, artifacts) -> VerdictReport. - Un formateador de salida (printer) que muestra los resultados por verificación y la aprobación/falla final.
- Una demostración con tres escenarios de tareas: aprobación limpia (clean pass), desviación de alcance (scope creep) y aceptación ausente (missing acceptance).
Ejecútalo:
python3 code/main.py
Salida: tres informes de veredicto, cada uno guardado junto al script.
Patrones de producción en el mundo real
Cuatro patrones elevan la compuerta de "otra tarea de análisis estático (lint)" a "el factor decisivo".
Defensa en profundidad, no una sola compuerta. Gancho de pre-commit → verificación de estado de CI → gancho de autorización previa a la herramienta → compuerta previa a la fusión (pre-merge). Cada capa es determinista, por lo que una falla en una capa es capturada por la siguiente. El manual de marzo de 2026 de microservices.io es explícito: el gancho de pre-commit no se puede omitir porque, a diferencia de una habilidad del lado del modelo, no depende de que el agente siga las instrucciones. La compuerta de verificación se encuentra en la capa de CI / pre-merge.
Defensa mediante verificación determinista, juez de modelo solo para matices. El emparejamiento Hybrid Norm de 2026 de Anthropic: las recompensas verificables (pruebas unitarias, verificaciones de esquemas, códigos de salida) responden a "¿el código resolvió el problema?" — las rúbricas de LLM responden a "¿el código es legible, seguro, sigue el estilo?". La compuerta ejecuta la primera clase; el revisor (Phase 14 · 39) ejecuta la segunda. Mezclarlos colapsa la señal.
Registro de anulación (override) firmado, no hilos de Slack. Cada anulación genera una fila en outputs/verification/overrides.jsonl con: marca de tiempo (timestamp), código de hallazgo, motivo, usuario firmante y commit HEAD actual. El tiempo de ejecución rechaza cualquier anulación que carezca de la firma; la pista de auditoría es rastreada por git. Esta es la línea entre una política de anulación y un simulacro de anulación.
Límite mínimo de cobertura (coverage floor) como verificación de primera clase. Un coverage_report.json alimenta una verificación de coverage_floor (por defecto 80%). La compuerta falla si la cobertura medida cae por debajo del límite mínimo o por debajo del límite mínimo de la fusión anterior por más de 1 punto porcentual. Sin esta verificación, los agentes eliminan silenciosamente las pruebas que fallan y los informes de verificación se mantienen en verde.
El modo --strict promueve las advertencias (warns) a bloqueos (blocks). Para ramas de lanzamiento (release branches), PR que bloquean el envío o triaje posterior a incidentes, --strict hace que cada advertencia sea una falla definitiva. La bandera es opcional por rama; no es el valor predeterminado global, porque aplicar rigidez estricta en todo corroe el flujo de trabajo diario.
Úsalo
Patrones de producción:
- Paso de CI. Un trabajo de
verify_agentejecuta la compuerta contra los artefactos finales del agente. La protección de fusión (merge) la rechaza sinpassed: true. - Gancho previo a la entrega (pre-handoff hook). El tiempo de ejecución del agente llama a la compuerta antes de generar el documento de entrega. Sin veredicto verde, no hay entrega.
- Triaje manual. Los operadores leen el informe cuando un agente alega éxito y un humano sospecha de ello.
La compuerta es el factor decisivo en el flujo del workbench. Todas las demás superficies están río arriba (upstream) de ella.
Envíalo
outputs/skill-verification-gate.md conecta la compuerta a un proyecto específico: qué comandos de aceptación la alimentan, qué reglas tienen severidad de bloqueo (block-severity), qué escrituras fuera de alcance se toleran y cómo se almacena el registro de auditoría de anulación (override).
Ejercicios
- Agrega una verificación de
coverage_floor: el comando de prueba debe producir un informe de cobertura con al menos 80%. Decide qué artefacto contiene el límite mínimo. - Admite un modo
--strictque promueva cadawarnablock. Documenta los casos en los que el modo estricto es el valor predeterminado correcto. - Haz que la compuerta produzca un resumen en Markdown además del JSON. Defiende qué campos pertenecen al resumen.
- Agrega una verificación de
time_since_last_human_touch: cualquier archivo editado dentro de los 60 segundos posteriores a una pulsación de tecla humana está exento de marcas de fuera de alcance. - Ejecuta la compuerta en un diff real de un agente de tu producto. ¿Cuántos hallazgos son reales y cuántos son ruido? ¿Hacia dónde necesita crecer la compuerta?
Términos Clave
| Term | What people say | What it actually means |
|---|---|---|
| Compuerta de verificación | "La verificación que detiene las cosas" | Función determinista sobre los artefactos del workbench que produce un veredicto de aprobación/falla |
| Severidad de bloqueo | "Falla grave" | Un hallazgo que impide passed: true y requiere una anulación firmada |
| Registro de anulación (override) | "Por que lo dejamos pasar" | Entradas firmadas con el motivo y el ID de usuario, auditadas por revisión |
| Comando de aceptación | "La prueba" | Un comando de shell cuyo código de salida cero es el significado de hecho |
| Ruta única de informe | "Fuente de la verdad" | outputs/verification/<task_id>.json, consumido tanto por la CI como por humanos |