Skip to content

🎯 Meta del capítulo: que las decisiones de tu equipo dejen de vivir en la cabeza de una persona y en un hilo de Slack perdido. Aquí tienes las cuatro plantillas que más valor aportan por lo poco que cuestan: el ADR, el documento de diseño, la revisión de código y el post-mortem.


25.1 · El problema: "¿por qué está esto así?"

Toda persona que entra en un proyecto se hace la misma pregunta, y casi nunca hay respuesta:

Nuevo:   "¿Por qué usamos MongoDB si todos los datos son relacionales?"
Equipo:  "Ni idea, ya estaba cuando llegué."
Nuevo:   "¿Lo cambiamos?"
Equipo:  "Uf… no sabemos qué se rompería."
         ⮕ Nadie toca nada durante 4 años.

Esto tiene nombre: erosión del conocimiento arquitectónico. La decisión se tomó por un motivo —quizá excelente, quizá pésimo— y ese motivo se evaporó. Sin él, el equipo no puede ni mantenerla con confianza ni revertirla con seguridad. Se queda paralizado.

🧠 La cuestión no es documentar más, es documentar lo que caduca peor. El código dice qué hace el sistema y siempre está actualizado. Lo que se pierde para siempre es el porqué: qué alternativas se valoraron, qué restricciones existían entonces y qué se sacrificó a conciencia.


25.2 · ADR: Architecture Decision Record

Un ADR es un archivo de texto corto, versionado junto al código, que registra una decisión significativa. Es la herramienta de documentación con mejor relación valor/esfuerzo que existe.

docs/adr/
├── 0001-usar-postgresql.md
├── 0002-autenticacion-con-jwt.md
├── 0003-monolito-modular-en-vez-de-microservicios.md
└── 0004-cola-de-emails-con-redis.md

Reglas: numerados, inmutables (nunca se editan; se sustituyen por otro que los reemplaza), cortos (una página) y viven en el repositorio, no en un wiki que nadie abrirá.

La plantilla

markdown
# ADR-0004 · Cola de emails con Redis + BullMQ

- **Estado:** Aceptada
- **Fecha:** 2026-07-28
- **Decide:** equipo de backend
- **Reemplaza a:**

## Contexto

El envío de emails ocurre dentro del request HTTP de creación de pedido, lo que añade
~2 s de latencia (p95 medido: 2,4 s). Cuando el proveedor de email tiene una incidencia,
la creación de pedidos falla entera aunque el cobro se haya completado — nos ocurrió el
14 de julio y perdimos 43 pedidos.

Volumen actual: ~800 emails/día, con picos de 200 en una hora.
Restricción: el equipo son 3 personas y no hay nadie dedicado a infraestructura.

## Decisión

Sacamos el envío de emails a una cola asíncrona con **Redis + BullMQ**, procesada por un
worker independiente, con 3 reintentos y retroceso exponencial, más una dead letter queue.

## Alternativas consideradas

| Opción | Por qué NO |
|--------|-----------|
| Seguir síncrono | No resuelve ninguno de los dos problemas medidos |
| RabbitMQ | Más garantías de las que necesitamos y una pieza más que operar |
| AWS SQS | Nos ata al proveedor; el equipo no usa AWS para nada más |
| Cron cada minuto sobre una tabla | Más simple, pero hasta 60 s de retraso y difícil de reintentar bien |

Redis ya está desplegado y en uso para sesiones y caché: **cero infraestructura nueva**.

## Consecuencias

**Positivas**
- La creación de pedido baja de ~2,4 s a ~400 ms (p95).
- Una caída del proveedor de email ya no impide crear pedidos.
- Los reintentos automáticos cubren los fallos transitorios.

**Negativas**
- Un proceso más que desplegar, monitorizar y reiniciar.
- Los emails pueden tardar unos segundos: hay que ajustar el copy de la interfaz
  ("te enviaremos un email en breve" en vez de "te hemos enviado un email").
- Redis pasa a ser crítico: si cae, los emails se encolan en memoria y pueden perderse.
  Mitigación: activada la persistencia AOF.
- **Las tareas deben ser idempotentes** (entrega "al menos una vez"): se deduplica con
  la clave `pedido:{id}:email-confirmacion`.

## Revisión

Revisar si superamos los 50.000 emails/mes o si la DLQ acumula >10 mensajes por semana.

