Segunda parte de la serie sobre cómo construir con calidad desde Lean Software Development. Si aún no has leído la primera parte de esta serie, donde explicamos los fundamentos de Lean Software Development, puedes encontrarla aquí: https://www.eferro.net/2025/04/lean-software-development-construyendo.html. Tras entender por qué la calidad no es solo el resultado final, en esta entrega nos enfocamos en cómo detectamos errores lo antes posible, detenemos el flujo cuando aparecen y aprendemos de ellos para mejorar el sistema.
Para evitar confusiones, utilizaremos "error" para referirnos a cualquier desviación del resultado esperado, y "defecto" para errores que impactan al cliente en producción.
Detectar los errores lo antes posible
En enfoques más tradicionales, suele priorizarse la clasificación de los defectos según su criticidad, lo que en algunos casos determina si se corrigen o no, y en qué plazo. Sin embargo, en Lean Software Development, que considera la calidad como una parte fundamental del producto y se enfoca en la mejora continua de procesos y sistemas, es más común clasificar los errores (potenciales defectos) según dónde y cuándo se han identificado dentro del proceso.
Disponer de esta información nos permite identificar las etapas del proceso donde los errores son más comunes y así enfocar nuestros esfuerzos de mejora para detectarlos lo antes posible (shift left), reduciendo la probabilidad de que se conviertan en defectos.
En mi experiencia, resulta muy útil clasificar la detección de errores dependiendo de la etapa en la que se identifican. Yo suelo usar la siguiente clasificación:
- Máquina local (trabajo en pareja o ensemble).
- Ciclo de desarrollo (incluyendo el ciclo TDD, verificación continua de estilo (linting), tipos, errores, etc).
- Pre-commit.
- Pre-push.
- CI Pipeline:
- Checks.
- Tests (clasificados de más rápidos a más lentos).
- Despliegue (incluyendo smoke tests y validaciones durante el rollout).
- Entorno de producción.
- Pre-release (desplegado, pero no activado para el cliente).
- Activación para el cliente.
Cuando una funcionalidad ya está activada para el cliente, es útil también clasificar los errores o defectos según quién o qué los detectó:
- Sistema automático, antes de que afecte al cliente (Monitoring).
- Usuario interno, como un miembro del equipo realizando pruebas o alguien de otro departamento.
- Usuario final, reportado el defecto a soporte.
Independientemente de la etapa o del responsable de la detección, el objetivo principal siempre es el mismo: detectar (y resolver) el error lo antes posible, idealmente antes de que sea identificado por un usuario final en el entorno de producción (cuando ya se considera un defecto).
Lean Software Development acepta que cometemos errores continuamente, y entiende que el coste (desperdicio generado) es mayor cuanto más tarde se detecte y arregle.
Para ilustrar cómo se estructura y visualiza esta detección progresiva de errores, a continuación muestro dos ejemplos reales de pipelines que usamos. En ambos casos, se organizan los distintos pasos (checks, tests, publicación, despliegue, validaciones en producción, rollback...) de forma que sea fácil detectar cualquier error lo antes posible, detener el proceso y corregirlo. Esta visualización ayuda no solo a estructurar mejor el flujo de trabajo, sino también a que todo el equipo entienda claramente en qué etapa puede aparecer cada tipo de error.
En este primer pipeline, cada componente (webapp, API, event processor…) tiene sus propios checks, tests unitarios, de integración y de aceptación, así como procesos de publicación y despliegue diferenciados por entorno (dev y mgmt). Además, se automatizan las pruebas end-to-end en producción antes de activar los cambios, y se incluye una lógica de rollback si algo falla. Esta estructura refuerza el principio de detener el flujo automáticamente ante errores y facilita la trazabilidad en cada etapa.
En este segundo ejemplo, más centrado en validaciones estructurales y pruebas especificas de ciertas tecnologías (argo workflows en este caso), se destacan fases adicionales como los static checks, tareas de cleanup antes de publicar la imagen en ECR y pruebas de integración con diferentes configuraciones. Este tipo de pipeline muestra cómo incluso tareas auxiliares como la validación de configuración o la limpieza del entorno son parte integral de un enfoque que busca detectar errores antes de que duelan.
Política parar y arreglar
Jidoka, también conocido como "autonomación" o "automatización con un toque humano", es un principio clave de Lean Software Development. No se trata solo de automatizar procesos, sino de automatizarlos de manera que se detengan automáticamente cuando se detecta un problema, permitiendo que los equipos investiguen y resuelvan la causa raíz antes de continuar. Aplicando el concepto Jidoka, los equipos que trabajan con Lean Software Development diseñan procesos de desarrollo en los que es muy fácil detectar errores. Bien porque son detectados de forma automática en la mayoría de los casos, o bien de forma manual gracias a un proceso de desarrollo que facilita la identificación de esos errores.
Para que la mejora continua de la calidad funcione, no solo necesitamos detectar esos errores, sino que es clave parar inmediatamente (Ver https://en.wikipedia.org/wiki/Andon_(manufacturing)) y contar con una política que nos obligue a priorizar su resolución de inmediato. Esta forma de trabajar puede parecer demasiado radical al principio y dar la impresión de que puede reducir la velocidad del equipo. Sin embargo, mi experiencia es justo la contraria. Si desde el principio adoptas un enfoque de trabajo en el que, al detectar un error, lo analizas, aprendes de él y lo solucionas de raíz —por ejemplo, añadiendo un test que evite que vuelva a ocurrir—, en muy poco tiempo consigues un proceso que resuelve los errores lo antes posible. Esto elimina un montón de retrabajo y de potenciales problemas para el cliente final, a la vez que genera una gran confianza en el equipo para moverse rápido, tomar riesgos y experimentar.
De hecho, considero que es la mejor forma de ir rápido de forma sostenida, y los estudios de los DORA Reports y el libro Accelerate confirman que la mejor manera de ser rápido es hacerlo con calidad. Al menos, si hablamos de desarrollo de producto.
En mi caso, esta aplicación del enfoque Jidoka se refleja en:
- Tests automáticos que, al detectar un fallo, interrumpen temporalmente el flujo de desarrollo para evitar que el error se propague.
- Git hooks (pre-commit, pre-push, etc.) que interrumpen el flujo si se intenta subir código con errores.
- Trabajo en trunk based development, una estrategia donde todos los desarrolladores integran sus cambios en una única rama principal. En esta configuración, ejecutamos todas las validaciones en la rama principal. Cuando un test falla en integración continua, paramos para arreglarlo inmediatamente. Esto es crucial en "trunk based development" porque cualquier fallo bloquea la capacidad de integrar nuevos cambios, asegurando que la rama principal siempre esté en un estado estable y listo para ser desplegado. Esta disciplina es fundamental para mantener la calidad y evitar la acumulación de errores, permitiéndonos movernos rápido con confianza.
- Priorización automática en el flujo de trabajo para la resolución de bugs detectados en producción, siguiendo un proceso de gestión de incidentes con postmortem para los incidentes de producción. Esta priorización automática se basa en la severidad del error y su impacto en el cliente, determinando qué bugs se abordan primero. (https://www.eferro.net/2024/12/using-blameless-incident-management-to.html).
- Pair programming o ensemble programming, donde varias personas trabajan juntas en una misma tarea, lo que permite detectar malentendidos o errores potenciales desde el inicio. Esta colaboración intensa actúa como una revisión continua que previene muchos errores, tanto en el entendimiento del problema como en la implementación de la solución.
Tratar con defectos y aprender de ellos
Asumir que vamos a cometer errores —y que algunos se convertirán en defectos— es parte fundamental del enfoque Lean. En lugar de negarlo o esconderlo, lo aceptamos como algo natural. Trabajamos en entornos complejos, con múltiples dependencias, incertidumbre constante y, además, somos humanos. Somos falibles por definición.
Eso no quiere decir que no intentemos evitar los errores o defectos. Al contrario, ponemos mucho esfuerzo en prevenirlos con técnicas como poka-yoke, tests automáticos, pair programming, diseño evolutivo y muchas otras prácticas que forman parte de nuestro día a día. Aun así, sabemos que ocurrirán. Y cómo lo sabemos, nos preparamos para que su impacto sea mínimo y el tiempo de recuperación, el menor posible.
Este cambio de mentalidad es clave: pasamos de una obsesión por evitar el error a toda costa a una estrategia más robusta y sostenible, basada en la rapidez de recuperación (resilience) y en la capacidad de aprendizaje. Porque cuando un defecto llega a producción, el primer objetivo es recuperar el servicio lo más rápido posible. Y justo después, aprender.
Durante los últimos años, en varios de los equipos en los que he trabajado, hemos ido refinando y aplicando un enfoque basado en blameless incident management. La idea es sencilla: cuando ocurre un incidente, no buscamos culpables. Nos centramos en entender qué ha pasado, cómo el sistema ha contribuido al error y qué podemos hacer para evitar que se repita o para reducir su impacto la próxima vez.
Este tipo de enfoque, por simple que parezca, ha tenido un impacto enorme en la cultura de los equipos. Aporta seguridad psicológica, genera confianza, fomenta la transparencia y ayuda a que la gente se atreva a hacer visibles los problemas sin miedo. En TheMotion, Nextail y ClarityAI lo usamos no solo como forma de gestionar incidentes, sino como una de las principales palancas para evolucionar la cultura hacia una más colaborativa, orientada al aprendizaje y centrada en la mejora continua.
Por ejemplo, en un incidente reciente donde un servicio falló, aplicamos los 5 Whys y descubrimos que el problema inicial (un error en una configuración) había desencadenado una serie de eventos en cascada debido a la falta de manejo de errores en otro servicio. Esto nos llevó a añadir tests de integración más robustos y a mejorar la resiliencia del segundo servicio.
Nuestro proceso de gestión de incidentes blameless se apoya en varios principios:
- Mantener la calma. No entrar en pánico. Incluso en los procesos de entrevista valoramos esta capacidad como una señal de madurez profesional.
- Asignar un Incident Commander que coordine la respuesta y asegure que nadie se quede solo apagando fuegos.
- Recuperar el servicio cuanto antes. A veces implica desactivar una funcionalidad, comunicar al cliente o hacer una mitigación temporal. Lo importante es estabilizar el sistema.
- Analizar en profundidad lo ocurrido, sin buscar una “causa raíz” única. Entendemos que los incidentes suelen deberse a una combinación de causas y circunstancias. Usamos técnicas como los 5 Whys, repitiendo la pregunta “¿por qué?” a partir del primer síntoma visible. Al hacerlo en grupo, desentrañamos los distintos factores que contribuyeron al incidente. Muchas veces descubrimos fallos en el proceso, en los supuestos, en la comunicación o incluso en la interpretación de los datos.
- Definir acciones correctivas y preventivas que no solo eviten el problema, sino que reduzcan el tiempo de recuperación futuro y aumenten la resiliencia del sistema.
- Integrar estas acciones en el flujo normal de trabajo, para que no se queden en papel mojado.
- Usar un informe de incidente blameless, público dentro de la empresa y colaborativo, que sirva como base para el aprendizaje colectivo. Este proceso de análisis y aprendizaje continuo es un ejemplo de Kaizen, la mejora continua aplicada a la gestión de incidentes, donde buscamos constantemente formas de mejorar nuestros procesos y evitar errores futuros.
Estos informes incluyen resumen, línea temporal, causas, acciones y aprendizajes. Compartirlos abiertamente refuerza el mensaje: los errores no se esconden, se aprenden. Y cuando todo el equipo lo interioriza, la organización mejora más rápido.
Al final, se trata de reforzar un mensaje claro: los incidentes son inevitables, pero cómo respondemos a ellos es lo que realmente define nuestra cultura. Podemos esconderlos, culpar y pasar página... o podemos usarlos como catalizadores de mejora y aprendizaje continuo. En Lean Software Development, elegimos lo segundo.
En la siguiente entrega…
Una vez que hemos establecido cómo detectar y responder rápidamente a los errores, es crucial construir una base sólida. En la tercera parte, profundizaremos en la calidad interna como base del desarrollo sostenible. Veremos por qué menos es más, cómo la simplicidad y el diseño bien cuidado aceleran el desarrollo y cómo una buena base técnica permite moverse rápido sin romper cosas.
No comments:
Post a Comment