Módulo 6: Postmortems And Iterating

El loop ship → measure → learn: lanzar no es el final, es el comienzo

Descripción

Todo el vocabulario que esta guía construyó hasta ahora —flags, rollout, guardrails, rollback— comparte una suposición implícita que esta lección hace explícita: que "lanzar" es un evento con un final claro, el momento en que el flag llega al 100%. Esta lección rompe esa suposición e instala el marco que le da sentido al resto del módulo: el loop ship → measure → learn. Enviar (ship) no es el punto final de un proceso lineal — es el primer tercio de un ciclo que se repite: envías un cambio, mides qué pasó de verdad en producción, y aprendes algo de esa medición que alimenta la siguiente decisión de qué enviar. El postmortem de las lecciones 2 a 4 es, precisamente, la forma más visible de la pieza learn cuando algo sale mal — pero el loop completo aplica también cuando todo sale bien: hasta un lanzamiento exitoso necesita medirse y aprenderse, no solo celebrarse.

Conexión con el módulo. Esta lección no construye ninguna función nueva reutilizable en el sentido técnico de las lecciones anteriores —no hay un guardrailCheck() o rolloutPlan() escondido aquí—; construye el marco narrativo que conecta el postmortem que ya cerraste (learn del primer ciclo) con la iteración que viene en la lección 6 (ship del segundo ciclo) y la medición que la cierra en la lección 7 (measure del segundo ciclo). Es la bisagra entre la primera mitad de este módulo —qué pasó y por qué— y la segunda —qué haces con lo que aprendiste.

Una analogía: cocinar no termina cuando el plato sale del fuego

Alguien que de verdad le importa el resultado de lo que cocina no apaga el fuego, sirve el plato, y se olvida de él. Prueba la comida —¿le falta sal, le sobra ácido, la textura es la correcta?—, ajusta según lo que prueba, y vuelve a probar. Ese ciclo de probar-ajustar-probar no es un fracaso de haber cocinado mal la primera vez: es, literalmente, cómo se cocina bien. Un cocinero que sirve un plato una sola vez, sin probarlo nunca, y asume que salió perfecto porque "siguió la receta", tiene muchas más probabilidades de servir algo desbalanceado que uno que prueba antes de servir y ajusta después de la primera reacción de quien lo come.

Lanzar recommendations es exactamente ese plato. Ship es sacarlo del fuego —encender el flag, subir la rampa—. Measure es probarlo —¿el guardrail se sostiene?, ¿la conversión realmente sube?, ¿el efecto se mantiene semana a semana?—. Learn es ajustar la sazón según lo que la prueba reveló —arreglar la latencia, agregar cache, o confirmar que ya está bien como está—. Ningún cocinero serio trata "salió del fuego" como sinónimo de "terminado". Ningún equipo de producto serio debería tratar "el flag llegó al 100%" como sinónimo de "terminado", tampoco.

Ejemplo trabajado: shipMeasureLearnLoop() sobre los dos ciclos de recommendations

// shipMeasureLearnLoop: modela el loop de lanzamiento como una secuencia de
// ciclos -- cada ciclo tiene lo que se envio (ship), lo que se midio
// (measure) y lo que se aprendio (learn). No es estadistica (eso sigue
// siendo product-metrics); es la ESTRUCTURA del loop aplicada al caso real,
// mostrando que el "learn" de un ciclo alimenta el "ship" del siguiente.
function shipMeasureLearnLoop(cycles) {
  return cycles.map((c, i) => ({ cycle: i + 1, ship: c.ship, measure: c.measure, learn: c.learn }));
}

const recommendationsCycles = [
  {
    ship: 'rollout de recommendations a 10% (canary ya paso limpio)',
    measure: 'checkoutConversion +18.75% (gana) pero p95Latency=910ms rompe el techo de 800ms',
    learn: 'la llamada al motor de recomendaciones es bloqueante y no escala a ese volumen -> 3 action items del postmortem',
  },
  {
    ship: 'llamada rediseñada a modo asincrono + cache; se re-lanza por la misma rampa (canary -> 10% -> 50% -> 100%)',
    measure: 'p95Latency se sostiene bajo el techo en las 4 etapas; falta confirmar si el lift de conversion se sostiene',
    learn: '¿el lift se mantiene semana a semana, o era efecto novedad? -> siguiente pregunta de este modulo',
  },
];

