<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alexis Román</title>
    <description>The latest articles on DEV Community by Alexis Román (@alexisromtz7).</description>
    <link>https://dev.to/alexisromtz7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4087143%2F38204829-874f-4696-93e8-685ca24caa36.jpg</url>
      <title>DEV Community: Alexis Román</title>
      <link>https://dev.to/alexisromtz7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexisromtz7"/>
    <language>en</language>
    <item>
      <title>Cómo encontrar bugs de importación en Tor usando Grafos AST</title>
      <dc:creator>Alexis Román</dc:creator>
      <pubDate>Tue, 27 Oct 2026 22:41:33 +0000</pubDate>
      <link>https://dev.to/alexisromtz7/como-encontrar-bugs-de-importacion-en-tor-usando-grafos-ast-49cn</link>
      <guid>https://dev.to/alexisromtz7/como-encontrar-bugs-de-importacion-en-tor-usando-grafos-ast-49cn</guid>
      <description>&lt;h1&gt;
  
  
  Cómo encontrar bugs de importación en Tor usando Grafos AST
&lt;/h1&gt;

&lt;p&gt;Hay una clase de bug que las pruebas no atrapan y los linters no ven: el módulo funciona, pero &lt;strong&gt;el orden en que lo importas decide si arranca&lt;/strong&gt;. El código no está roto; el grafo de dependencias sí.&lt;/p&gt;

&lt;p&gt;Este es el registro de uno real, encontrado en &lt;a href="https://github.com/torproject/stem" rel="noopener noreferrer"&gt;&lt;code&gt;torproject/stem&lt;/code&gt;&lt;/a&gt; —la librería de Python para controlar un daemon de Tor— y reportado en &lt;a href="https://github.com/torproject/stem/issues/160" rel="noopener noreferrer"&gt;torproject/stem#160&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 1 — Clonar el sujeto y declarar el universo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 50 https://github.com/torproject/stem.git stem_art
&lt;span class="nb"&gt;cd &lt;/span&gt;stem_art &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git rev-parse HEAD
&lt;span class="c"&gt;# d5012a1039f05c69ebe832723ce96ecbe8f79fe1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El universo es &lt;strong&gt;solo archivos &lt;code&gt;.py&lt;/code&gt;&lt;/strong&gt;. Cualquier cifra que se publique después tiene que declarar ese universo: un árbol sin Python no produce grafo, y un grafo vacío no es un grafo limpio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 2 — Construir el grafo de imports desde el AST
&lt;/h2&gt;

