Esta semana volví a un post de hace dos meses sobre testing y le agregué un simulador Monte Carlo al lado de una frase. Una sola frase. El post llevaba en línea desde abril, la gente ya lo había leído, y la línea que me seguía dando vueltas era esta: una tasa de flakes del 3% no es un problema del 3%.

La creía cuando la escribí. Había visto mi propio CI ponerse rojo con cambios que no tocaban nada. Pero podía sentir dónde archiva un lector esa frase: en exageración, junto a todos los demás bloggers que redondean para arriba por efecto. La matemática de fondo es una línea, 0.97^40 ≈ 0.30, y ese es exactamente el problema. Nadie siente un exponente. Puedes imprimir la fórmula en negrita, puedes graficarla, y los ojos del lector le pasan por encima a velocidad de lectura, que es justo la velocidad a la que la acumulación nunca parece grave.

Así que en vez de defender la frase con dos párrafos más, le construí una máquina.

La frase que nadie creía

Esta es la máquina. Cada punto es un test; cada test flaquea de forma independiente con la tasa de la izquierda. Pon la suite en 40 tests y mira la barra sin retries. Después arrastra la suite hacia arriba, que es la única dirección en la que crecen las suites reales.

P(suite verde) por presupuesto de retries — 2.000 corridas simuladas
sin retries
retry ×1
retry ×2
retry ×3
2.000 corridas simuladas por configuración. El mismo 3% que parecía inofensivo con 4 tests.

Ese desplome del 97% verde a un 30% es el exponente, sentido. Ningún párrafo mío te lleva ahí, porque leer es una actividad de espectador y la afirmación solo aterriza cuando fuiste tú quien hizo caer la barra. Las barras de retries cuelan después el segundo punto, el más incómodo: los retries devuelven el build al verde sin hacer que un solo test flaquee menos. El lector lo descubre arrastrando, antes de que yo lo diga. Un argumento al que llegaste solo no necesita defensa.

Esa es la idea completa detrás de la librería de componentes de este sitio. No es decoración. No es "engagement". Es una herramienta específica para un modo de falla específico: la afirmación que es cierta, que importa, y que la prosa físicamente no puede cargar.

Veinte años de trabajo previo

Nada de esto es idea mía, y fingir lo contrario sería ridículo cuando el linaje se rastrea tan fácil.

  1. 2011

    Explorable Explanations + Ladder of Abstraction

    Bret Victor le pone nombre al género en un ensayo y lo actúa en un segundo.

  2. 2016

    Nace Distill

    Investigación de machine learning publicada como artículos interactivos.

  3. 2017

    The Pudding

    Una publicación entera sobre la premisa de que hay ensayos que se juegan, no se leen.

  4. 2020

    Communicating with Interactive Articles

    Distill repasa la evidencia: la interacción mejora de forma medible la comprensión y el involucramiento.

  5. 2021

    Distill entra en pausa

    Producir a ese estándar agotaba a todos los involucrados. El costo es real.

  6. 2026

    Este post

    Un blog de ingeniería común intenta cerrar la brecha.

La formulación más clara es Explorable Explanations de Bret Victor, de 2011: un documento reactivo, escribió, le permite al lector "jugar con los supuestos y análisis del autor, y ver las consecuencias". Su Up and Down the Ladder of Abstraction es el mismo argumento actuado en vez de enunciado: aprendes el diseño de un algoritmo de dirección recorriendo con el dedo cada nivel de abstracción. Quince años después, los dos ensayos todavía se leen como una lista de pendientes que la web en general ignoró.

En general, no del todo. Distill pasó cinco años publicando investigación de machine learning como artículos interactivos, y su pieza de 2020, Communicating with Interactive Articles, es el mejor repaso que conozco de por qué esto funciona. Recorre la evidencia de que la interacción mejora la comprensión y el involucramiento, la conecta con la investigación sobre aprendizaje activo, y es ella misma interactiva, así que el argumento se demuestra solo mientras lo lees. Distill entró en pausa en 2021, en parte porque producir artículos a ese estándar agotaba a todos los involucrados. Ese detalle va aquí y no en una nota al final: el costo es real y ahora llego a él. Nicky Case junta el género completo en explorabl.es, y The Pudding construyó una publicación entera sobre la premisa de que hay ensayos que se juegan, no se leen.

Lo que me llama la atención de esa lista es lo que falta en ella: los blogs de ingeniería comunes. El género vive en el periodismo, en la investigación de ML, en proyectos de arte independientes. Los blogs técnicos personales, el lugar donde alguien le explica worktrees o tests flaky a un colega, siguen pegando capturas. Y no creo que sea porque los bloggers no estén de acuerdo con Victor. Creo que es porque una captura cuesta cero y un simulador no.

Una captura le muestra al lector lo que tú viste. Un componente le deja comprobar si tienes razón.

