Friday, May 16, 2025

Lean Software Development: Quality as the Foundation of Sustainable Development

Third part of the series on quality in Lean Software Development. After exploring how to detect errors early and learn from them, in this entry we explore how technical and internal quality is key to sustaining external quality, why less is more, and how to create a culture where working with quality is not the exception but the norm. In this entry, we explore how this foundational quality is not a luxury but the essential hygiene of a well-crafted software product.

Quality as a Development Accelerator

One of the most widespread beliefs, especially in organizations that haven’t yet adopted Lean approaches, is that working with quality slows down development. It’s assumed that writing tests, automating validations, or refactoring consumes time that could be spent "delivering faster." However, from the perspective of Lean Software Development, this view is not only wrong—it perpetuates waste.

In reality, well-understood quality is an accelerator. When the system is healthy—with reliable automated tests, simple design, and robust processes—every step we take has less friction. The team’s confidence in its ability to change the system grows, feedback is faster, and the cost of change drops dramatically. In other words, we go faster not despite quality, but thanks to it.

This is fully aligned with the Lean principles we've been explaining in this series (poka-yoke, jidoka, kaizen).

Moreover, when the team trusts its system—because it knows that errors are detected in time, that the design allows for easy evolution, and that experiments can be conducted without breaking anything—it dares to innovate, try new ideas, and quickly adapt to what it learns from the user. In short, it enables the continuous delivery of value.

In my experience, teams that invest in quality from the beginning and incorporate it as part of their way of working progress much more steadily, quickly, and with less emotional cost. They don’t have to constantly stop to "fix the system" because they never let it deteriorate. And that’s possible because they understand that quality isn’t inspected at the end—it’s built into every step.

Internal Quality as the Foundation of External Quality

In Lean Software Development, external quality—the one users or clients directly perceive—is a priority. However, to sustain that quality over time, solid internal quality is essential: a well-designed, understandable system that can be maintained and evolved without fear.

Many times, the defects visible to users originate from invisible problems within the system: tightly coupled code, unreliable tests, contextless technical decisions, or fragile processes. These issues not only cause errors, they slow down the team, hinder adaptation to change, and raise the cost of delivering value. They are a silent but very real form of waste.

Lean encourages us to see these structural problems as improvement opportunities (kaizen) and to address them systematically. It's not about “beautifying the code” or following arbitrary rules, but about building a solid technical foundation that reduces everyday friction and enables rapid, confident progress.

We also apply jidoka in this context: when a flaky test, opaque dependency, or hard-to-deploy system blocks progress, we flag it as a system problem, not an individual weakness. We stop, analyze, and improve the technical infrastructure to prevent recurrence. Every small change counts. For example, if a deployment fails repeatedly, we don’t just try again—we investigate the root cause and automate a solution, like a script that checks database availability before deployment.

Moreover, poka-yoke principles also apply to internal quality. Using strong typing, simple design patterns, proper encapsulation, and tools that make the right thing easy to do without constant effort are ways to prevent technical errors and ease system evolution. The easier it is to do the right thing, the less likely it is to introduce debt or accidental errors. For example, using a code linter to catch syntax errors before they reach production, or configuring version control to prevent unreviewed code from being committed.

In summary, internal quality isn’t an end in itself—it’s a means to sustainably ensure external quality. When the system is easy to understand, test, and change, the team can focus on delivering value, learning faster, and better adapting to customer needs. That structural simplicity is what allows us to build with quality—and move fast without breaking things.

Graph showing internal quality as the foundation upon which external quality is built.

Quality is Not Complexity or Sophistication

A common confusion in software engineering is associating quality with technical sophistication. “Beautiful” code, elegant solutions, or complex designs anticipating future needs are often praised. However, from a Lean Software Development perspective, this view is fundamentally flawed. In reality, quality is not a luxury—it is a basic necessity, the fundamental hygiene of a well-built software product.

Lean doesn’t reward unnecessary complexity or overdesign. Quite the opposite: it promotes deliberate simplicity as a way to reduce waste, ease system evolution, and ensure reliability. Quality in this context is not measured by how many design patterns we apply or how "intellectually interesting" the design is, but by how well it solves the current problem with the least effort and risk. It’s like cleanliness in a home: not an ornament, but the minimum necessary for healthy living.

Every line of code we don’t need right now is a potential source of error. It not only adds maintenance cost, but also complicates understanding, slows evolution, and can mislead decisions.

"The best code is no code at all" — Ward Cunningham

From Lean’s perspective, anticipating features that don’t yet exist or designing systems beyond current needs is a form of waste. It’s also a kaizen failure, as it prevents learning and iteration step by step. And it breaks poka-yoke by introducing optional, unvalidated paths not covered by tests. Instead of preventing errors, we’re planting them.

Quality in Lean is built with clear, tested, understandable code, limited to what is strictly necessary. We care about design not to make it more complex, but simpler, safer, and easier to evolve. We rely on tests, continuous feedback, evolutionary design, and constant refactoring to keep the system healthy without falling into the trap of planning the future from the present.

So no: technical beauty or overdesign is not quality. Often, it’s its enemy. Building with quality in Lean is, above all, having the humility to do just enough, do it well, and prepare to improve based on what we learn tomorrow.

Conclusions: Quality as Basic Hygiene

In summary, quality in Lean Software Development is not an optional feature or a sophisticated extra. It is the base, the foundation, the essential hygiene of a sustainable and valuable software product. It’s not about seeking complexity or elegance for their own sake, but about building a system that is clear, simple, tested, and easy to maintain.

Quality is like the air we breathe: we don’t always notice it, but its absence quickly suffocates us. Software without quality is software doomed to fail—full of bugs, hard to change, and expensive to maintain. That’s why investing in quality from the start, and seeing it as an essential practice rather than a luxury, is the best way to ensure long-term success.

