Capstone · Todo junto · 2:13:44 en el video
Del issue #27 a producción
En el video · capítulos de esta sección
- 2:13:44CAPSTONE · Del issue 27 a producción
- 2:15:06Empaquetar: una imagen reproducible por digest
- 2:16:34Staging con Terraform: cero drift
- 2:21:39/verify: probar la app real, no los tests
- 2:25:15Rollback real con una versión rota a propósito
- 2:30:21Incidente: investigar antes de arreglar
- 2:36:12El issue 27 termina solo, con puerta humana
- 2:40:55El camino del fallo: la promoción se bloquea sola
- 2:42:05Cierre: ya no es tu becario, es tu ingeniero
Objetivo: todo junto. Un artefacto reproducible, un entorno donde verificarlo, una forma explícita de volver atrás, y el issue #27 recorriendo el pipeline completo sin nadie en el teclado.
La vara: ningún cambio está terminado en el PR. FUNCIONA ≠ ESTÁ TERMINADO.
Producción de laboratorio: cloud real (identidad, secretos, pipeline y observabilidad reales) con recursos desechables y sin usuarios reales. Así se demuestran prácticas de producción sin poner nada importante en riesgo.
Requiere: fork con secretos y environment production con reviewer configurado (el gate humano exige repo público en GitHub), staging desplegado y verde, y el stack de infraestructura del runbook. Todo el capítulo se hace en modo manual: cada paso pasa por ti, porque las decisiones que vienen son tuyas.
C1 · Terminar de verdad: empaquetar, desplegar, probar
- Empaquetar:
Construye una imagen reproducible para la API y el worker. Sin secretosen el build. Etiquétala con el commit y consérvame el digest.Resultado esperado: build, y al final el digest en pantalla. Déjalo visible: se usa en el rollback y reaparece en C3. No se promociona una carpeta de código: se promociona un artefacto inmutable que se puede identificar y revertir.
- Desplegar, mostrando el plan, sin escribir recursos a mano:
Con el plan aprobado, propón el cambio mínimo de Terraform para desplegareste artefacto en staging: identidad de runtime, secretos, red necesaria,logs y outputs. NO ejecutes apply.terraform fmt -check && terraform validate && terraform plan -out=staging.tfplanResultado esperado: el agente puede detenerse en una decisión de arquitectura real (el worker no escucha HTTP y Cloud Run exige puerto) y traer opciones con trade-offs. La decisión de ingeniería válida es acotar: desplegar solo la API con este artefacto y anotar el worker como issue propio (Service vs Worker Pool). Decidir “todavía no” también es diseñar. Las tres cosas que siempre se miran en el plan: identidad (con qué service account corre), secreto (el token vive en el gestor de secretos y la app recibe la referencia, jamás el valor en git), runtime (dónde corre). Si el pipeline ya dejó staging idéntico a lo declarado, el diff sale vacío: cero drift, el estado ideal. Terraform es dueño de la forma; el pipeline es dueño del artefacto.
Dos reglas de diseño: Claude no recibe credenciales cloud (el runtime recibe una identidad acotada y Claude opera la capacidad expuesta). Y la API de guardia no controla la máquina donde ella misma corre: opera una VM objetivo desechable, separada.
- Probar. Los tests prueban condiciones conocidas; esto es ir a la aplicación de verdad y observar su comportamiento. Verificar jamás debería cambiar el sistema.
Verifica staging: versión desplegada, health, consulta de VM, lectura DNSy registro de auditoría. No ejecutes mutaciones destructivas.Resultado esperado: versión y health en verde. Si las rutas /infra/* fallan en staging es porque los secretos de GCP y Cloudflare no están inyectados ahí: issue anotado, al backlog. Esta disciplina también existe como comando: /verify.
- Romperlo a propósito. La pregunta más importante de cualquier deploy: ¿qué pasa el día que lo que subo está malo? Eso no se declara: se demuestra. La rama
smoke-rototiene un cambio de una letra: alguien normalizó el estado del health a mayúsculas.
Dentro de la sesión: !git checkout smoke-roto (el bang corre shell sin salir de la sesión), y:
Construye la imagen de esta versión y despliégala a staging por digest.Resultado esperado: el agente se frena, cita el CLAUDE.md (“el único camino sancionado es el pipeline; para saltarlo, pregúntale a Marcos”) y pide luz verde antes de saltarse el proceso. Si además te arregla el bug, se lo descartas: es el fixture de la demo. La luz verde se da como en la vida real: bypass puntual, consciente, supervisado.
Hablado con Marcos: luz verde para este bypass puntual, solo porque es elfixture del simulacro de rollback y lo estoy supervisando paso a paso.Despliega a mano por digest. El camino normal sigue siendo el pipeline,y lo vamos a usar en el cierre.Compruebas: !curl <URL staging>/health responde {"status": "OK"}. Funciona, y está mal: el contrato dice ok.
- Rollback:
Restaura staging al digest anterior.Health ok de nuevo. Ahora sí la frase completa: esta feature está terminada. Corre en un entorno reproducible, sabemos qué versión es, podemos observarla y podemos volver atrás. !git checkout main para dejar el árbol limpio.
C2 · El incidente: runtime verde, sistema roto
El escenario (snapshot del repo con el incidente diseñado adentro, base sembrada y logs plantados) se arma con el script del laboratorio. Es la misma tarea del eval del Nivel 7.
- Las tres pantallas antes de tocar nada:
tail -15 logs/worker.log: ayer procesó incidentes uno tras otro; hoy a las cinco de la mañana “worker up” y desde entonces silencio. Vivo, y mudo.select status, count(*) from incidents group by status;: seis incidentes reabiertos esperando. La cola no baja.curl -s <URL>/health:ok. Todo lo verde está verde, y el sistema no está sano. Liveness y salud de negocio no son lo mismo.
- Sesión nueva en el directorio del escenario. Investigar sin arreglar:
El incidente reabrió. La VM y el liveness están verdes, pero el worker noreduce la cola. Investiga sin proponer arreglos todavía. Correlacionalogs, métricas, configuración efectiva, versión desplegada y cambiosrecientes. Dame la causa raíz y la evidencia que la confirma o la falsaría.Si la base del escenario está en otro puerto, dáselo: La cola del incidente está en la base del escenario: postgres en localhost:5433, base c2demo, usuario incidents. Confirma ahí el estado de la cola y agrégalo a tu evidencia.
Resultado esperado: correlaciona digest, logs, cola, estado de la base y configuración. La causa raíz tiene dos lados que hay que conectar: alguien escribió un estado fuera del contrato (reopened, el importador legacy directo en la base), y el worker consume únicamente new. Seis incidentes huérfanos, invisibles para todo lo que observa el sistema. Verde perfecto sobre una cola fantasma. Puede además encontrar que el worker lleva horas muerto (crash al reiniciar Postgres, sin restart policy) y que el health tiene un TODO que no chequea la base.
- Causa raíz probada. Ahora sí, el arreglo, y no es solo código:
Causa raíz probada. Arregla: el fix con su test de regresión, la políticade restart que faltaba, el healthcheck del worker, y las señales de saludde negocio (queue lag, edad del mensaje más antiguo, tasa deprocesamiento), más una alerta simple y un runbook breve.Tres preguntas distintas: liveness dice si el proceso vive; readiness, si puede recibir trabajo; las señales de negocio, si el sistema cumple su función. Si el agente no puede observar el sistema, tampoco puede demostrar que lo arregló. Deploy del fix a staging, smoke, y el queue lag bajando a cero: arreglo demostrado, no declarado.
Lección doble: separar investigar de arreglar (“arregla esto” sin causa probada optimiza por callar el síntoma), y el costo de la confianza apresurada.
C3 · Nadie en el teclado: el issue #27 completo
issue etiquetado→ clasificador de elegibilidad→ agente implementa en runner aislado (credenciales mínimas + presupuesto)→ tests + revisión → PR draft→ HUMANO aprueba y fusiona (puerta 1)→ build UNA VEZ → artefacto por digest→ deploy a staging → smoke + verificación→ HUMANO aprueba ambiente (puerta 2)→ promover EL MISMO digest a producción de laboratorio→ verificación posterior→ si algo falla: LA PROMOCIÓN SE BLOQUEAFíjate en lo que no hay: un agente con permiso para improvisar un despliegue. El pipeline promociona un artefacto revisado bajo una política. El agente escribe código; el sistema decide cómo ese código viaja. Esto es un grafo: nodos, aristas y estado, con loops en cada verificación y un harness en cada puerta.
-
Todo en GitHub, tú solo abres puertas:
-
Etiquetar: Issues, #27, label
agente. Y te sales del camino. -
El clasificador: Actions, workflow
clasificador(~20-30 s). En el issue aparece el comentario ELEGIBLE con razones y costo. -
La implementación: nada que hacer (~2-3 min). Aparece el PR draft en Pull requests.
-
Puerta 1, el review: abres el PR, Files changed, recorres el diff con calma, Ready for review, Approve, Merge.
-
El pipeline a staging: Actions,
deploy-staging(~1-2 min). Build una sola vez, digest, deploy, smoke en verde. -
Puerta 2, la promoción: Actions,
promote-production, Run workflow. El run se pausa en “Review deployments”: marcasproduction, Approve and deploy. No reconstruye nada: sube el mismo digest verificado en staging. -
El final: el run termina verde y el issue #27 se cierra solo con su evidencia (commit, digest, tests, costo).
Tiempos reales del laboratorio: push a staging verde 1m12s · clasificador 21 s · implementación y PR ~2 min · promoción 1m15s, digest idéntico byte a byte en ambos ambientes.
C4 · Las dos demos que valen más que el éxito
-
El rechazo: etiqueta el issue #15 con
agente(toca IAM). Resultado esperado: el clasificador comenta RECHAZO con sus razones y el job de implementación ni aparece en Actions. Madurez no es automatizar todo: es saber qué no debe entrar al camino automático. -
El fallo bloqueado: abre un PR de
smoke-rotocontramain. Los tests del PR ya salen en rojo (primera red). Haz de compañero apurado y mergea igual. Resultado esperado:deploy-stagingse pone rojo en el paso Smoke (el grep del health falla por una letra). Lanzapromote-production: aborta en el gate técnico sin tocar producción. Compruébalo:curl -s <URL prod>/healthrespondeoky/versionmuestra el digest anterior. El mejor rollback fue no desplegar.
El sistema no está diseñado para que Claude siempre tenga éxito. Está diseñado para que un fallo no se convierta en un incidente.
Después: en el PR mergeado, Revert, merge del revert, y deploy-staging deja staging verde otra vez.
Cumples el capstone cuando
0/5Backlog: los cinco tachados. Marcador: autonomía llena, control lleno, juntos.