Cerrar un alcance también exige decir qué queda afuera
Una entrega puede estar completa sin incluir cada superficie relacionada. Cómo cerrar un alcance verificable sin esconder lo que queda pendiente.
La parte principal del cambio ya había pasado sus controles y funcionaba en el entorno elegido. Una aplicación complementaria, en cambio, todavía necesitaba otra ronda de validación antes de actualizarse.
La discusión parecía tener sólo dos salidas: frenar toda la entrega hasta que ambas piezas estuvieran listas o publicar todo junto y confiar en que la compatibilidad alcanzara.
Había una tercera opción: cerrar un alcance más chico, pero completo. Publicar únicamente el recorrido verificado, dejar la otra pieza sin cambios y registrar con precisión qué condición permitiría retomarla.
No era bajar la vara. Era dejar de usar “terminado” como sinónimo de “tocamos todo lo relacionado”.
Completo no significa total
Un cambio suele atravesar varias superficies: una aplicación web, un proceso en segundo plano, un cliente de escritorio, una migración o una integración externa. Que formen parte del mismo sistema no obliga a liberarlas en el mismo momento.
La pregunta útil no es si se terminaron todas las piezas imaginables, sino si el alcance que se quiere cerrar conserva sus invariantes por sí mismo:
- el recorrido publicado funciona de punta a punta;
- las piezas que quedan en su versión anterior siguen siendo compatibles;
- ninguna función incompleta queda activada por accidente;
- el límite de la entrega se puede observar y explicar;
- retomar lo diferido requiere una decisión explícita, no memoria informal.
Si esas condiciones se cumplen, un cierre parcial puede ser íntegro. Si no se cumplen, llamarlo “primera etapa” sólo disfraza una entrega rota.
Tres decisiones posibles
Frente a una pieza complementaria todavía no lista, aparecen tres estrategias comunes.
Esperar a que todo cierre
Es la opción más simple de explicar: nada sale hasta que cada superficie pasa sus controles. Sirve cuando las piezas deben cambiar de manera atómica o cuando una versión vieja no puede convivir con la nueva.
El costo es que una dependencia secundaria puede retener un resultado ya verificable. Además, agrandar el paquete suele alargar las pruebas, multiplicar las causas posibles de falla y hacer más difícil volver atrás.
Publicar todo junto
Reduce la espera, pero transforma evidencia incompleta en riesgo operativo. Una compilación correcta o algunos tests verdes no prueban que la pieza rezagada esté lista para promoción.
Esta alternativa suele apoyarse en una frase peligrosa: “debería ser compatible”. Si la compatibilidad es una condición de la entrega, tiene que medirse, no suponerse.
Cerrar un límite explícito
La tercera estrategia separa promoción de continuidad. La parte probada se publica. La complementaria permanece en su versión actual. El cierre nombra ambas decisiones y conserva un punto concreto para retomarla.
Para que no se convierta en deuda invisible, hacen falta cuatro datos:
- Qué quedó incluido. No una lista de tareas, sino el comportamiento que ya puede usarse.
- Qué quedó afuera. Una superficie concreta, sin eufemismos como “detalles menores”.
- Por qué la convivencia es segura. Evidencia de compatibilidad o una función desactivada por diseño.
- Qué habilita la continuación. Una prueba, una actualización previa, una ventana de mantenimiento o una nueva autorización.
Sin esos datos, el alcance no está cerrado: apenas quedó de costado.
La decisión se comprueba en los bordes
En el caso que originó esta idea, no alcanzaba con que el código principal estuviera integrado. El cierre se apoyó en varias comprobaciones distintas:
- la revisión esperada estaba realmente desplegada;
- las migraciones necesarias se habían aplicado;
- el modo nuevo permanecía apagado donde no correspondía;
- el comportamiento anterior seguía funcionando con la configuración existente;
- una operación completa atravesaba el recorrido publicado;
- las credenciales temporales de verificación se habían retirado;
- la aplicación diferida seguía sin promocionarse.
La última comprobación importa tanto como las anteriores. Si una pieza quedó fuera del alcance, verificar el cierre también implica confirmar que no entró por otro camino: un auto-update, una dependencia flotante, un job de publicación o una etiqueta movida por error.
Conviene expresar el resultado como una matriz pequeña:
| Superficie | Versión observada | Estado | Evidencia |
|---|---|---|---|
| Recorrido principal | Nueva | Publicada | prueba de comportamiento |
| Datos | Compatible | Aplicados | lectura posterior |
| Cliente complementario | Anterior | Diferido | versión sin promover |
| Función nueva | Apagada por defecto | Segura | configuración leída |
La tabla no reemplaza los tests. Obliga a declarar qué versión se observó en cada borde y evita que “la entrega” parezca una entidad única cuando en realidad combina artefactos con ritmos distintos.
Diferir no es abandonar
Un diferido sano tiene una puerta de entrada. Puede ser “retomar cuando se actualice la dependencia”, “cuando el test de carga pase con este umbral” o “cuando exista una ventana de mantenimiento acordada”.
Un pendiente vago, en cambio, dice “después vemos”. No tiene condición, responsable ni vínculo con la evidencia del cierre. Con el tiempo, alguien encuentra una rama antigua, supone que sólo falta publicarla y pierde el contexto que justificaba haberla dejado afuera.
También conviene evitar que el diferido reabra automáticamente el trabajo ya cerrado. La pieza pendiente debe conservar su propio control de promoción. Cuando llegue el momento, se revisan otra vez compatibilidad, versión, pruebas y rollback. Que el sistema principal haya salido bien semanas antes no valida un artefacto que permaneció quieto.
Esta separación cambia la conversación. En lugar de preguntar “¿está todo listo?”, se responden dos preguntas más precisas:
- ¿qué resultado está listo para operar ahora?
- ¿qué decisión independiente falta para ampliar ese resultado?
Cuándo no conviene partir el cierre
No todo alcance admite esta estrategia. Hay cambios que deben avanzar juntos porque una combinación de versiones puede corromper datos, romper seguridad o producir resultados ambiguos.
No conviene separar cuando:
- una migración vuelve ilegible los datos para la versión anterior;
- dos componentes comparten un protocolo sin compatibilidad hacia atrás;
- una autorización nueva deja un camino viejo sin controles equivalentes;
- una operación puede empezar en una versión y terminar en otra con reglas distintas;
- no existe una forma confiable de mantener apagada la función incompleta;
- el rollback de una pieza exige revertir también la otra.
En esos casos, esperar o diseñar primero una transición compatible es parte del trabajo, no burocracia. Un feature flag tampoco resuelve por sí solo el problema: si ambos caminos escriben datos incompatibles, apagar la interfaz no recupera la seguridad.
Una definición de terminado con frontera
Una lista de tareas cerradas describe actividad. Una definición de terminado debería describir un estado observable.
Para entregas con varias superficies, puede escribirse así:
El alcance termina cuando el comportamiento incluido funciona en el entorno objetivo, las versiones que conviven son compatibles, lo excluido permanece sin promover y existe una condición explícita para retomarlo.
Esta definición permite cerrar sin fingir totalidad. También evita el extremo opuesto: mantener un trabajo abierto para siempre porque siempre existe otra integración, otro cliente o alguna mejora relacionada.
Antes de declarar una entrega terminada, anotá cuatro cosas: resultado incluido, frontera excluida, prueba de convivencia y condición de reapertura. Después verificá el estado real de cada artefacto, no sólo el del repositorio principal.
Cerrar bien no es afirmar que ya no queda nada por hacer. Es poder señalar, sin ambigüedad, qué funciona ahora y dónde termina esa garantía.