console.log('=== El loop ship -> measure -> learn sobre recommendations ===\n');
shipMeasureLearnLoop(recommendationsCycles).forEach((c) => {
  console.log('Ciclo ' + c.cycle + ':');
  console.log('  ship:    ' + c.ship);
  console.log('  measure: ' + c.measure);
  console.log('  learn:   ' + c.learn);
  console.log('');
});

Qué esperar. Al correr el archivo con Node, la salida es exactamente esta:

=== El loop ship -> measure -> learn sobre recommendations ===

Ciclo 1:
  ship:    rollout de recommendations a 10% (canary ya paso limpio)
  measure: checkoutConversion +18.75% (gana) pero p95Latency=910ms rompe el techo de 800ms
  learn:   la llamada al motor de recomendaciones es bloqueante y no escala a ese volumen -> 3 action items del postmortem

Ciclo 2:
  ship:    llamada rediseñada a modo asincrono + cache; se re-lanza por la misma rampa (canary -> 10% -> 50% -> 100%)
  measure: p95Latency se sostiene bajo el techo en las 4 etapas; falta confirmar si el lift de conversion se sostiene
  learn:   ¿el lift se mantiene semana a semana, o era efecto novedad? -> siguiente pregunta de este modulo

Fíjate en la forma del learn de cada ciclo: no es un punto final, es la pregunta o la acción que define el ship del ciclo siguiente. El learn del ciclo 1 —la llamada bloqueante no escala— se convierte, directamente, en el ship del ciclo 2 —la llamada rediseñada—. Y el learn del ciclo 2 —¿se sostiene el lift, o era novedad?— todavía no tiene respuesta en esta tabla: es, literalmente, la pregunta que abre la lección 7. Esa es la naturaleza de un loop, en contraste con un proceso lineal: no hay un ciclo "final" dentro de la tabla — hay ciclos que ya se completaron y una pregunta abierta que define el próximo.

Profundización: de dónde viene este marco, y por qué "ship" reemplaza a "build"

El loop ship → measure → learn de esta guía es una adaptación directa del build-measure-learn que Eric Ries popularizó en The Lean Startup: construyes un producto mínimo viable, mides cómo responden los usuarios reales, y aprendes si conviene perseverar en la dirección actual o pivotar hacia una distinta. La idea central —convertir suposiciones en conocimiento lo más rápido y barato posible, en vez de perfeccionar un producto en el vacío antes de mostrarlo a nadie— es exactamente la misma.

El cambio de build a ship en el nombre no es cosmético: refleja dónde está parada esta guía dentro del arco completo de Product Engineering. product-thinking-for-engineers-guide decidió qué construir. product-discovery-and-prototyping-guide validó esa apuesta barato, antes de construir el producto completo. product-metrics-and-experimentation-guide midió el resultado del experimento con rigor estadístico. Para cuando esta guía entra en escena, el build original de Ries ya pasórecommendations ya está construido y ya ganó su A/B test—. Lo que queda, y lo que este loop describe, es el ciclo que empieza después de construir: enviarlo a producción real, medir qué pasa a esa escala, y aprender de esa medición — un ciclo que puede repetirse muchas veces sobre el mismo producto ya construido, cada vez con un ship distinto (un fix, un ajuste, una nueva etapa de rollout), sin necesidad de volver a construir nada desde cero.

Errores comunes