💡 La sección más valiosa es "Alternativas consideradas". Es la que responde a la pregunta que hará el nuevo dentro de dos años ("¿por qué no usasteis X?"), y la que demuestra que hubo una decisión y no una casualidad. Si esa tabla está vacía, no decidiste: aceptaste la primera idea que se te ocurrió.

Qué merece un ADR y qué no

✅ Sí❌ No
Elección de base de datosNombre de una variable
Modelo de autenticaciónQué librería de fechas
Monolito vs serviciosEstructura de una carpeta
Formato de la API pública (REST/GraphQL)Reglas del linter
Estrategia de multi-tenancyCómo se llama un endpoint interno
Proveedor de pagosVersión menor de una dependencia

🧠 La regla: escribe un ADR cuando la decisión sea de una vía (capítulo 23) o cuando vayas a tener que explicarla más de dos veces. Un equipo sano produce entre 5 y 15 ADRs al año. Si escribes 100, estás documentando decisiones triviales; si escribes 0, el conocimiento se está yendo por el desagüe.


25.3 · Documento de diseño (RFC): pensar antes de construir

Un ADR registra una decisión ya tomada. Un documento de diseño (o RFC) se escribe antes, para pensar y para recoger opiniones sobre algo grande — típicamente, algo que llevará más de dos semanas o que afecta a otros equipos.

markdown
# Diseño · Sistema de notificaciones

**Autor:** … · **Estado:** Borrador → En revisión → Aprobado → Implementado
**Revisores:****Fecha límite de comentarios:** 2026-08-05

