¿Qué controles de pull request de agentes deben bloquear un merge?
Usa siete controles medibles de pull request de agentes para frenar código inseguro: pruebas, CodeQL, dependencias, secretos, autorización, migración y rollback.

Un agente puede producir un diff limpio, una descripción convincente y código que supera una revisión rápida, y aun así dejar una aplicación expuesta o imposible de recuperar. La decisión de hacer merge debe depender de pruebas que el repositorio pueda medir, no de la seguridad con la que habla el agente ni de lo pequeño que parezca el cambio.
Uso siete controles bloqueantes: pruebas, CodeQL, revisión de dependencias, detección de secretos, controles de autorización, ensayo de migraciones y verificación del rollback. Cada uno responde a un tipo de fallo distinto. Una suite en verde no demuestra que un paquete nuevo sea seguro, y un análisis estático limpio no dice si una migración bloqueará la tabla con más tráfico.
Estos controles se aplican por igual a cambios humanos y de agentes. La autoría del agente cambia el volumen, la velocidad y la forma de los errores, pero no justifica una vía separada y más débil. Si un cambio no puede aportar las mismas pruebas que cualquier otro pull request, no está listo para el merge.
Un control debe producir pruebas, no consejos
Un control de merge debe devolver un resultado reproducible de éxito o fallo para el commit exacto que entrará en la rama protegida. Un comentario que dice «revisa esta dependencia» es un consejo. Un check obligatorio que identifica paquete, versión, aviso y umbral de gravedad es una prueba.
La diferencia importa porque muchas funciones de seguridad se limitan a informar después del momento útil para decidir. Un escáner puede crear una alerta, mandar un correo o abrir una incidencia mientras el botón de merge sigue disponible. El equipo dice entonces que el escaneo está activado, aunque no puede detener nada. Comprueba cuatro propiedades en cada control:
- Se ejecuta sobre el commit actual de la cabecera del pull request.
- La protección de rama exige su resultado con nombre.
- Un job omitido, agotado o fallido no cuenta como aprobado.
- El resultado registra detalles suficientes para reproducir la decisión.
Guarda la política en el repositorio. Un manifiesto pequeño se revisa mejor que una colección de ajustes que solo conocen los administradores:
merge_gates:
tests: required
codeql: required
dependency_review: required
secret_scan: required
authorization: required
migration_rehearsal: required_when_changed
rollback_verification: required
required_when_changed no es un atajo. El control detecta primero los archivos relevantes y después ejecuta el ensayo o registra un resultado claro de not applicable. No permitas que los filtros de rutas dejen pendiente para siempre un check requerido, ni que el agente decida que su propio cambio arriesgado está exento.
Reduce los permisos del workflow al mínimo que necesita cada job. El código de un pull request es una entrada no confiable, aunque la rama pertenezca a tu organización. Un control que expone un token de escritura o un secreto de producción al código que examina puede crear un problema peor que el que pretendía detectar.
Protege la identidad del check igual que su lógica. Las reglas de rama suelen exigir un nombre de estado, de modo que dos workflows capaces de informar el mismo nombre pueden permitir que el más débil satisfaga la regla. Da un nombre único al job de política, restringe quién modifica su archivo y exige revisión de sus propietarios. Si una cola de merge crea un nuevo commit combinado, vuelve a ejecutar los controles sobre él o vincula los resultados a esa revisión. La prueba de la cabecera de ayer no sirve para el merge de hoy.
Trata la configuración del control como código sensible. Un pull request que cambia un umbral, elimina una ruta, rebaja un paquete de consultas o añade una excepción cambia el significado de todos los resultados verdes posteriores. Muestra los diffs de política con claridad y exige un mantenedor que entienda el control afectado. El agente puede proponer el cambio, pero no debe pasar con más facilidad por editar el mecanismo que lo juzga.
Las pruebas bloquean regresiones observables
El control de pruebas debe bloquear cualquier cambio que rompa el comportamiento especificado en las versiones soportadas del runtime y la base de datos. Debe ejecutar las mismas entradas de build que usará el commit de merge, incluidas dependencias bloqueadas, archivos generados, feature flags y estado del esquema.
Los agentes son buenos satisfaciendo la aserción más cercana. Pueden añadir un fallback que vuelve verde una prueba y rompe el manejo de errores, la paginación, la concurrencia o un contrato de API contiguo. Exige pruebas nuevas o modificadas cuando cambie el comportamiento, pero no midas calidad por líneas de test. Comprueba si la prueba fallaría al eliminar o revertir la implementación.
Un control útil tiene capas con nombres separados:
- Pruebas unitarias para lógica local y casos límite.
- Pruebas de integración para contratos de base de datos, cola, caché y servicios externos.
- Pruebas de contrato para formas públicas de peticiones y respuestas.
- Una prueba de humo pequeña sobre el artefacto construido.
Corrige las pruebas inestables en vez de repetirlas automáticamente hasta que pasen. Un reintento puede recoger información de diagnóstico, pero el estado final debe mostrar el primer fallo. De lo contrario, el agente puede fusionar código cuya única propiedad demostrada es que funciona algunas veces.
La prueba de humo debe iniciar el artefacto, consultar un endpoint de salud y una ruta de escritura significativa, y detenerlo correctamente. Probar el código fuente sin iniciar la aplicación empaquetada pasa por alto archivos ausentes, valores de entorno incorrectos, migraciones rotas y fallos al arrancar. El resultado de un servicio web puede tener esta forma:
{"commit":"abc123","build":"pass","startup_ms":842,"health":200,"write_read_cycle":"pass"}
No uses un porcentaje universal de cobertura como control principal. La cobertura puede revelar un cambio sin probar, pero un repositorio llega a cifras altas con aserciones débiles. Bloquea por suites obligatorias y comportamiento modificado, y usa el movimiento de cobertura como prueba adicional para la revisión.
Protege las pruebas de la implementación que evalúan. Si un pull request cambia una regla y reescribe las aserciones para aceptar el nuevo resultado, la suite puede pasar mientras el contrato se mueve en silencio. Un revisor debe comparar las pruebas cambiadas con la API pública, la incidencia o la regla de aceptación. En parsers, validadores, facturación y acceso, añade mutation testing o entradas deliberadamente erróneas. La pregunta útil es si la suite rechaza una implementación incorrecta plausible.
Conserva artefactos cuando falle el control. Guarda la semilla que falló en pruebas aleatorias, la imagen exacta de base de datos, logs de servicios sin secretos y el comando de reproducción. Un estado sin esos datos devuelve al siguiente agente o ingeniero a las conjeturas. Limita la retención según las reglas de datos del repositorio y nunca subas un snapshot de producción solo porque facilita reproducir el fallo.
CodeQL bloquea rutas conocidas hacia vulnerabilidades
El control de CodeQL debe bloquear hallazgos nuevos de alta confianza en los lenguajes y artefactos generados que CodeQL analice de verdad. No debe sugerir que un resultado limpio demuestra que toda la aplicación es segura.
GitHub describe CodeQL como un sistema que compila código en una base consultable y ejecuta consultas sobre ella. El modelo sigue los datos por el código en vez de buscar solo texto sospechoso. También está limitado por soporte de lenguajes, éxito del build, selección de consultas y código presente durante el análisis. Si el build de la base excluye un servicio en silencio, el resultado verde cubre menos de lo que creen los revisores.
Usa un workflow con lenguajes explícitos y una política fija de consultas:
name: codeql
on: [pull_request]
permissions:
contents: read
security-events: write
jobs:
analyze:
strategy:
matrix:
language: [javascript-typescript, go]
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended
- uses: github/codeql-action/autobuild@v3
- uses: github/codeql-action/analyze@v3
Fija las actions de terceros a digests de commits revisados en un repositorio real. Las etiquetas hacen legible el ejemplo, pero una etiqueta mutable amplía el límite de confianza de un job de seguridad obligatorio.
Decide qué bloquea antes de que aparezca la primera alerta. Normalmente bloqueo hallazgos nuevos en el umbral de gravedad y precisión acordado, mientras la deuda existente queda visible en una base. Bloquear todo el historial desde el primer día fomenta descartes masivos. Ignorarlo para siempre crea un punto ciego. Asigna responsables y fechas a la base.
Revisa el conjunto de archivos analizados cuando cambien servicios, lenguajes o comandos de build. Un cliente móvil nuevo, un resolver generado o un backend separado pueden necesitar otro analizador o paso de compilación. «CodeQL pasó» solo significa algo si los revisores pueden decir qué examinó.
Separa fallos de análisis de análisis limpios. Si autobuild no compila un paquete, el job debe informar de infraestructura o configuración, no de cero hallazgos. Guarda el log de creación de la base y el recuento de fuentes analizadas por lenguaje. Compáralo con la rama base y marca una caída grande sin explicación. Así detectas un fallo corriente: el cambio de build excluye el módulo vulnerable y el check se vuelve rápido y verde porque vio menos código.
Revisa los descartes como cambios de política, no como limpieza. Un falso positivo necesita una explicación concreta ligada a la ruta y la consulta. Los comentarios de supresión deben ser estrechos, tener propietario y verse en el diff. Una exclusión global para archivos generados puede ser correcta, pero primero confirma que allí no hay plantillas o entradas del generador mantenidas a mano.
La revisión de dependencias detiene el riesgo antes de instalar
La revisión de dependencias debe bloquear cuando el diff introduce un paquete o versión que infringe una política explícita. Esta puede incluir gravedad de avisos conocidos, licencias denegadas, orígenes inesperados y dependencias directas sin responsable.
Este control no es una alerta de vulnerabilidad del repositorio. La alerta dice que una dependencia vulnerable existe en la rama. La revisión pregunta si este pull request empeora el grafo. La revisión de GitHub compara manifiestos y lockfiles, por lo que la decisión llega a tiempo y queda atribuida al cambio.
Exige coherencia del lockfile. Si un agente modifica package.json pero no el lockfile, o cambia el lockfile sin un manifiesto correspondiente, el job debe fallar. Los comandos que resuelven versiones nuevas en CI producen resultados no deterministas y pueden probar un grafo distinto del revisado.
Una política compacta puede ser:
dependency_policy:
fail_on_severity: high
deny_licenses:
- AGPL-3.0
allow_sources:
- registry.npmjs.org
- proxy.golang.org
require_owner_for_direct_additions: true
La lista exacta de licencias es una decisión legal y de producto, no un valor para copiar a ciegas. Lo útil es que el repositorio la declare y el check muestre el paquete que la activó.
No apruebes un paquete porque su nombre se parece al de una biblioteca sugerida. Los agentes pueden inventar nombres, elegir forks abandonados o añadir un cliente enorme para un helper trivial. La salida debe mostrar paquetes directos y transitivos nuevos, registro, versión resuelta, licencia y estado de avisos. El revisor puede decidir si basta el código existente o una dependencia menor.
Falla de forma cerrada si el servicio no produce un diff. Que no esté disponible el feed de avisos puede justificar retener el merge, no convertir incertidumbre en verde. Un procedimiento de emergencia puede admitir un override documentado por un mantenedor identificado, con el motivo unido al commit.
Comprueba la instalación en un job aislado cuyo acceso de red se limite a registros aprobados. Los lifecycle scripts y plugins de build ejecutan código al instalar, por lo que un paquete puede ser peligroso aunque la aplicación nunca lo importe. Registra nuevos scripts, binarios nativos o registros extraños. No entregues al job credenciales de publicación, tokens de nube ni una caché escribible compartida con builds confiables.
El código vendorizado y las imágenes de contenedor entran en la misma decisión, aunque la revisión normal de manifiestos no los vea. Compara digests, imágenes base, submódulos de Git y archivos incluidos. Exige digests inmutables en las entradas de release. Una etiqueta como latest hace imposible reproducir después el pull request porque los bytes cambian sin otro diff.
La detección de secretos debe mirar el diff y su historial
La detección debe bloquear si el pull request introduce un patrón de credencial o un secreto vivo verificado, aunque aparezca en un fixture, archivo eliminado, bundle generado o commit anterior del propio pull request.
La protección de push y el escaneo de pull requests resuelven problemas relacionados pero distintos. La primera puede detener un secreto reconocido antes del remoto. El control examina lo que ya llegó y cubre colaboradores o tipos de token que la protección omitió. Una alerta sin protección de rama no bloquea el merge.
Escanea el rango completo de commits respecto a la rama base, no solo el sistema de archivos final. Un agente puede añadir un token y borrarlo en el siguiente commit; seguirá en el historial de Git y puede haber llegado a logs o cachés. Trátalo como expuesto. Revoca o rota la credencial, elimínala del historial propuesto y repite el control.
Usa fixtures sintéticos que no puedan autenticar. Deben identificarse con claridad y coincidir con un patrón de prueba local en vez de copiar la forma de una clave real. Las allowlists amplias son peligrosas, pues accidentes y atacantes acaban encontrando el directorio ignorado. Mantén excepciones exactas, revisadas y próximas a la configuración.
Combina detectores de patrones con entropía y, cuando el proveedor lo permita con seguridad, verificación. Los patrones tienen menos riesgo de red y exposición, pero pierden tokens propios. Verificar reduce incertidumbre, aunque envía parte del secreto candidato a otro servicio y nunca debe usar un endpoint no confiable aportado por el pull request. Documenta qué detectores verifican, cuáles son locales y qué datos salen de CI.
Escanea codificaciones comunes y salidas generadas sin considerar credencial toda cadena aleatoria. Base64, URL encoding y bundles minificados pueden ocultar un secreto que antes apareció en claro. Ajusta el umbral con fixtures probados y revisa actualizaciones del detector como política. Un escáner ruidoso enseña a descartar; uno silencioso crea confianza falsa.
La salida necesita la ubicación sin revelar el valor:
{"result":"fail","detector":"generic-api-token","commit":"abc123","path":"config/dev.env","line":7,"fingerprint":"sha256:8f2c..."}
No imprimas la coincidencia completa en logs de CI ni comentarios. El enmascarado puede llegar tarde porque sistemas de logs, notificaciones y artefactos copian la salida.
El escaneo no sustituye la revisión de permisos del repositorio. Un workflow puede leer una credencial de producción sin ponerla en el diff, y un agente puede modificar un job de despliegue para extraerla. Mantén secretos fuera de jobs de pull request, restringe permisos y exige revisión humana en definiciones de CI.
Los controles de autorización mantienen prohibidas las acciones
El control de autorización debe demostrar que cada operación protegida rechaza al actor incorrecto y acepta al previsto en el límite del servicio. Las pruebas de login no prueban autorización.
Los equipos mezclan autenticación, autorización y visibilidad de la interfaz. La autenticación establece quién envía la petición. La autorización decide si esa identidad puede ejecutar la acción sobre ese objeto. Ocultar un botón de administrador en React no cambia la decisión de una API en Go. Si el backend acepta la petición, la aplicación sigue expuesta.
Crea una matriz de permisos para endpoints y acciones modificados, con propiedad y límites entre tenants:
read_private_project:
anonymous: deny
member: deny
other_tenant: deny
owner: allow
admin: allow
update_project:
anonymous: deny
other_tenant: deny
owner: allow
Genera pruebas desde la matriz o codifica casos tabulares en el lenguaje del servicio. Cada caso denegado debe llamar al handler real con identificadores realistas. Un mock que reemplaza el middleware puede demostrar que la ruta funciona y omitir el control que se pretendía probar.
Prueba el acceso por objeto, no solo los roles. Dos usuarios pueden tener rol member y pertenecer a organizaciones distintas. Cambia por separado identificadores de recurso y tenant para detectar referencias directas inseguras. Prueba endpoints masivos, exportaciones, jobs en segundo plano y resolvers GraphQL, que suelen eludir controles de handlers REST ordinarios.
Falla si una ruta protegida nueva no tiene mapeo de política. Así la autorización ausente deja de ser intuición y se convierte en defecto medible. El servidor debe denegar por defecto. Una regla allow explícita se audita mejor que código disperso que rechaza algunos casos conocidos.
Los agentes suelen reutilizar un handler cercano, conservar su camino feliz y perder la comprobación de propiedad. La matriz vuelve visible la omisión y ofrece un contrato estable si cambian roles o reglas de tenant.
Ejercita la autorización después de normalizar entradas. Mayúsculas, formatos alternativos de ID, parámetros duplicados y referencias anidadas pueden enviar peticiones equivalentes por rutas distintas. Prueba el endpoint directo y cualquier ruta batch o de importación que alcance la acción. Si un worker hace la escritura final, propaga actor y tenant al job en lugar de tratarlo como usuario todopoderoso.
Registra la decisión esperada y la regla que la produjo, sin exponer datos privados del objeto. Un fallo útil nombra clase de actor, acción, clase de objeto y estado esperado. No vuelca el token ni el registro completo. Así se distingue un fixture roto de un cambio real de privilegios.
El ensayo de migración mide bloqueos y reversibilidad
El control de migración debe aplicar cada cambio de esquema a una copia con forma de producción, ejecutar pruebas de compatibilidad y registrar duración, locks y rollback antes del merge. Una migración que funciona en una base vacía demuestra muy poco.
Usa un snapshot saneado o datos generados con tamaños, índices, constraints y distribución similares. Los datos exactos de producción no pertenecen a infraestructura de pull requests. Se busca recrear presión operativa sin copiar registros personales o confidenciales.
Ensaya la secuencia real de despliegue. Si quedan instancias antiguas mientras corre la migración, prueba código viejo con el esquema nuevo y código nuevo con el esquema de transición. Añadir una columna nullable suele ser compatible. Renombrarla en un paso puede romper todas las instancias antiguas que atienden tráfico.
Registra evidencia legible por máquinas:
{"migration":"20260727_add_project_state","apply_ms":18420,"max_lock_ms":310,"old_app_probe":"pass","new_app_probe":"pass","down":"pass"}
Define umbrales por base de datos y clase de tabla. Un lock de 300 milisegundos puede ser inocuo en una tabla y disruptivo en otra. El revisor debe ver el límite junto al resultado y la versión de base usada.
En PostgreSQL, examina operaciones que reescriben tablas, validan constraints o construyen índices bloqueando escrituras. Prefiere expandir y contraer: añade la forma nueva, despliega código compatible con ambas, rellena por lotes controlados, cambia lecturas y elimina la forma vieja después. Otro pull request cuesta menos que improvisar durante una caída.
No toda migración admite un down seguro. Eliminar una columna pierde datos y revertir una transformación puede ser ambiguo. Exige entonces recuperación hacia delante o un restore probado. Llamar reversible a una migración destructiva porque existe un archivo down no es honesto.
Prueba reintentos y fallos parciales. Un despliegue puede detenerse tras crear un índice y antes de registrar la migración; el siguiente intento no debe corromper estado ni fallar para siempre. Interrumpe el ensayo en un punto controlado, repítelo y verifica esquema y ledger. Un backfill largo debe reanudarse desde un cursor y repetir un lote sin duplicar ni borrar datos.
Mide disco y replicación además del tiempo. Reescribir una tabla consume espacio temporal, amplía logs de escritura y retrasa réplicas después de terminar la operación principal. No hace falta una predicción perfecta, pero sí registrar valores en los datos de ensayo y compararlos con límites del responsable. Sin ello, una migración local rápida puede agotar un volumen de producción.
La verificación del rollback debe ejecutar la recuperación
El control debe desplegar el candidato en un entorno aislado, crear estado representativo, ejecutar el método de rollback soportado y demostrar que la versión anterior todavía lee y escribe correctamente. Un plan escrito no es verificación.
Separa rollback de aplicación y de datos. Devolver tráfico al binario anterior puede tardar segundos, mientras deshacer un esquema destructivo puede ser imposible. El control debe informar ambos. Si la aplicación vieja no funciona con el esquema nuevo, marca el candidato como no reversible y exige despliegue por etapas.
Una secuencia práctica:
- Desplegar el commit actual de main y sembrar registros representativos.
- Actualizar al artefacto del pull request y ejercitar rutas modificadas.
- Crear registros nuevos en el estado actualizado.
- Restaurar el artefacto anterior o snapshot mediante el control documentado.
- Ejecutar pruebas de lectura, escritura, cola y jobs en segundo plano.
El check conservará identificadores de artefacto y snapshot, marcas de tiempo y resultados, pero no credenciales ni datos copiados de clientes. Mide el tiempo de recuperación como evidencia de tu objetivo operativo, no como promesa universal.
Los snapshots solo sirven si alguien demuestra que contienen todo lo necesario. Archivos, object storage, estado de colas, cambios de esquema y efectos externos pueden quedar fuera. Enumera esos límites. Un pago, correo o webhook ya enviado no se retira restaurando la base.
Haz la prueba más fuerte que un health check. Lee un registro creado antes de actualizar y otro creado después, modifica ambos si hay compatibilidad y procesa un job creado por cada versión. Compara la salida visible, no solo códigos. Un servidor que devuelve 200 mientras pierde un campo o interpreta mal un enum no se ha recuperado.
Prueba el control que usará la persona de guardia. Si el rollback exige elegir artefacto, restaurar snapshot o cambiar tráfico, el ensayo usará la misma interfaz y ruta de permisos. Un script privado en un portátil no es un control operativo. La evidencia debe mostrar que el rol operador recupera sin privilegios permanentes de administrador.
Koder.ai admite exportación de fuente, despliegue y hosting, snapshots y rollback, así que las aplicaciones creadas allí pueden usar esos artefactos concretos en el control. La regla es igual en cualquier plataforma: ejecuta la recuperación y prueba la aplicación restaurada.
Un único check obligatorio debe reunir los siete
La decisión final debe exigir un check estable de política que verifique los siete resultados para el commit exacto de cabecera. Los nombres de jobs cambian, las matrices se multiplican y las rutas opcionales omiten trabajo. Un agregador pequeño impide que la protección de rama se aparte de la política.
Haz que cada control emita un resultado firmado o acreditado por la plataforma con commit, versión de política, resultado y ubicación de pruebas. El agregador rechazará resultados ausentes, antiguos, neutrales o cancelados. Nunca inferirá éxito de un job que no informó.
{
"commit": "abc123",
"policy": "merge-gates-v3",
"results": {
"tests": "pass",
"codeql": "pass",
"dependency_review": "pass",
"secret_scan": "pass",
"authorization": "pass",
"migration_rehearsal": "not_applicable",
"rollback_verification": "pass"
},
"decision": "allow"
}
Define un camino estrecho para emergencias. Exige un mantenedor identificado, segundo aprobador, motivo escrito, caducidad e incidencia de seguimiento. El agente no pide ni aprueba su propia excepción. Informa overrides junto a resultados ordinarios para que sigan visibles después del incidente.
Estos controles añaden minutos a algunos pull requests y bastante más a las migraciones. Es aceptable cuando el tiempo compra pruebas concretas. Ejecuta primero controles baratos, cancela commits superados, cachea entradas confiables y reserva el ensayo completo para rutas relevantes. No debilites un control solo para que el panel se ponga verde antes.
Empieza haciendo observable el comportamiento actual. Pon los siete nombres en un archivo de política, conecta cada uno a un resultado obligatorio y obliga al trabajo omitido a explicarse. El primer pull request de agente que no pueda generar ese registro habrá encontrado un hueco en la entrega antes de encontrarlo en producción.
Preguntas frecuentes
¿Los pull requests de agentes deben tener reglas más estrictas que los humanos?
Usa las mismas pruebas bloqueantes para ambos. La velocidad de los agentes justifica más automatización, pero un diff humano puede introducir el mismo secreto, error de autorización o migración insegura.
¿Puede un revisor humano anular un control fallido?
Sí, pero solo con una excepción estrecha y registrada, dos responsables, un motivo y una caducidad. El agente que creó el cambio nunca debe aprobar su propia excepción.
¿Un CodeQL aprobado significa que el pull request es seguro?
No. Significa que las consultas elegidas no hallaron un resultado bloqueante en el código analizado con éxito. Dependencias, autorización en ejecución, secretos, configuración y recuperación necesitan pruebas separadas.
¿Qué ocurre si un escáner obligatorio no está disponible?
El check debe fallar de forma cerrada o seguir bloqueado. Si el cambio es una emergencia, usa el override documentado en vez de convertir un resultado desconocido en aprobado.
¿Debe la detección de secretos examinar commits borrados?
Debe examinar todo el rango de commits. Un secreto añadido y luego eliminado sigue en el historial y debe rotarse antes de aceptar el cambio limpio.
¿Cómo se prueba la autorización en un pull request?
Llama a handlers reales con una matriz de identidades, roles, tenants, objetos y acciones. Incluye denegaciones y cambios de propiedad, porque el login y una interfaz oculta no demuestran autorización del servidor.
¿Todas las migraciones necesitan un script down?
No. Algunos cambios destructivos no pueden revertirse con honestidad. Exige recuperación hacia delante o restauración de backup probadas y marca el cambio como no reversible.
¿Qué diferencia hay entre planificar y verificar un rollback?
La planificación describe los pasos previstos. La verificación los ejecuta con el artefacto candidato y estado representativo, y registra si la versión anterior puede leer y escribir correctamente.
¿Cómo evitar que siete controles ralenticen todos los pull requests?
Ejecuta primero los baratos, cancela commits superados, cachea entradas confiables y ensaya migraciones solo en cambios relevantes. Cada control debe dar un pass o not applicable explícito.
¿Qué resultado debe exigir la protección de rama?
Exige un resultado estable de política que agregue los siete controles para el commit exacto. Debe rechazar resultados ausentes, antiguos, omitidos, cancelados o neutrales.