Tratar el ciclo 1 de la tabla como "el lanzamiento que falló" y el ciclo 2 como "el lanzamiento real". Qué pasa: al reportar el resultado hacia arriba, alguien describe el primer intento de recommendations como un error o un fracaso, y solo el segundo (post-fix) como "el verdadero lanzamiento". Por qué pasa: el ciclo 1 terminó en un incidente, y es natural etiquetar cualquier cosa que termine en incidente como "lo que salió mal", en vez de "una iteración legítima del loop que generó el aprendizaje necesario para el ciclo 2". Cómo detectarlo: si el reporte no menciona que el learn del ciclo 1 —la causa técnica identificada, con sus tres action items— es exactamente lo que hizo posible que el ciclo 2 pasara limpio por las cuatro etapas, el ciclo 1 se está tratando como un descarte en vez de como una entrada necesaria del loop. Cómo corregirlo: como muestra la tabla de hoy, ambos ciclos son parte del mismo loop — el ciclo 1 no es un lanzamiento fallido seguido de uno real, es la primera vuelta de un proceso que, por diseño, mejora con cada vuelta.

Creer que el loop termina en el ciclo 2 solo porque ese ciclo pasó los guardrails. Qué pasa: al ver que la rampa completa del ciclo 2 avanza sin ningún HOLD, el equipo declara el loop cerrado y deja de mirar recommendations por completo. Por qué pasa: pasar los guardrails técnicos —la latencia, en este caso— se siente como la meta final, y es fácil olvidar que el measure del ciclo 2 en la tabla de hoy dice explícitamente "falta confirmar si el lift se sostiene". Cómo detectarlo: si nadie tiene programado volver a mirar checkoutConversion unas semanas después del relanzamiento, el learn del ciclo 2 nunca se va a completar — quedará como una pregunta abierta para siempre, no porque no importe, sino porque nadie volvió a mirar. Cómo corregirlo: el loop no tiene un número fijo de ciclos — tiene tantos como haga falta hasta que el learn deje de generar preguntas nuevas. La lección 7 de este módulo construye exactamente el chequeo que cierra esa pregunta pendiente.

Usar el vocabulario del loop sin que realmente cambie ninguna decisión. Qué pasa: un equipo empieza a usar las palabras "ship, measure, learn" en sus reportes y reuniones, pero en la práctica sigue lanzando cambios sin medir nada después, o mide pero nunca conecta lo medido con el siguiente ship. Por qué pasa: adoptar un vocabulario nuevo es mucho más rápido que cambiar el proceso real detrás de él, y las palabras pueden quedarse como una capa de barniz sobre el mismo comportamiento de siempre. Cómo detectarlo: si preguntas "¿qué aprendimos del último lanzamiento que cambió lo que vamos a lanzar después?", y la respuesta es vaga o inexistente, el equipo tiene el vocabulario del loop, pero no el loop. Cómo corregirlo: la prueba real del loop no es si alguien dice "ship, measure, learn" en una reunión — es si se puede señalar, como en la tabla de hoy, exactamente qué learn de un ciclo se convirtió en qué ship del ciclo siguiente.

Ejercicios

Ejercicio 1 — Completa un tercer ciclo hipotético. Supón que, seis semanas después del relanzamiento, el equipo confirma que el lift de conversión se sostiene (vas a ver el chequeo exacto en la lección 7). Escribe, en el mismo formato de la tabla de hoy (ship, measure, learn), cómo se vería un tercer ciclo que no trata sobre arreglar un problema, sino sobre expandir el éxito ya confirmado —por ejemplo, aplicar el mismo motor de recomendaciones a una superficie nueva del producto, como la página de inicio.

Ver solución

Una respuesta razonable: { ship: 'se extiende el motor de recomendaciones (ya validado y estable) a la pagina de inicio de Mercado, con su propio flag y su propia rampa', measure: 'se mide checkoutConversion y p95Latency en la pagina de inicio, con los mismos guardrails ya conocidos', learn: '¿el mismo efecto se repite en una superficie distinta, o el comportamiento del usuario en la pagina de inicio es diferente al de la pagina de producto?' }. Este ejercicio muestra algo importante: el loop no se detiene cuando un ciclo confirma éxito — simplemente cambia de pregunta, de "¿arreglamos el problema?" a "¿podemos capturar más valor con lo que ya funciona?".

