9. Cultura y liderazgo técnico
Conclusión. Las cinco respuestas comparten un hilo: hacer explícito lo que suele quedar implícito (supuestos, decisiones, costos, criterios) y convertir los acuerdos en mecanismos automáticos para que no dependan de la memoria ni de la autoridad de nadie. Cada respuesta se sostiene con la evidencia que deja este mismo trabajo.
9.1 Ambigüedad: cómo reducir riesgo sin frenar el avance
No espero a tener todas las respuestas: convierto cada duda en un par de pregunta y supuesto, avanzo sobre el supuesto y diseño para que el error sea barato. Lo importante es saber qué decisión cambia si el supuesto resulta falso, y aislar esa decisión.
Evidencia en este trabajo: el AS-IS no venía dado. Lo formulé como hipótesis y cada duda quedó registrada como pregunta, supuesto y decisión que cambia (sección 2). El riesgo R4 dice qué pasa si el supuesto principal es falso (que el OMS ya orquesta) y por qué el daño está acotado: la saga vive en un solo servicio y se puede reducir a un pase directo. La validación de ese supuesto está agendada en la semana 1 del MVP.
Dos casos de la construcción, con la misma mecánica. El OMS necesita la dirección de entrega y la regla es que ningún dato personal salga por Kafka; el contrato decía que quien la necesite la pida a order-service, pero ninguna operación lo permitía, y cada salida chocaba con una regla de arquitectura. En lugar de torcer una regla en silencio o frenar el avance, se escribieron cuatro opciones con lo que cada una sacrifica y una propuesta (ADR-025); el ADR se aceptó el 15/11/2026 y no está implementado; hasta entonces el límite queda dicho en este documento: la orden se registra en el OMS sin dirección (sección 4.4). Y el formato de los identificadores de la orden, que el diseño no fijaba, se registró como supuesto explícito (S27) y se verificó contra los datos que hoy se envían (1.143 SKU de la semilla, 5 ubicaciones, 4 canales y 200 clientes del CRM) antes de convertirlo en regla del contrato (ADR-026).
9.2 Cómo documentar decisiones para escalar el equipo
Una decisión que solo vive en una conversación se vuelve a discutir cada vez que entra alguien nuevo. Documento cada decisión de arquitectura en un ADR (architecture decision record: nota corta con contexto, opciones, decisión y costo), junto al código, y mantengo los contratos como fuente de verdad de la que se genera la documentación para terceros.
Evidencia en este trabajo: 27 ADR con contexto, opciones, decisión, qué se sacrifica y cuándo se revisaría (anexo D); contratos OpenAPI, AsyncAPI y Protocol Buffers que el pipeline valida en cada cambio; diagramas en texto versionados junto al código; y una plantilla de servicio que hace que un equipo nuevo no tenga que decidir nada de plataforma. Antecedente externo: el caso publicado por KrakenD sobre Linex Travel, donde la configuración del gateway como código deja el historial de cambios como registro de quién cambió qué.
Tres hechos del último tramo. El ADR-027 trae la fecha de consulta de cada una de sus nueve fuentes y, donde AWS no publicaba el precio de una opción (el EC2 Instance Connect Endpoint), dice "por medir" en lugar de estimarlo. El ADR-026 deja escrito cómo se encontró el defecto, con los números de la simulación, para que quien lo lea no tenga que reconstruir el razonamiento. Y una falla de herramienta que se repitió cinco veces el 10/11/2026 (editar archivos con comandos de una línea que terminaban sin error y sin escribir nada) quedó como regla en el archivo de reglas del repositorio (CLAUDE.md), junto con una segunda falla de la misma familia que ocurrió dos veces ese día: la regla es la memoria del equipo, no la conversación en la que se descubrió.
9.3 "Rápido" frente a seguridad y operación: cómo se negocia
Negocio el alcance funcional, no los mínimos de seguridad ni de operación. Cuando hay presión de tiempo, propongo entregar menos funciones completas en lugar de todas las funciones a medias, y hago visible lo que se pospone y su fecha.
Evidencia en este trabajo: el MVP recorta alcance (un partner, sin CRM, sin devoluciones, sin portal) pero no seguridad ni observabilidad: "no hay versión reducida de seguridad" (sección 8.2). La lista de lo que el MVP no entrega está escrita para que nadie la descubra tarde.
Dos hechos de la construcción, uno de costo y uno de seguridad. El costo en la nube se trata como un requisito: el clúster se enciende por horas y se apaga. El 14/11/2026 estuvo encendido 2 h 25 min (17:07 a 19:32 UTC), cerca de 1,30 dólares estimados a 0,54 la hora; el costo real queda por medir en Cost Explorer, la herramienta de AWS que muestra el gasto. El apagado no se da por hecho: make infra-audit comprobó que no quedaban "clúster, nodos, NAT, balanceador, discos ni IP elásticas del demo", y lo que sigue encendido, la base de la cuenta, cuesta 0,29 dólares por día (docs/plan.md, F7). En seguridad, la API de Kubernetes se dejó solo privada, con un bastión de unos 0,005 dólares por hora, aunque el endpoint público limitado por IP era gratis y más cómodo; la pérdida de comodidad y el costo están en el ADR-027, y el respaldo para el día de la presentación está escrito.
9.4 Desacuerdos técnicos fuertes: cómo se gestionan
Saco la discusión del terreno de las preferencias: acordamos primero los criterios, verificamos los hechos en la documentación oficial o con una medición, decidimos, y registramos lo que se sacrifica y bajo qué condición se revisaría. Quien no gana la discusión sabe exactamente qué evidencia la reabriría.
Evidencia en este trabajo: Kong frente a KrakenD se comparó con criterios escritos y verificados en documentación, y el ADR registra lo que se sacrifica y cuándo se revisaría (sección 3.4). Igual con SNS y SQS frente a Kafka, y con agregar un servicio en Go o Rust por rendimiento: decide una medición (la función de aptitud F1), no una preferencia.
Dos casos con el mismo método. En el detector de tarjetas (ADR-026) había cuatro opciones, y la que parecía más simple, quitar el detector, era también la que sacaría a la capa del alcance reducido de PCI DSS; se decidió con una medición y no con una opinión: de 2.000.000 de llaves al azar, 4.315 (una de cada 463) caían en el detector y rechazaban una compra válida. Quedó registrado lo que se sacrifica (una tarjeta puesta a propósito en un identificador no se detecta) y por qué se acepta. Para entrar a Kubernetes (ADR-027) se compararon cuatro caminos con su costo por hora y con lo que cada uno sacrifica, y la elección más cara que la gratuita se justificó por escrito, con el camino anterior como respaldo.
9.5 Calidad sin volver lento el delivery
La calidad que depende de revisiones manuales escala mal y frena. La convierto en compuertas automáticas y en un camino dorado: lo correcto es lo más fácil de hacer, y lo incorrecto lo detiene una prueba sin esperar a una persona. Ese es el criterio de diseño; la sección 3.8 dice cuáles ya son compuerta y cuáles todavía no.
Evidencia en este trabajo: diez funciones de aptitud definidas y clasificadas con honestidad (sección 3.8): una compuerta hoy en el pipeline (F5, más el lint de contratos, los secretos y la redacción), siete pruebas ejecutables que pasan cuando se corren y entran al pipeline según el roadmap, y dos todavía por construir (F3 y F4); plantilla de servicio y de adaptador; y el gateway modular, que deja a cada equipo cambiar sus rutas sin esperar a plataforma, con políticas que el pipeline exige (ninguna ruta sin scope, sin transformaciones, timeouts acotados). Antecedente externo: en el caso de Linex Travel publicado por KrakenD, el tiempo para lanzar una variante de producto pasó de meses a semanas.
Cuatro hechos de la construcción, con sus fuentes:
- Una prueba intermitente que destapó un defecto real. La prueba F9 (la misma orden enviada 5 veces en paralelo) fallaba de vez en cuando con
400, 409, 409, 409, 409y cero órdenes. En lugar de repetirla hasta que pasara, se reprodujo a voluntad y se halló un defecto de la capa: el detector de tarjetas rechazaba una de cada ~450 compras válidas de la tienda, y el reintento con la misma llave recibía el mismo 400, guardado por la idempotencia. Terminó en el ADR-026, con una prueba de 100.000 llaves al azar sin un solo rechazo (antes, entre 225 y 246) y una comprobación enmake verifyque falla si la lista de campos y el contrato difieren. Después,make f4-e2etres veces seguidas en 105 de 105 y la orden duplicada por reintento en 0 de más en 20 (commits3460176y9d006f6;tests/load/results/to-be/orden-duplicada-20261115T033312Z.json). - Una prueba que pasaba por suerte de tiempos.
make f4-webhooks-testexigía quepayment.approvedllegara primero, aunque el pago viaja por otro tópico que las órdenes: pasaba si el consumidor de pagos llegaba antes, y solo 2 de 4 corridas salieron limpias. Antes de corregir se midió: los registros de una corrida fallida mostraron que el consumidor de pagos entró al grupo 3 s antes que el de órdenes, y en otra, reproducida en local, las transacciones de un evento de orden y de un pago empezaron con 2 ms de diferencia. En los dos casos el orden de entrega era el que el diseño ya describía. Se corrigió la prueba, no el servicio, porque ordenar portimedentro del servicio obligaría a retener entregas; cinco corridas seguidas dieron 45 de 45 (commita540942;services/webhook-service/README.md, hueco 4). - Un hueco de despliegue encontrado al revisar qué llegaba a la nube: Keycloak y KrakenD, el borde de la capa, no tenían todavía paquete de despliegue para EKS, y la malla, que pasaba todas las validaciones sin clúster, falló en vivo en varios puntos (una ruta de llaves bloqueada, cuotas sin descriptor, una llamada que el sidecar cerraba). De ahí salió una prueba en vivo,
make mesh-kind-test, que hoy cubre la cuota por partner, el mTLS estricto y el circuit breaker. El hueco del borde está registrado en el plan y su cierre está en curso (docs/plan.md;tests/e2e/mesh/README.md). - Ensayar gratis antes de gastar. Al probar el despliegue en un clúster local apareció un choque entre el volumen de credenciales de EKS Pod Identity y la ruta de secretos del contrato de plataforma: el contenedor no arrancaba. Se encontró y se resolvió antes de encender nada en AWS (ADR-024, contexto).