&lt;p&gt;La herramienta no ejecuta el código: parsea cada &lt;code&gt;.py&lt;/code&gt; con &lt;code&gt;ast&lt;/code&gt;, extrae las sentencias &lt;code&gt;import&lt;/code&gt;/&lt;code&gt;from ... import&lt;/code&gt;, las resuelve a módulos del corpus y separa dos subgrafos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;eager&lt;/strong&gt;: la sentencia corre cuando se importa el módulo (cuerpo del módulo, incluido el cuerpo de una &lt;code&gt;class&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;diferida&lt;/strong&gt;: vive dentro de una función; no corre al importar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esa separación es todo el método. Un ciclo diferido no puede cerrarse al importar. Un ciclo &lt;strong&gt;eager&lt;/strong&gt; sí.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 tools/grafo_ciclos_tt_metal_20261026.py &lt;span class="nt"&gt;--root&lt;/span&gt; /tmp/stem_art &lt;span class="nt"&gt;--raices-no-resueltas&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Salida, medida sobre &lt;code&gt;d5012a1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;archivos python     : 219
aristas import      : 611
  eager (al importar): 594
  diferidas          : 17
SCC total           : 5
SCC eager           : 5
  ciclo(11): stem/connection.py, stem/control.py, stem/response/__init__.py,
             stem/response/authchallenge.py, stem/response/events.py,
             stem/response/getconf.py, stem/response/getinfo.py,
             stem/response/mapaddress.py, stem/response/onion_client_auth.py,
             stem/response/protocolinfo.py, stem/socket.py
  CICLO EAGER(2): stem/response/__init__.py, stem/socket.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cinco componentes fuertemente conexas, y &lt;strong&gt;las cinco contienen al menos una arista eager&lt;/strong&gt;. La más pequeña es la interesante: &lt;code&gt;stem/response/__init__.py&lt;/code&gt; ↔ &lt;code&gt;stem/socket.py&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 3 — Convertir la sospecha en una reproducción de dos comandos
&lt;/h2&gt;

&lt;p&gt;Un ciclo eager es una hipótesis, no un hallazgo. El falsificador más barato son dos procesos nuevos, con puntos de entrada distintos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'import stem.response'&lt;/span&gt;   &lt;span class="c"&gt;# entrada por el paquete&lt;/span&gt;
python &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'import stem.socket'&lt;/span&gt;     &lt;span class="c"&gt;# entrada por el otro extremo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Medido con Python 3.12.13:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- import stem.response:  RC=1
Traceback (most recent call last):
  File "&amp;lt;string&amp;gt;", line 1, in &amp;lt;module&amp;gt;
  File "stem/response/__init__.py", line 37, in &amp;lt;module&amp;gt;
    import stem.socket
  File "stem/socket.py", line 105, in &amp;lt;module&amp;gt;
    class BaseSocket(object):
  File "stem/socket.py", line 253, in BaseSocket
    async def _recv(self, handler: Callable[[asyncio.StreamReader], Awaitable[stem.response.ControlMessage]]) -&amp;gt; stem.response.ControlMessage:
                                                                              ^^^^^^^^^^^^^
AttributeError: cannot access submodule 'response' of module 'stem' (most likely due to a circular import)

--- import stem.socket:    RC=0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El mismo código, dos resultados opuestos según por dónde entres. Eso es la firma de un defecto de &lt;strong&gt;orden de carga&lt;/strong&gt;, no de una función mal escrita.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por qué es un defecto de orden de carga
&lt;/h2&gt;

&lt;p&gt;Tres hechos, cada uno verificable en el archivo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;stem/response/__init__.py:37&lt;/code&gt; hace &lt;code&gt;import stem.socket&lt;/code&gt; &lt;strong&gt;mientras &lt;code&gt;stem.response&lt;/code&gt; todavía se está inicializando&lt;/strong&gt;. En ese instante, &lt;code&gt;stem.response&lt;/code&gt; existe en &lt;code&gt;sys.modules&lt;/code&gt;, pero el atributo &lt;code&gt;response&lt;/code&gt; del paquete &lt;code&gt;stem&lt;/code&gt; —el que hace funcionar &lt;code&gt;stem.response.ControlMessage&lt;/code&gt;— aún no está ligado.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stem/socket.py:105&lt;/code&gt; abre &lt;code&gt;class BaseSocket(object):&lt;/code&gt;. El cuerpo de una clase &lt;strong&gt;se ejecuta al importar&lt;/strong&gt;, y &lt;code&gt;stem/socket.py&lt;/code&gt; no tiene &lt;code&gt;from __future__ import annotations&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Por eso la anotación de &lt;code&gt;stem/socket.py:253&lt;/code&gt; se evalúa de inmediato, en el momento exacto en que el nombre &lt;code&gt;stem.response&lt;/code&gt; no es alcanzable como atributo.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;La anotación no es código que corra; es metadata que Python 3 evalúa con ganas (eager) si no se le dice lo contrario. Y &lt;code&gt;stem/socket.py:90&lt;/code&gt; (&lt;code&gt;import stem.response&lt;/code&gt;) cierra el círculo: los dos módulos se necesitan, y &lt;strong&gt;quién termina primero decide si la anotación resuelve&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Cuando entras por &lt;code&gt;stem.socket&lt;/code&gt;, &lt;code&gt;stem.socket&lt;/code&gt; se inicializa primero, su &lt;code&gt;import stem.response&lt;/code&gt; corre hasta el final, y para cuando toca evaluar la anotación el nombre ya existe. Cuando entras por &lt;code&gt;stem.response&lt;/code&gt;, el orden se invierte y revienta.&lt;/p&gt;

&lt;h2&gt;
  
  
  El arreglo
&lt;/h2&gt;

&lt;p&gt;Cualquiera de los dos rompe la dependencia de orden:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;annotations&lt;/span&gt;   &lt;span class="c1"&gt;# al inicio de stem/socket.py
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o citar la anotación afectada (&lt;code&gt;'stem.response.ControlMessage'&lt;/code&gt;). Ambos dejan &lt;code&gt;typing.get_type_hints()&lt;/code&gt; funcionando, porque los nombres resuelven cuando el paquete ya está cargado.&lt;/p&gt;

&lt;p&gt;Medido, no supuesto: con la línea añadida, &lt;code&gt;import stem.response&lt;/code&gt; sale &lt;strong&gt;RC 0&lt;/strong&gt;; revertida la línea, vuelve a salir &lt;strong&gt;RC 1&lt;/strong&gt; con el mismo &lt;code&gt;AttributeError&lt;/code&gt;. El defecto y su cierre están en el mismo par de comandos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por qué un grafo AST y no un linter
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Un linter de imports mira un archivo; el bug &lt;strong&gt;no está en un archivo&lt;/strong&gt;, está en el par.&lt;/li&gt;
&lt;li&gt;Las pruebas de &lt;code&gt;stem&lt;/code&gt; no lo ven porque cada módulo de prueba importa lo que necesita en el orden que le conviene: el orden accidental del test enmascara el orden real del usuario.&lt;/li&gt;
&lt;li&gt;El grafo cuesta segundos y no ejecuta el sujeto. Produce un &lt;strong&gt;ranking&lt;/strong&gt;: 5 SCC, todas con arista eager. Eso reduce el espacio de búsqueda de "219 archivos" a "un par".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El costo real está en la resolución de nombres, no en el parseo: sobre este checkout, &lt;strong&gt;1 015 imports no resolvieron&lt;/strong&gt; (913 de &lt;code&gt;STDLIB&lt;/code&gt;, 102 de dependencias externas como &lt;code&gt;cryptography&lt;/code&gt;), y &lt;strong&gt;211 aristas hacia el &lt;code&gt;__init__&lt;/code&gt; de un paquete ancestro fueron descartadas&lt;/strong&gt; a propósito —el paquete ya está en &lt;code&gt;sys.modules&lt;/code&gt; cuando corre el hijo, contarlas fabrica ciclos que el runtime nunca recorre—. Un motor que no declara esas dos decisiones publica ciclos falsos con total comodidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alcance y límites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ninguna afirmación de seguridad.&lt;/strong&gt; Es un defecto de tiempo de importación: se manifiesta como un &lt;code&gt;AttributeError&lt;/code&gt; duro en vez de un import que funciona.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No se probó contra un daemon de Tor en ejecución.&lt;/strong&gt; Solo el import, en un intérprete limpio.&lt;/li&gt;
&lt;li&gt;El bug es del sujeto, no del método: el método solo lo hizo visible sin leer &lt;code&gt;stem/socket.py&lt;/code&gt; de arriba abajo primero.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prueba
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Issue abierto: &lt;a href="https://github.com/torproject/stem/issues/160" rel="noopener noreferrer"&gt;torproject/stem#160 — &lt;em&gt;AttributeError on class-body annotation evaluation in stem/socket.py when importing stem.response first&lt;/em&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Observado y reproducible en &lt;code&gt;d5012a1039f05c69ebe832723ce96ecbe8f79fe1&lt;/code&gt;, Python 3.12.13, macOS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si mantienes una librería con paquetes que se importan entre sí, el experimento te cuesta dos comandos: construye el grafo, separa eager de diferido, y prueba cada ciclo pequeño con dos puntos de entrada opuestos. El que falle en uno y no en el otro es tu bug.&lt;/p&gt;

</description>
      <category>python</category>
      <category>staticanalysis</category>
      <category>ast</category>
      <category>tor</category>
    </item>
    <item>
      <title>Cómo preparar tu primera carrera de 10k en 8 semanas</title>
      <dc:creator>Alexis Román</dc:creator>
      <pubDate>Thu, 20 Aug 2026 20:08:54 +0000</pubDate>
      <link>https://dev.to/alexisromtz7/como-preparar-tu-primera-carrera-de-10k-en-8-semanas-5e00</link>
      <guid>https://dev.to/alexisromtz7/como-preparar-tu-primera-carrera-de-10k-en-8-semanas-5e00</guid>
      <description>&lt;p&gt;Correr tu primer 10k es una meta que está más cerca de lo que crees. No necesitas ser un atleta de élite ni haber corrido antes; solo necesitas un plan realista, constancia y el equipo adecuado. En Kinestesia sabemos que el miedo al 'no voy a poder' es el primer obstáculo, por eso diseñamos esta guía de 8 semanas para que llegues a la meta con confianza y sin lesiones.&lt;br&gt;
La distancia de 10 kilómetros (10k) es perfecta para quien ya camina rápido o ha corrido distancias cortas como 5k. Es un reto que exige preparación, pero no te esclaviza: con tres o cuatro días de entrenamiento por semana es suficiente. Lo importante es la consistencia, no la velocidad. Al final, lo que recordarás no es tu tiempo, sino la sensación de cruzar la línea.&lt;br&gt;
Antes de empezar, visita a tu médico si tienes alguna condición de salud o llevas mucho tiempo sin hacer ejercicio. También invierte en un par de tenis para correr que se ajusten bien a tu pisada; no tiene que ser el más caro, pero sí el adecuado. Y en cuanto a ropa, elige prendas transpirables que no te rocen. Aquí es donde Kinestesia te acompaña: playeras técnicas que se secan rápido y shorts con bolsillo para tu teléfono hacen que cada entrenamiento sea más cómodo.&lt;br&gt;
En las próximas secciones te doy el plan semana a semana, consejos de nutrición, cómo elegir tu ropa y cómo mantener la motivación. Al final, tendrás todo lo necesario para inscribirte a tu primer 10k y disfrutarlo. Recuerda: correr es más mental que físico, y tu mente ya está lista.&lt;br&gt;
H2: Plan de entrenamiento para 10k en 8 semanas&lt;br&gt;
Este plan está pensado para corredores principiantes que ya pueden trotar 20 minutos sin parar. Si aún no llegas a eso, toma dos semanas extras para caminar rápido y trotar de forma intermitente. La base es alternar carrera y caminata, aumentando gradualmente el tiempo de carrera.&lt;br&gt;
Semana 1: Entrena tres días. Lunes: 20 minutos de trote suave + 10 minutos de caminata. Miércoles: 25 minutos de trote + 5 de caminata. Sábado: 30 minutos de trote continuo. Entre cada día, descansa o haz caminata ligera.&lt;br&gt;
Semana 2: Aumenta a cuatro días. Lunes: 25 minutos de trote. Miércoles: 30 minutos de trote. Viernes: 20 minutos de trote + 10 de caminata. Sábado: 35 minutos de trote continuo. Escucha a tu cuerpo; si sientes dolor, baja la intensidad.&lt;br&gt;
Semana 3: Lunes: 30 minutos de trote. Miércoles: 35 minutos de trote. Viernes: 25 minutos de trote. Sábado: 40 minutos de trote continuo. Esta semana es clave para construir resistencia.&lt;br&gt;
Semana 4: Lunes: 30 minutos de trote. Miércoles: 40 minutos de trote. Viernes: 30 minutos de trote. Sábado: 45 minutos de trote continuo. Al final de esta semana, deberías sentir que 5k ya es cómodo.&lt;br&gt;
Semana 5: Lunes: 35 minutos de trote. Miércoles: 40 minutos de trote. Viernes: 30 minutos de trote. Sábado: 50 minutos de trote continuo. Aquí es donde tu cuerpo empieza a adaptarse a distancias más largas.&lt;br&gt;
Semana 6: Lunes: 40 minutos de trote. Miércoles: 45 minutos de trote. Viernes: 30 minutos de trote. Sábado: 55 minutos de trote continuo. Si puedes, busca una ruta con subidas suaves para fortalecer piernas.&lt;br&gt;
Semana 7: Lunes: 40 minutos de trote. Miércoles: 45 minutos de trote. Viernes: 30 minutos de trote. Sábado: 60 minutos de trote continuo. Esta es tu semana más larga; ya puedes correr 8-9k sin problema.&lt;br&gt;
Semana 8: Lunes: 30 minutos de trote suave. Miércoles: 20 minutos de trote suave. Viernes: descanso total. Sábado: ¡carrera! No intentes correr más de lo que has entrenado; el objetivo es terminar, no hacer un tiempo récord.&lt;br&gt;
H2: Cómo elegir la ropa adecuada para tu primer 10k&lt;br&gt;
La ropa que usas para correr no es un lujo, es una herramienta. Una playera de algodón se empapa de sudor, se pega al cuerpo y te hace sentir pesado. En cambio, una playera técnica transpirable te mantiene seco y fresco, especialmente en el clima cálido de Morelos, donde corremos casi todo el año.&lt;br&gt;
En Kinestesia encontrarás playeras running con tejidos que evacuan la humedad y costuras planas que evitan rozaduras. También shorts y bikers con bolsillo para tu teléfono y llaves, para que no cargues nada en las manos. Si corres en la mañana o al atardecer, un rompevientos ligero te protege del viento sin que pases calor.&lt;br&gt;
Para las mujeres, los tops y sets deportivos ofrecen soporte y libertad de movimiento. No necesitas gastar una fortuna; solo prendas que se ajusten bien y te hagan sentir segura. Recuerda: cuando te sientes cómodo con tu ropa, corres mejor y disfrutas más.&lt;br&gt;
H2: Nutrición e hidratación para correr 10k&lt;br&gt;
Lo que comes antes de correr afecta tu rendimiento. Dos horas antes de tu entrenamiento, come algo ligero como un plátano, una tostada con mermelada o un puñado de nueces. Evita comidas pesadas o muy grasosas, porque te sentirás lento.&lt;br&gt;
La hidratación es clave, sobre todo en climas cálidos. Bebe agua durante el día, no solo justo antes de correr. Si tu entrenamiento dura más de 45 minutos, lleva una botella de agua o planifica una ruta con fuentes. Después de correr, repón electrolitos con agua de coco o una bebida deportiva.&lt;br&gt;
El día de la carrera, no experimentes con comidas nuevas. Desayuna lo mismo que has probado en tus entrenamientos largos. Llega con tiempo, calienta caminando 10 minutos y haz algunos estiramientos dinámicos. Tu cuerpo ya sabe lo que es correr 10k; solo tienes que dejar que lo haga.&lt;br&gt;
H2: Motivación y comunidad: no corras solo&lt;br&gt;
Uno de los secretos para no abandonar es encontrar una comunidad. Correr con otros te empuja a salir incluso los días que no tienes ganas. En Cuernavaca hay parques como el Chapultepec o la Barranca de Amanalco donde siempre verás corredores. También puedes buscar grupos de running en redes sociales.&lt;br&gt;
En Kinestesia creemos en el poder de la comunidad. Por eso organizamos retos y compartimos consejos con nuestra comunidad de corredores. Además, en el ecosistema Tiendas Platino encontrarás aliados como Narada Yoga, ideal para estirar y recuperarte después de tus entrenamientos, o Moon &amp;amp; Rain para vestir con estilo fuera de la pista.&lt;br&gt;
Otra forma de mantenerte motivado es fijar metas pequeñas: correr 10 minutos sin parar, completar tu primer 5k, o simplemente salir tres veces a la semana. Celebra cada logro, por pequeño que sea. Y si un día fallas, no te castigues; retoma al día siguiente. La constancia es más importante que la perfección.&lt;br&gt;
H2: Preguntas frecuentes sobre preparar tu primer 10k&lt;br&gt;
¿Puedo correr 10k en 8 semanas si nunca he corrido? Sí, si ya caminas rápido o has corrido 5k. Si partes de cero, toma 2-3 semanas extra para construir una base. El plan es progresivo y respeta los descansos.&lt;br&gt;
¿Qué hago si me duele algo durante el entrenamiento? Escucha a tu cuerpo. Dolor muscular leve es normal, pero dolor en articulaciones o punzadas no. Descansa un día extra, aplica hielo y si persiste, consulta a un especialista. No corras con dolor fuerte.&lt;br&gt;
¿Qué ropa necesito para el día de la carrera? Usa la misma ropa con la que entrenaste: playera técnica, short o legging con bolsillo, y tenis ya probados. No estrenes nada el día de la carrera. En Kinestesia encuentras todo lo que necesitas.&lt;br&gt;
H2: Tu primera carrera de 10k te espera&lt;br&gt;
Preparar tu primer 10k en 8 semanas es totalmente posible si sigues un plan, escuchas a tu cuerpo y te rodeas de apoyo. No se trata de ser el más rápido, sino de superar tu propio límite y disfrutar el proceso. Cada kilómetro que corras te acerca a una versión más fuerte de ti.&lt;br&gt;
Equípate para tu próxima carrera en kinestesia.com.mx y aprovecha tu 10% de bienvenida con el código BIENVENIDO10. Tenemos playeras transpirables, shorts con bolsillo y todo lo que necesitas para que tu primer 10k sea una experiencia increíble. Nos vemos en la meta.&lt;/p&gt;

</description>
      <category>10k</category>
      <category>entrenamiento</category>
      <category>plandecarrera</category>
      <category>running</category>
    </item>
  </channel>
</rss>