Ejercicio 2 — Ubica el error de un compañero. Un compañero de equipo dice: "Ya terminamos con recommendations — el ciclo 2 pasó todos los guardrails, así que el loop está cerrado." Usando el vocabulario de esta lección, ¿qué error de los "Errores comunes" está cometiendo, y qué pregunta le harías para corregirlo?

Ver solución

Está cometiendo el segundo error común: confundir "pasó los guardrails técnicos" con "el loop está cerrado", sin notar que el measure del ciclo 2 en la tabla de hoy dejó una pregunta explícitamente sin responder —si el lift de conversión se sostiene—. La pregunta correctora: "¿ya medimos checkoutConversion varias semanas después del relanzamiento, o solo confirmamos que la latencia se sostuvo el día que se encendió el flag?" — si la respuesta es que solo se confirmó la latencia, el learn del ciclo 2 sigue abierto, y el loop no está cerrado todavía.

Ejercicio 3 — Explica el loop a alguien sin contexto técnico. Usando la analogía de cocinar, escribe en 2-3 frases cómo le explicarías a alguien del equipo comercial de Mercado por qué "lanzar recommendations al 100%" no significa que el trabajo del equipo de producto haya terminado.

Ver solución

Una respuesta razonable: "Lanzar recommendations al 100% es como sacar un plato del fuego — todavía no sabemos si quedó bien sazonado hasta que lo probamos. Ya lo probamos una vez (el primer lanzamiento) y encontramos que le faltaba algo —la latencia se disparaba—, así que lo ajustamos y lo volvimos a servir. Ahora que pasó esa segunda prueba, seguimos revisando, semana a semana, que el sabor —en este caso, la mejora en conversión— se mantenga con el tiempo, en vez de asumir que porque salió del fuego ya terminamos."

Resumen y siguiente paso

En esta lección instalaste el marco que da sentido al resto del módulo: el loop ship → measure → learn, donde lanzar es el primer tercio de un ciclo, no un punto final. Con shipMeasureLearnLoop() viste los dos ciclos reales de recommendations: el primero terminó en un incidente que se convirtió en aprendizaje concreto (los tres action items del postmortem); el segundo relanzó el producto ya arreglado y dejó una pregunta abierta —¿se sostiene el lift, o era efecto novedad?— que todavía no tiene respuesta.

Antes de avanzar deberías poder: explicar por qué "ship" reemplaza a "build" en esta versión del loop, dado dónde está parada esta guía en el ecosistema; distinguir un ciclo del loop que está genuinamente cerrado de uno que solo pasó sus guardrails técnicos; y anticipar que la pregunta pendiente del ciclo 2 —el lift, ¿se sostiene?— es exactamente lo que viene después.

La lección 6 toma el ship del ciclo 2 —el que en esta lección solo se describió en una frase— y lo ejecuta en detalle: con los tres action items del postmortem ya resueltos, recommendations se relanza por la misma rampa del módulo 3, y esta vez la latencia se sostiene en las cuatro etapas.

Recursos

  • Eric Ries, The Lean Startup — resumen oficial del framework en theleanstartup.com/principles. La fuente original del ciclo build-measure-learn, y la base conceptual completa de esta lección. En inglés.
  • Strategyzer, "Don't Build When You Build-Measure-Learn" — strategyzer.com/library/dont-build-when-you-build-measure-learn. Un análisis práctico sobre por qué el loop empieza, en realidad, con aprender qué vale la pena probar, no con construir de entrada — relevante para entender por qué esta guía adapta el nombre a "ship" en vez de "build". En inglés.
  • Google SRE Book, Capítulo 3, "Embracing Risk" — sre.google/sre-book/embracing-risk. La idea de error budget que ya viste en el módulo 4 comparte la misma lógica de fondo: ningún sistema se declara "terminado", se gestiona en ciclos continuos de medición y ajuste. En inglés.