Quality is not a bonus—it’s the bare minimum. And simplicity is its best ally.

In the fourth part, we’ll see how collaboration and visibility are also essential to maintain this hygiene and build sustainable quality software.


Thursday, May 15, 2025

Lean Software Development: Superando resistencias y creando condiciones para la calidad

Quinto artículo sobre calidad en Lean Software Development. En los posts anteriores hablamos de cómo construir con calidad desde los errores, el diseño técnico, la colaboración y la visibilidad. Ahora abordamos un tema clave: por qué muchas organizaciones aún no trabajan así, y qué podemos hacer para cambiarlo.

En el mundo del desarrollo de software, existe un mito persistente: que la calidad y la velocidad son fuerzas opuestas, que hay que sacrificar una para obtener la otra. Sin embargo, la realidad, como demuestran los informes DORA y la experiencia de equipos de alto rendimiento, es que la calidad es el camino más directo y sostenible hacia la mayor velocidad posible.

Existe una paradoja fundamental: cuanto más nos obsesionamos con la velocidad inmediata sacrificando calidad, más lentos nos volvemos. Los equipos que acumulan deuda técnica, bugs no resueltos, o código difícil de mantener hacen que cada nueva funcionalidad sea exponencialmente más costosa. Lo que parecía una decisión "pragmática" se convierte en un lastre que ralentiza todo el sistema.