## 1. Problema
Qué duele hoy, con DATOS. ("47 tickets de soporte este trimestre porque los usuarios
no se enteran de X".) Si no puedes cuantificarlo, quizá no sea un problema todavía.

## 2. Objetivos y NO objetivos
Objetivos:     lo que esto debe conseguir, medible.
NO objetivos:  📌 lo que explícitamente NO vamos a hacer.
La sección de no-objetivos es la que evita que el alcance crezca sin control
durante la implementación y la que corta antes las discusiones.

## 3. Propuesta
El diseño. Diagramas, esquema de datos, contratos de API, flujos.

## 4. Alternativas consideradas
Al menos dos, con el motivo real del descarte.

## 5. Riesgos y mitigaciones
Qué puede salir mal y qué haremos al respecto.

## 6. Plan de implementación
Fases entregables por separado (rebanadas verticales, capítulo 23).

## 7. Cómo sabremos si funcionó
Métricas concretas y cuándo se miden.

## 8. Preguntas abiertas
Lo que aún no sabes. Escribirlo NO es debilidad: es dónde necesitas ayuda.

💡 El valor está en escribirlo, no en el documento. Explicar un diseño en prosa te obliga a encontrar los huecos: la mitad de los problemas aparecen mientras redactas la sección 3, antes de escribir una línea de código. Es la revisión de código más barata que existe, porque el código todavía no existe.


25.4 · Evaluar una tecnología sin dejarte llevar por la moda

Cada semana sale un framework que "lo cambia todo". Un marco para decidir con la cabeza:

1. ¿QUÉ PROBLEMA MÍO resuelve?
   Si no lo sabes formular en una frase, la respuesta es no.
   "Está de moda" y "lo usa Netflix" no son problemas tuyos.

2. ¿QUÉ ANTIGÜEDAD TIENE?
   < 1 año  → juguete. Interesante para un proyecto personal, no para producción.
   1-3 años → viable si hay una empresa detrás y comunidad activa.
   > 3 años → maduro. Los bugs raros ya los sufrió otro y están documentados.

3. ¿QUÉ PASA SI EL PROYECTO MUERE?
   ¿Puedo mantenerlo yo? ¿Hay salida? ¿Cuánto costaría migrar?
   Mira: commits del último mes, nº de mantenedores (¿solo uno?), issues sin
   respuesta, si hay una empresa que dependa de ello.

4. ¿PUEDE MI EQUIPO USARLO?
   Una tecnología que solo entiende una persona es un punto único de fallo humano.
   ¿Hay documentación? ¿Se encuentra gente que lo conozca? ¿Hay respuestas cuando
   buscas un error concreto?

5. ¿CUÁL ES EL COSTE TOTAL?
   Aprendizaje + migración + operación + el coste de tenerlo en el CV del equipo
   cuando alguien se vaya. Casi nunca es solo `npm install`.

6. ¿ES REVERSIBLE?  (capítulo 23)
   Una librería de utilidades: trivial de quitar.
   Un ORM o un framework: te toca reescribir medio proyecto.

⚠️ La regla del "presupuesto de innovación" (Dan McKinley, Choose Boring Technology): un equipo solo puede permitirse dos o tres tecnologías "aburridas pero probadas" sustituidas por algo nuevo a la vez. Gástalo en lo que sea tu ventaja competitiva real, y elige lo aburrido para todo lo demás.

PostgreSQL, Redis y Nginx son aburridos: los conoce todo el mundo, los fallos están documentados y llevan décadas funcionando. Esa es exactamente la razón para usarlos. Lo emocionante debería ser tu producto, no tu stack.


25.5 · Revisar código: la decisión más frecuente

Una revisión de código es una decisión en miniatura, y ocurre varias veces al día. Hacerla bien es una de las habilidades que más se notan.

Qué buscar, por orden de importancia

1. ¿RESUELVE el problema correcto?     ← si esto falla, lo demás da igual
2. ¿Es CORRECTO?                       ← casos límite, nulos, concurrencia, errores
3. ¿Es SEGURO?                         ← inyección, autorización, datos expuestos en logs
4. ¿Se puede MANTENER?                 ← ¿lo entenderé en 6 meses?
5. ¿Está PROBADO?                      ← ¿los tests cubren el caso que falla?
6. Estilo                              ← 📌 esto lo hace el linter, no tú

⚠️ Si tus comentarios de revisión son sobre comas, comillas y saltos de línea, tu equipo necesita un formateador automático, no un revisor. Configura Prettier, gofmt, Black o php-cs-fixer y no vuelvas a discutir de estilo jamás. El tiempo humano se gasta en los puntos 1 a 5.

Cómo escribir los comentarios

❌ "Esto está mal."
✅ "Si `usuarios` viene vacío, esta línea lanza IndexError. ¿Añadimos una guarda?"

❌ "¿Por qué no usaste un map?"
✅ "Un `map` aquí evitaría la variable mutable. ¿Qué te parece? (no bloqueante)"

❌ "Yo esto lo habría hecho distinto."
✅ (Si funciona, es seguro y se entiende: no lo comentes. No es tu código.)

Etiqueta tus comentarios por severidad. Es un cambio pequeño con un efecto enorme:

  • [bloqueante] — no puede entrar así (bug, agujero de seguridad, pérdida de datos).
  • [sugerencia] — mejora, pero tú decides.
  • [duda] — no lo entiendo, explícamelo.
  • [nit] — detalle menor, ignórame si quieres.

💡 Sin etiquetas, quien recibe la revisión no sabe qué es obligatorio y qué es opinión, así que o lo cambia todo (perdiendo tiempo) o se defiende de todo (generando fricción). Con etiquetas, una revisión de 15 comentarios de los que 2 son bloqueantes se resuelve en 10 minutos y sin tensión.

🧠 Y para quien recibe la revisión: el código no eres tú. Un comentario sobre una función no es un juicio sobre tu valía. La forma más rápida de ganarse el respeto de un equipo es responder "tienes razón, no había pensado en ese caso" sin dramatismo.


25.6 · Post-mortems sin culpables

Cuando algo se rompe en producción, hay dos formas de reaccionar. Una hace al sistema más fuerte y la otra hace al equipo más silencioso.

❌ CULTURA DE LA CULPA               ✅ CULTURA SIN CULPA (blameless)
"¿Quién lo rompió?"                  "¿Qué permitió que esto ocurriera?"
→ La gente oculta errores            → La gente los reporta pronto
→ Nadie toca nada arriesgado         → El sistema mejora tras cada fallo
→ El mismo fallo se repite           → Cada incidente se paga una sola vez

🧠 El principio: si una persona pudo tirar producción con un comando, el problema es el sistema, no la persona. Faltaba una confirmación, un entorno de pruebas, un permiso, una alerta o una revisión. Despedir a esa persona deja el mismo agujero abierto para la siguiente.

Plantilla de post-mortem

markdown
# Incidente 2026-07-24 · Caída de la API (47 minutos)

## Resumen
Entre las 14:12 y las 14:59 UTC la API devolvió 503 al 100% del tráfico.
Impacto: ~12.000 peticiones fallidas, 340 usuarios afectados, 8 pedidos perdidos.

## Cronología (UTC)
14:12  Se despliega la versión v2.4.0.
14:13  Empiezan los errores 503. **Nadie se entera.**
14:31  Un cliente escribe a soporte.
14:38  Soporte avisa al equipo de backend.
14:41  Se identifica el despliegue como causa probable.
14:52  Se revierte a v2.3.9.
14:59  Servicio restablecido.

## Causa raíz
La migración de la v2.4.0 añadía un índice sobre `pedidos` (14M filas) SIN
`CONCURRENTLY`, bloqueando la tabla durante 6 minutos. El pool de conexiones se
agotó esperando y la aplicación dejó de responder por completo.

## Los 5 porqués
1. ¿Por qué cayó la API?          → Se agotó el pool de conexiones.
2. ¿Por qué se agotó?             → Todas esperaban un bloqueo sobre `pedidos`.
3. ¿Por qué había un bloqueo?     → `CREATE INDEX` sin `CONCURRENTLY`.
4. ¿Por qué se desplegó así?      → La revisión no detectó el riesgo de la migración.
5. ¿Por qué no lo detectó?        → No existe una checklist de revisión para migraciones,
                                     y en staging la tabla tiene 200 filas, no 14M.

## Qué funcionó bien
- El rollback tardó 7 minutos desde que se identificó la causa.
- El procedimiento de reversión estaba documentado y probado.

## Qué falló
- 26 minutos hasta enterarnos: **nos avisó un cliente, no una alerta**.
- Staging no representa el volumen real de producción.

## Acciones  (con responsable y fecha — sin esto, un post-mortem no sirve de nada)
| # | Acción | Responsable | Fecha |
|---|--------|-------------|-------|
| 1 | Alerta si la tasa de 5xx > 1% durante 2 min | Ana | 26-jul |
| 2 | Checklist obligatoria de revisión de migraciones | Beto | 31-jul |
| 3 | Linter que rechace `CREATE INDEX` sin `CONCURRENTLY` en CI | Ana | 07-ago |
| 4 | Poblar staging con un volumen realista de datos | Carla | 21-ago |

💡 La pregunta que más valor extrae de un incidente no es "¿por qué falló?" sino "¿por qué tardamos 26 minutos en enterarnos?". Los fallos son inevitables; la detección lenta, no. Un incidente de 5 minutos detectado por una alerta y otro de 47 detectado por un cliente enfadado son problemas de naturaleza completamente distinta, aunque la causa raíz sea la misma.

🧠 La regla de los "5 porqués" tiene truco: no pares en el primero que suene técnico. "Fue un error humano" nunca es una causa raíz: es el sitio donde dejas de preguntar. Sigue hasta llegar a algo que puedas arreglar en el sistema — una alerta que no existía, una barrera que no había, un entorno que mentía.


25.7 · Desacuerdo y compromiso

Vas a discrepar con decisiones de tu equipo. Cómo lo gestiones define tu carrera más que tu código.

1. ARGUMENTA CON DATOS, NO CON GUSTOS
   ❌ "MongoDB es horrible."
   ✅ "Nuestro modelo tiene 8 tablas con relaciones y hacemos JOINs en 12 consultas.
       Emularlos en la aplicación nos costaría X. ¿Qué gana MongoDB aquí?"

2. ARGUMENTA CONTRA LA MEJOR VERSIÓN DE LA OTRA POSTURA
   Formula el argumento contrario mejor de lo que lo formularía quien lo defiende.
   Si no puedes, todavía no lo has entendido lo suficiente para rebatirlo.

3. SEPARA "ME PARECE PEOR" DE "ESTO NOS VA A HACER DAÑO"
   Reserva tu capital político para lo segundo. Quien discute todo con la misma
   intensidad deja de ser escuchado en lo que de verdad importa.

4. DISCREPA Y COMPROMÉTETE
   Una vez tomada la decisión, se apoya de verdad. Sabotear pasivamente algo que
   se decidió es peor que cualquier decisión técnica mala.

5. DÉJALO POR ESCRITO
   "Mi preocupación es X; si ocurre Y, revisémoslo." Sin reproches y con un
   criterio objetivo. Si Y ocurre, la conversación ya está preparada; y si no
   ocurre, aprendiste algo sobre tus propias intuiciones.

🧠 La honestidad intelectual es tu activo más valioso a largo plazo. Decir "me equivoqué, tenías razón" cuesta cinco segundos y te da credibilidad durante años. Defender una postura que ya sabes indefendible te la quita para siempre.


✅ Ejercicio del capítulo

Parte 1 — Escribe un ADR de verdad

  1. Elige una decisión técnica real de un proyecto tuyo (o de cualquier capítulo del libro: por qué FastAPI y no Flask, por qué Docker, por qué JWT y no sesiones).
  2. Escribe el ADR completo con la plantilla de 25.2. Obligatorio: al menos tres alternativas con su motivo real de descarte, y consecuencias negativas — si tu sección de negativas está vacía, no estás siendo honesto, estás vendiendo.
  3. Añade un criterio de revisión concreto y medible.

Parte 2 — Evalúa una tecnología

  1. Coge la última tecnología que te haya llamado la atención (un framework, una base de datos, un runtime) y pásale las 6 preguntas de 25.4. Busca los datos de verdad: fecha del último commit, número de mantenedores, issues abiertos sin responder, quién la usa en producción.
  2. Concluye con una recomendación en tres frases: usarla, no usarla, o usarla solo en X caso.

Parte 3 — Revisión de código

  1. Revisa este fragmento y escribe tus comentarios con las etiquetas de severidad de 25.5:
python
@app.route("/api/usuarios/<id>")
def obtener_usuario(id):
    usuario = db.execute(f"SELECT * FROM usuarios WHERE id = {id}").fetchone()
    app.logger.info(f"Usuario consultado: {usuario}")
    return jsonify(dict(usuario))
  1. Ordena tus hallazgos por severidad. ¿Cuál es el bloqueante más grave y por qué?

Parte 4 — Post-mortem

  1. Escribe un post-mortem completo para este incidente:

    Un despliegue del viernes a las 18:00 introdujo una consulta sin índice. El sábado por la mañana, con el tráfico del fin de semana, la base de datos llegó al 100% de CPU. La web estuvo lenta (respuestas de 8-15 s) desde las 09:00 hasta las 14:00, cuando alguien del equipo lo vio por casualidad en Twitter. No hubo alertas. El despliegue del viernes no tuvo revisión porque "era un cambio pequeño".

  2. Aplica los 5 porqués hasta llegar a causas sistémicas, no humanas.

  3. Escribe al menos cinco acciones con responsable y fecha. Al menos dos deben ser sobre detección, no sobre prevención.

💡 Pistas de la solución (abre solo si te atascas)

Parte 3 — los hallazgos, por severidad:

  • [bloqueante] Inyección SQL. El f-string mete id directamente en la consulta: /api/usuarios/1 OR 1=1 devuelve todos los usuarios, y 1; DROP TABLE usuarios-- hace algo peor. Es el fallo más grave del fragmento y por sí solo justifica rechazar el cambio. Se arregla con una consulta parametrizada: db.execute("SELECT * FROM usuarios WHERE id = ?", (id,)).
  • [bloqueante] Fuga de datos en los logs. Se registra el objeto usuario completo: hash de contraseña, email, teléfono, lo que haya. Los logs se envían a servicios externos, los ve gente de soporte y se conservan meses. Esto es un incidente de privacidad y, con datos personales, probablemente un incumplimiento del RGPD. Registra solo el id.
  • [bloqueante] Falta control de autorización. Cualquiera puede consultar cualquier usuario por su id. Debe comprobarse que el solicitante tiene derecho a ver ese recurso.
  • [bloqueante] SELECT * devuelve todas las columnas al cliente, incluidas las internas (hash de contraseña, tokens de recuperación, marcas de borrado). Enumera las columnas públicas.
  • [bloqueante] No se maneja el caso "no existe". Si fetchone() devuelve None, dict(None) lanza una excepción y el usuario recibe un 500 en vez de un 404.
  • [sugerencia] id llega como cadena y no se valida que sea un entero.

Fíjate en algo importante: un fragmento de cuatro líneas tiene cinco bloqueantes. Por eso la revisión de código no va de comas.

Parte 4 — el post-mortem. El error típico es quedarse en "faltó un índice". Los 5 porqués deben llegar mucho más lejos: ¿por qué no hubo revisión? → porque no es obligatoria para cambios "pequeños" → ¿por qué se juzga el riesgo por el tamaño del diff? → porque no existe ningún criterio escrito de qué requiere revisión.

Y la parte que más se olvida: cinco horas de degradación detectadas por Twitter. Aunque el índice hubiera estado, la ausencia total de alertas seguiría ahí, esperando al siguiente incidente. De ahí que se te pidan dos acciones sobre detección: alerta por latencia p95 y alerta por CPU sostenida de la base de datos. Un tercer tema de fondo, que también merece una acción, es el despliegue del viernes por la tarde sin nadie de guardia.


🧠 Autoevaluación

Porque su valor está en ser un registro histórico: dice qué se decidió, cuándo y con qué información disponible en ese momento. Si lo editas cuando cambias de opinión, destruyes exactamente lo que lo hacía útil — la capacidad de entender el razonamiento de entonces y de distinguir "nos equivocamos" de "el contexto cambió".

Cuando una decisión queda obsoleta, se escribe un ADR nuevo que la reemplaza, y en el antiguo solo se cambia el estado a "Reemplazada por ADR-0012". Así se lee la evolución completa del sistema como una secuencia, no como una foto retocada.

"Alternativas consideradas". El resto se puede reconstruir mirando el código: qué base de datos se usa es evidente al abrir el proyecto. Lo que resulta imposible de recuperar es qué se valoró y por qué se descartó.

Sin esa sección, cada persona nueva propone las mismas alternativas ya estudiadas y el equipo repite la misma discusión cada dos años. Con ella, la conversación empieza en un punto mucho más avanzado: "descartamos SQS porque no usábamos AWS; ahora sí lo usamos, así que ese motivo ya no aplica y merece la pena revisarlo". Eso es progreso; lo otro es un bucle.

Es un análisis de un incidente centrado en las condiciones del sistema que lo hicieron posible, no en quién ejecutó la acción final. Parte de una premisa: la gente actúa razonablemente con la información y las herramientas que tiene, así que si alguien pudo tirar producción con un comando, lo que falta es una barrera, no un castigo.

Es más eficaz por un motivo práctico: en una cultura de culpa, la gente oculta los errores y evita tocar nada arriesgado, así que los mismos fallos se repiten con menos información cada vez. En una cultura sin culpa, los incidentes se reportan pronto —cuando aún son pequeños— y cada uno genera una mejora permanente del sistema. La organización paga cada fallo una sola vez.

Sin culpa no significa sin responsabilidad: las acciones correctoras tienen responsable y fecha. La responsabilidad es sobre arreglar el sistema, no sobre haber estado allí.

Porque una tecnología madura viene con algo que ninguna nueva puede ofrecer: años de fallos ya descubiertos por otros. Cuando te encuentras un error raro en PostgreSQL, hay una respuesta en Stack Overflow de 2017. Cuando te lo encuentras en algo de hace ocho meses, eres tú quien abre el issue y espera.

A eso se suma que puedes contratar gente que ya lo conoce, la documentación es completa y existen herramientas de monitorización, backup y migración probadas. El "presupuesto de innovación" es la idea de que un equipo solo puede permitirse dos o tres apuestas nuevas simultáneas antes de que la carga de descubrir problemas por su cuenta lo paralice.

La consecuencia práctica: gasta ese presupuesto en aquello que sea tu ventaja competitiva real, y elige lo aburrido y probado para todo lo demás. Tu producto debería ser lo emocionante; tu base de datos, no.

Porque es trabajo que una máquina hace mejor, gratis y sin generar fricción entre personas. Cada comentario sobre comillas, indentación o longitud de línea gasta atención humana —la del revisor y la del revisado— que no se está gastando en detectar el bug de concurrencia o el fallo de autorización que sí hay en el mismo cambio.

Además ahoga la señal: en una revisión con 20 comentarios de los que 18 son de estilo, los 2 importantes pasan desapercibidos. Y a nivel humano, recibir una lista larga de correcciones triviales se siente como una crítica personal, lo que hace que la gente evite pedir revisiones.

La solución es estructural: un formateador automático en el pre-commit y en el CI, y ninguna discusión de estilo nunca más. El tiempo humano se reserva para corrección, seguridad, diseño y mantenibilidad.

Significa defender tu postura con toda tu energía mientras se está decidiendo, y una vez tomada la decisión —aunque no sea la tuya— apoyarla de verdad: implementarla bien, no minarla en pasillos y no reservarte un "ya lo dije" para cuando falle.

Importa porque la alternativa hunde equipos. Sin ella se dan dos patologías: o la parálisis —nadie decide hasta que todos estén de acuerdo, lo que nunca ocurre— o el sabotaje pasivo, donde la decisión se ejecuta a medias, funciona mal por eso, y el resultado "confirma" que era mala.

La forma madura de discrepar es dejarlo por escrito sin reproche: "mi preocupación es X; propongo revisarlo si ocurre Y", con Y medible. Si Y ocurre, la conversación ya está preparada con datos; si no ocurre, has aprendido algo sobre la calidad de tus propias intuiciones. En ambos casos ganas.


Siguiente: 26-casos-de-estudio.md — cinco sistemas diseñados de principio a fin, con las decisiones razonadas.