Lo que cuesta un componente de verdad

Le voy a poner números al costo, porque la versión honesta de este post admite que el costo es la razón entera de que el género sea tan flaco.

30
componentes en producción
cada uno con demo en /es/lab/
4
construidos en una sesión
la parte barata
×5
costos ocultos cada uno
teclado · movimiento reducido · dark mode · etiquetas ES · re-init

Este sitio corre hoy 30 componentes. Los cuatro más nuevos (el simulador de suites flaky de arriba, un grafo de git paso a paso, un reproductor del ciclo de un agente, un editor de curvas de easing arrastrable) tomaron una sesión completa de trabajo, y esa fue la parte barata. La cara vino después: cada uno necesita navegación por teclado, comportamiento con movimiento reducido, dark mode, versión en español de cada etiqueta incluyendo las que se generan en el cliente, y reinicialización cuando las transiciones de página del sitio le cambian el DOM por debajo. Nada de eso se ve en un GIF de demo, y todo eso es la diferencia entre un componente y un juguete.

Y después está la parte que me saltaría si este post fuera marketing. La cuadrícula de puntos de ese simulador, la única parte cuyo propósito entero es ser vista, salió a producción invisible. Astro acota los estilos de un componente con un selector de atributo, los puntos se crean desde un script del cliente, los nodos creados en el cliente no llevan ese atributo, y cada punto se renderizaba con altura cero. Las barras funcionaban, el veredicto funcionaba, la matemática estaba bien, y la pieza central era un hueco. Lo descubrí días después, cuando un screenshot de Playwright volvió con una franja vacía en mitad de la figura. El arreglo fue un :global(), dos minutos. Encontrarlo exigió mirar la página renderizada en vez del código, que era justo lo que yo venía no haciendo con toda confianza. No voy a fingir que fue elegante. Construí una máquina para hacer cosas visibles y no noté que era invisible.

Este es el arreglo completo:

src/components/blog/FlakySuite.astro css
Before
1 .flaky-dot {
2 width: 12px;
3 height: 12px;
4 border-radius: 3px;
5 opacity: 0;
6 animation: fkPop 0.25s var(--ease-spring) forwards;
7 }
After
1 + /* Dots are created from the client script, so they don't carry
2 + Astro's scope attribute — style them through :global. */
3 + .flaky-grid :global(.flaky-dot) {
4 width: 12px;
5 height: 12px;
6 border-radius: 3px;
7 opacity: 0;
8 animation: fkPop 0.25s var(--ease-spring) forwards;
9 }
Astro compila .flaky-dot a .flaky-dot[data-astro-cid-…] al construir el sitio. Los puntos los crea un script del cliente y nunca reciben ese atributo, así que el selector no coincidía con ningún nodo y cada punto se renderizaba con altura cero.

Ese bug se gana su lugar aquí porque es el argumento más fuerte que tengo a favor de todo este enfoque. Yo había leído el código de ese componente varias veces y estaba convencido de que funcionaba. Leer no alcanzó. A mí, el autor, con mi propio código. Esa es exactamente la posición del lector frente a cada afirmación que publicas, y por eso "descríbelo mejor" sigue perdiendo contra "deja que lo corra".

La regla que mantiene esto honesto

Treinta componentes también es la receta para terminar con un blog que parece el demo reel de un vendedor de componentes, así que hay una sola regla que decide si algo se construye: un componente existe solo cuando un post concreto lo necesita para una afirmación que la prosa no podía cargar. El grafo de git existe porque el post de worktrees cuenta la historia de tres ramas que no chocan, y "no chocar" es una secuencia, no una imagen. El editor de easing existe porque un post sobre game feel le estaba pidiendo al lector que aceptara cuatro números de una curva bezier por fe.

Cada componente documenta esa razón en su propia página, en una sección que se llama «por qué existe», en los dos idiomas. La librería completa corre en vivo en /es/lab/, con los mismos estilos, el mismo dark mode y las mismas transiciones que recibe un post. Nada simulado. Si el párrafo de "por qué existe" de un componente alguna vez se lee como "se veía bonito", ese componente no debió construirse.

El corolario corta para el otro lado también, y es la parte que me toca reaprender cada tanto: la mayoría de las afirmaciones no necesita un componente. La mayor parte de cada post de este sitio sigue siendo párrafos, porque la mayoría de las frases se defiende sola. El simulador de arriba existe para la única frase por post que los lectores archivan en exageración. Gastarse una sesión de trabajo en esa frase solo tiene sentido si de verdad quieres que te crean. Sospecho que ese es el filtro real, y es bastante menos cómodo que el costo de construcción.

Yo sé de qué lado estoy. Los puntos fueron invisibles durante tres días, y leer mi propio código me tenía convencido de que no lo eran. Tú estás en esa misma posición con este post, ahora mismo. Sube y arrastra el slider.