# xAI publicó el código del algoritmo de X: lo analicé línea por línea y esto esconden

> Analicé el código fuente del algoritmo de X publicado por xAI. Encontré 4 tipos de shadowban, embeddings que no caducan y por qué el dwell time aplasta a los likes 5 a 1.

**Autor:** Pedro Luis Cuevas Villarrubia | **Fecha:** 2026-05-17 | **Tags:** SEO, marketing, blogging
**URL:** https://asturwebs.es/blog/algoritmo-x-twitter-codigo-fuente-analisis-2026/

---
El 16 de mayo de 2026, xAI publicó el código fuente del algoritmo de X — internamente llamado **Phoenix**. [Javi López (@javilop) se gastó 500$ en Claude para diseccionar los 207 archivos del repositorio](https://x.com/javilop/status/2055680198268404038), y luego publicó su análisis completo como una skill abierta para que cualquiera pueda usarlo. El trabajo pesado es suyo.

Lo que yo he hecho es coger esa investigación y organizarla por impacto real: lo que más te fastidia el alcance, lo que son mitos, y una rutina semanal de publicación basada exclusivamente en lo que el código dice que funciona. Si quieres el destripe técnico con referencias a cada archivo Rust, ve al hilo de Javi. Si quieres saber qué hacer con todo eso el lunes a las 9 de la mañana, sigue leyendo.

## El embedding de autor: tu huella digital interna

Cada cuenta de X tiene un **embedding asociado en el espacio latente**. Es un vector de números que resume cómo se comporta tu cuenta: qué temas tocas, qué engagement generas, con quién interactúas. Como la huella digital que los modelos de IA usan para describirte.

Phoenix lo consulta cada vez que decide a quién enseñar tus posts. Y aquí viene lo fuerte:

**Ese embedding no se resetea.** Lo que hagas hoy se queda dentro durante semanas, contaminando todo lo que publiques después, aunque sea bueno.

<div class="not-prose my-6 space-y-2">
<div class="flex items-center gap-3 bg-green-50 border border-green-200 rounded-lg p-3">
<span class="shrink-0 w-3 h-3 rounded-full bg-green-500 inline-block"></span>
<div class="text-sm"><strong class="text-green-800">Historial limpio, buen engagement</strong> → <span class="text-green-700">El modelo te empuja</span></div>
</div>
<div class="flex items-center gap-3 bg-red-50 border border-red-200 rounded-lg p-3">
<span class="shrink-0 w-3 h-3 rounded-full bg-red-500 inline-block"></span>
<div class="text-sm"><strong class="text-red-800">Señales negativas acumuladas</strong> → <span class="text-red-700">Penalización automática silenciosa</span></div>
</div>
<div class="flex items-center gap-3 bg-gray-50 border border-gray-200 rounded-lg p-3">
<span class="shrink-0 w-3 h-3 rounded-full bg-gray-400 inline-block"></span>
<div class="text-sm"><strong class="text-gray-800">Dejas de postear</strong> → <span class="text-gray-600">Las señales malas se congelan, no se diluyen</span></div>
</div>
</div>

Por eso salir de un shadowban se siente como mover una rueda oxidada. No es tu imaginación. El modelo simplemente aprendió que tu cuenta da mal engagement y se autocorrigió.

Los tiempos de recuperación son lentos pero reales: **6-8 semanas** para notar mejora, **12-16 semanas** para un cambio significativo, asumiendo que creas contenido que le gusta al algoritmo y no acumulas más señales negativas.

## Los primeros 30 minutos lo son todo

Si tu post no recibe interacciones en la primera media hora, **Grok ni siquiera lo evalúa**. Sin nota de calidad, sin análisis profundo, sin posibilidad de llegar a quien no te sigue. Muerto y enterrado.

La ventana de vida del post está capada a 80 horas (`POST_AGE_MAX_MINUTES = 4800`), organizada en buckets de 1 hora:

<div class="not-prose my-8">
<div class="grid grid-cols-4 gap-2 text-center text-sm">
  <div class="rounded-lg bg-green-100 border border-green-200 p-3">
    <div class="text-lg font-bold text-green-700">0-12h</div>
    <div class="text-green-600 text-xs mt-1">Máxima distribución</div>
    <div class="mt-2 h-2 rounded-full bg-green-500" style="width:100%"></div>
  </div>
  <div class="rounded-lg bg-yellow-100 border border-yellow-200 p-3">
    <div class="text-lg font-bold text-yellow-700">12-24h</div>
    <div class="text-yellow-600 text-xs mt-1">Bucket peor</div>
    <div class="mt-2 h-2 rounded-full bg-yellow-500" style="width:60%"></div>
  </div>
  <div class="rounded-lg bg-orange-100 border border-orange-200 p-3">
    <div class="text-lg font-bold text-orange-700">24-80h</div>
    <div class="text-orange-600 text-xs mt-1">Progresivamente peor</div>
    <div class="mt-2 h-2 rounded-full bg-orange-500" style="width:25%"></div>
  </div>
  <div class="rounded-lg bg-red-100 border border-red-200 p-3">
    <div class="text-lg font-bold text-red-700">+80h</div>
    <div class="text-red-600 text-xs mt-1">Overflow: ignorar</div>
    <div class="mt-2 h-2 rounded-full bg-red-500" style="width:5%"></div>
  </div>
</div>
<p class="text-center text-xs text-gray-500 mt-2"><code class="bg-gray-100 px-1.5 py-0.5 rounded text-xs">POST_AGE_MAX_MINUTES = 4800</code> — lejos de incentivar evergreen como YouTube, X quiere carnaza fresca continua</p>
</div>

<div class="not-prose my-8 px-5 py-4 border-l-4 border-primary/30 bg-primary/5 rounded-r-lg">
<p class="text-sm text-gray-700 m-0">Publicar sin estrategia en X es tirar el dinero. Si necesitas una estrategia de contenidos basada en datos reales, <a href="/servicios/seo/" class="text-primary font-semibold hover:underline">mira mis servicios de SEO y marketing de contenidos</a>.</p>
</div>

## Los 4 tipos de shadowban (todos existen, todos en el código)

<div class="not-prose my-8 grid grid-cols-1 sm:grid-cols-2 gap-4">

<div class="rounded-xl border-2 border-red-300 bg-red-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-red-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-red-600 bg-red-100 px-2 py-0.5 rounded">Severo</span>
<h3 class="text-base font-bold text-red-900 m-0">1. Hard Drop</h3>
</div>
<p class="text-sm text-red-800 m-0">X elimina tu post del feed de todo el mundo sin avisarte. Se aplica a contenido grave o cuentas suspendidas. Tú ni te enteras.</p>
</div>

<div class="rounded-xl border-2 border-orange-300 bg-orange-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-orange-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-orange-600 bg-orange-100 px-2 py-0.5 rounded">Alto</span>
<h3 class="text-base font-bold text-orange-900 m-0">2. DO_NOT_AMPLIFY</h3>
</div>
<p class="text-sm text-orange-800 m-0">Campo literal en el código. Los anuncios dejan de aparecer junto a tus posts. X deja de ganar dinero mostrándote, así que el sistema deja de pushearte. Apagón en seco.</p>
</div>

<div class="rounded-xl border-2 border-yellow-300 bg-yellow-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-yellow-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-yellow-600 bg-yellow-100 px-2 py-0.5 rounded">Medio</span>
<h3 class="text-base font-bold text-yellow-900 m-0">3. Reglas BotMaker</h3>
</div>
<p class="text-sm text-yellow-800 m-0">Panel interno desde el que empleados de X pueden limitar cuentas concretas a mano. Las categorías están documentadas (Content, Safety, Grok...), pero <strong>a quién se las aplican y por qué</strong> no se ha publicado.</p>
</div>

<div class="rounded-xl border-2 border-purple-300 bg-purple-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-purple-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-purple-600 bg-purple-100 px-2 py-0.5 rounded">Crítico</span>
<h3 class="text-base font-bold text-purple-900 m-0">4. Embedding envenenado</h3>
</div>
<p class="text-sm text-purple-800 m-0">El modelo aprende que tu cuenta da mal engagement y te penaliza automáticamente. Nadie tomó la decisión. Nadie te notificó. El sistema se autocorrigió basándose en tus datos históricos. <strong>El más peligroso</strong>.</p>
</div>

</div>

## Las 5 señales que matan tu alcance

Phoenix predice 22 acciones por post. Cinco son pesos negativos que se restan directamente de tu score:

<div class="not-prose my-6 space-y-2">
<div class="flex items-center gap-3 bg-orange-50 border border-orange-200 rounded-lg p-3">
<span class="shrink-0 text-xs font-bold uppercase tracking-wider text-orange-600 bg-orange-100 px-2 py-0.5 rounded">Medio</span>
<div class="text-sm"><code class="bg-orange-100 px-1.5 py-0.5 rounded text-xs text-orange-800">not_interested</code> → <span class="text-orange-700">Penalización directa</span></div>
</div>
<div class="flex items-center gap-3 bg-red-50 border border-red-200 rounded-lg p-3">
<span class="shrink-0 text-xs font-bold uppercase tracking-wider text-red-600 bg-red-100 px-2 py-0.5 rounded">Grave</span>
<div class="text-sm"><code class="bg-red-100 px-1.5 py-0.5 rounded text-xs text-red-800">block_author</code> → <span class="text-red-700">Penalización grave</span></div>
</div>
<div class="flex items-center gap-3 bg-orange-50 border border-orange-200 rounded-lg p-3">
<span class="shrink-0 text-xs font-bold uppercase tracking-wider text-orange-600 bg-orange-100 px-2 py-0.5 rounded">Medio</span>
<div class="text-sm"><code class="bg-orange-100 px-1.5 py-0.5 rounded text-xs text-orange-800">mute_author</code> → <span class="text-orange-700">Penalización media</span></div>
</div>
<div class="flex items-center gap-3 bg-red-50 border border-red-200 rounded-lg p-3">
<span class="shrink-0 text-xs font-bold uppercase tracking-wider text-red-600 bg-red-100 px-2 py-0.5 rounded">Grave</span>
<div class="text-sm"><code class="bg-red-100 px-1.5 py-0.5 rounded text-xs text-red-800">report</code> → <span class="text-red-700">Penalización grave</span></div>
</div>
<div class="flex items-center gap-3 bg-purple-50 border-2 border-purple-300 rounded-lg p-3">
<span class="shrink-0 text-xs font-bold uppercase tracking-wider text-purple-700 bg-purple-100 px-2 py-0.5 rounded">Brutal</span>
<div class="text-sm"><code class="bg-purple-100 px-1.5 py-0.5 rounded text-xs text-purple-800">not_dwelled</code> → <span class="text-purple-700 font-semibold">Hacer scroll sin pararse — matemáticamente peor que no publicar</span></div>
</div>
</div>

Esa última es devastadora. Un post que la gente ignora completamente (scroll sin detenerse) es matemáticamente **peor** que uno que nunca se llegó a publicar.

## Dwell time vs likes: 5 a 1

El scorer de Phoenix tiene **5 señales distintas de dwell** (dwell, cont_dwell_time, click_dwell_time...) pero solo **1 señal de favorito**.

<div class="not-prose my-8 grid grid-cols-2 gap-4">
<div class="rounded-xl border-2 border-red-200 bg-red-50 p-5 text-center">
<div class="text-4xl font-black text-red-500 mb-1">1 seg</div>
<div class="text-sm font-semibold text-red-700 mb-3">Lectura + muchos likes</div>
<div class="text-2xl font-black text-red-600">Score BAJO</div>
</div>
<div class="rounded-xl border-2 border-green-200 bg-green-50 p-5 text-center">
<div class="text-4xl font-black text-green-500 mb-1">8 seg</div>
<div class="text-sm font-semibold text-green-700 mb-3">Lectura + pocos likes</div>
<div class="text-2xl font-black text-green-600">Score ALTO</div>
</div>
</div>

Optimiza por tiempo de lectura, no por likes. Pregúntate: ¿alguien se va a parar a leer esto o va a hacer scroll?

<img src="/images/2026-05-asturwebs-central-algoritmo-x-mecanismos.webp" alt="Diagrama visual de los 4 tipos de shadowban en X mostrando Hard Drop, DO_NOT_AMPLIFY, reglas BotMaker y embedding envenenado con sus mecanismos" width="1280" height="768" />

## Qué funciona según el código

No todo es penalización. El código también revela qué señales **suman** puntos a tu post:

<div class="not-prose my-8 grid grid-cols-1 sm:grid-cols-2 gap-4">

<div class="rounded-xl border-2 border-green-300 bg-green-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-green-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-green-600 bg-green-100 px-2 py-0.5 rounded">Crítico</span>
<h3 class="text-base font-bold text-green-900 m-0">Engagement en los primeros 10 min</h3>
</div>
<p class="text-sm text-green-800 m-0">Si no hay interacciones rápidas, Grok ni evalúa tu post. Manda DM a colegas, ping a tu comunidad, lo que sea — pero que las primeras reacciones lleguen ya.</p>
</div>

<div class="rounded-xl border-2 border-green-300 bg-green-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-green-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-green-600 bg-green-100 px-2 py-0.5 rounded">Alto</span>
<h3 class="text-base font-bold text-green-900 m-0">Horario de tu audiencia</h3>
</div>
<p class="text-sm text-green-800 m-0">Para targetear US: publica entre las 14 y 17h hora España (8-11am ET). No postees en tu horario si tu audiencia está en otro.</p>
</div>

<div class="rounded-xl border-2 border-green-300 bg-green-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-green-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-green-600 bg-green-100 px-2 py-0.5 rounded">Alto</span>
<h3 class="text-base font-bold text-green-900 m-0">Citar virales de tu nicho</h3>
</div>
<p class="text-sm text-green-800 m-0">El modelo ya sabe que el original engancha. Tu cita se apila encima de esa señal positiva. Es caballo ganador.</p>
</div>

<div class="rounded-xl border-2 border-green-300 bg-green-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-green-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-green-600 bg-green-100 px-2 py-0.5 rounded">Medio</span>
<h3 class="text-base font-bold text-green-900 m-0">Vídeos ≥10 segundos con audio</h3>
</div>
<p class="text-sm text-green-800 m-0">Por debajo de <code class="bg-green-100 px-1 rounded text-xs">MinVideoDurationMs</code> pierdes el peso VQV entero. Y Grok ejecuta ASR (speech-to-text) en cada vídeo — sin audio = señal en blanco.</p>
</div>

</div>

## Lo que te destroza el alcance (y no lo sabes)

Las penalizaciones no siempre son shadowbans. A veces son mecanismos sutiles que silencian tu contenido sin que te des cuenta:

### El filtro de hilos: DedupConversationFilter

El código tiene un filtro que **solo deja 1 tweet por conversación** en cada feed. Si haces un hilo de 15 tweets, el sistema solo muestra uno al usuario. Los otros 14 son invisibles. Esto convierte los megahilos en desperdicio matemático puro.

### AuthorDiversityDecay: el castigo por publicar seguido

Cada post consecutivo tuyo se multiplica por `decay^position`. El primero sale normal. El segundo sale penalizado. El cuarto ya está en el suelo. Si publicas 5 cosas seguidas, solo la primera tiene posibilidades reales de llegar a alguien que no te sigue.

**Regla práctica:** máximo 2 posts por sesión, separados por al menos 2 horas.

### El campo slop_score: Grok detecta contenido generado por IA

Hay literalmente un campo `slop_score` en el output del BangerScreen. El clasificador de Grok evalúa si tu post parece generado por IA y le asigna una puntuación. No sabemos el peso exacto (no publicaron los diales), pero **el código lo mide explícitamente**.

Si usas IA para generar posts, reescribe el output. Añade voz personal, datos concretos, referencias locales. Lo que hace que un texto parezca humano — precisamente lo que los LLMs omiten por defecto.

<div class="not-prose my-8 px-5 py-4 border-l-4 border-primary/30 bg-primary/5 rounded-r-lg">
<p class="text-sm text-gray-700 m-0">Si vas a usar IA para tu contenido, mejor que sea con estrategia. <a href="/servicios/ia/" class="text-primary font-semibold hover:underline">Te ayudo a integrar IA en tu flujo de contenidos sin que el algoritmo te penalice</a>.</p>
</div>

## Posts originales vs replies: dos juegos distintos

Solo los **posts originales** pasan por el BangerScreen — el clasificador de calidad de Grok. Las respuestas y retweets nunca entran.

Pero las replies no son tierra de nadie. Tienen su propio sistema:

<div class="not-prose my-6 space-y-2">
<div class="flex items-center gap-3 bg-blue-50 border border-blue-200 rounded-lg p-3">
<span class="shrink-0 text-xs font-bold uppercase tracking-wider text-blue-600 bg-blue-100 px-2 py-0.5 rounded">Cuentas grandes</span>
<div class="text-sm"><strong class="text-blue-800">ReplyRanker (Grok)</strong> → Puntúa de 0 a 3. "¡Primero!" o solo emojis = 0. Aportar valor = máximo.</div>
</div>
<div class="flex items-center gap-3 bg-gray-50 border border-gray-200 rounded-lg p-3">
<span class="shrink-0 text-xs font-bold uppercase tracking-wider text-gray-600 bg-gray-100 px-2 py-0.5 rounded">Cuentas pequeñas</span>
<div class="text-sm"><strong class="text-gray-800">SpamEapiLowFollowerClassifier</strong> → Escáner anti-spam. Respuestas genéricas = penalización.</div>
</div>
</div>

Si te pasas el día respondiendo a cuentas virales, estás optimizando para el Reply Ranker, no para amplificación. **Escribe posts originales si quieres que te descubran fuera de tu red.**

## La rutina de publicación óptima (según el código)

Con todo lo anterior en la mesa, sinteticé una **plantilla semanal de publicación** basada exclusivamente en lo que el código dice que funciona:

<div class="not-prose my-8 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">

<div class="rounded-lg border border-blue-200 bg-blue-50 p-4">
<div class="flex items-center gap-2 mb-2">
<span class="text-blue-600 font-black text-sm">LUN</span>
<span class="text-blue-400 text-xs">Post original largo</span>
</div>
<p class="text-sm text-blue-900 m-0 mb-1"><strong>300-500 palabras</strong></p>
<p class="text-xs text-blue-700 m-0">Máximo dwell time → score alto. Inicio de semana = más atención.</p>
</div>

<div class="rounded-lg border border-green-200 bg-green-50 p-4">
<div class="flex items-center gap-2 mb-2">
<span class="text-green-600 font-black text-sm">MAR</span>
<span class="text-green-400 text-xs">Cita-remix</span>
</div>
<p class="text-sm text-green-900 m-0 mb-1"><strong>Cita viral + opinión tuya</strong></p>
<p class="text-xs text-green-700 m-0">Te apoyas en la señal positiva del original. Bajo riesgo, buena visibilidad.</p>
</div>

<div class="rounded-lg border border-purple-200 bg-purple-50 p-4">
<div class="flex items-center gap-2 mb-2">
<span class="text-purple-600 font-black text-sm">MIE</span>
<span class="text-purple-400 text-xs">Vídeo</span>
</div>
<p class="text-sm text-purple-900 m-0 mb-1"><strong>Vídeo ≥10 seg con audio</strong></p>
<p class="text-xs text-purple-700 m-0">Peso VQV completo. ASR activo. Formato que más dwell genera.</p>
</div>

<div class="rounded-lg border border-gray-200 bg-gray-50 p-4">
<div class="flex items-center gap-2 mb-2">
<span class="text-gray-500 font-black text-sm">JUE</span>
<span class="text-gray-400 text-xs">Descanso</span>
</div>
<p class="text-sm text-gray-900 m-0 mb-1"><strong>Replies de calidad o nada</strong></p>
<p class="text-xs text-gray-600 m-0">Evitar AuthorDiversityDecay. Replies solo a cuentas grandes con valor.</p>
</div>

<div class="rounded-lg border border-amber-200 bg-amber-50 p-4">
<div class="flex items-center gap-2 mb-2">
<span class="text-amber-600 font-black text-sm">VIE</span>
<span class="text-amber-400 text-xs">Post personal</span>
</div>
<p class="text-sm text-amber-900 m-0 mb-1"><strong>Dato o historia personal</strong></p>
<p class="text-xs text-amber-700 m-0">Anti slop_score: voz personal = humano. Viernes = más tiempo de lectura.</p>
</div>

<div class="rounded-lg border border-indigo-200 bg-indigo-50 p-4">
<div class="flex items-center gap-2 mb-2">
<span class="text-indigo-600 font-black text-sm">SAB-DOM</span>
<span class="text-indigo-400 text-xs">Ligero</span>
</div>
<p class="text-sm text-indigo-900 m-0 mb-1"><strong>Nada, o 1 post corto</strong></p>
<p class="text-xs text-indigo-700 m-0">Dejar respirar el embedding. Si publicas, que sea visual.</p>
</div>

</div>

<p class="not-prose text-center text-xs text-gray-500 -mt-4 mb-8">Horario óptimo para audiencia US: 14-17h (España). Para audiencia ES: 9-11h. Siempre en el huso horario de <strong>tu audiencia</strong>, no en el tuyo.</p>

**3 reglas que no se mencionan en ningún análisis del algoritmo:**

1. **La regla del 80/20 del dwell.** El 80% de tu dwell time viene del primer párrafo y del último. Abre con un dato que paren el scroll. Cierra con algo que haga reflexionar (no con un CTA).

2. **El patrón de cita-remix.** En vez de hilos propios, cita un tweet viral de tu nicho y añade tu perspectiva. Recibes la señal positiva del original + tu valor añadido. El algoritmo ve dos señales buenas en vez de una.

3. **La estrategia anti-embedding tóxico.** Si tu embedding está contaminado, no dejes de publicar (las señales malas se congelan). Publica contenido que genere dwell — el engagement nuevo es lo único que sobrescribe las señales viejas. Piensa en ello como rehab: lento, pero funciona si eres constante.

## Si eres negocio (no creador), la estrategia es distinta

Todo lo que lees sobre el algoritmo de X está escrito para creadores de contenido. Pero si tienes un negocio local o un servicio B2B, optimizar para viralidad es perder el tiempo. Tu objetivo no son 100K impresiones — son 10 impresiones a la persona correcta.

El código confirma que esto funciona diferente:

<div class="not-prose my-8 grid grid-cols-1 sm:grid-cols-2 gap-4">

<div class="rounded-xl border-2 border-blue-300 bg-blue-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-blue-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-blue-600 bg-blue-100 px-2 py-0.5 rounded">Clave</span>
<h3 class="text-base font-bold text-blue-900 m-0">Embedding de nicho</h3>
</div>
<p class="text-sm text-blue-800 m-0">Tu embedding debe reflejar tu sector, no entretenimiento. Si interactúas con tu nicho (clientes, proveedores, sector), Phoenix te asocia con ese clúster. No es como Google Local — X agrupa por intereses semánticos, no por ciudad. Un consultor cloud cuyo embedding dice "AWS + Terraform + infraestructura" llega mejor a decisores técnicos que uno cuyo embedding dice "memes trending".</p>
<p class="text-xs text-blue-600 mt-2 m-0 font-mono">→ <code class="bg-blue-100 px-1 rounded text-xs">phoenix/recsys_model.py:93</code>: el transformer recibe <code class="bg-blue-100 px-1 rounded text-xs">num_author_hashes = 2</code> — aprende patrones de engagement por cuenta</p>
</div>

<div class="rounded-xl border-2 border-green-300 bg-green-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-green-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-green-600 bg-green-100 px-2 py-0.5 rounded">A tu favor</span>
<h3 class="text-base font-bold text-green-900 m-0">Dwell técnico</h3>
</div>
<p class="text-sm text-green-800 m-0">Un post sobre un problema concreto que resuelves retiene más segundos que un meme. Explica cómo resolviste un caso real — genera dwell, replies y profile clicks. Tres señales positivas de golpe.</p>
</div>

<div class="rounded-xl border-2 border-purple-300 bg-purple-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-purple-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-purple-600 bg-purple-100 px-2 py-0.5 rounded">Práctico</span>
<h3 class="text-base font-bold text-purple-900 m-0">Min-traction con tu red</h3>
</div>
<p class="text-sm text-purple-800 m-0">No necesitas 100 likes en 30 minutos. Necesitas que tus primeros seguidores (clientes, colegas del sector) interactúen rápido. El mecanismo: avisa a tu equipo o red cercana cuando publicas (Slack, Telegram, WhatsApp business) para que interactúen en esa ventana. Employee advocacy o tráfico desde tus canales propios fuerza la tracción inicial que el algoritmo necesita.</p>
<p class="text-xs text-purple-600 mt-2 m-0 font-mono">→ <code class="bg-purple-100 px-1 rounded text-xs">candidate_hydrators/engagement_counts_hydrator.rs:33</code>: posts &lt;30 min se refrescan cada 5 min; los viejos cada 10 min — engagement temprano se refleja más rápido en tu score</p>
</div>

<div class="rounded-xl border-2 border-red-300 bg-red-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-red-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-red-600 bg-red-100 px-2 py-0.5 rounded">Peligro</span>
<h3 class="text-base font-bold text-red-900 m-0">Slop_score te castiga más</h3>
</div>
<p class="text-sm text-red-800 m-0">Si usas IA para generar "5 consejos para elegir un fontanero", el BangerScreen detecta contenido genérico y te baja el score. Pero un caso real con datos concretos es irreproducible por un LLM — y el modelo lo nota.</p>
<p class="text-xs text-red-600 mt-2 m-0 font-mono">→ <code class="bg-red-100 px-1 rounded text-xs">grox/classifiers/content/banger_initial_screen.py</code>: el output de Grok incluye un campo <code class="bg-red-100 px-1 rounded text-xs">slop_score</code> explícito que mide contenido de baja calidad</p>
</div>

<div class="rounded-xl border-2 border-teal-300 bg-teal-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-teal-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-teal-600 bg-teal-100 px-2 py-0.5 rounded">Técnico</span>
<h3 class="text-base font-bold text-teal-900 m-0">Topics reducen tu penalización OON</h3>
</div>
<p class="text-sm text-teal-800 m-0">El código tiene un <code class="bg-teal-100 px-1 rounded text-xs">TopicOonWeightFactor</code> distinto del penalty OON general. Si tu post matchea un topic reconocido (IA, legal, construcción, salud...), el descuento por ser "fuera de red" se reduce. Usa vocabulario técnico de tu sector — marcas, acrónimos, nombres de herramientas — porque el clasificador reconoce entidades, no hashtags sueltos. Un exceso de hashtags incrementa el rebote y perjudica el dwell.</p>
<p class="text-xs text-teal-600 mt-2 m-0 font-mono">→ <code class="bg-teal-100 px-1 rounded text-xs">filters/topic_ids_filter.rs:109</code>: 80+ categorías reconocidas · <code class="bg-teal-100 px-1 rounded text-xs">scorers/oon_scorer.rs</code>: peso OON distinto cuando hay topic match</p>
</div>

<div class="rounded-xl border-2 border-indigo-300 bg-indigo-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-indigo-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-indigo-600 bg-indigo-100 px-2 py-0.5 rounded">Calidad</span>
<h3 class="text-base font-bold text-indigo-900 m-0">50 seguidores que siguen a 50 cuentas > 5000 que siguen a 5000</h3>
</div>
<p class="text-sm text-indigo-800 m-0">El VMRanker (scorer alternativo) recibe <code class="bg-indigo-100 px-1 rounded text-xs">viewer_following_count</code> como feature. Un seguidor tuyo que sigue a 50 cuentas compite menos por su atención que uno que sigue a 5000. Para un negocio, followers de calidad (pocas cuentas seguidas, activos en tu sector) valen más matemáticamente que números grandes.</p>
<p class="text-xs text-indigo-600 mt-2 m-0 font-mono">→ <code class="bg-indigo-100 px-1 rounded text-xs">scorers/vm_ranker.rs:102</code>: el request al value model incluye <code class="bg-indigo-100 px-1 rounded text-xs">viewer_following_count</code> del usuario</p>
</div>

</div>

<div class="not-prose my-8 px-5 py-4 border-l-4 border-primary/30 bg-primary/5 rounded-r-lg">
<p class="text-sm text-gray-700 m-0">La regla para negocios: publica como si le explicaras un caso a un colega en un café, no como si escribieras un post de LinkedIn. El algoritmo premia la autenticidad sectorial sobre la viralidad genérica. Si necesitas ayuda con tu estrategia de contenidos, <a href="/servicios/seo/" class="text-primary font-semibold hover:underline">trabajamos juntos</a>.</p>
</div>

## Lo que NO publicaron

<div class="not-prose my-8 border-l-4 border-amber-400 bg-amber-50 rounded-r-lg p-5">
<p class="font-bold text-amber-800 text-sm m-0 mb-3">Que no te vendan la moto. El esqueleto es público. Los diales no:</p>
<ul class="m-0 space-y-2 text-sm text-amber-900 list-none p-0">
<li class="flex items-start gap-2"><span class="text-amber-500 font-bold shrink-0">×</span> Los valores numéricos exactos de cada peso (<code class="bg-amber-100 px-1 rounded text-xs">FavoriteWeight</code>, <code class="bg-amber-100 px-1 rounded text-xs">ReplyWeight</code>, <code class="bg-amber-100 px-1 rounded text-xs">AuthorDiversityDecay</code>)</li>
<li class="flex items-start gap-2"><span class="text-amber-500 font-bold shrink-0">×</span> Los 7 prompts reales de Grok (política, seguridad, calidad)</li>
<li class="flex items-start gap-2"><span class="text-amber-500 font-bold shrink-0">×</span> Las reglas de BotMaker aplicadas a cuentas concretas</li>
<li class="flex items-start gap-2"><span class="text-amber-500 font-bold shrink-0">×</span> <code class="bg-amber-100 px-1 rounded text-xs">util/phoenix_request.rs</code> — la llamada final al modelo</li>
<li class="flex items-start gap-2"><span class="text-amber-500 font-bold shrink-0">×</span> 25+ crates <code class="bg-amber-100 px-1 rounded text-xs">xai_*</code> referenciados pero no incluidos</li>
<li class="flex items-start gap-2"><span class="text-amber-500 font-bold shrink-0">×</span> Los pesos del Phoenix de producción (solo publicaron la versión mini)</li>
</ul>
<p class="text-sm text-amber-700 mt-3 mb-0">Nos han dado el esqueleto. El músculo (los pesos) y el cerebro (los prompts y las reglas manuales) son completamente opacos.</p>
</div>

## Lo que el código SÍ responde (preguntas frecuentes, verificado)

<section class="not-prose my-8 space-y-4">

<div class="rounded-xl border-2 border-emerald-300 bg-emerald-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-emerald-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-emerald-600 bg-emerald-100 px-2 py-0.5 rounded">Verificado</span>
<h3 class="text-base font-bold text-emerald-900 m-0">¿Poner un link externo te penaliza?</h3>
</div>
<p class="text-sm text-emerald-800 m-0">En el código publicado, no hay flag de penalización. El bitset (<code class="bg-emerald-100 px-1 rounded text-xs">tweet_type_metrics_hydrator.rs</code>) no rastrea URLs. <strong>Pero</strong> la métrica North Star de X es User Active Minutes — un link saca al usuario de la plataforma y destruye el dwell time de esa sesión. La comunidad SEO ha verificado empíricamente que posts con links sufren menos alcance. Que no esté en el código publicado no significa que no exista en la capa opaca. <strong>Estrategia segura: pon el enlace en el primer comentario del hilo.</strong></p>
</div>

<div class="rounded-xl border-2 border-sky-300 bg-sky-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-sky-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-sky-600 bg-sky-100 px-2 py-0.5 rounded">Verificado</span>
<h3 class="text-base font-bold text-sky-900 m-0">¿Borrar tweets te penaliza?</h3>
</div>
<p class="text-sm text-sky-800 m-0">No hay penalización visible. El sistema usa <strong>tombstones</strong>: borras un tweet → se elimina del mapa <code class="bg-sky-100 px-1 rounded text-xs">posts</code> y se marca en <code class="bg-sky-100 px-1 rounded text-xs">deleted_posts</code>. Los tombstones caducan a los 2 días (retention por defecto). El evento de borrado se loguea en Kafka con timestamp, así que si el modelo de embedding usa frecuencia de borrado como señal, no lo sabemos — no está publicado. Pero en el código visible, borrar es limpio.</p>
</div>

<div class="rounded-xl border-2 border-violet-300 bg-violet-50 p-5 relative overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-1 bg-violet-500"></div>
<div class="flex items-center gap-2 mb-2">
<span class="text-xs font-bold uppercase tracking-wider text-violet-600 bg-violet-100 px-2 py-0.5 rounded">Verificado</span>
<h3 class="text-base font-bold text-violet-900 m-0">¿Tener Premium te da ventaja en el algoritmo?</h3>
</div>
<p class="text-sm text-violet-800 m-0">Sí, pero no como piensas. No hay un "boost automático" por pagar. Lo que hay es: el pipeline trata tu contenido distinto (<code class="bg-violet-100 px-1 rounded text-xs">subscription_hydrator.rs</code> hidrata un <code class="bg-violet-100 px-1 rounded text-xs">subscription_author_id</code> específico) y te saltas ciertos filtros de "karma" que las cuentas gratuitas tienen que escalar poco a poco. Es como empezar la carrera unos peldaños más arriba — no te hace ganar, pero sales con ventaja.</p>
</div>

</section>

## Chuleta para no olvidar

<div class="not-prose my-8 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">

<div class="flex items-start gap-3 bg-green-50 border border-green-200 rounded-lg p-3">
<span class="text-green-600 text-lg shrink-0">&#9201;</span>
<div class="text-sm"><strong class="text-green-800">Primeros 30 min</strong><br/><span class="text-green-700">Importan más que cualquier otra cosa</span></div>
</div>

<div class="flex items-start gap-3 bg-blue-50 border border-blue-200 rounded-lg p-3">
<span class="text-blue-600 text-lg shrink-0">&#127760;</span>
<div class="text-sm"><strong class="text-blue-800">Tu ubicación</strong><br/><span class="text-blue-700">Irrelevante. Tu timing y tu idioma, no</span></div>
</div>

<div class="flex items-start gap-3 bg-purple-50 border border-purple-200 rounded-lg p-3">
<span class="text-purple-600 text-lg shrink-0">&#128065;</span>
<div class="text-sm"><strong class="text-purple-800">Dwell &gt; Like</strong><br/><span class="text-purple-700">El dwell time le gana al like 5 a 1</span></div>
</div>

<div class="flex items-start gap-3 bg-red-50 border border-red-200 rounded-lg p-3">
<span class="text-red-600 text-lg shrink-0">&#128065;&#xFE0F;&#x200D;&#x1F479;</span>
<div class="text-sm"><strong class="text-red-800">4 shadowbans</strong><br/><span class="text-red-700">El peor: embedding envenenado</span></div>
</div>

<div class="flex items-start gap-3 bg-amber-50 border border-amber-200 rounded-lg p-3">
<span class="text-amber-600 text-lg shrink-0">&#9997;&#xFE0F;</span>
<div class="text-sm"><strong class="text-amber-800">Posts originales</strong><br/><span class="text-amber-700">Las replies no pasan por calidad</span></div>
</div>

<div class="flex items-start gap-3 bg-orange-50 border border-orange-200 rounded-lg p-3">
<span class="text-orange-600 text-lg shrink-0">&#128220;</span>
<div class="text-sm"><strong class="text-orange-800">Hilos largos</strong><br/><span class="text-orange-700">DedupConversationFilter: 1 por hilo</span></div>
</div>

<div class="flex items-start gap-3 bg-pink-50 border border-pink-200 rounded-lg p-3">
<span class="text-pink-600 text-lg shrink-0">&#127909;</span>
<div class="text-sm"><strong class="text-pink-800">Vídeos sin audio</strong><br/><span class="text-pink-700">Señal en blanco para Grok</span></div>
</div>

<div class="flex items-start gap-3 bg-teal-50 border border-teal-200 rounded-lg p-3">
<span class="text-teal-600 text-lg shrink-0">&#129302;</span>
<div class="text-sm"><strong class="text-teal-800">AI slop</strong><br/><span class="text-teal-700">El BangerScreen tiene un campo slop_score</span></div>
</div>

<div class="flex items-start gap-3 bg-cyan-50 border border-cyan-200 rounded-lg p-3">
<span class="text-cyan-600 text-lg shrink-0">&#128276;</span>
<div class="text-sm"><strong class="text-cyan-800">2 posts max</strong><br/><span class="text-cyan-700">AuthorDiversityDecay penaliza publicar seguido</span></div>
</div>

<div class="flex items-start gap-3 bg-lime-50 border border-lime-200 rounded-lg p-3">
<span class="text-lime-600 text-lg shrink-0">&#128200;</span>
<div class="text-sm"><strong class="text-lime-800">Cita-remix</strong><br/><span class="text-lime-700">Cita virales + opinión = dos señales positivas</span></div>
</div>

<div class="flex items-start gap-3 bg-gray-50 border border-gray-200 rounded-lg p-3">
<span class="text-gray-600 text-lg shrink-0">&#128300;</span>
<div class="text-sm"><strong class="text-gray-800">50% en A/B</strong><br/><span class="text-gray-700">La mitad del tráfico siempre en experimentos</span></div>
</div>

<div class="flex items-start gap-3 bg-indigo-50 border border-indigo-200 rounded-lg p-3">
<span class="text-indigo-600 text-lg shrink-0">&#128274;</span>
<div class="text-sm"><strong class="text-indigo-800">Lo mejor, oculto</strong><br/><span class="text-indigo-700">Pesos, prompts y reglas: opacos</span></div>
</div>

<div class="flex items-start gap-3 bg-emerald-50 border border-emerald-200 rounded-lg p-3">
<span class="text-emerald-600 text-lg shrink-0">&#128279;</span>
<div class="text-sm"><strong class="text-emerald-800">Links externos</strong><br/><span class="text-emerald-700">Sin flag en el código, pero empíricamente sí penalizan. Pon el link en el primer comentario</span></div>
</div>

<div class="flex items-start gap-3 bg-sky-50 border border-sky-200 rounded-lg p-3">
<span class="text-sky-600 text-lg shrink-0">&#128465;</span>
<div class="text-sm"><strong class="text-sky-800">Borrar tweets</strong><br/><span class="text-sky-700">Tombstone limpio, sin penalización visible</span></div>
</div>

<div class="flex items-start gap-3 bg-violet-50 border border-violet-200 rounded-lg p-3">
<span class="text-violet-600 text-lg shrink-0">&#11088;</span>
<div class="text-sm"><strong class="text-violet-800">Premium</strong><br/><span class="text-violet-700">Pipeline distinto, te saltas filtros de karma</span></div>
</div>

</div>

---

<div class="not-prose my-12 bg-indigo-50 border border-indigo-100 rounded-2xl p-8 text-center">
<p class="text-xl font-semibold text-gray-900 mb-2">¿Cansado de publicar y que no te lea nadie?</p>
<p class="text-gray-600 mb-6">Te ayudo a diseñar una estrategia de contenidos basada en cómo funciona realmente el algoritmo, no en mitos de LinkedIn.</p>
<a href="/contacto/" class="inline-block bg-primary text-white px-8 py-3 rounded-lg font-semibold hover:bg-primary-hover transition-colors">Contacta conmigo →</a>
</div>