El verdadero pragmatismo está alineado con los principios Lean: posponer decisiones hasta tener información suficiente, aplicar YAGNI (You Aren't Gonna Need It), mantener un diseño simple, e iterar constantemente para tener la versión más sencilla del sistema que cumpla con las necesidades actuales. Esto es ser realmente pragmático.

Es importante entender que en la época que vivimos, de continuo cambio y adaptación del software, cuando hablamos de "medio plazo" en realidad nos referimos a unas pocas semanas. No estamos hablando de meses o años para ver los beneficios de la calidad. Los efectos de trabajar con calidad se notan en muy poco tiempo, y ese supuesto trade-off a corto plazo solo tiene sentido para software de usar y tirar.

En el pensamiento Lean, la forma de tener más impacto es minimizar el desperdicio, siendo la falta de calidad uno de los principales desperdicios en software. Así que la combinación ganadora en desarrollo de software es maximizar el impacto, minimizando la cantidad de software generada, y haciéndolo con calidad en el proceso. El enfoque no es hacer peor o más rápido, sino ser inteligente y disciplinado para conseguir tener más impacto con menos, y con calidad. Esta es la verdadera forma de ir rápido, lograr el máximo impacto y ser un equipo de alto rendimiento sostenible.

Motivos comunes para no trabajar así (resistencias frecuentes)

Presión por velocidad a corto plazo

"No tenemos tiempo para escribir tests", "hay que entregar ya". Esta es la más clásica. Sin embargo, como ya hemos visto, los tests bien integrados en el flujo de desarrollo permiten avanzar más rápido y con menor coste a medio plazo.

En entornos donde se valora el output inmediato, invertir en calidad al inicio puede parecer más lento, pero evita una ralentización mayor incluso a corto plazo. No estamos hablando de beneficios que tardan meses en llegar —en cuestión de semanas ya se nota la diferencia cuando la deuda técnica no se acumula y el desperdicio se mantiene bajo control. Las prácticas Lean suelen malinterpretarse como un freno inicial, pero su verdadero valor se revela claramente cuando el sistema empieza a fallar y se evidencia el coste real de no haber invertido en calidad.

Desalineación entre negocio y tecnología

Si el negocio solo mide entregas visibles (features) y no entiende el valor del refactor, los tests o el diseño simple, se generan incentivos perversos que empujan a evitar todo lo que no "se vea".

Aquí es necesario alinear los incentivos, demostrando con datos que la inversión en calidad genera un mayor retorno. Además, el desperdicio de construir funcionalidades innecesarias o mal entendidas se dispara cuando falta esta alineación. Y no nos engañemos, el desperdicio fundamental en el desarrollo de producto software es implementar lo que no se necesita, y además mantenerlo durante toda la vida del producto. Ya sabemos que el coste basal no se aplica solo a las funcionalidades que se usan.

Falta de formación o experiencia

Para muchas personas, esta forma de trabajar es nueva. No han visto entornos con trunk-based development, TDD o automatización real. Si no han vivido sus beneficios, es normal que desconfíen o los subestimen. Algunas de estas prácticas requieren un cambio de mentalidad significativo y competencias técnicas específicas que necesitan tiempo para desarrollarse. La inversión en formación y mentorización es clave para superar esta barrera inicial y construir la confianza necesaria en estos métodos.

Miedo al cambio

El temor a lo desconocido es una respuesta natural humana. Muchos equipos se sienten cómodos con sus procesos actuales, incluso si son ineficientes. Cambiar rutinas establecidas genera incertidumbre y resistencia. Este miedo puede manifestarse como escepticismo ("esto no funcionará aquí") o incluso como sabotaje pasivo. La transición requiere liderazgo efectivo, comunicación clara de los beneficios esperados y creación de un entorno seguro donde experimentar con nuevos métodos sea valorado y respaldado.

Falta de calidad estructural

Algunos equipos quieren trabajar con calidad, pero ya tienen un sistema lleno de deuda, sin tests, sin confianza. Cambiar requiere una inversión que muchas veces la organización no está dispuesta a hacer. Aquí la mejora debe ser incremental, con wins visibles: reducir el tiempo de despliegue en un 10%, arreglar los 3 bugs más críticos, etc. Establecer "zonas limpias" en el código y expandirlas gradualmente puede ser una estrategia efectiva para recuperar terreno sin necesidad de una reescritura completa.

Inercia organizativa y estructuras rígidas

Si los equipos no tienen autonomía, si las decisiones se toman desde arriba sin feedback técnico, o si los procesos de release, QA o seguridad están fuera del equipo, es difícil aplicar jidoka o reaccionar rápido a problemas.

El sistema inhibe la calidad y el desperdicio de tiempo y recursos aumenta exponencialmente mientras los problemas persisten.

Cultura del castigo y la culpa

Si la organización no tolera errores, si se busca culpables en lugar de causas, o si los incidentes generan miedo en vez de aprendizaje, se oculta el error en lugar de visibilizarlo. Y sin visibilidad, no hay mejora ni se puede reducir el desperdicio.

El miedo paraliza la innovación, retrasa la identificación de problemas y oculta el desperdicio en todos los niveles.


Aunque parezca exagerado, muchas organizaciones se enfrentan a esta disyuntiva cuando ven que su forma de trabajar ya no es sostenible. Mejorar requiere esfuerzo, pero no mejorar tiene consecuencias inevitables.

Improve or die meme


Crear las condiciones para construir con calidad

Trabajar con calidad, como hemos visto a lo largo de esta serie, no depende solo de herramientas ni de talento individual. Es una consecuencia directa del entorno (sistema) que construimos. La calidad no surge de forma espontánea: necesita espacio, alineación y una cultura que la valore.

Desde Lean Software Development, partimos de una premisa: las personas quieren hacer un buen trabajo. Pero si los incentivos, los hábitos y la cultura no acompañan, incluso los equipos con las mejores intenciones caerán en prácticas que sacrifican la calidad en favor de la urgencia, el volumen o la apariencia de productividad. Y esto inevitablemente lleva a generar mucho desperdicio.

“A bad system will beat a good person every time.”
—W. Edwards Deming

Como líderes en desarrollo de productos, tenemos una responsabilidad clara: crear las condiciones adecuadas para que la calidad no solo sea posible, sino inevitable. Esto implica intervenir en tres dimensiones clave: los incentivos, los sistemas de trabajo y la cultura.



La calidad no mejora actuando solo sobre lo visible. Como bien resume Donella Meadows, existen muchos niveles desde los que intervenir en un sistema. Cuanto más profundo es el punto de intervención (mentalidad, cultura, estructura), mayor es su impacto. Este marco nos recuerda que si queremos calidad sostenible, no basta con ajustar métricas: hay que transformar cómo pensamos y cómo trabajamos.

Lugares para intervenir en un sistema según Donella Meadows
Lugares para intervenir en un sistema según Donella Meadows

Redefinir el éxito

En lugar de celebrar solo la cantidad de funcionalidades entregadas o la velocidad aparente, enfoquémonos en el impacto real, en la sostenibilidad del sistema y en la capacidad del equipo para adaptarse con confianza.

Calidad no es entregar más, sino poder entregar mejor: con menos riesgo, manteniendo un ritmo sostenible, aprendiendo continuamente y anticipando mejor los cambios.

Dar espacio al aprendizaje y la mejora continua

Uno de los errores más comunes es pensar que el tiempo para el Kaizen es prescindible. Pero reservar tiempo para refactorizar, automatizar, revisar procesos o simplificar no es un lujo: es parte del trabajo del equipo y una inversión en salud del sistema.

Para hacerlo posible, necesitamos introducir slack intencional: espacio planificado para observar, aprender y mejorar. Sin ese margen, todo el tiempo se dedica a entregar, y no queda energía ni foco para el Kaizen.

La mejora continua requiere tiempo, atención y un ritmo sostenible. Es lo que permite reducir el desperdicio de forma constante.

Cuidar la cultura del equipo

La seguridad psicológica es clave. Si hay miedo a equivocarse o a señalar problemas, no habrá jidoka, kaizen ni visibilidad. Solo en un entorno donde se pueda dudar, explorar y aprender sin castigo podremos detectar errores a tiempo y mejorar juntos, reduciendo el desperdicio que generan.

También debemos evitar incentivar el trabajo heroico: cuando el buen resultado depende solo del esfuerzo extraordinario de una persona, es señal de que el sistema está fallando.

En lugar de héroes, necesitamos equipos que trabajen de forma sostenible, con procesos que aseguren calidad de manera continua y predecible. El trabajo heroico suele ser un generador crónico de desperdicio.

Además, hay que dar autonomía real: decidir tecnologías, diseñar los procesos de testing, tener voz en la planificación, etc. Un equipo sin control sobre su entorno técnico, su flujo de trabajo o su forma de validar lo que construye, difícilmente podrá garantizar calidad.

La autonomía, combinada con responsabilidad compartida, es uno de los pilares más fuertes de la calidad en Lean.

Por último, hay que alinear los incentivos con la calidad. Reconocer y visibilizar el trabajo que permite que todo fluya: no solo las nuevas funcionalidades, sino también cuando se reduce deuda técnica, se mejora el proceso de testing, se evita una caída en producción o se simplifica una parte crítica del sistema.

Todo eso también es valor entregado. Y suele ser el que más perdura.

Cómo hacer que la calidad sea inevitable: liderazgo en la práctica

Hacer posible la calidad no consiste en pedir más esfuerzo a los equipos. Consiste en cambiar el sistema para que trabajar con calidad sea lo más natural, lo más sencillo y lo más rápido. A lo largo de los años, he intentado sistematizar este enfoque con decisiones muy concretas. Aquí algunas de ellas:

  • Reservar espacio para el aprendizaje. Decidir activamente qué parte del tiempo se invierte en aprender. A veces es formación, otras veces simplemente es preguntar: “¿Qué habéis aprendido? ¿Qué podéis compartir?”.
  • Convertir los errores en aprendizaje colectivo. Introducir blameless postmortems. Liderar los primeros, definir el proceso, normalizar que los errores no son culpa, sino oportunidades de mejora.
  • Liderar con el ejemplo. Aplicar TDD, diseño evolutivo, pairing. Ser el primero en documentar y actuar sobre incidencias. No exigir lo que no se practica.
  • Introducir Technical Coaching. Aprender junto a quienes ya dominan prácticas como TDD o Pair Programming. Si es posible, traer personas expertas con experiencia real.
  • Cambiar los procesos de contratación. Evaluar cómo trabajan, no solo qué saben. Introducir TDD, pairing, diseño colaborativo como parte del proceso.
  • Recompensar y visibilizar mejoras estructurales. Valorar explícitamente lo que mejora la calidad: reducción de deuda, mejor estrategia de tests, simplificaciones, etc.

Este tipo de liderazgo que busca cambiar el sistema para hacer la calidad inevitable no es una intuición aislada. Estudios como los del informe DORA demuestran que el liderazgo transformacional, junto con prácticas Lean, tiene un impacto claro en la performance del equipo, el bienestar y los resultados de negocio.

Modelo de impacto del liderazgo transformacional según DORA
Modelo de impacto del liderazgo transformacional según DORA / Accelerate


Liderar para hacer la calidad inevitable

Construir con calidad no es solo una cuestión de prácticas técnicas: es, sobre todo, una cuestión de liderazgo. Nuestro papel como líderes no es exigir calidad como si fuera un extra opcional, sino entender que es la base para una velocidad sostenible, para reducir el desperdicio y para maximizar el impacto real.

La calidad no es una meta ni una opción: es el sistema operativo sobre el que se apoya todo lo demás. Si ese sistema falla, cualquier intento de avanzar rápido nos lleva directo al colapso.

Nuestro trabajo como líderes es crear las condiciones donde la calidad no dependa de la voluntad individual, sino que sea lo más fácil, lo más rápido y lo más natural. Donde construir con calidad no sea un acto heroico, sino lo inevitable.

Wednesday, April 30, 2025

Good talks/podcasts (April)

These are the best podcasts/talks I've seen/listened to recently:
  • AWS re:Invent 2023 - Do modern cloud applications lock you in? (Gregor Hohpe) [Architecture, Cloud, Software Design, Technology Strategy] [Duration: 00:55] (⭐⭐⭐⭐⭐) This talk reframes modern cloud application lock-in as switching costs, explaining how to manage them through architecture trade-offs, increasing developer velocity, and focusing on design intent rather than just service selection
  • Test Driven DESIGN - Step by Step (Dave Farley) [Small Safe Steps (3s), Software Design, Technical Practices, testing] [Duration: 00:24] In this episode Dave Farley describes how to use TDD to build your system in a series of small steps, using a project of his own to demonstrate the approach.
  • Anthropic CEO Declares Programming Over, We Respond (Ray Myers) [AI, Engineering Culture, Generative AI] [Duration: 00:22] (⭐⭐⭐⭐⭐) The talk discusses reactions and scenarios related to the Anthropic CEO's prediction that AI will soon write essentially all code, proposing challenges to this claim and exploring different potential futures for software engineering roles and processes
  • Keynote: AI without the BS, for humans (Scott_Hanselman) [AI, Generative AI, Mental models, ethics] [Duration: 00:58] Scott Hanselman's "AI without the BS" talk cuts through the hype, explaining AI models as statistical predictors based on context and biased data, highlighting ethical concerns, and demonstrating the practicality of running smaller models locally
  • Observability 2.0: Transforming Logging & Metrics • Charity Majors & James Lewis (Charity Majors, James Lewis) [Engineering Culture, Observability, Platform engineering] [Duration: 00:30] Interesting interview about observability, and the tools and models needed to develop a systems thinking approach that allows us to understand and manage our software systems, which are often complex and distributed.
  • Observability & Testing in Production (Charity Majors, Luca Rossi) [Continuous Delivery, Observability, Testing in production] [Duration: 00:53] Charity Majors, CTO at Honeycomb and observability expert, discusses observability, testing in production, continuous delivery, and developer experience
  • Human Robot Agent: Scouting AI Beyond Hype and Doom (Jurgen Appelo) [AI, Agile, Generative AI, Teams] [Duration: 00:53] (⭐⭐⭐⭐⭐) Jurgen Appelo discusses how AI is fundamentally changing the nature of work, teams, and processes within an agile context, highlighting new uncertainties and the enduring importance of the human experience.
  • Software Engineering F&*K Up Behind The Passport E-gate Failure" (Dave Farley) [Architecture, Resilience, Software Design] [Duration: 00:17] In this episode, Dave Farley talks about the issue, how poor software engineering led to this, how distributed systems come into it all, how to avoid something like this happening again and at the end of the video asks for answers on some concerning issues around the whole story.
Reminder: All of these talks are interesting, even just listening to them.

You can now explore all recommended talks and podcasts interactively on our new site: The new site allows you to:
  • 🏷️ Browse talks by topic
  • 👤 Filter by speaker
  • 🎤 Search by conference
  • 📅 Navigate by year
Feedback Welcome!
Your feedback and suggestions are highly appreciated to help improve the site and content. Feel free to contribute or share your thoughts!
Related:

Sunday, April 27, 2025

Lean Software Development: Calidad desde la colaboración y la visibilidad

 Cuarta parte de la serie sobre calidad en Lean Software Development. En la entrega anterior hablamos de cómo la calidad técnica e interna es clave para sostener la calidad externa y acelerar el desarrollo.

Calidad desde la colaboración y el diseño compartido

Una parte esencial de la calidad, que a menudo se subestima, no está en el código ni en las herramientas, sino en cómo trabajamos juntos. En Lean Software Development, los errores no se entienden solo como fallos técnicos, sino también como fallos de entendimiento. Muchos de los defectos que llegan a producción no se deben a que el código esté mal escrito, sino a que no resuelve el problema correcto, o no lo hace de la forma adecuada.

Por eso, uno de los mecanismos clave para construir con calidad es la colaboración cercana y continua entre todas las personas involucradas: quienes diseñan, desarrollan, prueban o hablan con los usuarios. Cuanto antes se comparta el entendimiento del problema y se alineen expectativas, menos errores se introducirán en el sistema. De nuevo, calidad desde el origen.

Prácticas como el pair programming, el trabajo en ensemble, el uso de ejemplos concretos en conversaciones con negocio o el diseño compartido de soluciones son mecanismos que permiten detectar errores —técnicos y conceptuales— tan pronto como aparecen. De esta forma, favorecen una intervención temprana coherente con el espíritu de jidoka. Y lo hacemos de forma natural, porque hay muchas miradas sobre el problema, muchas oportunidades de hacer visibles los malentendidos.

Este enfoque colaborativo también refuerza el kaizen, porque facilita la mejora continua. Las ideas se contrastan, se explican, se afinan. El sistema evoluciona de forma más coherente porque no depende de decisiones individuales aisladas, sino de un conocimiento compartido y distribuido.

Además, colaborar reduce el desperdicio: se construye lo que realmente se necesita, se evitan suposiciones erróneas y se minimizan los retrabajos. Las soluciones tienden a ser más simples porque han sido discutidas y refinadas desde distintos ángulos.

En definitiva, si entendemos que construir con calidad es evitar defectos, reducir desperdicio y mantener un sistema sano que podamos evolucionar con confianza, entonces colaborar no es opcional. Es una de las formas más potentes de prevenir errores antes de que se conviertan en código.


El valor de visibilizar la calidad (o su falta)

Uno de los principios fundamentales de Lean es hacer los problemas visibles. Si no podemos ver un problema, no podemos mejorarlo. Y si la calidad no es visible para el equipo, para quienes toman decisiones o para quienes dan soporte al producto, entonces difícilmente será una prioridad.

Por eso, en Lean Software Development es esencial visibilizar el estado real de la calidad en todo momento. No solo mediante métricas técnicas, sino también con mecanismos que hagan evidente cuándo algo está fallando, cuándo acumulamos desperdicio o cuándo estamos arriesgando la estabilidad del sistema.

Esto se conecta directamente con jidoka: cualquier señal de problema, por pequeña que sea, debería detener el flujo o hacernos prestar atención. Ya sea un test que falla, una alerta de monitorización, una caída en la cobertura o un aumento del tiempo medio de resolución de bugs, todo debería encender una luz. El objetivo es que nada pase desapercibido y podamos actuar a tiempo.

También es un refuerzo constante de kaizen: lo que no se ve, no se mejora. Visibilizar la calidad —interna y externa— nos permite tomar decisiones informadas sobre dónde enfocar nuestro esfuerzo de mejora. Si vemos que los defectos en producción provienen siempre de cierta parte del sistema, probablemente necesitemos reforzar nuestras pruebas allí. Si la velocidad de cambio se reduce, quizás la complejidad esté creciendo sin control.

Los mecanismos para visibilizar la calidad pueden ser muchos: desde dashboards de integración continua hasta alarmas en producción, desde paneles físicos con bugs abiertos hasta reuniones periódicas de revisión de incidentes. Lo importante no es la herramienta, sino el hábito de mirar con honestidad el estado del sistema y del proceso.

Hacer visible la calidad (o su ausencia) también tiene un efecto cultural: refuerza la responsabilidad compartida. Si todos vemos que hay un problema de calidad, es más fácil que todos participemos en su solución. Se elimina la invisibilidad del deterioro, se evita la resignación y se fomenta un entorno donde los problemas se atacan en cuanto aparecen.

Porque, al final, construir con calidad es también construir con transparencia.

Calidad como hábito organizativo

Construir con calidad no es una fase del proceso, ni una tarea asignada a una persona concreta, ni algo que se pueda “añadir al final”. Es una forma de trabajar, un hábito que se cultiva a diario y que atraviesa todo lo que hacemos: cómo diseñamos, cómo escribimos código, cómo colaboramos, cómo resolvemos problemas y cómo aprendemos.

En Lean Software Development, la calidad no es negociable, porque es la base de todo lo demás. Sin calidad, el flujo se rompe, el aprendizaje se ralentiza, el coste del cambio crece y la confianza desaparece. Por eso, la calidad no se persigue por un ideal técnico, sino porque es el camino más eficaz para entregar valor de forma continua y sostenible.

Los principios de jidoka, poka-yoke y kaizen están presentes en cada práctica que hemos mencionado: en los tests automatizados que detienen el flujo ante un fallo, en los procesos que previenen errores humanos, en la mejora constante de nuestras herramientas y procesos, en la forma en que tratamos los incidentes como oportunidades de aprendizaje.

Pero nada de esto funciona si no se convierte en parte de la cultura del equipo. La calidad no emerge por azar ni por buenas intenciones: surge cuando hay prácticas concretas que la sustentan, cuando existen acuerdos compartidos sobre cómo trabajar, y cuando el entorno refuerza esos comportamientos una y otra vez. Es decir, cuando hay hábitos.

Y como todo hábito, se entrena. Se empieza con pequeños gestos: escribir un test antes de arreglar un bug, parar el desarrollo para investigar un error, revisar el diseño con otra persona antes de implementar. Con el tiempo, estos gestos se vuelven la forma natural de trabajar. El equipo gana confianza, el sistema se mantiene sano y los problemas se abordan con rapidez y serenidad.


En la última entrega, exploraremos por qué muchas organizaciones aún no trabajan con calidad, incluso sabiendo sus beneficios. Veremos las resistencias más comunes y cómo podemos crear un entorno donde la calidad no dependa del esfuerzo heroico, sino que sea una consecuencia natural del sistema.


Sunday, April 20, 2025

Lean Software Development: Calidad como base del desarrollo sostenible

Tercera parte de la serie sobre calidad en Lean Software Development. Después de ver cómo detectar errores a tiempo y aprender de ellos, en esta entrega exploramos cómo la calidad técnica e interna es clave para sostener la calidad externa, por qué menos es más y cómo crear una cultura donde trabajar con calidad no sea la excepción, sino la norma. En esta entrega, exploraremos cómo esta calidad fundamental no es un lujo, sino la higiene esencial de un producto de software bien hecho.

Calidad como acelerador del desarrollo

Una de las creencias más extendidas, especialmente en organizaciones que aún no han adoptado enfoques Lean, es que trabajar con calidad ralentiza el desarrollo. Se asume que escribir tests, automatizar validaciones o refactorizar consume tiempo que podríamos dedicar a “entregar más rápido”. Sin embargo, desde la perspectiva de Lean Software Development, esta visión no sólo es errónea, sino que perpetúa el desperdicio.

En realidad, la calidad bien entendida es un acelerador. Cuando el sistema está sano —con tests automatizados fiables, diseño simple y procesos robustos—, cada paso que damos tiene menos fricción. La confianza del equipo en su capacidad para cambiar el sistema crece, el feedback es más rápido y el coste del cambio se reduce drásticamente. Es decir, vamos más rápido no a pesar de la calidad, sino gracias a ella.

Esto está completamente alineado con los principios Lean que hemos ido explicando en esta serie (poka-yoke, jidoka, kaizen).

Además, cuando el equipo confía en su sistema —porque sabe que los errores se detectan a tiempo, que el diseño permite evolucionar fácilmente y que se puede experimentar sin romper nada—, se atreve a innovar, probar ideas nuevas y adaptarse rápido a lo que aprende del usuario. Es decir, se potencia la entrega continua de valor.

En mi experiencia, los equipos que invierten en calidad desde el principio y la incorporan como parte de su forma de trabajar avanzan de forma mucho más sostenida, rápida y con menor coste emocional. No tienen que parar constantemente para “arreglar el sistema”, porque nunca lo han dejado deteriorarse. Y eso es posible porque entienden que la calidad no se inspecciona al final, sino que se construye en cada paso.


Calidad interna como cimiento de la externa

En Lean Software Development, la calidad externa —la que perciben directamente los usuarios o clientes— es prioritaria. Sin embargo, para que esa calidad se mantenga en el tiempo, es imprescindible contar con una calidad interna sólida: un sistema bien diseñado, comprensible, que se pueda mantener y evolucionar sin miedo.

Muchas veces, los defectos visibles para los usuarios tienen su origen en problemas invisibles dentro del sistema: código acoplado, tests poco fiables, decisiones técnicas tomadas sin contexto o procesos frágiles. Estos problemas no solo generan errores, sino que ralentizan al equipo, dificultan la adaptación al cambio y elevan el coste de entregar valor. Son una forma silenciosa, pero muy real, de desperdicio.

Lean nos invita a ver estos problemas estructurales como oportunidades de mejora (kaizen) y a abordarlos de forma sistemática. No se trata de “embellecer el código” ni de seguir reglas arbitrarias, sino de construir una base técnica sólida que reduzca la fricción del día a día y permita avanzar con rapidez y confianza.

Aplicamos jidoka también en este contexto: cuando un test flaky, una dependencia opaca o un sistema difícil de desplegar nos impide avanzar, lo señalamos como un problema del sistema, no como una debilidad individual. Paramos, analizamos y mejoramos la infraestructura técnica para evitar que vuelva a ocurrir. Cada pequeño cambio suma. Por ejemplo, si un despliegue falla repetidamente, no solo lo intentamos de nuevo, sino que investigamos la causa raíz y automatizamos una solución para evitar que vuelva a ocurrir, como un script que verifica la disponibilidad de la base de datos antes del despliegue.

Además, los principios de poka-yoke también son aplicables a la calidad interna. Usar tipado fuerte, patrones de diseño sencillos, encapsulación adecuada y herramientas que faciliten el trabajo sin requerir esfuerzo constante son formas de prevenir errores técnicos y facilitar la evolución del sistema. Cuanto más fácil sea hacer lo correcto, menos probable será introducir deuda o errores involuntarios. Por ejemplo, usar un linter de código para detectar errores de sintaxis automáticamente antes de que lleguen a producción o configurar un sistema de control de versiones que impida el envío de código sin una revisión adecuada.

En resumen, la calidad interna no es un fin en sí mismo, sino un medio para garantizar la calidad externa de forma sostenible. Cuando el sistema es fácil de entender, probar y modificar, el equipo puede centrarse en entregar valor, aprender más rápido y adaptarse mejor a lo que necesita el cliente. Esa simplicidad estructural es la que permite construir con calidad… y moverse rápido sin romper cosas.


Gráfico que muestra la calidad interna como la base sobre la que se construye la calidad externa.

Calidad no es complejidad ni sofisticación

Una confusión habitual en ingeniería de software es asociar la calidad con la sofisticación técnica. Se valora el código “bonito”, las soluciones elegantes o los diseños complejos que anticipan futuras necesidades. Sin embargo, desde la perspectiva de Lean Software Development, este enfoque es profundamente equivocado. En realidad, la calidad no es un lujo, sino una necesidad básica, la higiene fundamental de un producto de software bien hecho.

Lean no premia la complejidad innecesaria ni el sobrediseño. Todo lo contrario: promueve la simplicidad deliberada como vía para reducir el desperdicio, facilitar la evolución del sistema y garantizar su fiabilidad. La calidad, en este contexto, no se mide por cuántos patrones aplicamos o lo "intelectualmente interesante" del diseño, sino por lo bien que resuelve el problema actual, con el menor esfuerzo y el menor riesgo posible. Es como la limpieza en una casa: no es un adorno, es lo mínimo indispensable para vivir saludablemente.

Cualquier línea de código que no necesitamos ahora mismo es una fuente potencial de errores. No solo añade coste de mantenimiento, sino que complica la comprensión del sistema, frena su evolución y puede inducir a decisiones equivocadas. 

"el mejor código es el que no existe" Ward Cunningham

Desde Lean, adelantarse a funcionalidades que aún no existen o diseñar sistemas más allá de las necesidades actuales es una forma de desperdicio. También es un fallo de kaizen, porque impide iterar y aprender paso a paso. Y rompe con poka-yoke, al introducir caminos opcionales no validados ni protegidos con tests. En lugar de evitar errores, los estamos sembrando.

La calidad en Lean se construye con código claro, probado, comprensible y limitado a lo estrictamente necesario. Cuidamos el diseño no para hacerlo más complejo, sino más simple, seguro y fácil de evolucionar. Nos apoyamos en tests, feedback continuo, diseño evolutivo y refactorización constante para mantener el sistema sano sin caer en la trampa de planificar el futuro desde el presente.

Así que no: la belleza técnica o el sobrediseño no son calidad. A menudo, son su enemigo. Construir con calidad en Lean es, ante todo, tener la humildad de resolver lo justo, hacerlo bien y prepararnos para mejorar según lo que aprendamos mañana.


Conclusiones: Calidad como higiene básica

En resumen, la calidad en Lean Software Development no es una característica opcional ni un adorno sofisticado. Es la base, el cimiento, la higiene fundamental de un producto de software sostenible y valioso. No se trata de buscar la complejidad o la elegancia por sí mismas, sino de construir un sistema claro, simple, probado y fácil de mantener.

La calidad es como el aire que respiramos: no siempre la notamos, pero su ausencia nos ahoga rápidamente. Un software sin calidad es un software destinado al fracaso, lleno de errores, difícil de cambiar y costoso de mantener. Por eso, invertir en calidad desde el principio, y entenderla como una práctica esencial y no como un lujo, es la mejor manera de asegurar el éxito a largo plazo.

La calidad no es un extra, es lo mínimo indispensable. Y la simplicidad, la mejor aliada para conseguirla.

En la cuarta parte, veremos cómo la colaboración y la visibilidad son también fundamentales para mantener esta higiene y construir un software de calidad sostenible.


Friday, April 18, 2025

Lean Software Development: Detect errors before they hurt

Second part of the series on how to build with quality from Lean Software Development. If you haven't yet read the first part of this series, where we explain the fundamentals of Lean Software Development, you can find it here: https://www.eferro.net/2025/04/lean-software-development-building-with.html. After understanding why quality is not just the final result, in this installment we focus on how we detect errors as early as possible, stop the flow when they appear, and learn from them to improve the system.

To avoid confusion, we will use "error" to refer to any deviation from the expected result, and "defect" for errors that impact the customer in production.

Detecting errors as early as possible  

In more traditional approaches, defects are often prioritized based on their criticality, which sometimes determines whether they are fixed and within what timeframe. However, in Lean Software Development, which considers quality a fundamental part of the product and focuses on the continuous improvement of processes and systems, it is more common to classify errors (potential defects) based on where and when they were identified within the process.

Having this information allows us to identify the stages where errors are most common, helping us focus our improvement efforts on detecting them as early as possible (shift left), reducing the likelihood of them becoming defects.

In my experience, it is very useful to classify error detection depending on the stage where they are identified. I usually use the following classification:

  1. Local machine (pair or ensemble work)
    1. Development cycle (including TDD cycle, continuous style verification (linting), type checks, errors, etc.)
    2. Pre-commit
    3. Pre-push
  2. CI Pipeline:
    1. Checks
    2. Tests (classified from fastest to slowest)
    3. Deployment (including smoke tests and validations during rollout)
  3. Production environment
    1. Pre-release (deployed but not activated for the client)
    2. Client activation

When a feature is already activated for the client, it is also useful to classify errors or defects based on who or what detected them:

  1. Automatic system, before it impacts the client (Monitoring)
  2. Internal user, such as a team member running tests or someone from another department
  3. Final user, reporting the defect to support

Regardless of the stage or who detected it, the main goal is always the same: detect (and fix) the error as early as possible, ideally before it is identified by an end user in production (when it is already considered a defect).

Lean Software Development accepts that we make mistakes continuously and understands that the cost (waste generated) increases the later the error is detected and fixed.

To illustrate how this progressive error detection is structured and visualized, I will show two real examples of pipelines we use. In both cases, the various steps (checks, tests, publishing, deployment, production validations, rollback, etc.) are organized to easily detect any error as soon as possible, stop the process, and fix it. This visualization not only helps structure the workflow better but also ensures that the entire team clearly understands at what stage each type of error can appear.

In this first pipeline, each component (webapp, API, event processor…) has its own checks, unit, integration, and acceptance tests, as well as differentiated publishing and deployment processes for different environments (dev and mgmt). Additionally, end-to-end tests are automated in production before activating changes, and a rollback logic is included if something fails. This structure reinforces the principle of automatically stopping the flow when errors occur and facilitates traceability at each stage.

In this second example, more focused on structural validations and specific testing of certain technologies (argo workflows in this case), additional phases such as static checks, cleanup tasks before publishing the image to ECR, and integration tests with different configurations are highlighted. This type of pipeline shows how even auxiliary tasks like configuration validation or environment cleanup are an integral part of an approach that seeks to detect errors before they hurt.

Stop and fix policy

Jidoka, also known as "autonomation" or "automation with a human touch," is a key principle of Lean Software Development. It’s not just about automating processes but doing so in a way that they automatically stop when a problem is detected, allowing teams to investigate and fix the root cause before continuing. Applying the Jidoka concept, teams working with Lean Software Development design development processes that make it very easy to detect errors—either automatically in most cases, or manually thanks to a development process that facilitates identifying those errors.

For continuous quality improvement to work, we not only need to detect those errors but it is crucial to stop immediately (See https://en.wikipedia.org/wiki/Andon_(manufacturing)) and have a policy that forces us to prioritize their immediate resolution. This way of working may seem too radical at first and might give the impression that it slows the team down. However, my experience is quite the opposite. If you adopt a working approach where, upon detecting an error, you analyze it, learn from it, and fix it at the root—by, for example, adding a test to prevent it from happening again—you soon achieve a process that resolves errors as early as possible. This eliminates a lot of rework and potential problems for the end customer while generating great confidence within the team to move quickly, take risks, and experiment.

In fact, I believe it’s the best way to move fast sustainably, and the DORA Reports studies and the book Accelerate confirm that the best way to be fast is to build with quality—at least when it comes to product development.

In my case, this application of the Jidoka approach is reflected in:

  • Automatic tests that, upon detecting a failure, temporarily interrupt the development flow to prevent the error from propagating.
  • Git hooks (pre-commit, pre-push, etc.) that interrupt the flow if an attempt is made to push code with errors.
  • Working with trunk-based development, a strategy where all developers integrate their changes into a single main branch. In this setup, we run all validations on the main branch. When a test fails in continuous integration, we stop to fix it immediately. This is crucial in trunk-based development because any failure blocks the ability to integrate new changes, ensuring the main branch is always stable and ready for deployment. This discipline is fundamental to maintaining quality and avoiding error accumulation, allowing us to move fast with confidence.
  • Automatic prioritization in the workflow for resolving bugs detected in production, following an incident management process with postmortems for production incidents. This automatic prioritization is based on the severity of the error and its impact on the customer, determining which bugs are addressed first. (https://www.eferro.net/2024/12/using-blameless-incident-management-to.html).
  • Pair programming or ensemble programming, where multiple people work together on the same task, allowing misunderstandings or potential errors to be detected from the start. This intense collaboration acts as a continuous review that prevents many errors, both in understanding the problem and in implementing the solution.

Dealing with defects and learning from them

Accepting that we are going to make mistakes—and that some will become defects—is a fundamental part of the Lean approach. Instead of denying or hiding it, we embrace it as something natural. We work in complex environments, with multiple dependencies, constant uncertainty, and, moreover, we are human. We are fallible by definition.

That does not mean we don't try to avoid errors or defects. On the contrary, we put a lot of effort into preventing them with techniques like poka-yoke, automated testing, pair programming, evolutionary design, and many other practices that are part of our daily work. Even so, we know they will happen. And since we know it, we prepare to minimize their impact and recover as quickly as possible.

This shift in mindset is key: we move from an obsession with avoiding mistakes at all costs to a more robust and sustainable strategy based on fast recovery (resilience) and learning capability. Because when a defect reaches production, the first objective is to restore service as quickly as possible. And immediately after, to learn.

Over the past years, in several teams I've worked with, we've refined and applied a blameless incident management approach. The idea is simple: when an incident occurs, we don't look for someone to blame. We focus on understanding what happened, how the system contributed to the error, and what we can do to prevent it from happening again or reduce its impact next time.

This type of approach, simple as it may seem, has had a huge impact on team culture. It brings psychological safety, builds trust, promotes transparency, and encourages people to make problems visible without fear. At TheMotion, Nextail, and ClarityAI, we used it not only to manage incidents but also as a major lever to evolve the culture toward one that is more collaborative, learning-oriented, and focused on continuous improvement.

For example, in a recent incident where a service failed, we applied the 5 Whys technique and discovered that the initial problem (a configuration error) had triggered a cascade of events due to the lack of error handling in another service. This led us to add more robust integration tests and improve the resilience of the second service.

Our blameless incident management process relies on several principles:

  • Stay calm. Don’t panic. We even value this ability during interviews as a sign of professional maturity.
  • Assign an Incident Commander to coordinate the response and ensure no one is left alone firefighting.
  • Restore the service as soon as possible. Sometimes this means disabling a feature, communicating with customers, or applying a temporary mitigation. The important thing is to stabilize the system.
  • Analyze what happened in depth without seeking a single “root cause.” We understand that incidents usually stem from a combination of causes and circumstances. We use techniques like the 5 Whys, asking “why?” starting from the first visible symptom. Doing this in a group allows us to uncover the various factors that contributed to the incident. Often, we find flaws in the process, assumptions, communication, or even data interpretation.
  • Define corrective and preventive actions that not only avoid the problem but also reduce future recovery time and increase system resilience.
  • Integrate these actions into the normal workflow so they don't just remain on paper.
  • Use a blameless incident report, public within the company and collaborative, as the basis for collective learning. This continuous analysis and learning process is an example of Kaizen—continuous improvement applied to incident management, where we constantly seek ways to improve our processes and prevent future errors.

These reports include summaries, timelines, causes, actions, and learnings. Sharing them openly reinforces the message: errors are not hidden, they are learned from. And when the whole team internalizes this, the organization improves faster.

In the end, the message is clear: incidents are inevitable, but how we respond to them truly defines our culture. We can hide them, blame, and move on... or we can use them as catalysts for improvement and continuous learning. In Lean Software Development, we choose the latter.

In the next article...  

Once we have established how to detect and respond quickly to errors, it is crucial to build a solid foundation. In the third part, we will delve into internal quality as the basis for sustainable development. We will see why less is more, how simplicity and well-thought-out design accelerate development, and how a good technical foundation allows us to move fast without breaking things.


Related content