<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es-ES">
  <generator uri="https://jekyllrb.com/" version="custom">Jekyll</generator>
  <link href="https://paelladoc.com/es/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="https://paelladoc.com/es/" rel="alternate" type="text/html" hreflang="es"/>
  <link href="https://paelladoc.com/feed.xml" rel="alternate" type="application/atom+xml" hreflang="en"/>
  <updated>2026-07-22T14:12:02+00:00</updated>
  <id>https://paelladoc.com/es/feed.xml</id>
  <title type="html">PAELLADOC — La Fábrica Local de Software</title>
  <subtitle>Construye y dirige software desde una idea o un repo. Discovery, especificaciones, sprints, agentes, grafos de código y evidencia, en tu Mac.</subtitle>
  <author>
    <name>PAELLADOC</name>
    <email>contact@paelladoc.com</email>
  </author>

  <entry>
    <title type="html">Vibe coding vs ingeniería asistida por IA: la línea que importa</title>
    <link href="https://paelladoc.com/es/blog/vibe-coding-vs-ingenieria-asistida/" rel="alternate" type="text/html" title="Vibe coding vs ingeniería asistida por IA: la línea que importa"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/vibe-coding-vs-ingenieria-asistida/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/vibe-coding-vs-ingenieria-asistida/"><![CDATA[<p>El término vibe coding empezó describiendo una cosa genuina y útil: dejar que un agente escriba código mientras tú diriges por sensación, apenas leyendo el output, persiguiendo una idea a la velocidad de una conversación. Addy Osmani trazó la distinción útil que se me ha quedado, entre ese modo y algo que él llama ingeniería asistida por IA. Los dos usan los mismos modelos y los mismos editores. No son la misma actividad, y confundirlas está detrás de mucho sufrimiento.</p>
<p>Quiero hacer esa línea concreta, porque “ingeniería” puede sonar a reprimenda, como si la respuesta fuera solo ser más serio y escribir más tests. No va de seriedad. Va de una cosa concreta que haces o no haces, y todo lo demás se deriva de ella.</p>
<h2 id="la-línea-no-está-donde-la-gente-cree">La línea no está donde la gente cree</h2>
<p>La gente intenta ubicar la diferencia en los sitios equivocados, y cada sitio equivocado lleva a una mala conclusión.</p>
<p>No son las herramientas. La misma sesión de Cursor puede producir cualquiera de los dos modos. No es la velocidad. La ingeniería asistida por IA no es vibe coding más lento con más ceremonia atornillada, y tratarla así solo hace que odies la ceremonia. Ni siquiera es si escribes tests, porque puedes escribir tests que no demuestran nada y seguir haciendo vibe coding con pasos extra.</p>
<p>La línea es la aceptación. El vibe coding acepta el código generado porque parece funcionar. La ingeniería acepta el código generado porque se ha demostrado que cumple un contrato que definiste. Esa es la distinción entera, y es más pequeña y más afilada de lo que sugiere el marco habitual. Uno confía en el output. El otro lo verifica contra algo enunciado por adelantado.</p>
<p>Todo lo que la gente asocia con los dos modos se deriva de esa única diferencia. El vibe coding se siente rápido y libre porque confiar es más rápido que verificar. La ingeniería se siente más deliberada porque existe un contrato y el código tiene que superarlo. Mismo paso de generación, distinta puerta al final.</p>
<h2 id="por-qué-el-vibe-coding-no-es-el-enemigo">Por qué el vibe coding no es el enemigo</h2>
<p>No estoy construyendo hacia “vibe coding malo, ingeniería buena”. Ese marco es a la vez incorrecto e inútil.</p>
<p>El vibe coding es el modo correcto para un conjunto grande y legítimo de trabajo. Explorar una idea, montar un prototipo para ver si algo merece la pena, scripts desechables, cualquier cosa donde equivocarse es barato y aprender rápido es el objetivo. En esa zona, pararse a definir contratos y verificar contra ellos es puro sobrecoste. Estarías haciendo ingeniería de algo que estás a punto de borrar, que es su propio tipo de desperdicio. La velocidad de confiar en el output es exactamente lo que quieres cuando lo que está en juego en ese output es casi cero.</p>
<p>El fallo no es el vibe coding. El fallo es el vibe coding pasado de fecha de caducidad: quedarte en el modo de confiar-en-el-output después de que el output empezó a importar. Es la transición exacta que intento trazar al ir <a href="/es/blog/vibe-coding-a-produccion/">del vibe coding a producción</a>. El modo que era correcto para el prototipo se vuelve peligroso para el producto, y nadie te manda una notificación cuando cruzas la línea.</p>
<h2 id="qué-cambia-cuando-cruzas">Qué cambia cuando cruzas</h2>
<p>En el momento en que el código empieza a importar, lo más barato que puedes añadir no son tests ni tipos. Es un contrato: una declaración, antes de que el agente construya, de qué debe hacer el cambio y cómo reconocerás un resultado correcto. Es el núcleo del <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a>, y es la cosa más pequeña posible que convierte el vibe coding en ingeniería, porque le da a la aceptación algo contra lo que comprobar.</p>
<p>Con un contrato en su sitio, la verificación deja de ser sensaciones. “Funciona” se convierte en “cumple el contrato, y aquí está la evidencia”. Sin uno, incluso una suite de tests que pasa es solo una sensación más elaborada, porque los tests describen lo que el código resultó hacer en vez de lo que se suponía que hacía. El contrato es lo que le da a la palabra “hecho” algún significado.</p>
<p>También es por eso que el modo de ingeniería es más caro, y por eso ese gasto es el punto. Definir el contrato es trabajo real. Es el trabajo que la IA no eliminó. Generar el código se abarató, así que la actividad escasa y valiosa se movió a decidir qué significa correcto y demostrar que el código lo cumple. En el modo de ingeniería estás haciendo ese trabajo escaso. En el modo vibe te lo saltas, lo que está bien hasta que no.</p>
<h2 id="los-dos-modos-y-la-deuda">Los dos modos y la deuda</h2>
<p>La diferencia práctica más clara aparece después, en lo que cada modo deja atrás. El vibe coding acumula <a href="/es/blog/deuda-tecnica-vibe-coding/">deuda en tres capas</a>, comprensión, verificación y arquitectura, precisamente porque nada se verificó contra un contrato sobre la marcha. La ingeniería paga un coste pequeño por adelantado, el contrato y la evidencia, y arrastra mucha menos de esa deuda.</p>
<p>Así que la elección entre los modos es en realidad una elección sobre cuándo pagas. El vibe coding lo aplaza todo a un ajuste de cuentas futuro. La ingeniería paga un poco de forma continua. Ninguno es universalmente correcto. En un prototipo, aplazar es correcto. En un producto, <a href="https://martinfowler.com/bliki/TechnicalDebt.html">la factura aplazada</a> es el <a href="/es/blog/vibe-coding-a-produccion/">colapso de los 90 días</a> con el que todo el mundo acaba topando. Saber en qué modo estás es saber a qué calendario de pagos te apuntaste.</p>
<p>Y explica un miedo del que he escrito en otro sitio. La razón de que la gente acabe con <a href="/es/blog/miedo-a-tocar-el-codigo/">miedo a tocar su propio código</a> casi siempre es que se quedó en modo vibe demasiado tiempo. No hay contrato contra el que comprobar un cambio ni evidencia de que nada funcione, así que cada edición es un salto. El miedo es la experiencia sentida de haber aceptado mucho código sin verificar ninguno.</p>
<h2 id="sigues-siendo-tú-quien-decide">Sigues siendo tú quien decide</h2>
<p>Aquí está la parte que ninguno de los dos modos elimina. Confíes o verifiques, hagas vibe o ingeniería, eres tú quien toma esa decisión, cambio a cambio. El agente no sabe si este código importa. No puede distinguir si estás prototipando o publicando. Ese juicio es tuyo, y es el trabajo de verdad ahora.</p>
<p>Es lo que quiero decir cuando afirmo que <a href="/es/blog/eres-el-runtime/">tú eres el runtime</a>. El agente genera. Tú decides qué modo pide el momento, defines el contrato cuando hace falta uno, y aguantas la línea de la evidencia cuando importa. La línea entre vibe coding e ingeniería no la dibujan tus herramientas. La dibujas tú, cada vez que decides si “funciona” es suficiente.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La parte difícil de vivir en el lado correcto de esta línea es que el contrato y la evidencia tienen que existir en algún sitio duradero, o el modo de ingeniería se degrada en silencio hasta volver a ser vibe coding. Un contrato en un chat cerrado no es un contrato. Evidencia que no guardaste no es evidencia.</p>
<p>PaellaDoc existe para hacer del modo de ingeniería el camino de menor resistencia: un sitio donde enunciar el contrato antes de que el agente construya, un vínculo de ese contrato al código que lo implementa, y la evidencia de que se cumplió, todo junto en local en vez de repartido. No te impide hacer vibe coding cuando el vibe coding es lo correcto. Hace que cruzar a la ingeniería sea lo bastante barato como para que de verdad lo hagas cuando el código empieza a importar.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿El vibe coding es malo?</strong> No. Es el modo correcto para exploración, prototipos y cualquier trabajo donde equivocarse es barato. Solo se vuelve un problema cuando te quedas en él después de que el código empieza a importar, lo que convierte la verificación saltada en riesgo acumulado.</p>
<p><strong>¿Qué separa de verdad el vibe coding de la ingeniería asistida por IA?</strong> La aceptación. El vibe coding acepta el código generado porque parece funcionar. La ingeniería lo acepta porque se ha demostrado que cumple un contrato definido por adelantado. Las herramientas, los modelos y la velocidad son los mismos.</p>
<p><strong>¿Tengo que elegir un modo para todo el proyecto?</strong> No. El modo es una decisión por cambio. Prototipa una feature por sensaciones y cambia a ingeniería cuando esa feature pase a sostener peso. La habilidad es saber cuál pide el momento.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿El vibe coding es malo?", "acceptedAnswer": { "@type": "Answer", "text": "No. Es el modo correcto para exploración, prototipos y cualquier trabajo donde equivocarse es barato. Solo se vuelve un problema cuando te quedas en él después de que el código empieza a importar, lo que convierte la verificación saltada en riesgo acumulado." } },
    { "@type": "Question", "name": "¿Qué separa de verdad el vibe coding de la ingeniería asistida por IA?", "acceptedAnswer": { "@type": "Answer", "text": "La aceptación. El vibe coding acepta el código generado porque parece funcionar. La ingeniería lo acepta porque se ha demostrado que cumple un contrato definido por adelantado. Las herramientas, los modelos y la velocidad son los mismos." } },
    { "@type": "Question", "name": "¿Tengo que elegir un modo para todo el proyecto?", "acceptedAnswer": { "@type": "Answer", "text": "No. El modo es una decisión por cambio. Prototipa una feature por sensaciones y cambia a ingeniería cuando esa feature pase a sostener peso. La habilidad es saber cuál pide el momento." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[El vibe coding y la ingeniería asistida por IA usan las mismas herramientas y los mismos modelos. La línea entre ellos no es la velocidad ni el output. Es si aceptas el código generado por fe o le haces demostrarse.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="ingenieria-asistida"/><category term="ai-coding"/><category term="verificacion"/><category term="spec-driven-development"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">El ajuste de cuentas del día 90: por qué las apps vibe-coded se rompen al tercer mes</title>
    <link href="https://paelladoc.com/es/blog/vibe-coding-dia-90/" rel="alternate" type="text/html" title="El ajuste de cuentas del día 90: por qué las apps vibe-coded se rompen al tercer mes"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/vibe-coding-dia-90/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/vibe-coding-dia-90/"><![CDATA[<p>Hay un patrón que aparece tan a menudo que casi es un calendario. Alguien hace vibe coding de una app, funciona, la publica, y durante semanas parece magia. Las features nuevas caen en minutos. Y entonces, hacia el tercer mes, la misma app que parecía sin esfuerzo se convierte en un sitio donde cada cambio rompe algo y nadie, incluida la persona que la construyó, sabe decir por qué.</p>
<p>Este es el ajuste de cuentas del día 90. No es mala suerte y no es tu culpa como constructor. Es la factura de la estructura que se saltó para ir rápido, y llega con un reloj predecible. Saber por qué cae en el mes 3 en concreto es lo que te deja salirle al paso antes de que él te salga a ti.</p>
<h2 id="qué-aspecto-tiene-el-ajuste-de-cuentas">Qué aspecto tiene el ajuste de cuentas</h2>
<p>Lo reconocerás por los síntomas antes de entender la causa:</p>
<ul>
<li>Un cambio que debería llevar cinco minutos lleva un día, y ni así estás seguro de que sea seguro.</li>
<li>Arreglas una cosa y se rompen otras dos, a menudo en partes que no tocaste.</li>
<li>Empiezas teniendo miedo a desplegar un viernes, y luego miedo a desplegar y punto.</li>
<li>Abres un archivo que escribiste tú mismo hace dos meses y no puedes seguirlo.</li>
<li>Las features nuevas se ralentizan hasta arrastrarse, justo lo contrario de cómo empezó.</li>
</ul>
<p>La señal es la inversión. El vibe coding empieza rápido y, pasado el ajuste de cuentas, se vuelve más lento que hacer la cosa con cuidado desde el principio. La curva no se aplana. Se dobla hacia abajo.</p>
<h2 id="por-qué-el-mes-3-y-no-el-mes-1">Por qué el mes 3, y no el mes 1</h2>
<p>El momento no es místico. Tres fuerzas se cruzan más o menos en el mismo punto.</p>
<p><strong>Tu memoria del código se degrada con calendario.</strong> Cuando haces vibe coding, la comprensión de cómo funciona vive en tu cabeza, no en el código, porque nunca leíste la mayor parte. La memoria humana de ese tipo de contexto no escrito se desvanece en semanas. En la segunda semana aún recuerdas por qué el agente hizo las cosas. Para el tercer mes esa memoria se ha ido, y no hay nada escrito que la sustituya. Ahora mantienes el código de un desconocido, y el desconocido eras tú.</p>
<p><strong>La complejidad compone, no suma.</strong> Cada feature se generó asumiendo que el resto de la app se queda quieta. Las interacciones entre N features crecen mucho más rápido que N. Para el primer puñado los choques son raros. Pasado un umbral, cada añadido toca algo que no estaba diseñado para conocer, y <a href="/es/blog/features-que-rompen-features/">las features nuevas rompen las viejas de forma rutinaria</a>. Ese umbral suele caer hacia el tercer mes de añadidos constantes.</p>
<p><strong>El prototipo se convirtió en el producto sin avisar.</strong> En las primeras semanas nadie depende de él, así que una rotura no cuesta nada. Para el tercer mes hay gente real que confía en él, y la misma rotura que antes era invisible ahora es una caída, un número mal, un registro perdido. Nada del código cambió. Lo que cambió fue lo que hay en juego, y la red que falta pasa a soportar peso.</p>
<p>Junta todo: tu memoria se ha ido, las interacciones han compuesto más allá de lo que puedes sostener, y el coste de cada error ha dado un salto. Esa intersección es el ajuste de cuentas.</p>
<h2 id="la-versión-pública-de-la-misma-lección">La versión pública de la misma lección</h2>
<p>La versión suave es una app lenta y un fundador nervioso. La versión severa sale en las noticias. Hubo un incidente muy comentado en 2025 en el que un agente de código, operando sobre un proyecto en vivo, borró la base de datos de producción de una empresa durante lo que se suponía era una congelación. No voy a adornar los detalles más allá de lo que fue público, porque el punto no necesita adorno: cuando un agente opera sobre un sistema que nadie ha mapeado del todo, sin límites obligados y sin red, el modo de fallo no es un bug pequeño. Es todo, de golpe.</p>
<p>La mayoría de los ajustes de cuentas son más silenciosos que ese. Pero tienen la misma forma, a menor escala: un agente, o tú, cambiando un sistema que ya no tiene una estructura conocible, y descubriendo por las malas qué estaba conectado con qué.</p>
<h2 id="el-ajuste-de-cuentas-es-una-deuda-y-la-deuda-tiene-condiciones">El ajuste de cuentas es una deuda, y la deuda tiene condiciones</h2>
<p>La forma útil de pensar esto no es “la app es mala”. Es que <a href="https://martinfowler.com/bliki/TechnicalDebt.html">pediste un préstamo</a>. El vibe coding te presta velocidad por adelantado, y el préstamo es real y a menudo vale la pena pedirlo. Pero tiene condiciones, y el ajuste de cuentas es el vencimiento. Qué debes exactamente, y cuándo vencen las distintas partes, vale la pena calcularlo a propósito en vez de descubrirlo por sorpresa; ese es todo el tema de <a href="/es/blog/deuda-tecnica-vibe-coding/">la deuda técnica del vibe coding</a>.</p>
<p>La trampa es tratar el préstamo como gratis porque los primeros pagos son invisibles. El interés se acumula desde el día uno. Solo que no lo sientes hasta que la memoria se desvanece y las interacciones componen, que es, otra vez, hacia el tercer mes.</p>
<h2 id="cómo-salirle-al-paso-pronto">Cómo salirle al paso pronto</h2>
<p>No evitas el ajuste de cuentas haciendo menos vibe coding. Lo evitas amortizando la deuda antes de que venza, mientras aún recuerdas cómo funciona el código.</p>
<p>La jugada es dejar de tratar “funciona” como la meta en cuanto alguien empieza a depender de la app. Antes de que se desvanezca la memoria, haz las tres cosas baratas que convierten la deuda en estructura: escribe qué se supone que hace la app de verdad, captura el comportamiento actual en <a href="https://martinfowler.com/bliki/SelfTestingCode.html">una red</a> para que los cambios anuncien su daño, y haz el código legible para tu yo futuro. Ese es el cruce, y la ruta completa por etapas está en <a href="/es/blog/vibe-coding-a-produccion/">de vibe coding a producción</a>. Cuanto antes lo empieces, menos cuesta, porque pagas con memoria que aún tienes en vez de con arqueología que te toca rehacer.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La razón por la que cae el ajuste de cuentas es que el conocimiento de cómo funciona la app no tiene casa fuera de tu cabeza, y tu cabeza se vacía con calendario. El trabajo de PaellaDoc es darle a ese conocimiento una casa: lee el repo y lo convierte en un modelo que puedes navegar, mantiene las specs y las decisiones pegadas al código, y vuelve a ejecutar la app para probar que los comportamientos siguen en pie. No hace desaparecer la deuda. Hace que la deuda deje de ser invisible, para que el tercer mes sea un pago programado en vez de una emboscada.</p>
<p>Puedes salirle al paso al ajuste de cuentas pronto y barato, o tarde y caro. La fecha está más o menos fijada. Lo que pagas, no.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Por qué las apps vibe-coded se rompen hacia el mes 3 en concreto?</strong> Tres cosas se cruzan en ese punto: tu memoria de cómo funciona el código se ha desvanecido, las interacciones entre features han compuesto más allá de lo que te cabe en la cabeza, y ahora hay gente real que depende de la app, así que los fallos por fin cuestan algo.</p>
<p><strong>¿Se puede evitar el ajuste de cuentas?</strong> La fecha está más o menos fijada, pero el coste no. Amortizar la deuda pronto, mientras aún recuerdas el código, convierte una crisis en una tarea programada. Hacer menos vibe coding no es el arreglo; añadir estructura antes del vencimiento sí.</p>
<p><strong>¿Qué hago en cuanto noto los síntomas?</strong> Deja de añadir features y empieza el cruce: escribe qué debería hacer la app, pon una red alrededor del comportamiento actual y vuelve a hacer el código legible. Añadir más sobre una base sin mapear solo sube el interés.</p>]]></content>
    <summary type="html"><![CDATA[Las apps vibe-coded tienden a romperse con calendario. Semanas de magia y, hacia el mes 3, la misma app se vuelve imposible de cambiar con seguridad. Aquí está por qué llega cuando llega, y cómo salirle al paso pronto.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="deuda-tecnica"/><category term="ai-coding"/><category term="de-prototipo-a-producto"/><category term="mantenibilidad"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">De vibe coding a producción: el puente que nadie explica</title>
    <link href="https://paelladoc.com/es/blog/vibe-coding-a-produccion/" rel="alternate" type="text/html" title="De vibe coding a producción: el puente que nadie explica"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/vibe-coding-a-produccion/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/vibe-coding-a-produccion/"><![CDATA[<p>Describiste una app en lenguaje normal y un agente la construyó. Funcionaba. Se la enseñaste a alguien, empezó a usarla, y en algún punto dejó de ser un experimento. Ahora es de lo que depende la gente, y eres la única persona que puede mantenerla en marcha, salvo que no tienes claro cómo se mantiene en marcha.</p>
<p>Ese es el cruce que nadie explica. Hay contenido infinito sobre cómo empezar a hacer vibe coding y casi nada sobre la parte que de verdad duele: el día en que el prototipo se convirtió en el producto y los cimientos nunca llegaron a ponerse.</p>
<p>Este es el mapa de ese cruce. No un aviso para que vayas más despacio, ni una excusa para reescribirlo todo “como Dios manda”. Un puente por etapas que puedes recorrer con la app en producción.</p>
<h2 id="dónde-estás-en-realidad">Dónde estás en realidad</h2>
<p>Voy a ser preciso con la situación, porque casi todos los consejos apuntan a otra.</p>
<p>No eres un principiante que tiene que aprender a programar. Publicaste algo real, rápido, y funciona lo bastante bien como para que la gente volviera. Eso es genuinamente difícil y las herramientas que te trajeron aquí son buenas haciéndolo. Si quieres la definición completa de la técnica y el punto donde deja de sostenerte, en <a href="/es/blog/que-es-vibe-coding/">qué es el vibe coding y dónde deja de funcionar</a> trazo esa línea sin desprecio.</p>
<p>El problema no es el código que tienes. Es el código que no puedes ver. Un prototipo es un conjunto de comportamientos que funcionaron una vez. Un producto es un conjunto de comportamientos que siguen funcionando mientras los cambias, mientras los usa más gente, mientras duermes. La distancia entre esos dos estados no es talento. Es estructura que un prototipo se salta legítimamente para ir rápido, y que un producto no puede saltarse.</p>
<p>Todo el mundo cruza esta distancia tarde o temprano. La mayoría la cruza por accidente, con pánico, en el peor momento posible. La alternativa es cruzarla a propósito.</p>
<h2 id="las-cuatro-cosas-que-un-prototipo-se-salta">Las cuatro cosas que un prototipo se salta</h2>
<p>Un prototipo vibe-coded se salta justo lo que no aparece en una demo. No es pereza, es lo que lo hace rápido. Cada una <a href="https://martinfowler.com/bliki/TechnicalDebt.html">vence más tarde</a>.</p>
<figure class="tp-diagram tp-diagram--graph" data-diagram-type="graph" role="img" aria-label="Las cuatro cosas que un prototipo se salta para ir rápido. Ninguna aparece en la demo; las cuatro vencen mientras lo mantienes."><svg viewBox="0 0 760 320" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="380" y1="160" x2="140" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="140" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="140" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">SIN SPEC</text><line x1="380" y1="160" x2="620" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="620" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="620" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">SIN MEMORIA DEL PORQUÉ</text><line x1="380" y1="160" x2="96" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="96" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="96" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">SIN RED</text><line x1="380" y1="160" x2="664" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="664" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="664" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">SIN CONTRATO</text><circle cx="380" cy="160" r="14" fill="var(--tp-mostaza)" fill-opacity="0.16" stroke="var(--tp-mostaza)" stroke-width="1.8"></circle>
  <text x="380" y="194" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">EL PROTOTIPO</text></svg><figcaption>Las cuatro cosas que un prototipo se salta para ir rápido. Ninguna aparece en la demo; las cuatro vencen mientras lo mantienes.</figcaption></figure>
<p><strong>Un modelo de lo que hace.</strong> El prototipo tiene comportamientos, no una especificación. Nadie escribió qué significa “correcto”, así que nadie sabe cuándo se rompe. El conocimiento vive en tu cabeza, y tu cabeza olvida.</p>
<p><strong>Una memoria del porqué.</strong> Cada decisión de diseño que tomó el agente es invisible. Por qué esta forma de datos, por qué este flujo, qué evita hacer a propósito. Tres semanas después ese razonamiento se ha ido, también de ti, un <a href="/es/blog/entender-codigo-generado-por-ia/">patrón ya documentado</a>.</p>
<p><strong>Una red de seguridad.</strong> Nada te avisa cuando un cambio rompe algo que funcionaba. En un prototipo te enteras haciendo clic. En un producto se enteran antes tus usuarios.</p>
<p><strong>Un contrato entre las partes.</strong> Cada feature se generó por su cuenta, asumiendo que el mundo a su alrededor se quedaba quieto. Nada obliga a que esa asunción se cumpla, y por eso <a href="/es/blog/features-que-rompen-features/">cada feature nueva empieza a romper una vieja</a> en cuanto tienes más de un puñado.</p>
<p>Ninguna aparece mientras construyes. Las cuatro aparecen mientras mantienes. El cruce es el trabajo de devolverlas sin parar el mundo.</p>
<h2 id="el-puente-etapa-a-etapa">El puente, etapa a etapa</h2>
<p>No reescribes. Una reescritura tira el único activo que tienes, comportamiento que funciona, para perseguir estructura que podrías añadir sin apagar nada. Añades la estructura por debajo de lo que ya funciona.</p>
<h3 id="etapa-1-ver-lo-que-tienes">Etapa 1: Ver lo que tienes</h3>
<p>No puedes mantener lo que no puedes leer. Antes de cualquier arreglo, el trabajo es convertir un montón opaco de código generado en algo que puedas navegar: cuáles son las partes reales, cómo se hablan, dónde vive el dato, qué pasa de verdad cuando un usuario pulsa el botón principal.</p>
<p>Esto no es “léete cada línea”. Es dibujar un mapa, a la altura de componentes y flujos, no de sintaxis. Cuando puedes señalar las cuatro o cinco piezas reales de tu app y decir para qué sirve cada una, has pasado de pasajero a conductor. El método completo está en <a href="/es/blog/entender-codigo-generado-por-ia/">qué hacer cuando publicaste código que no sabes leer</a>.</p>
<h3 id="etapa-2-escribir-la-spec-que-nunca-se-escribió">Etapa 2: Escribir la spec que nunca se escribió</h3>
<p>Ahora escribe qué se supone que hace la app, en presente, desde fuera. No cómo funciona el código, cuál es el comportamiento: un usuario con este rol puede hacer esto, no puede hacer aquello, este número siempre cuadra con ese otro. Son especificaciones retroactivas, y son lo más barato que harás en todo el puente.</p>
<p>Por qué importan: una especificación es el contrato que dice qué significa “correcto”. Sin ella, “funciona” solo quiere decir “aún no se ha roto de forma visible”. Un build en verde <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">no es una feature correcta</a>, es un build que compiló. La spec es lo que convierte una vaga sensación de que funciona en algo que puedes comprobar.</p>
<h3 id="etapa-3-fijar-el-comportamiento-con-tests">Etapa 3: Fijar el comportamiento con tests</h3>
<p>Una vez escrito lo que hace la app, captúralo en tests de caracterización: tests cuyo trabajo no es definir el comportamiento correcto sino congelar el comportamiento actual, para que el siguiente cambio te avise en el momento en que mueve algo. Esta es <a href="https://martinfowler.com/bliki/SelfTestingCode.html">la red</a>. Es lo que convierte el miedo a tu propio código en una señal sobre la que puedes actuar.</p>
<p>No lo pruebas todo. Pruebas los caminos que dolerían si se rompieran: la aritmética del dinero, la frontera de permisos, el flujo que la gente usa de verdad. Todo lo de aguas abajo se vuelve más fácil una vez que estos existen, porque ahora puedes cambiar cosas y saberlo.</p>
<h3 id="etapa-4-poner-cimientos-sin-reescribir">Etapa 4: Poner cimientos sin reescribir</h3>
<p>Con un mapa, specs y una red, por fin puedes reforzar la estructura: poner límites donde las features se meten unas en otras, añadir el contrato que impide que una feature rompa otra en silencio, retirar el código copiado y pegado que multiplica cada bug. Este es el trabajo de carga, y solo es seguro después de las tres primeras etapas, porque ahora cada cambio está comprobado. La secuencia completa está en <a href="/es/blog/arreglar-app-vibe-coding/">arreglar una app vibe-coded sin reescribirla</a>.</p>
<h2 id="por-qué-el-orden-es-todo">Por qué el orden es todo</h2>
<p>No puedes saltar a la etapa 4. Reforzar la estructura sin red es como “un arreglito” se lleva por delante cuatro cosas a las 2 de la mañana. Tampoco puedes saltar a la etapa 3: unos tests que fijan comportamiento que no entiendes solo congelan tus bugs en su sitio. El orden es mapa, spec, red, cimientos, y no es negociable, porque cada etapa es lo que hace segura la siguiente.</p>
<p>Por eso también “reescríbelo bien y ya” es mal consejo. Una reescritura son las cuatro etapas a la vez, a ciegas, con la versión que funciona apagada. Pierdes el comportamiento que tenías y reconstruyes los mismos huecos en código nuevo. El puente se tarda más en describir y muchísimo menos en vivir, porque la app nunca deja de funcionar mientras cruzas.</p>
<p>He visto la diferencia en abierto. Cuando le pedí a un agente que construyera la misma app sin estructura, <a href="/es/blog/codex-app-dia-siguiente/">no sobrevivió al primer clic</a>. La distancia nunca fue lo bien que se veía el código generado. Fue si había algo debajo que aguantara peso.</p>
<h2 id="lo-que-el-cruce-no-es">Lo que el cruce no es</h2>
<p>Ayuda nombrar lo que este puente no es, porque el miedo que lo rodea suele venir de imaginar el trabajo equivocado.</p>
<p>No es aprender ciencias de la computación. No necesitas entender compiladores ni notación big-O para escribir qué hace tu app y comprobar que lo sigue haciendo. Las cuatro etapas son trabajo con forma de producto, no de académico: qué debería ser cierto, ¿sigue siéndolo?, dónde vive.</p>
<p>No es contratar a un ingeniero para que te lo quite de las manos. Puedes traer a uno, y uno bueno te agradecerá haber hecho las etapas uno y dos primero. Pero el cruce está diseñado para que lo camine la persona que construyó el prototipo, porque esa persona tiene lo único que ningún fichaje tiene: la memoria de qué se suponía que hacía, mientras esa memoria aún está fresca.</p>
<p>No es dejar de publicar. Sigues lanzando durante todo el cruce. El puente añade estructura bajo una app en vivo, en piezas pequeñas, cada una verificada. Nada de esto exige una congelación, y una congelación suele ser justo donde las apps vibe-coded van a morir.</p>
<p>Y no es un proyecto de una sola vez que terminas y olvidas. La razón por la que el prototipo perdió su estructura es que la estructura nunca se mantuvo al día. El sentido de cruzar a propósito es dejar tras de ti una spec, una red y un mapa que sigan pegados al código, para que no despiertes en el mismo sitio una segunda vez.</p>
<h2 id="la-señal-de-que-estás-listo-para-empezar">La señal de que estás listo para empezar</h2>
<p>No esperas a que la app esté rota para empezar. Empiezas en cuanto notas cualquiera de estas: alguien que no eres tú depende de ella, dudas antes de cambiar algo, o abres un archivo que escribiste y no puedes seguirlo. Cada una es la app diciéndote que cruzó de prototipo a producto mientras estabas ocupado publicando. Cuanto antes respondas, más barato el cruce, porque pagas con memoria que aún tienes en vez de con arqueología que te toca reconstruir.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Cada etapa de este puente es manual ahora mismo. Eres tú quien lee el código para hacer el mapa, quien tiene la spec en la cabeza, quien se acuerda de pasar las comprobaciones, quien caza la feature que rompió otra feature. Eso funciona hasta que la app es lo bastante grande como para que no puedas sostenerla entera, que es más o menos el momento en que se volvió digna de mantener.</p>
<p>PaellaDoc existe para que el puente sea un sistema en vez de un acto heroico. Lee un repo existente y lo convierte en un modelo navegable de lo que hay, mantiene las specs y las decisiones junto al código que gobiernan, y ejecuta la app para producir evidencia de que un comportamiento sigue funcionando en vez de fiarse de un build en verde. La idea no es hacer el cruce por ti. Es que el mapa, el contrato y la prueba vivan en un solo sitio y sigan al día, en vez de degradarse en tu memoria como lo hicieron la primera vez. El argumento amplio de ese sistema es el pilar sobre <a href="/es/blog/construir-software-con-agentes-de-ia/">construir software con agentes de IA</a>.</p>
<p>Ya hiciste la parte difícil y creativa. Construiste algo que la gente usa. El puente es cómo consigues quedártelo.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Tengo que reescribir mi app vibe-coded para que esté lista para producción?</strong> No. Una reescritura descarta el comportamiento que ya funciona para perseguir estructura que puedes añadir por debajo. El enfoque por etapas, mapa, luego spec, luego tests, luego cimientos, añade lo que producción necesita con la app en marcha.</p>
<p><strong>¿Cuándo se convierte un prototipo en producto?</strong> El día en que alguien empieza a depender de él, normalmente antes de que decidas que ha pasado. Esa es la señal para empezar el cruce, no el tamaño ni la edad de la app.</p>
<p><strong>¿Qué es lo primero que hago?</strong> Hacer el código legible para ti: un mapa de las partes y flujos reales. No puedes especificar, probar ni reforzar lo que no puedes navegar, así que todas las etapas siguientes dependen de esta.</p>]]></content>
    <summary type="html"><![CDATA[El vibe coding te da un prototipo que funciona en una tarde. Nadie explica lo que viene después: el día en que el prototipo se convirtió en el producto y tienes que mantenerlo en pie. Aquí está el puente, etapa a etapa.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="de-prototipo-a-producto"/><category term="ai-coding"/><category term="deuda-tecnica"/><category term="spec-driven-development"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Verificar código generado por IA: evidencia, no sensaciones</title>
    <link href="https://paelladoc.com/es/blog/verificar-codigo-generado-por-ia/" rel="alternate" type="text/html" title="Verificar código generado por IA: evidencia, no sensaciones"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/verificar-codigo-generado-por-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/verificar-codigo-generado-por-ia/"><![CDATA[<p>Un agente termina una tarea y te responde: «Hecho. Todos los tests pasan». No lo has visto ejecutar nada. Tienes un diff, una frase segura y una decisión que tomar. ¿Te lo crees?</p>
<p>Multiplícalo por ocho sesiones en paralelo, una docena de tareas cada una y una cola que se llena más rápido de lo que puedes leerla. Esta es la forma real de construir con agentes en 2026. El código llega. La pregunta nunca es si el modelo sabe escribirlo. La pregunta es si puedes fiarte de lo que ha vuelto, y <a href="/es/blog/brecha-de-confianza/">cuánto de tu día te cuesta ya esa confianza</a>.</p>
<p>Este es el artículo que ata todo lo demás. La generación está resuelta. <strong>El cuello de botella es la confianza, no el output.</strong> Todo lo que viene debajo es una sola idea vista desde seis ángulos: deja de verificar con sensaciones y empieza a verificar con evidencia.</p>
<h2 id="las-sensaciones-no-son-evidencia">Las sensaciones no son evidencia</h2>
<p>Hay una forma cómoda de trabajar con agentes, y es silenciosamente peligrosa. El agente suena seguro. La prosa es limpia. El plan se lee bien. Así que apruebas, integras y sigues. No has verificado nada. Has sentido algo.</p>
<p>Una sensación es una señal sobre la superficie del output: parece correcto, se lee como código que escribiría alguien competente, los nombres de variable tienen sentido. La evidencia es una señal sobre el comportamiento del output: este test se ejecutó, contra esta versión, y esto es lo que imprimió. En el hueco entre ambas es donde el software roto se publica con una marca verde encima.</p>
<p>El replanteamiento que recorre todo este cluster es sencillo. El informe de un agente es una afirmación. Una afirmación no es una prueba. La verificación es el trabajo de convertir una en la otra, y es un trabajo que tienes que diseñar, porque el agente no lo hará por ti a menos que le fuerces la forma de la respuesta.</p>
<p>Haz concreta la distinción. «La lógica de reintentos está implementada y testeada» es una afirmación. Podría ser cierta. También es exactamente lo que el agente escribiría si implementó la lógica y no ejecutó ni un test, porque esa frase es el final natural de una tarea que pedía lógica de reintentos testeada. Ahora compara: «ejecuté <code>pytest tests/retry_test.py</code>, 14 pasaron, 0 fallaron, contra los criterios de aceptación v3». Eso es evidencia. Puedes leerla, puedes re-ejecutarla y nombra la versión del contrato contra la que se comprobó. La primera frase te pide confianza. La segunda se la gana, o falla a gritos. Toda la verificación consiste en mover tus decisiones del primer tipo de frase al segundo.</p>
<h2 id="por-qué-se-dice-los-tests-pasan-cuando-no-se-ejecutó-nada">Por qué se dice «los tests pasan» cuando no se ejecutó nada</h2>
<p>Empieza por el fallo que más sorprende: el agente dice que los tests pasan y no se ejecutó ni uno.</p>
<p>Ayuda ver el mecanismo en vez de enfadarse con la máquina. Un modelo de lenguaje completa texto. Cuando el contexto que lo rodea es una implementación terminada y una tarea que pedía tests en verde, la continuación más probable es una frase que informa de éxito. «Los tests pasan» es como suelen acabar esas situaciones en los datos de entrenamiento, así que eso es lo que se escribe. El modelo no miente en ningún sentido humano. Produce la frase probable, y la frase probable y la frase verdadera no son lo mismo.</p>
<p>Esta es la <a href="/es/blog/exitos-falsos-de-agentes/">anatomía de un éxito falso</a>: un informe generado por probabilidad, desconectado de cualquier ejecución. No es maldad y no es estupidez. Es el comportamiento por defecto de la herramienta, y en cuanto lo ves dejas de sorprenderte y empiezas a diseñar alrededor.</p>
<p>El arreglo no es un prompt mejor suplicándole al agente que diga la verdad. El arreglo es estructural: que el agente no sea quien informa del éxito. Que el éxito sea algo que un <a href="/es/blog/bucles-de-verificacion/">paso aparte observa y registra</a>.</p>
<h2 id="hecho-tiene-que-significar-hecho">Hecho tiene que significar hecho</h2>
<p>Si una afirmación es barata, la compleción tiene que ser cara. Tiene que costarle al agente una demostración.</p>
<p>«Hecho» es una de las palabras más sobrecargadas de este trabajo. Para un agente, hecho puede significar «escribí código que parece cumplir lo que se pedía». Para ti, hecho significa que el comportamiento cambió, que el comportamiento antiguo no se rompió, y que hay algo que puedes señalar para probar ambas cosas. Son <a href="/es/blog/definicion-de-hecho/">definiciones distintas</a>, y toda la disciplina de <a href="/es/blog/hecho-significa-hecho/">hacer que hecho signifique hecho</a> consiste en cerrar la distancia entre ellas.</p>
<p>¿Qué cuenta como prueba? No una casilla. No el resumen del agente. Un comando que se ejecutó, su salida y la versión del contrato contra la que se ejecutó. Cuando hecho exige una demostración, el agente deja de ser el juez de su propio trabajo y pasa a ser la parte que tiene que aportar pruebas. Ese solo movimiento elimina casi toda la clase de fallo en la que la prosa segura tapa un resultado vacío. El build en verde nunca fue el objetivo. Como no se cansa de repetir el desarrollo guiado por especificaciones, <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>; que el build pase y que la feature esté bien son dos afirmaciones, y normalmente solo se comprueba una, sobre todo cuando el agente <a href="/es/blog/probar-codigo-de-ia/">escribió los tests en la misma tirada que el código</a>.</p>
<h2 id="no-puedes-leerlo-todo-así-que-lee-en-los-momentos-correctos">No puedes leerlo todo, así que lee en los momentos correctos</h2>
<p>Aun cuando la evidencia es real, hay demasiada. Los agentes escriben más rápido de lo que lee ningún humano. Las <a href="https://survey.stackoverflow.co/2025/">encuestas a desarrolladores</a> repiten lo que el día ya te dice: revisar código generado por IA suele costar más atención que revisar el de un colega, porque nada de la intención del autor vino con él. Esto es la <a href="/es/blog/fatiga-de-revision/">fatiga de revisión</a>, y no es un defecto de carácter. Es un desajuste de caudal.</p>
<p>La respuesta no es leer con más fuerza. Es leer en los momentos que llevan más información por minuto invertido. Aprueba el alcance antes de que el agente construya, para dirigir la intención en vez de auditar un hecho consumado. <a href="/es/blog/revisar-codigo-ajeno/">Comprueba el diff contra ese alcance</a>, no contra tu recuerdo vago de lo que querías. Mira al final la evidencia: qué se ejecutó, qué pasó, contra qué contrato. Revisar en ese orden convierte una tarea de lectura sin límites en unos pocos puntos de control de alto apalancamiento. La misma lógica explica por qué la revisión más barata es la que haces sobre la spec, antes de que exista una sola línea, y conecta directo con <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">para qué sirve el desarrollo guiado por especificaciones</a>.</p>
<h2 id="el-cuello-de-botella-se-movió-de-producir-a-asegurar">El cuello de botella se movió de producir a asegurar</h2>
<p>Aléjate un paso y el patrón es económico. Durante décadas, la parte escasa y cara del software fue producirlo: escribir el código, hacerlo compilar, conseguir que funcionara siquiera. Los agentes hundieron el coste de esa parte. Lo que no se abarató es saber que lo producido es correcto, seguro y coherente con todo lo que lo rodea.</p>
<p>Así que el cuello de botella se movió. Pasó <a href="/es/blog/aseguramiento-de-software/">de producir a asegurar</a>. La estación cara de la línea ya no es la que escribe código, es la que decide si fiarse de él. Si tu proceso sigue tratando la producción como la parte difícil y el aseguramiento como un sello de goma al final, has optimizado la estación equivocada, y se nota en una base de código que crece rápido y se pudre más rápido. Es el mismo desplazamiento que convierte cada cambio aislado y plausible en un sistema <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto y globalmente incoherente</a> cuando nadie asegura el conjunto.</p>
<h2 id="cierra-el-trabajo-con-la-prueba-adjunta">Cierra el trabajo con la prueba adjunta</h2>
<p>El último ángulo es donde aterriza todo esto: qué te quedas cuando una tarea termina. La mayoría de los flujos se quedan el diff y tiran la evidencia. El test se ejecutó, imprimió verde, y la salida se perdió en un scrollback de terminal que nadie volverá a encontrar. Tres semanas después no sabes si aquel verde llegó a existir ni contra qué versión.</p>
<p>El <a href="/es/blog/desarrollo-basado-en-evidencia/">desarrollo basado en evidencia</a> es la práctica de cerrar el trabajo con su prueba adjunta: el cambio, y junto a él qué se ejecutó, qué pasó y contra qué contrato, guardado donde la siguiente persona y el siguiente agente puedan encontrarlo. Una casilla marcada es estado. No es evidencia. Cuando la implementación abunda y el autor es a menudo un modelo, la prueba duradera deja de ser papeleo y se convierte en lo único que te deja fiarte del estado del sistema sin volver a verificarlo a mano. Por eso una especificación es solo la mitad de la historia si la prueba no viaja con ella, que es el argumento de las <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">especificaciones de software portables</a>.</p>
<h2 id="la-cadena-de-la-afirmación-a-la-prueba">La cadena, de la afirmación a la prueba</h2>
<p>Leídos como un solo flujo, los seis ángulos son un pipeline por el que una afirmación baja hasta salir por el otro extremo convertida en algo de lo que puedes fiarte. El agente hace una afirmación. La compleción se niega a aceptarla bajo su palabra y exige una demostración. La demostración tiene que ser una ejecución real, no una frase generada, y por eso importa entender el éxito falso: te dice que la afirmación y la ejecución nunca estuvieron conectadas de entrada. La ejecución produce evidencia, y esa evidencia se captura y se conserva junto al cambio en vez de evaporarse. La revisión ocurre entonces en los momentos que llevan más información, leyendo la evidencia capturada en vez de reconstruirla. Y toda la línea la dimensiona su estación más lenta, el aseguramiento, porque es ahora la restricción.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="Los seis ángulos como una tubería: una afirmación solo se vuelve confianza si sobrevive a cada estación en orden."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="94" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">AFIRMACIÓN</text><path d="M 154 95 L 176 95 M 170 89 L 176 95 L 170 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="182" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="236" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">DEMOSTRAR</text><path d="M 296 95 L 318 95 M 312 89 L 318 95 L 312 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="324" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="378" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EJECUTAR</text><path d="M 438 95 L 460 95 M 454 89 L 460 95 L 454 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="466" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="520" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EVIDENCIA</text><path d="M 580 95 L 602 95 M 596 89 L 602 95 L 596 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="608" y="62" width="108" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="662" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">ASEGURAR</text></svg><figcaption>Los seis ángulos como una tubería: una afirmación solo se vuelve confianza si sobrevive a cada estación en orden.</figcaption></figure>
<p>Falla cualquier eslabón y la cadena gotea. Exige una demostración pero deja que el agente la narre, y el éxito falso pasa de largo. Captura evidencia pero tírala al integrar, y la revisión no tiene nada que leer. Asegura con diligencia pero solo al final, y has optimizado la estación equivocada mientras el trabajo sin verificar se amontonaba delante. El sentido de un hub es hacer visibles los eslabones, porque en la práctica los equipos arreglan uno y dejan los demás abiertos, y luego se preguntan por qué la confianza nunca llega.</p>
<h2 id="el-cuello-de-botella-es-la-confianza-no-el-output">El cuello de botella es la confianza, no el output</h2>
<p>Junta los seis ángulos y sale una sola afirmación. <a href="/es/blog/construir-software-con-agentes-de-ia/">Construir software con agentes</a> no lo frena cuánto código puedes generar. Lo frena cuánto de ese código puedes creer sin pararte a comprobarlo a mano. Cada hora gastada en re-verificar un trabajo que el agente ya dijo terminar es el impuesto de la evidencia que falta.</p>
<p>La verificación con evidencia es cómo amortizas ese impuesto. No confiando más, ni leyéndolo todo, sino haciendo que el sistema produzca prueba como subproducto de hacer el trabajo, para que la confianza sea algo que puedas inspeccionar en vez de algo que tengas que sentir.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Construyo <a href="/">PaellaDoc</a> porque este problema es el que más me cuesta cada día. El movimiento que hace es negarse al éxito auto-declarado. Nada llega a «hecho» con una frase. Llega a hecho cuando el contrato de aceptación fijado antes de empezar se ha ejecutado contra el resultado real y la evidencia se ha capturado junto al cambio. El agente deja de ser el juez y pasa a ser la parte que aporta pruebas. La confianza deja de ser una sensación y pasa a ser una carpeta que puedes abrir.</p>
<p>Los agentes seguirán mejorando en escribir código. Eso nunca fue lo difícil. Lo difícil es saber que acertaron, y saberlo lo bastante rápido para seguir avanzando.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Qué significa verificar código generado por IA?</strong> Sustituir la afirmación de éxito del agente por una prueba comprobable: un comando que se ejecutó, su salida y la versión del contrato de aceptación contra la que corrió, guardada junto al cambio. El agente informa; un paso aparte verifica y registra.</p>
<p><strong>¿Por qué los agentes dicen que los tests pasan si no los ejecutaron?</strong> Porque un modelo de lenguaje completa el texto más probable para la situación, y tras una implementación terminada la continuación probable es una frase de éxito. Genera el informe probable, no observa una ejecución real. El arreglo es estructural: que el agente no sea quien declara el éxito.</p>
<p><strong>¿No es revisarlo todo la respuesta segura?</strong> No, no escala. Los agentes producen más de lo que nadie puede leer a fondo. La respuesta duradera es revisar en los momentos de alto apalancamiento (alcance, luego diff, luego evidencia) y hacer que el sistema capture la prueba de forma automática, para que la confianza descanse en la evidencia y no en una lectura exhaustiva.</p>]]></content>
    <summary type="html"><![CDATA[Generar código está resuelto. Lo que no está resuelto es la confianza. Un agente que informa «hecho, los tests pasan» ha producido la frase más probable, no un resultado verificado. Verificar código generado por IA es sustituir la sensación de compleción por evidencia que puedes inspeccionar: la afirmación, la prueba y la puerta entre ambas.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="verify-ai-code"/><category term="ai-coding"/><category term="verificacion"/><category term="aseguramiento-de-software"/><category term="desarrollo-basado-en-evidencia"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Trae tu propio modelo: claves API, motores locales y portabilidad</title>
    <link href="https://paelladoc.com/es/blog/tu-propio-modelo/" rel="alternate" type="text/html" title="Trae tu propio modelo: claves API, motores locales y portabilidad"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/tu-propio-modelo/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/tu-propio-modelo/"><![CDATA[<p>Elegiste una herramienta de código con IA. Te registraste. En algún punto de ese flujo, o se quedó con tu cuenta de proveedor, o te entregó su propio modelo sin manera de cambiarlo. Fue cómodo durante una semana.</p>
<p>Luego el modelo del que dependías cambió. O se movió el precio. O necesitaste correr una tarea en un avión sin red. Y descubriste, por las malas, que el modelo no era un ajuste que pudieras editar. Estaba soldado al producto, y cambiarlo significaba cambiar de producto.</p>
<p>Traer tu propio modelo es la apuesta contraria. Tú pones la clave. Tú apuntas al motor. La herramienta trata el modelo como una pieza, no como su propio corazón. Suena a checkbox. En realidad es una decisión sobre cómo está construido todo lo demás, y hay que tomarla antes de la primera línea del producto, no atornillarla después.</p>
<h2 id="una-clave-que-tienes-tú-no-es-lo-mismo-que-una-clave-que-tienen-ellos">Una clave que tienes tú no es lo mismo que una clave que tienen ellos</h2>
<p>Empecemos por la fontanería aburrida, porque decide todo lo que viene encima.</p>
<p>Cuando una herramienta te pide entrar con su cuenta y luego llama al modelo por ti, la relación que tienes con el proveedor del modelo pasa por la herramienta. Tu consumo es su línea de gasto. Tus rate limits son los que ellos negociaron. Tu acuerdo de datos es el suyo, no el tuyo. Si cambian de plan, o los compran, o deciden que tu tramo ya no les sale a cuenta, ese es tu problema entrando por su puerta.</p>
<p>Cuando traes tu propia clave, la cuenta es tuya. Tienes la API key de Anthropic, de OpenAI, de quien sea. La <a href="/es/blog/controlar-costes-de-ia/">factura va a tu tarjeta</a>, bajo tus términos. Los rate limits son los que contrataste. El acuerdo de tratamiento de datos es el que leíste y aceptaste. La herramienta es un cliente apuntando a tus credenciales, y mañana puede apuntar a otro sitio.</p>
<p>Esto no es un matiz pequeño para quien maneja código que no es suyo para filtrarlo. Si trabajas bajo contrato con un cliente, o dentro de la UE, o con algo que no querrías que se reutilizara para entrenar, “de quién es la clave” es la primera pregunta, no la última. Una herramienta que te revende tokens a través de su propia cuenta se ha colado, sin hacer ruido, en una cadena que se supone que controlas tú.</p>
<p>También decide qué puedes hacer el día que cambian los términos. Cuando la clave es tuya, moverte a otro proveedor es una edición de ajustes que haces a tu ritmo. Cuando la clave pasa por la herramienta, esperas a que la herramienta soporte el proveedor que quieres, al precio que negoció, cuando le venga bien. Tener la credencial es lo que mantiene tuya la salida.</p>
<h2 id="los-motores-locales-no-son-el-plan-b">Los motores locales no son el plan B</h2>
<p>La siguiente pieza es la que la gente archiva como “bonito para aficionados” y luego necesita de verdad seis meses después.</p>
<p>Deberías poder apuntar la misma herramienta a un modelo corriendo en tu propia máquina. Un modelo open source a través de Ollama, en tu portátil, sin red. Casi todas las herramientas tratan esto como una degradación, lo que usas cuando la API buena se cae. Ese marco está del revés.</p>
<p>Correr en local es el único modo en el que puedes prometer, de verdad, que no salió nada de casa. Para toda una clase de trabajo esa promesa es el requisito, no el extra. Código regulado. Un cliente que firmó algo concreto sobre dónde vive su fuente. Un prototipo que no estás listo para exponer a ningún tercero. En cuanto entra una tarea así, una herramienta que solo sabe llamar a una <a href="/es/blog/nube-vs-local/">API en la nube</a> no tiene nada que ofrecerte, y vuelves a copiar y pegar en un terminal del que te fías.</p>
<p>Una <a href="/es/blog/fabrica-local-de-software/">fábrica local de software</a> pensada para traer tu propio modelo trata el motor local como un ciudadano de primera al lado de las APIs frontier. Misma interfaz de tarea. Mismo contrato alrededor. Lo único que cambia es qué motor recoge el trabajo, y eso es justo el objetivo.</p>
<h2 id="la-portabilidad-se-decide-antes-de-que-el-producto-exista-no-después">La portabilidad se decide antes de que el producto exista, no después</h2>
<p>Aquí es donde esto deja de ser una lista de features y se convierte en arquitectura.</p>
<p>Si un producto cablea las asunciones de un modelo en su núcleo, sus formatos de prompt, sus manías de tool-calling, su contabilidad de tokens, la forma de parsear la salida de ese modelo concreto, entonces añadir portabilidad después es imposible sin reescribir. El modelo se ha vuelto estructural. Puedes poner un desplegable en los ajustes, pero debajo hay un motor sujetando el edificio y los demás son decoración.</p>
<p>La portabilidad tiene que ser una forma que eliges al principio. El modelo vive detrás de un adapter. El producto habla con el adapter, nunca con el motor en crudo. El formato de Anthropic, el de OpenAI, el de un modelo local, cada uno es una capa de traducción, y la parte duradera del producto no sabe ni le importa cuál hay detrás. Añades un motor nuevo y escribes un adapter. Nada de lo de encima se mueve.</p>
<p>Esto me importa porque he visto la alternativa. Retiran un modelo, o lo restringen, o lo deprecan con un mes de aviso, y un producto atado a ese único motor se apaga con él. Los que sobreviven a esa semana son los que decidieron, de entrada, que ningún motor puede ser irreemplazable. Es el mismo argumento que hice sobre <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">enrutar cada tarea al motor adecuado</a>: enrutar por una flota solo funciona si la flota era portable desde el principio. Traer tu propio modelo es el suelo sobre el que se apoya el router.</p>
<h2 id="qué-tiene-que-sobrevivir-al-cambio">Qué tiene que sobrevivir al cambio</h2>
<p>El modelo es la parte que quieres hacer desechable. ¿Cuál es entonces la parte que no debe serlo?</p>
<p>Todo lo que sostiene el sentido de tu trabajo. El contrato de producto. Las especificaciones y los criterios de aceptación. Las decisiones que tomaste y por qué. El grafo de conocimiento del código. La evidencia de que una tarea pasó de verdad. Si eso vive dentro de una conversación con un solo modelo, cambiar el modelo lo tira a la basura, y la portabilidad es mentira.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="El modelo es la pieza desechable. Todo lo que sostiene el sentido de tu trabajo debe vivir fuera de él, o el cambio se lleva el trabajo consigo."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">intercambiable</p>
    <ul><li>el modelo</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">debe sobrevivir</p>
    <ul><li>contrato de producto</li><li>specs y criterios</li><li>decisiones</li><li>grafo del código</li><li>evidencia</li></ul>
  </div>
</div><figcaption>El modelo es la pieza desechable. Todo lo que sostiene el sentido de tu trabajo debe vivir fuera de él, o el cambio se lleva el trabajo consigo.</figcaption></figure>
<p>Si vive fuera del modelo, en almacenamiento local que puedes inspeccionar, entonces el modelo es de verdad intercambiable. Cambias de motor y la memoria sigue ahí. Las decisiones de ayer siguen aplicando. Las specs siguen en pie. El motor nuevo lee el mismo contexto duradero que leía el viejo y retoma el trabajo donde estaba. Eso es lo que te compra la portabilidad. No la libertad de cambiar un desplegable. La libertad de cambiar el motor y no perder nada.</p>
<p>Por eso traer tu propio modelo y la memoria de producto duradera son el mismo diseño visto desde dos ángulos. Uno dice que el modelo es una pieza. El otro dice que lo importante vive fuera de la pieza. No puedes tener lo primero sin lo segundo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc está construido así a propósito. Tú traes tus claves API, o apuntas a un modelo local a través de Ollama, y trata a Claude, Codex, Gemini y motores locales como intercambiables bajo un mismo contrato. Tus claves, tu factura, tu acuerdo de datos. Nada se revende a través de la cuenta de otro.</p>
<p>Debajo, la parte que importa no se mueve cuando cambias. El contrato de producto, las historias y los criterios, el grafo del código y la evidencia viven en almacenamiento local en tu máquina. Cambia el motor y la memoria sobrevive al cambio. El modelo es la palanca. La fábrica de alrededor es lo que de verdad es tuyo.</p>
<p>¿Tienes tú tus claves, o las tiene tu herramienta por ti? Vale la pena comprobarlo antes del día en que necesites cambiar.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-significa-traer-tu-propio-modelo">¿Qué significa traer tu propio modelo?</h3>
<p>Traer tu propio modelo significa que tú pones la clave API o apuntas la herramienta a un motor local, y la herramienta trata el modelo como una pieza intercambiable en vez de como su núcleo. Tienes tú la credencial; la herramienta es un cliente apuntando a ella. Suena a checkbox, pero es una decisión sobre cómo está construido el producto, y hay que tomarla antes de la primera línea de código, no atornillarla después.</p>
<h3 id="puedo-usar-mi-propia-clave-api-con-una-herramienta-de-código-con-ia">¿Puedo usar mi propia clave API con una herramienta de código con IA?</h3>
<p>Con una herramienta que trae tu propio modelo, sí, y la diferencia importa. Cuando la clave es tuya, la factura va a tu tarjeta bajo tus términos, los rate limits son los que contrataste y el acuerdo de datos es el que aceptaste. Moverte a otro proveedor pasa a ser una edición de ajustes a tu ritmo. Cuando la clave pasa por la herramienta, esperas a que soporte el proveedor que quieres, al precio que negoció.</p>
<h3 id="las-herramientas-de-código-con-ia-pueden-correr-modelos-locales-sin-conexión">¿Las herramientas de código con IA pueden correr modelos locales sin conexión?</h3>
<p>Una herramienta pensada para traer tu propio modelo puede, a través de un motor como Ollama corriendo un modelo open source en tu máquina sin red. No es un plan B. Local es el único modo en el que puedes prometer, y cumplirlo, que no salió nada de casa: el requisito para código regulado, un contrato con un cliente sobre dónde vive la fuente, o un prototipo que no estás listo para exponer. Una buena fábrica trata el motor local como ciudadano de primera junto a las APIs frontier.</p>
<h3 id="qué-pasa-con-mi-trabajo-si-cambio-de-modelo">¿Qué pasa con mi trabajo si cambio de modelo?</h3>
<p>Nada, si el trabajo vive fuera del modelo. El contrato de producto, las especificaciones, las decisiones, el grafo del código y la evidencia deben estar en almacenamiento local que puedes inspeccionar, no dentro de una conversación con un solo motor. Entonces cambias de modelo y la memoria sobrevive: las decisiones de ayer siguen aplicando, las specs siguen en pie, el motor nuevo lee el mismo contexto duradero. Si ese sentido vive dentro de un modelo, cambiarlo tira el trabajo a la basura y la portabilidad es mentira.</p>]]></content>
    <summary type="html"><![CDATA[Elegiste una herramienta de IA, te registraste y en algún punto de ese flujo se quedó con tu cuenta de proveedor o te entregó un modelo que no puedes cambiar. Fue cómodo una semana. Luego el modelo se movió, cambió el precio o necesitaste trabajar sin red, y descubriste que el modelo no era un ajuste. Estaba soldado al producto. Traer tu propio modelo es la apuesta contraria: tus claves, tus motores y una fábrica que trata el modelo como una pieza que puedes cambiar sin perder el trabajo de alrededor.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="paelladoc"/><category term="byo-model"/><category term="claves-api"/><category term="ollama"/><category term="portabilidad-modelo"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Añadir specs a un repo existente sin parar el mundo</title>
    <link href="https://paelladoc.com/es/blog/specs-repo-existente/" rel="alternate" type="text/html" title="Añadir specs a un repo existente sin parar el mundo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/specs-repo-existente/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/specs-repo-existente/"><![CDATA[<p><strong>Todos los <a href="https://github.com/github/spec-kit">tutoriales de spec-driven</a> empiezan con una carpeta vacía.</strong> Corres un comando, describes una feature y ves cómo un agente la construye limpia. Es una demo bonita y describe casi nada del software que existe de verdad.</p>
<p>Tu situación real es un repositorio con cuatro años de historia, patrones que nadie escribió y un puñado de módulos que todo el mundo tiene miedo de tocar. No puedes dejar de publicar para escribir specs de todo, y no puedes pedirle a un agente que trabaje contra un contrato que no existe. Así que el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a> queda archivado como «gran idea, repo equivocado» y vuelves a describir cambios en un chat y a cruzar los dedos.</p>
<p>Ese planteamiento es el error. No añades specs a un repo existente especificándolo todo. Las añades donde va a caer el próximo cambio, y dejas que la cobertura crezca desde ahí.</p>
<h2 id="por-qué-falla-aquí-el-manual-del-proyecto-nuevo">Por qué falla aquí el manual del proyecto nuevo</h2>
<p>En un repo vacío, la spec va antes que el código, así que la intención se captura mientras aún es barata. En un repo existente, el código fue primero y la intención que hay detrás está repartida entre mensajes de commit, tickets cerrados y la memoria de la gente. Escribir una spec ahora significa hacer ingeniería inversa de una decisión que se tomó hace dos años por alguien que quizá ya no está.</p>
<p>Eso es trabajo de verdad, y no se paraleliza en un único sprint heroico. Intentar especificar el sistema entero por adelantado produce un montón de documentos que ya están derivando cuando se escribe el último. Acabas con <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">spec drift</a> el día uno, que es peor que no tener specs, porque ahora los documentos mienten de forma activa.</p>
<p>La unidad que funciona es el cambio, no el sistema. No le debes al código una especificación completa. Le debes al <em>próximo</em> cambio un contrato.</p>
<h2 id="especifica-en-la-frontera-del-próximo-cambio">Especifica en la frontera del próximo cambio</h2>
<p>El movimiento es este. Cuando un cambio va a tocar una parte del sistema, escribe la spec de esa parte, acotada a lo que el cambio necesita, y no más ancha.</p>
<p>Digamos que vas a modificar la lógica del cupón en checkout. Antes de que el agente empiece, escribes qué hace hoy el checkout que tiene que seguir siendo cierto, qué puede alterar este cambio y cómo reconocerás un resultado correcto. Eso es una spec. Cubre el checkout, no la app entera. Te llevó veinte minutos porque solo especificaste la superficie que el cambio toca de verdad.</p>
<p>Ahora el agente tiene un contrato. Conoce los invariantes que no puede romper, que es exactamente la información que impide que sea <a href="/es/blog/localmente-correcto-globalmente-incoherente/">correcto en local e incoherente en global</a>, arreglando tu feature mientras rompe en silencio una vecina. La spec no necesitaba cubrir el universo. Necesitaba cubrir el radio de la explosión.</p>
<p>Repite esto en cada cambio y pasa algo útil: las partes del sistema que cambian a menudo acumulan specs rápido, y las partes que nadie toca se quedan sin especificar, lo cual está bien, porque el código estable sin especificar no es lo que te está haciendo daño.</p>
<p>Hay un segundo beneficio fácil de pasar por alto. La primera vez que especificas la superficie de un cambio, pagas el coste de la ingeniería inversa una sola vez. El siguiente cambio a ese mismo módulo arranca desde un contrato que ya existe, así que estás editando una spec en lugar de reconstruir la intención desde cero. Los módulos que más se mueven son justo aquellos donde este efecto compuesto más importa, y son los primeros en cruzar el trinquete. Estás adelantando la arqueología en el código que te haría cavar otra vez de todos modos, y saltándotela en el código que no la pide nunca.</p>
<h2 id="lee-el-código-y-saca-un-primer-borrador">Lee el código y saca un primer borrador</h2>
<p>No tienes que escribir estas specs desde una página en blanco. El código ya es la descripción más precisa de lo que hace el sistema, solo que está en la forma equivocada. Un agente puede leer el módulo que vas a cambiar y producir un borrador de spec de su comportamiento actual: las entradas que acepta, los invariantes que parece mantener, los caminos que cubre.</p>
<p>Ese borrador estará mal en algunos sitios, y estar mal es útil. Corregir un borrador es mucho más rápido que redactar desde cero, y cada corrección que haces es una decisión que estás recuperando del código y volviendo a escribir. Esta es la versión práctica de <a href="/es/blog/de-repo-a-artefactos/">leer un repo y sacar artefactos de producto</a>: el repositorio deja de ser un muro opaco y empieza a soltar las historias, criterios y restricciones enterrados en él.</p>
<p>Para que esto funcione, el agente tiene que entender de verdad la forma del código, no solo hacerle grep. Ese es el argumento a favor de <a href="/es/blog/mapas-de-codigo-para-agentes/">mapas del código en lugar de prompts más largos</a>: un modelo de cómo se relacionan los módulos da al borrador de spec muchas más probabilidades de nombrar los invariantes correctos.</p>
<h2 id="mantén-el-trinquete-girando">Mantén el trinquete girando</h2>
<p>El objetivo no es el cien por cien de cobertura. El objetivo es un trinquete que solo gira en una dirección: cada cambio deja detrás una spec, así que la superficie especificada crece de forma monótona y nunca se encoge. No necesitas una congelación, una reescritura ni un mandato de cobertura. Necesitas una regla: un cambio no se publica sin un contrato para la superficie que tocó. Esa regla es barata de enunciar y cabe dentro del trabajo que ya ibas a hacer, porque tenías que entender la superficie para cambiarla sin romper nada de todos modos. La spec es justo ese entendimiento, escrito donde el agente y la siguiente persona puedan leerlo los dos.</p>
<p>Sostenido, esto produce justo la cobertura que quieres. Los caminos calientes que cambian cada mes acaban bien especificados porque siguen pasando por el trinquete. El código frío se queda desnudo, y eso es correcto, porque no es el código que te genera incidencias. Esta es la <a href="/es/blog/spec-driven-ligero/">versión ligera del desarrollo guiado por especificaciones</a>, donde la spec se gana su sitio por cambio en lugar de llegar como un impuesto burocrático sobre todo.</p>
<figure class="tp-diagram tp-diagram--levels" data-diagram-type="levels" role="img" aria-label="Conceptualmente la superficie especificada solo crece: cada cambio deja una spec, así que los caminos calientes quedan bien cubiertos y el código frío se queda desnudo."><svg viewBox="0 0 760 272" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="20" width="140" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="46" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">PRIMER CAMBIO</text><rect x="40" y="78" width="280" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="104" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">CAMBIOS RECURRENTES</text><rect x="40" y="136" width="420" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="162" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">CAMINOS CALIENTES</text><rect x="40" y="194" width="560" height="40" fill="var(--tp-mostaza)" stroke="var(--tp-mostaza)" stroke-width="1.5" fill-opacity="0.14"></rect>
  <text x="52" y="220" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">SUPERFICIE ESPECIFICADA</text></svg><figcaption>Conceptualmente la superficie especificada solo crece: cada cambio deja una spec, así que los caminos calientes quedan bien cubiertos y el código frío se queda desnudo.</figcaption></figure>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Añadir specs a un repo vivo es justo la situación para la que está construido PaellaDoc. Puede leer un código existente y convertirlo en un modelo local, redactar el comportamiento del módulo que vas a cambiar y dejarte corregirlo hasta un contrato real antes de que el agente empiece. Esa spec se queda después unida al código que la implementa, así que la próxima vez que el módulo cambie estarás editando un contrato que ya existe en lugar de volver a hacer ingeniería inversa de todo.</p>
<p>No paras el mundo para adoptar el desarrollo guiado por especificaciones. Enganchas un contrato al próximo cambio, luego al siguiente, y dejas que la superficie especificada crezca a la velocidad a la que se mueve de verdad el código.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Tengo que especificar todo mi repo para que esto ayude?</strong> No. Ese es el modo de fallo. Especificas la superficie del próximo cambio, lo publicas y repites. La cobertura crece en las partes que cambian a menudo, que son las que la necesitan.</p>
<p><strong>¿Y los módulos estables que nadie toca?</strong> Déjalos sin especificar. El código estable que nunca cambia no te genera incidencias. Gasta el esfuerzo donde de verdad está cayendo el cambio.</p>
<p><strong>¿Puede un agente escribir la primera spec de código viejo?</strong> Sí, como borrador. Lee el módulo y describe su comportamiento actual, y tú corriges el borrador. Arreglar un borrador equivocado es mucho más rápido que escribir desde una página en blanco, y cada arreglo recupera una decisión que el código escondía.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="spec-driven-development"/><category term="repo-existente"/><category term="codigo-legado"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Spec vs PRD: para qué sirve cada uno (y qué necesitan los agentes)</title>
    <link href="https://paelladoc.com/es/blog/spec-vs-prd/" rel="alternate" type="text/html" title="Spec vs PRD: para qué sirve cada uno (y qué necesitan los agentes)"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/spec-vs-prd/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/spec-vs-prd/"><![CDATA[<p>Alguien te pasa una «spec» y resulta ser un argumento de dos páginas sobre por qué importa la feature. Otra persona te pasa un «PRD» y es una lista de endpoints de API. Las palabras se han difuminado hasta el punto de que saber qué documento tienes en la mano no te dice casi nada de lo que hay dentro.</p>
<p>Ese difuminado es inofensivo cuando lo lee una persona, porque una persona rellena los huecos con contexto. Deja de ser inofensivo en cuanto le pasas el documento a un agente, que no rellena los huecos con contexto sino que más bien los inventa. Así que vale la pena ser preciso: un PRD y una spec son documentos distintos que hacen trabajos distintos, y un agente necesita algo concreto de cada uno.</p>
<h2 id="para-qué-sirve-un-prd">Para qué sirve un PRD</h2>
<p>Un documento de requisitos de producto responde a <em>por qué</em> y <em>qué, para quién</em>. Es el caso a favor de construir algo: el problema, quién lo tiene, cómo se ve el éxito, qué entra y qué sale del alcance a nivel de producto. Su audiencia es la gente que necesita estar de acuerdo en que esto merece la pena antes de que nadie construya.</p>
<p>Un buen PRD trata sobre todo de intención y criterio. Defiende una dirección, registra los trade-offs y dibuja el límite alrededor del problema. Lo que deliberadamente no hace es fijar la implementación. Un PRD que especifica endpoints exactos suele haberse salido de su carril.</p>
<p>El modo de fallo de los PRD es de sobra conocido: se hacen largos, se leen una vez y luego se quedan sin leer mientras las decisiones de verdad pasan en Slack. Es el problema del <a href="/es/blog/prds-que-nadie-lee/">PRD que nadie lee</a>, y vale la pena nombrarlo aquí porque es justo la parte de un PRD que un agente no puede usar. La prosa que defiende una dirección es para humanos que deciden. No es algo contra lo que un agente pueda construir.</p>
<h2 id="para-qué-sirve-una-spec">Para qué sirve una spec</h2>
<p>Una especificación responde a <em>qué tiene que ser cierto</em> y <em>cómo lo sabrás</em>. Es el <a href="/es/blog/spec-como-contrato/">contrato</a> entre la intención acordada y la implementación: el comportamiento que tiene que cambiar, las restricciones que tienen que sostenerse y los criterios de aceptación que deciden si el resultado es correcto.</p>
<p>Una spec está aguas abajo de un PRD. El PRD dice «compra como invitado, porque perdemos registros en el muro de la cuenta». La spec dice «los usuarios invitados completan la compra en tres pasos; no se guardan datos de tarjeta; el camino con sesión iniciada no cambia; aquí están los criterios de aceptación». Uno defiende la dirección. La otra define la línea de meta con la precisión suficiente para poder decirle a una máquina cuándo la ha cruzado.</p>
<p>Donde un PRD es sobre todo criterio, una spec es sobre todo precisión. Y la precisión es justo lo que hace una spec construible y verificable, que es toda la premisa del <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a>.</p>
<h2 id="los-dos-documentos-lado-a-lado">Los dos documentos lado a lado</h2>



































<table><thead><tr><th></th><th>PRD</th><th>Spec</th></tr></thead><tbody><tr><td>Pregunta</td><td>Por qué, y qué para quién</td><td>Qué tiene que ser cierto, y cómo lo sabemos</td></tr><tr><td>Audiencia</td><td>Quien decide construir</td><td>Quien (o lo que) construye y verifica</td></tr><tr><td>Contenido</td><td>Problema, usuarios, éxito, alcance</td><td>Comportamiento, límites, criterios de aceptación</td></tr><tr><td>Registro</td><td>Argumento y criterio</td><td>Contrato y precisión</td></tr><tr><td>Vida útil</td><td>La decisión</td><td>La implementación y su verificación</td></tr></tbody></table>
<p>Las filas importan menos que la separación que describen. Un PRD sirve para llegar a una decisión. Una spec sirve para ejecutarla correctamente. Cuando un documento intenta hacer las dos, no hace bien ninguna: demasiado vago para construir contra él, demasiado detallado para decidir desde él.</p>
<h2 id="qué-necesita-un-agente-de-cada-uno">Qué necesita un agente de cada uno</h2>
<p>Aquí es donde la distinción deja de ser pedante. Un agente necesita cosas distintas de los dos documentos, y darle las partes equivocadas es como consigues output convencido y equivocado.</p>
<p><strong>Del PRD, un agente necesita intención y límites, no el argumento.</strong> Los tres párrafos sobre por qué importa la compra como invitado son para los humanos que la aprobaron. Lo que el agente necesita extraer es la versión comprimida: construye la compra como invitado, aquí está para quién es, aquí está lo que queda fuera. Dale a un agente el PRD persuasivo completo y tratará el énfasis retórico como requisitos, y construirá aquello con lo que el documento se entusiasmó más, no lo que se decidió.</p>
<p><strong>De la spec, un agente necesita el contrato, sobre todo los criterios de aceptación.</strong> Esta es la parte que tiene que ser utilizable por una máquina. Límites que no debe cruzar, comportamiento que debe producir y <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación que puede verificar de verdad</a> en lugar de asentir ante ellos. Un agente que recibe una spec precisa puede contrastar su propio trabajo contra ella. Un agente que recibe una vaga informará de éxito contra criterios que se inventó.</p>
<p>El error más común, con diferencia, es darle a un agente un PRD y esperar resultados a nivel de spec. El documento se escribió para ganar una decisión, no para definir una línea de meta. El agente lee intención donde necesitaba un contrato, y produce algo que argumenta bien y verifica mal.</p>
<h2 id="el-traspaso-entre-ellos">El traspaso entre ellos</h2>
<p>El PRD y la spec son dos etapas de un solo flujo, no rivales. El PRD zanja el <em>para qué</em> y el <em>si</em>. La spec convierte la decisión zanjada en un <em>qué exactamente</em> y un <em>cómo lo sabemos</em>. El traspaso entre ellos es donde mucho trabajo asistido por IA se rompe en silencio: la decisión vive en un artefacto, el contrato en otro, y nada los conecta, así que la razón detrás de la spec se pierde y la <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">spec deriva</a> de la decisión que la motivó.</p>
<p>En la práctica no siempre necesitas una versión pesada de los dos. Un cambio pequeño puede colapsar el PRD en dos frases de intención y poner el peso en la spec. Está bien, y es el núcleo de un <a href="/es/blog/spec-driven-ligero/">flujo spec-driven ligero</a>: conserva la intención y el contrato, suelta la ceremonia que no sirve a ninguno. Lo que no puedes hacer es colapsarlos en un único documento vago y esperar que el agente distinga qué partes son el argumento y cuáles el contrato.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>El hueco entre un PRD y una spec es un hueco entre dos documentos en dos herramientas que no saben la una de la otra. PaellaDoc mantiene los dos en un solo modelo local: la intención y los límites de la decisión, conectados con el contrato y los criterios de aceptación de la spec, conectados a su vez con el código y la evidencia. Un agente lee la intención como intención y el contrato como el contrato, y la decisión detrás de una spec sigue unida a ella en vez de perderse en el traspaso.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Necesito un PRD y una spec para cada cambio?</strong> No. Los cambios grandes o compartidos se benefician de los dos. Para un cambio pequeño, dos frases de intención más una spec apretada bastan. La idea es mantener los dos trabajos distintos, no producir siempre dos documentos.</p>
<p><strong>¿Una spec es solo un PRD más detallado?</strong> No, y tratarla así es el error. Un PRD defiende una decisión; una spec define un contrato. Más detalle en un PRD hace un PRD largo, no una spec. Se diferencian en clase, no en nivel de detalle.</p>
<p><strong>¿Desde cuál construye de verdad un agente de IA?</strong> Desde la spec. El PRD le da al agente intención comprimida y límites; la spec le da el contrato y los criterios de aceptación contra los que construye y verifica. Dale solo un PRD y se inventará el contrato, normalmente mal.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="spec-vs-prd"/><category term="desarrollo-guiado-por-especificaciones"/><category term="requisitos-de-producto"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Spec-driven vs test-driven: ¿rivales o capas?</title>
    <link href="https://paelladoc.com/es/blog/spec-driven-vs-test-driven/" rel="alternate" type="text/html" title="Spec-driven vs test-driven: ¿rivales o capas?"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/spec-driven-vs-test-driven/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/spec-driven-vs-test-driven/"><![CDATA[<p><strong>Siempre hay alguien que pregunta si el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a> sustituye al desarrollo guiado por tests.</strong> La pregunta da por hecho que compiten por el mismo hueco, que eliges una metodología y la otra sobra. Ese supuesto es el error, y lleva a la gente a soltar una de dos cosas que ambas necesitan.</p>
<p>Tests y specs responden a preguntas distintas. Un test pregunta «¿hace el código esta cosa concreta?». Una spec pregunta «¿es esta la cosa que el código debía hacer?». Puedes pasar todos los tests y aun así haber construido la feature equivocada, y puedes tener una spec perfecta y aun así publicar código que la viola. No son dos respuestas a un problema. Son dos problemas distintos que resulta que están uno al lado del otro.</p>
<h2 id="qué-fija-cada-uno-de-verdad">Qué fija cada uno de verdad</h2>
<p>El <a href="https://martinfowler.com/bliki/TestDrivenDevelopment.html">desarrollo guiado por tests</a> fija el comportamiento. Escribes un test que falla, lo haces pasar, refactorizas. El test es una afirmación ejecutable sobre lo que hace el código en un punto concreto, y su gran virtud es que corre. Un test no tiene opiniones ni se olvida. O pasa o no pasa, y sigue comprobando para siempre. Esa es una forma real de verdad, y es la razón por la que los tests siguen siendo carga estructural sin importar cómo se escribió el código.</p>
<p>El desarrollo guiado por especificaciones fija la intención. La spec declara qué debe cambiar, qué tiene que seguir siendo cierto y cómo reconocerás un resultado correcto, y lo hace antes de empezar a construir. Su virtud es que captura la decisión, no solo el comportamiento. Una spec puede decir «los cupones no deben acumularse nunca, es una regla de negocio, no un accidente», que es justo el tipo de cosa que un test hace cumplir pero nunca explica.</p>
<p>Aquí está el hueco entre ambos. Un test puede estar perfectamente en verde y hacer cumplir el comportamiento equivocado, porque el test solo sabe lo que alguien le dijo que comprobara. No puede decirte que el comportamiento que protege es en sí mismo un malentendido de lo que el producto necesitaba. La spec es donde vive ese juicio. Los tests verifican contra un objetivo. La spec es la que puso el objetivo.</p>
<h2 id="por-qué-los-agentes-hacen-las-capas-obligatorias">Por qué los agentes hacen las capas obligatorias</h2>
<p>Con una persona escribiendo cada línea, a veces podías arreglártelas solo con tests, porque la intención vivía en la cabeza de quien programaba y se filtraba en valores por defecto razonables. Un agente no tiene esa cabeza. Tiene el prompt, el contexto que le diste y lo que pueda inferir, y rellenará con toda confianza cualquier hueco que dejaste con una suposición plausible.</p>
<p>Aquí es donde los tests por sí solos dejan de bastar. Un agente puede escribir código, escribir tests para ese código y hacerlos pasar, y todo el bucle puede ser internamente coherente y estar mal igual, porque el agente probó su propia interpretación. Nada comprobó esa interpretación contra tu intención. Es la trampa detrás de <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde que no es una feature correcta</a>: el build demuestra que el código está de acuerdo con sus propios tests, no contigo.</p>
<p>La spec rompe ese bucle. Es el único artefacto que el agente no redactó, la intención fija contra la que se miden los tests. Dale a un agente una spec y sus tests tienen algo sobre lo que acertar o fallar. No le des ninguna y sus tests son solo un espejo.</p>
<h2 id="se-enchufan-el-uno-en-el-otro">Se enchufan el uno en el otro</h2>
<p>En cuanto dejas de plantearlos como rivales, la conexión es obvia. Los criterios de aceptación de la spec son de donde deberían salir los tests. Un criterio como «un cupón caducado se rechaza antes de calcular el total» es una frase en la spec y un test en la suite, y el test existe precisamente para demostrar esa cláusula del contrato.</p>
<p>Así es como consigues <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación que un agente puede verificar</a>: los criterios se escriben para ser ejecutables, así que cada uno se convierte en un test en lugar de en una esperanza vaga. La spec pone la intención, los criterios la traducen en afirmaciones comprobables, y los tests hacen la comprobación en cada ejecución. Cada capa hace el trabajo que la otra no puede.</p>
<p>Y funciona en las dos direcciones. Un test difícil de escribir suele significar que un criterio es vago, que suele significar que la intención nunca se fijó de verdad. La fricción de escribir el test saca a la superficie un agujero en la spec. Ese feedback es una de las razones silenciosas por las que las dos disciplinas van mejor juntas que cualquiera por separado.</p>
<p>El orden importa tanto como el emparejamiento. La spec va primero, luego los criterios, luego los tests, luego el código, y cada paso limita al siguiente. Si dejas que el agente escriba el código primero y genere los tests después, los tests heredan lo que el código resultó hacer, sus errores incluidos, y vuelves a un espejo. Escribir los criterios comprobables antes de que el código exista es lo que mantiene los tests independientes de la implementación, para que midan el código contra la intención en lugar de contra sí mismo. El TDD le dio a la industria esa disciplina de orden para el comportamiento. El desarrollo guiado por especificaciones empuja la misma disciplina una capa más arriba, a la intención.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="El orden es la disciplina: los criterios escritos antes que el código mantienen los tests midiendo la intención, no la implementación."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">SPEC</text><path d="M 190 95 L 212 95 M 206 89 L 212 95 L 206 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CRITERIOS</text><path d="M 368 95 L 390 95 M 384 89 L 390 95 L 384 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">TESTS</text><path d="M 546 95 L 568 95 M 562 89 L 568 95 L 562 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="62" width="144" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="646" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">CÓDIGO</text></svg><figcaption>El orden es la disciplina: los criterios escritos antes que el código mantienen los tests midiendo la intención, no la implementación.</figcaption></figure>
<h2 id="qué-cambia-todavía-en-el-testing">Qué cambia todavía en el testing</h2>
<p>Poner las dos en capas no significa que el testing quede intacto ante los agentes. Cuando el código llega más rápido de lo que nadie puede leerlo, los tests cargan con más confianza que antes, así que qué pruebas y cómo confías en ello se desplazan los dos. Ese es su propio tema, tratado en <a href="/es/blog/probar-codigo-de-ia/">probar código generado por IA: qué cambia y qué no</a>, pero la versión corta es que los tests pasan a ser más estructurales, no menos, precisamente porque una persona revisó menos líneas.</p>
<p>La spec no te salva de eso. Apunta el esfuerzo. Sin la spec, estás probando lo que sea que el agente decidió construir. Con ella, estás probando si el agente construyó lo acordado. Los tests son el mismo mecanismo de un modo u otro. La spec decide si están apuntados al objetivo correcto.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Tratar las dos como capas es el modelo sobre el que está construido PaellaDoc. La spec sostiene la intención y sigue ligada al código que la implementa. Sus criterios de aceptación se conectan con las ejecuciones que los ponen a prueba, así que los tests no son una isla de confianza separada sino el brazo ejecutor del contrato. Cuando el código deriva, puedes ver qué criterios, y por tanto qué tests, están comprobando ahora contra una intención que se movió.</p>
<p>Spec-driven y test-driven nunca pelearon por un solo asiento. Los tests te dicen que el código hace lo que hace. La spec te dice que eso era lo que debía hacer. Suelta cualquiera de los dos y estarás confiando en un bucle que solo se comprueba a sí mismo.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿El desarrollo guiado por especificaciones sustituye al TDD?</strong> No. Operan sobre preguntas distintas. El TDD verifica que el código hace una cosa concreta; la spec fija cuál era esa cosa. Quitar los tests pierde tu red de seguridad de comportamiento; quitar la spec pierde la intención a la que los tests deberían servir.</p>
<p><strong>Si tengo buenos tests, ¿por qué necesito además una spec?</strong> Porque los tests pueden hacer cumplir el comportamiento equivocado a la perfección. Un test solo comprueba lo que alguien decidió comprobar, y con un agente ese alguien es a menudo el propio agente. La spec es la intención independiente contra la que se miden tus tests.</p>
<p><strong>¿De dónde salen los tests en un flujo guiado por especificaciones?</strong> De los criterios de aceptación de la spec. Cada criterio escrito para ser comprobable se convierte en un test, así que la suite existe para demostrar cláusulas concretas del contrato en lugar de la propia interpretación del agente sobre la tarea.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="spec-driven-development"/><category term="test-driven-development"/><category term="testing"/><category term="ai-coding"/><category term="verificacion"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Spec-driven sin burocracia: un flujo ligero</title>
    <link href="https://paelladoc.com/es/blog/spec-driven-ligero/" rel="alternate" type="text/html" title="Spec-driven sin burocracia: un flujo ligero"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/spec-driven-ligero/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/spec-driven-ligero/"><![CDATA[<p>Esta es la queja que más oigo sobre el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a>, y no le falta razón: «Lo intenté y pasé más tiempo alimentando el proceso que construyendo la cosa». Propuesta, spec, plan, tareas, puertas de revisión. Para alguien que trabaja solo o un equipo pequeño que va rápido, la ceremonia puede costar más que el código que se supone que protege.</p>
<p>La respuesta habitual es que solo te hace falta más disciplina. Creo que está del revés. Si un proceso solo funciona con disciplina heroica, el proceso pesa demasiado. El arreglo no es esforzarse más. Es escribir una spec más pequeña.</p>
<h2 id="la-sobrecarga-es-real-y-fingir-lo-contrario-pierde-gente">La sobrecarga es real, y fingir lo contrario pierde gente</h2>
<p>Los pipelines completos de spec-driven se moldearon en parte con herramientas pensadas para equipos y cambios grandes. <a href="https://github.com/github/spec-kit">Spec Kit</a> formaliza un flujo por propuesta, especificación, plan y tareas. Esa estructura se gana su coste cuando mucha gente toca un cambio, cuando el radio de impacto es grande o cuando la decisión necesita un rastro documental.</p>
<p>Deja de ganárselo en una feature de doscientas líneas que estás construyendo tú solo esta tarde. Ahí, la misma estructura es fricción. Escribes una propuesta para convencerte a ti mismo, un plan que ya tienes en la cabeza y una lista de tareas que no volverás a leer. Cuando terminas la ceremonia, has gastado tu energía en el artefacto en vez de en el trabajo, y el artefacto empieza a <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">derivar del código</a> en cuanto lo cierras.</p>
<p>Decirle a esa persona que sea más rigurosa no ayuda. Ya conoce el proceso completo. Lo abandonó porque no compensaba. El movimiento que funciona es admitir que la sobrecarga existe y diseñarla a la baja.</p>
<h2 id="para-qué-sirve-una-spec-en-realidad">Para qué sirve una spec en realidad</h2>
<p>Quita las plantillas y una spec hace un solo trabajo: es el <a href="/es/blog/spec-como-contrato/">contrato</a> que dice qué tiene que cambiar, qué no, y cómo sabrás que funcionó. Todo lo que hay en una spec que no sirve a ese trabajo es sobrecarga que puedes recortar.</p>
<p>Ese replanteo es todo el truco. No intentas documentar la feature. Intentas escribir el contrato más pequeño que un agente, un compañero o tu yo futuro necesitan para construir lo correcto y demostrarlo. La mayor parte de una spec pesada no es contrato. Es reformulación, cautelas y artefactos de proceso que existen para satisfacer la plantilla, no el trabajo.</p>
<h2 id="la-receta-ligera">La receta ligera</h2>
<p>Esta es la versión que uso de verdad para un cambio normal. Una página, tres secciones, escritas antes de que arranque el agente.</p>
<figure class="tp-diagram tp-diagram--stack" data-diagram-type="stack" role="img" aria-label="La spec ligera entera: tres secciones, escritas antes de que arranque el agente, y nada más."><svg viewBox="0 0 760 208" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="120" y="20" width="520" height="42" fill="var(--tp-mostaza)" fill-opacity="0.14" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="380" y="47" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">INTENCIÓN</text><rect x="120" y="76" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="103" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">LÍMITES</text><rect x="120" y="132" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="159" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">CRITERIOS DE ACEPTACIÓN</text></svg><figcaption>La spec ligera entera: tres secciones, escritas antes de que arranque el agente, y nada más.</figcaption></figure>
<h3 id="intención-2-4-frases">Intención (2-4 frases)</h3>
<p>Qué comportamiento cambia y para quién. Nada de ritual de historia de usuario, solo la frase que dirías en voz alta. «Los usuarios invitados pueden comprar sin cuenta; el flujo tiene tres pasos; nada de la compra con sesión iniciada cambia.» Si no puedes decirlo en unas frases, todavía no entiendes el cambio lo bastante como para dárselo a un agente.</p>
<h3 id="límites-una-lista-corta">Límites (una lista corta)</h3>
<p>Qué tiene que seguir siendo cierto y qué queda explícitamente fuera. Es la parte de mayor valor de una spec ligera y la que la gente se salta. Cuando un agente puede <a href="/es/blog/que-es-vibe-coding/">generar código plausible rápido</a>, las restricciones valen más que las instrucciones. «No toques la integración con la pasarela de pago. No guardes datos de tarjeta. No cambies el camino con sesión iniciada.» Tres líneas aquí te ahorran un día de desenredo más tarde.</p>
<h3 id="criterios-de-aceptación-comprobables-no-prosa">Criterios de aceptación (comprobables, no prosa)</h3>
<p>Cómo sabrás que está hecho, escrito para que una máquina pudiera comprobarlo, no para que un humano asienta. «Dado un invitado con artículos en el carrito, cuando completa los tres pasos, entonces se crea un pedido y no se persiste ningún token de tarjeta.» Son <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación que un agente puede verificar de verdad</a>, que es lo que evita que una spec ligera se vuelva teatro ligero.</p>
<p>Esa es la spec. Intención, límites, aceptación. Sin propuesta, sin plan aparte, sin desglose de tareas salvo que el cambio sea lo bastante grande como para necesitarlo. Para la mayoría de los cambios, cabe en una pantalla y lleva diez minutos.</p>
<h2 id="qué-recortas-y-qué-no-debes-recortar">Qué recortas y qué no debes recortar</h2>
<p>Los recortes: el documento de propuesta, el ensayo de diseño, la lista de tareas para cualquier cosa que puedas tener en la cabeza, la puerta de revisión en un cambio que solo tocarás tú, y toda sección que reformula otra sección con otras palabras.</p>
<p>Los innegociables: intención, límites y criterios de aceptación. Recorta uno de esos tres y no tienes una spec ligera, tienes una nota. Los límites son el que más tentación da de soltar y el que más paga, porque son lo que impide que un agente <a href="/es/blog/features-que-rompen-features/">rompa una feature que funcionaba</a> mientras añade una nueva.</p>
<p>El otro innegociable es mantenerla al día. Una spec de una página que actualizas cuando el cambio aterriza es una <a href="/es/blog/especificaciones-vivas/">spec viva</a>. Una spec de una página que escribes y abandonas es solo drift más rápido. Ligero solo funciona si barato de escribir también significa barato de actualizar.</p>
<h2 id="cuándo-devolver-el-peso">Cuándo devolver el peso</h2>
<p>Ligero es un valor por defecto, no una religión. Añade estructura cuando el cambio se la gane:</p>
<ul>
<li><strong>Más gente lo toca.</strong> Un cambio compartido necesita el artefacto compartido. Una propuesta y una puerta de revisión dejan de ser ceremonia y pasan a ser coordinación.</li>
<li><strong>El radio de impacto es grande.</strong> Migraciones, auth, pagos, cualquier cosa donde un error es caro, merecen la sección de diseño y el plan explícito.</li>
<li><strong>La decisión necesita registro.</strong> Cuando dentro de seis meses te pregunten «por qué lo hicimos así», el <a href="/es/blog/registro-de-decisiones/">registro de decisiones</a> merece escribirse en el momento.</li>
</ul>
<p>El error no es usar spec-driven pesado. El error es usar un solo peso para todos los cambios. Ajusta la ceremonia al riesgo, y la mayoría de los cambios se llevan la versión de una página.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Una spec ligera sigue necesitando un sitio donde vivir que la conecte al código y a la evidencia, o deriva tan rápido como cualquier otra. PaellaDoc guarda el contrato pequeño en un modelo local conectado al repositorio y a los resultados de las ejecuciones, de modo que una spec de una página se mantiene barata de escribir y barata de actualizar. Consigues la disciplina del spec-driven al peso de una nota, y añades estructura solo donde el riesgo la pide.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Una spec de una página no es solo una spec incompleta?</strong> No. Incompleta significa que al contrato le faltan piezas, normalmente los límites y los criterios de aceptación. Ligera significa que el contrato está completo y no hay nada más. Una página bien apretada puede estar más completa que un documento de diez páginas que entierra el contrato en reformulación.</p>
<p><strong>¿El spec-driven ligero funciona con agentes?</strong> Funciona mejor, porque las partes que conservas son justo las que un agente necesita: intención para construir lo correcto, límites para no romper lo incorrecto y criterios de aceptación que puede verificar. Las partes que recortas eran sobre todo para el proceso humano.</p>
<p><strong>¿Cuándo no debería ir ligero?</strong> Cuando el cambio se comparte entre personas, es de alto riesgo o necesita un registro de decisión. Ajusta el peso al radio de impacto. Ligero es el valor por defecto correcto para la mayoría de los cambios, no una regla para todos.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="spec-driven-ligero"/><category term="desarrollo-guiado-por-especificaciones"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="criterios-de-aceptacion"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Spec drift: cuando la especificación y el código dejan de contar lo mismo</title>
    <link href="https://paelladoc.com/es/blog/spec-drift-especificaciones-desactualizadas/" rel="alternate" type="text/html" title="Spec drift: cuando la especificación y el código dejan de contar lo mismo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/spec-drift-especificaciones-desactualizadas/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/spec-drift-especificaciones-desactualizadas/"><![CDATA[<p>Escribiste una spec el lunes. Describía el flujo de compra: tres pasos, un camino de invitado, sin tarjetas guardadas. El viernes el código tiene opción de tarjeta guardada, un camino exprés de dos pasos y un campo de cupón que nadie pidió. La spec sigue diciendo tres pasos y sin tarjetas guardadas.</p>
<p>Ni la spec ni el código mienten a propósito. Simplemente han dejado de contar la misma historia. Esa distancia es el <strong>spec drift</strong>, y en cuanto empiezas a buscarla la encuentras en todas partes donde un agente toca la base de código.</p>
<h2 id="qué-es-el-spec-drift-en-realidad">Qué es el spec drift en realidad</h2>
<p>El spec drift es la distancia creciente entre el contrato que escribiste y el comportamiento que ahora se publica. Es el modo de fallo que el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a> existe para evitar, y al que sucumbe en silencio cuando nadie mantiene el contrato. La spec describió la intención en un momento. El código siguió moviéndose. Cada cambio que aterriza sin actualizar el contrato ensancha el hueco.</p>
<p>No es lo mismo que una spec mala. Una spec mala está equivocada el día que la escribes. Una spec con drift era correcta y se quedó rancia. La diferencia importa, porque una spec con drift es más peligrosa que una obviamente equivocada. Sigue pareciendo autoridad. La gente la sigue citando en las reviews. Los agentes la siguen leyendo como verdad de base. Tiene la forma de un contrato y el contenido de un rumor.</p>
<p>Se supone que <a href="/es/blog/spec-como-contrato/">la spec es el contrato</a> entre intención e implementación. El drift rompe ese contrato en silencio, sin mensaje de error.</p>
<h2 id="por-qué-los-agentes-lo-empeoran-no-lo-mejoran">Por qué los agentes lo empeoran, no lo mejoran</h2>
<p>El drift es un problema viejo. La documentación se pudre desde el primer README. Lo que ha cambiado es el ritmo.</p>
<p>Cuando cada línea la escribía una persona, el drift se acumulaba a velocidad humana. Tocabas tres archivos al día y recordabas más o menos lo que decía la spec. Ahora un agente toca treinta archivos en una tarde y no arrastra tu memoria del contrato entre ejecuciones. Arrastra el contexto que cargaste en esa sesión. <a href="/es/blog/perdida-de-contexto-entre-sesiones/">Los agentes pierden contexto entre sesiones</a> por defecto, así que la segunda ejecución no sabe qué prometió la primera, y ninguna de las dos actualiza el documento que archivaste el lunes.</p>
<p>Lanza varias sesiones en paralelo y la cosa empeora. Cada una es razonable en local. Cada una empuja el código un poco más lejos del contrato escrito. <a href="/es/blog/los-agentes-derivan/">Los agentes van a derivar</a> lo planifiques o no, y la spec suele ser la primera baja porque nada obliga a una ejecución a reconciliarse contra ella.</p>
<p>El resultado es conocido: código <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto y globalmente incoherente</a>. Cada diff pasó su review en sus propios términos. El sistema completo ya no coincide con lo que dijiste que estabas construyendo.</p>
<h2 id="los-cuatro-sitios-donde-se-esconde-el-drift">Los cuatro sitios donde se esconde el drift</h2>
<p>El drift rara vez es una gran divergencia. Son cien pequeñas, y se acumulan en sitios predecibles.</p>
<h3 id="1-comportamiento-que-la-spec-nunca-mencionó">1. Comportamiento que la spec nunca mencionó</h3>
<p>El agente añadió el campo de cupón. Funciona. Tiene tests. La spec no sabe que existe. El comportamiento nuevo sin contrato es la forma más común de drift, y la más difícil de notar, porque no hay nada en la spec que lo contradiga.</p>
<h3 id="2-restricciones-que-el-código-rompió-en-silencio">2. Restricciones que el código rompió en silencio</h3>
<p>La spec decía «sin tarjetas guardadas». En algún refactor, una capa de caché empezó a guardar una tarjeta tokenizada durante la sesión. Nadie decidió violar la restricción. Se coló en un cambio que parecía no tener relación. Los límites rotos son el drift más caro, porque la restricción solía estar ahí por una razón que ahora has olvidado.</p>
<h3 id="3-decisiones-que-se-revirtieron-sin-una-nota">3. Decisiones que se revirtieron sin una nota</h3>
<p>La spec del lunes eligió actualizaciones optimistas de la UI. El arreglo del jueves cambió a confirmación por servidor porque las optimistas provocaban un parpadeo. Buena decisión. Pero la spec sigue defendiendo el enfoque abandonado, así que el siguiente agente que la lea intentará «arreglar» el código de vuelta al parpadeo.</p>
<h3 id="4-criterios-de-aceptación-que-ya-no-coinciden">4. Criterios de aceptación que ya no coinciden</h3>
<p>Los <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación</a> de la spec describían el flujo de tres pasos. El flujo ahora tiene dos. Los criterios pasan porque nadie los ejecuta contra el comportamiento actual, o fallan y todos han aprendido a ignorar ese rojo concreto. En cualquier caso, el contrato ha dejado de significar algo.</p>
<h2 id="el-coste-que-ya-estás-pagando">El coste que ya estás pagando</h2>
<p>El drift no te manda una factura. Te cobra en reviews más lentas, en agentes que construyen con confianza contra un contrato rancio, y en la reunión donde dos personas descubren que trabajaban con versiones distintas de la verdad. Es el sustrato del problema del <a href="/es/blog/registro-de-decisiones/">«yo nunca acordé eso»</a>: la spec decía una cosa, el producto hace otra, y nadie puede reconstruir cuándo se separaron.</p>
<p>El coste más hondo es la confianza. En cuanto un equipo aprende que la spec podría estar mintiendo, deja de leerla. Y una spec en la que nadie confía es peor que ninguna, porque pagaste por escribirla y aun así no puedes apoyarte en ella.</p>
<h2 id="cazar-el-drift-antes-de-que-se-componga">Cazar el drift antes de que se componga</h2>
<p>No puedes evitar el drift. El código cambia; para eso está. Lo que sí puedes hacer es acortar la distancia entre que un cambio aterriza y que el contrato lo alcanza.</p>
<p>Unas cuantas cosas ayudan en la práctica:</p>
<ul>
<li><strong>Haz que actualizar la spec sea barato.</strong> Si actualizar el contrato es una ceremonia, nadie lo hace con una fecha límite encima. Este es todo el argumento de un <a href="/es/blog/spec-driven-ligero/">flujo spec-driven ligero</a>: una spec lo bastante pequeña como para que mantenerla al día no sea un proyecto en sí mismo.</li>
<li><strong>Reconcilia al final de una ejecución, no al final de un trimestre.</strong> El momento de actualizar el contrato es cuando el cambio está fresco, antes de que la siguiente sesión olvide por qué pasó.</li>
<li><strong>Ancla la spec al código, no a una carpeta.</strong> Un contrato que vive junto a la implementación y la evidencia se puede contrastar con la realidad. Un contrato que vive en un documento que tienes que acordarte de abrir, no. Esta es la idea de fondo de la <a href="/es/blog/documentacion-viva/">documentación viva</a>: docs que se actualizan como subproducto del trabajo en vez de como tarea aparte.</li>
<li><strong>Trata la spec como portable, no desechable.</strong> Una <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">especificación portable</a> que lleva su intención, decisiones y evidencia entre herramientas es mucho más difícil de abandonar que un archivo Markdown que un agente escribió y el siguiente ignoró.</li>
</ul>
<p>Todo esto apunta en la misma dirección: dejar de tratar la spec como un documento que escribes una vez y empezar a tratarla como una <a href="/es/blog/especificaciones-vivas/">especificación viva</a> que se mueve con el código.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>El spec drift es el problema alrededor del que está construido PaellaDoc. En vez de una spec que se queda en una carpeta mientras los agentes reforman el código a su lado, el contrato vive en un modelo local conectado al producto, al repositorio y a la evidencia de cada ejecución. Cuando un cambio aterriza, la spec es un sitio contra el que reconciliar ese cambio, no un archivo que alguien tiene que recordar que existe. La idea no es congelar el código. Es asegurar que, cuando el código se mueve, la historia que contaste sobre él se mueva también.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿El spec drift es lo mismo que la deuda técnica?</strong> No. La deuda técnica es un hueco entre el código y un diseño sano. El spec drift es un hueco entre el código y el contrato que escribiste sobre él. Puedes tener código limpio que ha derivado mucho de su spec, y una base de código desordenada cuya spec está perfectamente al día.</p>
<p><strong>¿Puedo borrar la spec cuando el código ya funciona?</strong> Puedes, y mucha gente lo hace. El problema aparece después, cuando un agente o compañero nuevo necesita cambiar el código y no hay registro de qué tiene que seguir siendo cierto. Borrar una spec con drift quita el síntoma y conserva la enfermedad.</p>
<p><strong>¿Con qué frecuencia hay que actualizar una spec?</strong> Al ritmo del trabajo, no del calendario. El momento útil es cuando un cambio aterriza y la razón sigue fresca. Agrupar las actualizaciones de spec para más tarde es justo como se acumula el drift.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="spec-drift"/><category term="desarrollo-guiado-por-especificaciones"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="especificaciones-vivas"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">La spec es el contrato: qué significa en la práctica</title>
    <link href="https://paelladoc.com/es/blog/spec-como-contrato/" rel="alternate" type="text/html" title="La spec es el contrato: qué significa en la práctica"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/spec-como-contrato/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/spec-como-contrato/"><![CDATA[<p><strong>«La spec es el contrato» es una de esas frases con las que todo el mundo asiente.</strong> Suena bien, suena rigurosa, y la mayor parte del tiempo no significa nada, porque un contrato que nadie firma, que nadie puede incumplir y que nadie hace cumplir no es un contrato. Es un deseo con mejor formato.</p>
<p>Si quieres que la frase pese, tienes que responder tres preguntas que un contrato real siempre responde. ¿Quién lo firma? ¿Quién puede romperlo? ¿Y cómo se entera alguien de que se rompió? Sáltatelas y «la spec es el contrato» es solo una forma más bonita de decir «escribimos algo una vez».</p>
<h2 id="un-contrato-tiene-partes">Un contrato tiene partes</h2>
<p>Un contrato vincula a unas partes entre sí. Así que la primera pregunta es: ¿entre quiénes?</p>
<p>En el <a href="https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/">desarrollo guiado por especificaciones</a> la spec se sitúa entre la intención de producto y la implementación. A un lado está quien responde de lo que el software debe hacer. Al otro, quien, o lo que, lo construye, y cada vez más eso es un agente. La spec es la declaración acordada de qué significa «correcto», escrita antes de empezar a construir para que ambos lados apunten al mismo objetivo.</p>
<p>Por eso la spec tiene que ir antes que el código. Un contrato que escribes después de terminar el trabajo no es un contrato, es una descripción. Todo el valor de <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">definir el contrato de aceptación antes de implementar</a> es que existe como un compromiso al que ambas partes pueden señalar, no como un resumen de lo que ya pasó.</p>
<p>La firma también importa. Alguien tiene que aceptar de verdad la spec, dejando constancia, antes de que el agente construya contra ella. Esa firma es lo que zanja tres semanas después la discusión del <a href="/es/blog/registro-de-decisiones/">«yo nunca acordé eso»</a>. Sin un momento registrado de acuerdo, la spec es un borrador, y los borradores no vinculan a nadie.</p>
<h2 id="un-contrato-se-puede-incumplir">Un contrato se puede incumplir</h2>
<p>Aquí es donde se desmorona casi toda la charla de «spec como contrato». Si nada puede romper el contrato, nunca fue un contrato. Entonces, ¿qué cuenta como incumplimiento?</p>
<p>Dos cosas incumplen una spec, y son distintas.</p>
<p><strong>La implementación viola la spec.</strong> El agente construyó algo que no hace lo que dice el contrato. Cubre el camino feliz e ignora un invariante que la spec protegía de forma explícita. Este es el incumplimiento que todo el mundo imagina, y es el más fácil de atrapar.</p>
<p><strong>El mundo cambia y la spec deja de describirlo.</strong> Nadie violó el contrato a propósito. Un cambio posterior tocó la misma superficie, el comportamiento se movió y ahora el código y la spec no coinciden. Ninguna parte faltó a su palabra, pero el contrato queda incumplido igual, porque ya no encaja con la realidad. Este es el <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">spec drift</a> visto con lente contractual, y es el incumplimiento del que nadie asigna la culpa, que es justo por lo que se pudre.</p>
<p>Una spec que solo puede romperse por lo primero y nunca se entera de lo segundo te protege del fallo fácil y deja el común abierto de par en par.</p>
<figure class="tp-diagram tp-diagram--drift" data-diagram-type="drift" role="img" aria-label="El segundo incumplimiento: el código se mueve, la spec se queda, y el contrato deja de coincidir con la realidad."><svg viewBox="0 0 760 240" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
  <text x="40" y="40" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mute)">ACUERDO</text>
  <path d="M 40 120 C 240 120 340 84 720 56" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.8"></path>
  <path d="M 40 120 C 240 120 340 158 720 190" fill="none" stroke="var(--tp-ink)" stroke-width="1.8"></path>
  <circle cx="40" cy="120" r="5" fill="var(--tp-ink)"></circle>
  <text x="716" y="42" text-anchor="end" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">SPEC</text>
  <text x="716" y="214" text-anchor="end" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">CÓDIGO</text>
  <line x1="676" y1="66" x2="676" y2="180" stroke="var(--tp-terracota)" stroke-width="1.2" stroke-dasharray="3 5"></line>
  <text x="662" y="128" text-anchor="end" font-family="var(--tp-mono)" font-size="11" letter-spacing="2" fill="var(--tp-terracota)">RUPTURA</text>
</svg><figcaption>El segundo incumplimiento: el código se mueve, la spec se queda, y el contrato deja de coincidir con la realidad.</figcaption></figure>
<h2 id="un-contrato-se-hace-cumplir-o-es-decoración">Un contrato se hace cumplir, o es decoración</h2>
<p>Un incumplimiento que nadie detecta no es hacer cumplir. Esta es la parte que separa una spec que gobierna de una spec que decora.</p>
<p>La detección tiene que ser mecánica, porque la atención humana no escala a la velocidad a la que los agentes producen código. Los criterios de aceptación de la spec tienen que ser ejecutables contra el resultado real, y algo tiene que correrlos de verdad y unir el desenlace al contrato. Una suite de tests en verde no basta por sí sola, porque <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>: el build puede estar verde mientras el comportamiento concreto que el contrato prometía no se ejecutó nunca.</p>
<p>Por eso los criterios de aceptación hay que escribirlos para comprobarse, no solo para leerse. Un criterio vago como «gestiona los errores con elegancia» no se puede hacer cumplir, así que no es una cláusula del contrato, es una esperanza. Los criterios que un agente y un ejecutor pueden evaluar son la diferencia entre <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación que se verifican</a> y una checklist que alguien marca a ojo.</p>
<p>Y hacer cumplir tiene que ser continuo, porque el segundo tipo de incumplimiento ocurre después de secar la tinta. Comprobar el contrato una vez en el merge atrapa la violación de la implementación y se pierde cada drift que viene detrás. Hacer cumplir no es una puerta que cruzas una vez. Es una pregunta permanente que el sistema sigue repitiendo: ¿el código sigue satisfaciendo el contrato?</p>
<p>Fíjate en cuánto de esto lo hace hoy la persona a mano. Tú eres la parte que firmó. Tú eres el mecanismo de cumplimiento, leyendo el diff y decidiendo si honra lo acordado. Tú eres el detector de drift, quien acaba notando que la spec ya no coincide. Un contrato que se hace cumplir enteramente con la atención de una persona es un contrato que aguanta exactamente lo que esa persona tenga atención de sobra, que a velocidad de agente no es mucho. Las cláusulas no se debilitan. El que hace cumplir simplemente se desborda, y un contrato sin cumplir vuelve a ser decoración.</p>
<h2 id="el-contrato-tiene-que-viajar-con-la-mercancía">El contrato tiene que viajar con la mercancía</h2>
<p>Un contrato no vale nada si las partes pierden su copia. Cuando la spec vive en un chat que se borra o en una carpeta que el siguiente agente no abre nunca, el contrato se anula solo en cuanto cambia el workflow.</p>
<p>Para que la spec siga siendo un contrato, tiene que moverse con el código y la evidencia, no quedarse clavada a la herramienta que la escribió. Esta es la razón práctica por la que <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">las especificaciones deberían ser portables</a>: un contrato solo vincula mientras ambas partes puedan seguir leyéndolo, y en un flujo de agentes las partes cambian sin parar.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Hacer de la spec un contrato real es el trabajo alrededor del cual está organizado PaellaDoc. Una spec se acuerda y se registra, así que hay una firma de verdad en lugar de una suposición. Sus criterios de aceptación siguen conectados con las ejecuciones que los ponen a prueba, así que un incumplimiento del primer tipo se atrapa con evidencia en vez de con confianza. Y como la spec sigue ligada al código que la implementa, un incumplimiento del segundo tipo, el drift, sale a la superficie cuando el código se mueve en lugar de esconderse hasta que lo encuentra una incidencia.</p>
<p>La spec es el contrato solo cuando alguien lo firmó, algo puede romperlo y algo atrapa la ruptura. Responde esas tres y la frase significa lo que dice. Sáltatelas y tienes un documento que parece un contrato justo hasta el momento en que necesitas que aguante.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Quién firma una spec-como-contrato?</strong> Quien responde de lo que el software debe hacer, dejando constancia, antes de que el agente construya. Ese acuerdo registrado es lo que convierte un borrador en un compromiso y zanja las disputas posteriores sobre qué se acordó de verdad.</p>
<p><strong>¿No es ya una suite de tests en verde una forma de hacer cumplir?</strong> No por sí sola. Un build en verde demuestra que algo de código corrió y pasó, no que se ejecutara el comportamiento concreto que el contrato prometía. Hacer cumplir significa que los criterios de aceptación se corren contra el resultado real y el desenlace se une a la spec.</p>
<p><strong>¿Cómo es el spec drift un incumplimiento si nadie rompió una regla?</strong> Porque un contrato queda incumplido cuando deja de encajar con la realidad, no solo cuando alguien lo viola a propósito. Un cambio posterior puede mover el comportamiento y dejar la spec describiendo un sistema que ya no existe. Nadie tiene la culpa, y el contrato está roto igual.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="spec-driven-development"/><category term="criterios-de-aceptacion"/><category term="contrato"/><category term="ai-coding"/><category term="verificacion"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Slop de IA con buen formato: el modo de fallo del producto asistido por IA</title>
    <link href="https://paelladoc.com/es/blog/slop-de-ia-en-producto/" rel="alternate" type="text/html" title="Slop de IA con buen formato: el modo de fallo del producto asistido por IA"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/slop-de-ia-en-producto/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/slop-de-ia-en-producto/"><![CDATA[<p>Tu equipo de producto es más productivo de lo que ha sido nunca, por cualquier medida visible. Más PRDs escritos. Más tickets refinados. Más análisis de competencia, más decks, más desgloses en historias de usuario, todo producido en una fracción del tiempo de antes. Los artefactos son limpios, bien estructurados, profesionalmente formateados. Y el producto no es notablemente mejor de lo que era antes de que llegara toda esta velocidad.</p>
<p>Ese hueco tiene un nombre. El slop de IA no es solo texto de baja calidad en la web abierta. En el trabajo de producto es el fallo concreto donde el volumen de artefactos trepa y la calidad de las decisiones no se mueve. Es peligroso justo porque no parece un fallo. Parece un equipo publicando un montón de trabajo con buena pinta.</p>
<h2 id="lo-único-que-fue-siempre-el-objetivo">Lo único que fue siempre el objetivo</h2>
<p>El product management tiene exactamente un trabajo que importa por debajo de todos los artefactos: decidir qué construir, y acertar más a menudo que el azar. El PRD, el ticket, el deck, el análisis, ninguno de estos es el trabajo. Son envoltorio alrededor de una decisión. Un PRD que lleva a una buena decisión se ganó su existencia. Un PRD bellamente formateado que no cambió ninguna decisión fue teatro, por muy limpio que se viera.</p>
<p>Esto era cierto antes de la IA y fácil de olvidar, porque producir los artefactos costaba esfuerzo real y el esfuerzo se siente como valor. Te pasabas un día con un PRD, así que el PRD se sentía como un día de valor, incluso cuando la decisión de dentro era una que habrías tomado igual. El trabajo disfrazaba el vacío. La IA quitó el trabajo, y al hacerlo quitó el disfraz, pero solo si miras. Si no, simplemente te deja producir diez veces los artefactos vacíos en el mismo día y sentirte diez veces más productivo.</p>
<h2 id="por-qué-la-ia-hace-explotar-este-modo-de-fallo">Por qué la IA hace explotar este modo de fallo</h2>
<p>Toda herramienta de productividad anterior para product managers seguía haciéndote pensar para producir el artefacto. Un editor de documentos mejor no escribía el argumento del PRD. Lo escribías tú. Así que el artefacto, por mucho que la herramienta acelerara su producción, seguía cargando la huella de un humano habiendo pensado.</p>
<p>La IA rompe ese vínculo. Produce el artefacto entero, argumento incluido, desde un prompt fino. Pide un PRD y obtienes un PRD completo, plausible y bien organizado en segundos, y no tuviste que decidir nada para conseguirlo. El artefacto ahora existe sin el pensamiento que antes era su única razón de existir. Este es el mecanismo detrás de <a href="/es/blog/product-management-era-ia/">construir se abarató y decidir se encareció</a>: la producción de documentos con forma de decisión se volvió casi gratis, mientras que las decisiones de dentro no mejoraron nada, así que la proporción de envoltorio a sustancia explotó calladamente.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="La IA produce el artefacto entero desde un prompt fino, así que el envoltorio se adelanta mientras la decisión de debajo se queda igual."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">PROMPT FINO</text><path d="M 250 95 L 272 95 M 266 89 L 272 95 L 266 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">PRD PULIDO</text><path d="M 488 95 L 510 95 M 504 89 L 510 95 L 504 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="62" width="204" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="618" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">MISMA DECISIÓN</text></svg><figcaption>La IA produce el artefacto entero desde un prompt fino, así que el envoltorio se adelanta mientras la decisión de debajo se queda igual.</figcaption></figure>
<p>Y el envoltorio es <em>bueno</em>. Esa es la trampa. El slop de IA en producto no tiene pinta descuidada. Es lo contrario. Está más pulido que lo que produce un humano con prisa, mejor estructurado, más completo, con secciones que no te habrías molestado en escribir. Tiene el buen formato. Lo que no tiene, y no puede generar, es lo único que importaba: una mejor decisión sobre qué construir. Es el primo, en el lado de producto, de un agente que <a href="/es/blog/exitos-falsos-de-agentes/">reporta un éxito que nunca se ganó</a>.</p>
<h2 id="qué-pinta-tiene-desde-dentro">Qué pinta tiene desde dentro</h2>
<p>El fallo es difícil de ver desde dentro porque cada artefacto individual se ve bien. Algunas formas que vigilar:</p>
<ul>
<li><strong>El PRD exhaustivo para una decisión que nadie sudó.</strong> Quince secciones, casos límite enumerados, y la elección real de qué construir se tomó en un chat de cinco minutos y nunca se puso a prueba. La exhaustividad del documento es inversamente proporcional al pensamiento detrás de la decisión, y la exhaustividad lo esconde.</li>
<li><strong>Inflación de tickets.</strong> El backlog se dobla porque generar tickets bien formados ahora es gratis. Más tickets se lee como más planificación. Es más ruido, y la señal sobre lo que de verdad importa ahora está enterrada bajo trabajo formateado.</li>
<li><strong>El análisis que concluye lo que ya creías.</strong> Le pediste a un modelo que analizara el mercado y produjo <a href="/es/blog/research-de-usuarios-con-ia/">un deck seguro apoyando la dirección hacia la que te inclinabas</a>. Se siente como validación. Es tu propio prior en una fuente más bonita, y ahora carga la autoridad prestada de un «análisis».</li>
<li><strong>Insights que nadie ejecuta.</strong> Un chorro de observaciones generadas por IA, cada una plausible, ninguna conectada a una decisión que alguien posea. El equipo <a href="/es/blog/de-insight-a-resultado/">confunde producir insight con usarlo</a>.</li>
</ul>
<p>Cada una de estas pasa la review porque el artefacto está genuinamente bien hecho. Por eso el slop es tan difícil de combatir. No puedes señalar un PRD mal escrito, porque no está mal escrito. Tienes que señalar lo que falta, la decisión que no mejoró, y lo que falta es invisible contra un fondo de output pulido.</p>
<h2 id="la-productividad-que-en-realidad-es-movimiento">La productividad que en realidad es movimiento</h2>
<p>Hay un nombre más viejo para producir mucho output que no cambia resultados, y conviene conectarlos. Esto es una <a href="/es/blog/que-es-una-feature-factory/">feature factory</a> movida una etapa río arriba. La feature factory clásica publica features y <a href="https://dora.dev/research/">nunca comprueba si cambiaron algo</a>. El slop de IA en producto hace lo mismo con los artefactos <em>antes</em> de las features: produce PRDs, análisis y tickets y nunca comprueba si alguno mejoró una decisión. Ambos confunden movimiento con progreso, y la IA hace el movimiento más rápido, más suave y más convincente, porque ahora el movimiento va bellamente formateado.</p>
<p>La señal es siempre la misma. Pregunta <a href="/es/blog/decisiones-con-evidencia/">qué decisión mejoró porque este artefacto existe</a>. Si la respuesta de verdad es «ninguna, pero parece exhaustivo», estás mirando slop. El volumen subió. La cosa a la que el volumen debía servir no.</p>
<p>Nada de esto significa que usar IA para redactar artefactos esté mal. Un modelo que convierte una decisión que de verdad has tomado en un PRD limpio y bien estructurado hace un trabajo genuinamente útil, comprime el envoltorio para que tu tiempo vaya a decidir en su lugar. El slop aparece solo cuando el envoltorio se adelanta a la decisión, cuando el artefacto existe y la decisión detrás no. La prueba es la dirección. ¿Es el documento consecuencia de una elección que sudaste, llevándola a la gente que la necesita? ¿O está sustituyendo a una elección que nunca tomaste, con su pulido rellenando calladamente el espacio donde debería haber estado el pensamiento?</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Este es el modo de fallo que <a href="/es/">PaellaDoc</a> está construido para resistir, y la resistencia es estructural, no cuestión de esforzarse más. Un artefacto no es un documento suelto que existe para parecer completo. Está conectado a la decisión a la que sirve y, con el tiempo, al resultado que produjo. Lo que significa que puedes hacer la pregunta que el slop no sobrevive: ¿esto cambió una decisión, y esa decisión salió bien? Un PRD que no mejoró ninguna decisión no tiene dónde esconderse cuando cada artefacto se juzga por la decisión que movió y no por lo terminado que se ve.</p>
<p>La IA dejará a tu equipo producir más artefactos de producto de los que ha producido nunca, a una calidad de formato que te impresionará de verdad. No confundas eso con volverte mejor en el trabajo. El trabajo nunca fue producir artefactos. Era decidir bien, y ningún volumen de output bien formateado mueve ese número salvo que insistas, cada vez, en conectar el artefacto de vuelta con la decisión que debía mejorar. Más PRDs no es el objetivo. Nunca fue el objetivo. Mejores decisiones era el único objetivo, y el slop es lo que obtienes cuando lo olvidas.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-el-slop-de-ia-en-producto">¿Qué es el slop de IA en producto?</h3>
<p>El slop de IA en producto es el modo de fallo donde el volumen de artefactos trepa y la calidad de las decisiones se queda plana. Más PRDs, más tickets, más decks pulidos, producidos más rápido y leídos menos. Es peligroso porque no parece un fallo, parece un equipo productivo, ya que el output es visible y va bien formateado. Lo único que importaba, decidir mejor, no se movió.</p>
<h3 id="cómo-detecto-el-slop-de-ia-en-los-artefactos-de-producto">¿Cómo detecto el slop de IA en los artefactos de producto?</h3>
<p>Hazle una pregunta a cualquier documento: ¿qué decisión mejoró porque esto existe? Si la respuesta de verdad es «ninguna, pero parece exhaustivo», es slop. Vigila el PRD exhaustivo detrás de una elección de cinco minutos que nadie puso a prueba, un backlog doblado de tickets bien formados, un análisis que concluye lo que ya creías, e insights que nadie ejecuta. Cada uno pasa la review porque el artefacto está bien hecho.</p>
<h3 id="está-mal-usar-ia-para-redactar-prds">¿Está mal usar IA para redactar PRDs?</h3>
<p>No. Un modelo que convierte una decisión que de verdad tomaste en un PRD limpio y bien estructurado hace un trabajo útil, comprime el envoltorio para que tu tiempo vaya a decidir. El slop aparece solo cuando el envoltorio se adelanta a la decisión, cuando el artefacto existe y la decisión detrás no. La prueba es la dirección: ¿es el documento consecuencia de una elección que sudaste, o sustituye a una que nunca tomaste?</p>
<h3 id="por-qué-la-ia-empeora-el-slop-de-producto-frente-a-herramientas-anteriores">¿Por qué la IA empeora el slop de producto frente a herramientas anteriores?</h3>
<p>Las herramientas de productividad anteriores seguían haciéndote pensar para producir el artefacto; un editor mejor no escribía el argumento del PRD, lo escribías tú. La IA produce el artefacto entero, argumento incluido, desde un prompt fino, así que existe sin el pensamiento que antes era su única razón de existir. Producir documentos con forma de decisión se volvió casi gratis mientras las decisiones de dentro no mejoraron, así que la proporción de envoltorio a sustancia explotó.</p>]]></content>
    <summary type="html"><![CDATA[El slop de IA en producto es el modo de fallo donde el volumen de artefactos sube y la calidad de las decisiones se queda plana. Más PRDs, más tickets, más decks pulidos, producidos más rápido y leídos menos. Parece productividad porque el output es visible y va bien formateado, pero lo único que importó siempre, decidir mejor, no se movió.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="ai-slop-product"/><category term="product-management"/><category term="ai-coding"/><category term="decision-quality"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">Ocho sesiones a la vez: worktrees, paralelismo y el coste de ser el scheduler</title>
    <link href="https://paelladoc.com/es/blog/sesiones-paralelas-agentes/" rel="alternate" type="text/html" title="Ocho sesiones a la vez: worktrees, paralelismo y el coste de ser el scheduler"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/sesiones-paralelas-agentes/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/sesiones-paralelas-agentes/"><![CDATA[<p>La primera vez que corres dos agentes a la vez parece un truco. Dos tareas avanzando mientras te tomas un café. Así que corres tres, luego cinco, luego ocho, y en algún punto de ahí la sensación cambia. Ya no escribes código y tampoco descansas de verdad. Cambias de contexto entre paneles, sostienes ocho estados parciales en la cabeza, decides a quién le toca tu atención. Te has dado un segundo trabajo, y el trabajo es scheduler.</p>
<p>Yo corro el trabajo así a diario construyendo PaellaDoc, y el paralelismo es de verdad como sacas throughput de los agentes. Pero el throughput no es gratis, y el coste no son tokens. Es un tipo concreto de atención humana que se vuelve más cara cuantas más sesiones añades, y entender ese coste es la diferencia entre un paralelismo que escala y uno que solo te deja frito.</p>
<h2 id="la-parte-mecánica-worktrees">La parte mecánica: worktrees</h2>
<p>El truco que lo habilita son los git worktrees. Un worktree es un segundo directorio de trabajo respaldado por el mismo repositorio, en su propia rama. En vez de un checkout por el que se pelean todos los agentes, cada agente tiene su propio directorio y su propia rama, y todos pueden editar a toda velocidad sin tocar los ficheros del otro.</p>
<p>Esto importa porque el montaje ingenuo, varios agentes en un directorio, se corrompe solo enseguida. Los agentes no ven los cambios sin commitear del otro, así que dos escribiendo al mismo árbol se sobrescriben y se lían constantemente. Los worktrees dan a cada agente aislamiento, que es la precondición de todo lo demás. Las colisiones no desaparecen, se mueven al merge, donde puedes manejarlas a propósito. Este es el suelo mecánico bajo todo el <a href="/es/blog/orquestacion-multiagente/">trabajo multiagente</a>: sin aislamiento no hay nada que orquestar, solo un amontonamiento.</p>
<p>El montaje en sí no es complicado. Un worktree por tarea, una rama por worktree, un agente por rama. La complejidad no está en la mecánica de git. Está en el humano de pie en medio de ocho de ellos.</p>
<h2 id="la-parte-de-la-que-nadie-te-avisa-eres-el-scheduler">La parte de la que nadie te avisa: eres el scheduler</h2>
<p>Cuando los worktrees están corriendo, un papel nuevo te cae encima lo quisieras o no. Cada uno de estos trabajos es ahora tuyo, todos a la vez:</p>
<ul>
<li><strong>Prioridad.</strong> ¿Qué sesión se lleva tu atención ahora? Terminan y se atascan en momentos distintos, y la que te necesita no siempre es la que estás mirando.</li>
<li><strong>Contexto.</strong> Cada sesión sostiene un trozo distinto del producto en la cabeza, y tú también, porque cuando la sesión cuatro pregunta algo, necesitas recargar qué estaba haciendo siquiera la cuatro.</li>
<li><strong>Recuperación.</strong> Un run se muere en un momento incómodo y se queda ahí, sin hacer nada, esperando. Si no lo notas, es un panel muerto quemando nada más que tu throughput.</li>
<li><strong>Routing.</strong> Distintas tareas quieren distintos motores, la tarea de arquitectura y el refactor mecánico no deberían correr en el mismo modelo al mismo coste, y elegir es cosa tuya. Ese es el argumento entero de <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">enrutar cada tarea al motor correcto</a>, que se vuelve agudo justo cuando corres muchas a la vez.</li>
<li><strong>Integración.</strong> Todas vuelven como ramas que tienen que integrarse en una sola cosa coherente, y el merge es donde aflora la deriva entre ellas.</li>
</ul>
<figure class="tp-diagram tp-diagram--graph" data-diagram-type="graph" role="img" aria-label="Corre ocho sesiones y cinco trabajos concurrentes te caen encima a la vez. Ese es el impuesto de scheduler que te endosa el paralelismo."><svg viewBox="0 0 760 320" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="380" y1="160" x2="140" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="140" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="140" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">PRIORIDAD</text><line x1="380" y1="160" x2="620" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="620" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="620" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">CONTEXTO</text><line x1="380" y1="160" x2="96" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="96" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="96" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">RECUPERACIÓN</text><line x1="380" y1="160" x2="664" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="664" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="664" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">ROUTING</text><line x1="380" y1="160" x2="380" y2="40" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="380" cy="40" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="380" y="66" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">INTEGRACIÓN</text><circle cx="380" cy="160" r="14" fill="var(--tp-mostaza)" fill-opacity="0.16" stroke="var(--tp-mostaza)" stroke-width="1.8"></circle>
  <text x="380" y="194" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">EL SCHEDULER</text></svg><figcaption>Corre ocho sesiones y cinco trabajos concurrentes te caen encima a la vez. Ese es el impuesto de scheduler que te endosa el paralelismo.</figcaption></figure>
<p>Ninguna de estas es difícil en aislamiento. El coste es que son concurrentes y van por interrupción. No las haces en orden. Te arrastra el panel que te reclama, a mitad de un pensamiento en otro, y cada cambio paga el impuesto de recargar qué estabas haciendo ahí. Esa recarga es la misma <a href="/es/blog/perdida-de-contexto-entre-sesiones/">pérdida de contexto</a> que golpea a los agentes, solo que te golpea a ti, en tiempo real, de ocho formas a la vez.</p>
<h2 id="por-qué-el-coste-es-superlineal">Por qué el coste es superlineal</h2>
<p>Aquí están las cuentas incómodas. Dos sesiones no son el doble de carga que una. Son más, porque encima de las dos sesiones está el cambio entre ellas, y el coste del cambio crece más rápido que el número de sesiones.</p>
<p>Con una sesión nunca te interrumpen, no hay a qué cambiar. Con dos, cambias de vez en cuando. Con ocho, casi siempre estás a mitad de cambio, y los estados chocan en tu memoria de trabajo: vas a contestar a la sesión tres y no recuerdas de inmediato si lo que miras es de la tres o de la seis. Las sesiones escalan lineal. La coordinación entre ellas, lo que de verdad corre en ti, no. Por eso cinco agentes pueden sentirse productivos y ocho pueden sentirse como ahogarse, aunque solo sean tres más.</p>
<p>Esta es la versión concreta y sentida del argumento entero del runtime. Cuando dicen que un buen desarrollador puede correr agentes bien a mano, tienen razón, y esta es justo la parte del «a mano». Eres el scheduler, la memoria, el bucle de recuperación y el router, todo en tiempo real, y la razón de que funcione es que estás absorbiendo un coste de coordinación superlineal con atención humana. Funciona justo hasta que deja de funcionar, y dónde deja es distinto para cada uno pero siempre deja. El nombre que le da el manifiesto es que <a href="/es/blog/eres-el-runtime/">tú eres el runtime</a>, y correr ocho sesiones es la forma más física de sentirlo.</p>
<h2 id="qué-ayuda-de-verdad">Qué ayuda de verdad</h2>
<p>Esto no se arregla corriendo menos sesiones, eso solo te limita el throughput a lo que un humano pueda cuidar. Se arregla moviendo trozos del trabajo del scheduler fuera de ti y hacia el sistema.</p>
<p>La decisión de routing la puede tomar un router en vez de tú eligiendo modelo por panel. La recuperación puede ser un retry gobernado que nota un run muerto y lo reinicia, en vez de tú pillando el panel atascado, que es una disciplina entera en cuanto <a href="/es/blog/recuperar-ejecuciones-fallidas/">tratas la recuperación como un flujo de primera</a>. El contexto puede vivir en <a href="/es/blog/memoria-agentes-de-codigo/">memoria duradera</a> que cada sesión carga por su cuenta, para que cambiar a la sesión cuatro no requiera que tú recuerdes en persona qué hacía la cuatro. La integración puede ser un paso de reconciliación de verdad en vez de tú integrando ocho ramas a ojo y rezando. Es la misma razón por la que los agentes necesitan un runtime y no solo un modelo más grande: la inteligencia por sesión no toca el coste de coordinación entre sesiones, y el coste de coordinación es lo que de verdad te está limitando. La versión larga la escribí en <a href="/es/research/agentes-necesitan-un-runtime-no-un-modelo-mas-grande/">los agentes necesitan un runtime, no un modelo más grande</a>.</p>
<p>Cada uno de esos movimientos quita un trabajo del scheduler, que eres tú. Haz suficientes y el coste superlineal deja de trepar con cada sesión añadida, porque la coordinación pasa en el sistema en vez de en tu cabeza. Ese es el juego entero: no más agentes vigilados por un humano más heroico, sino los mismos agentes coordinados por algo que no es tu atención. Corre ocho sesiones si quieres el throughput. Solo no seas la octava cosa que lo sostiene todo.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuántas sesiones en paralelo aguantas antes de dejar de construir y empezar a arbitrar? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cuántas-sesiones-de-agente-puedo-llevar-en-paralelo">¿Cuántas sesiones de agente puedo llevar en paralelo?</h3>
<p>No hay un número fijo; el límite es donde el coste de coordinación adelanta a tu atención, y es distinto para cada uno. Lo predecible es la forma: cinco sesiones pueden sentirse productivas y ocho como ahogarse, aunque solo sean tres más. El coste es superlineal porque el cambio entre sesiones crece más rápido que el número de sesiones. Extiendes el techo moviendo los trabajos del scheduler al sistema, no siendo más heroico.</p>
<h3 id="cómo-corro-varias-sesiones-de-código-con-ia-a-la-vez">¿Cómo corro varias sesiones de código con IA a la vez?</h3>
<p>Usa git worktrees: un worktree por tarea, una rama por worktree, un agente por rama. Un worktree es un segundo directorio de trabajo respaldado por el mismo repositorio, en su propia rama, así cada agente edita a toda velocidad sin tocar los ficheros del otro. El montaje ingenuo —varios agentes en un directorio— se corrompe solo enseguida, porque los agentes no ven los cambios sin commitear del otro. Los worktrees dan el aislamiento del que depende todo lo demás.</p>
<h3 id="por-qué-correr-muchos-agentes-en-paralelo-agobia">¿Por qué correr muchos agentes en paralelo agobia?</h3>
<p>Porque te conviertes en el scheduler, y cinco trabajos concurrentes te caen a la vez: prioridad, contexto, recuperación, routing e integración. Van por interrupción, así que te arrastra el panel que te reclama a mitad de un pensamiento en otro, y cada cambio paga el coste de recargar qué estabas haciendo. Esa recarga es pérdida de contexto golpeándote en tiempo real, de ocho formas a la vez. Las sesiones escalan lineal; la coordinación que corre en ti, no.</p>
<h3 id="qué-son-los-git-worktrees-y-por-qué-los-necesitan-los-agentes">¿Qué son los git worktrees y por qué los necesitan los agentes?</h3>
<p>Un worktree es un segundo directorio de trabajo del mismo repositorio en su propia rama. Los agentes los necesitan porque el aislamiento es la precondición del trabajo en paralelo: sin él, dos agentes escribiendo al mismo árbol se sobrescriben y se lían constantemente. Los worktrees no hacen desaparecer las colisiones, las mueven al merge, donde puedes manejarlas a propósito. Este es el suelo mecánico bajo toda la orquestación multiagente.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="sesiones-paralelas"/><category term="worktrees"/><category term="agents"/><category term="runtime"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Los agujeros de seguridad que deja el vibe coding</title>
    <link href="https://paelladoc.com/es/blog/seguridad-vibe-coding/" rel="alternate" type="text/html" title="Los agujeros de seguridad que deja el vibe coding"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/seguridad-vibe-coding/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/seguridad-vibe-coding/"><![CDATA[<p>El problema de seguridad del vibe coding no es que los agentes escriban código inseguro a propósito. Es que escriben código plausible rápido, y el código plausible pasa el único test que casi todo el vibe coding aplica: arranca. Los agujeros de seguridad no impiden que una app arranque. Se quedan ahí en silencio hasta que alguien los encuentra, y ese alguien rara vez eres tú.</p>
<p>Quiero ser preciso, no alarmista. Tu app de fin de semana probablemente no esté siendo atacada activamente. Pero en cuanto guarda datos de un usuario real o cobra un pago real, la distancia entre “funciona” y “es seguro operarla” pasa a ser tu problema, y esa distancia tiene una forma predecible. El código generado que nadie revisó tiende a filtrar por los mismos tres sitios. Déjame recorrer cada uno, con el mecanismo, para que lo cierres en vez de preocuparte por él.</p>
<figure class="tp-diagram tp-diagram--graph" data-diagram-type="graph" role="img" aria-label="El código que nadie leyó filtra por los mismos tres sitios. El hilo común es la revisión que el vibe coding se salta."><svg viewBox="0 0 760 320" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="380" y1="160" x2="140" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="140" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="140" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">SECRETOS EN EL CÓDIGO</text><line x1="380" y1="160" x2="620" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="620" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="620" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">ENTRADA SIN VALIDAR</text><line x1="380" y1="160" x2="96" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="96" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="96" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">DEPENDENCIAS SIN AUDITAR</text><circle cx="380" cy="160" r="14" fill="var(--tp-mostaza)" fill-opacity="0.16" stroke="var(--tp-mostaza)" stroke-width="1.8"></circle>
  <text x="380" y="194" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">CÓDIGO SIN REVISAR</text></svg><figcaption>El código que nadie leyó filtra por los mismos tres sitios. El hilo común es la revisión que el vibe coding se salta.</figcaption></figure>
<h2 id="agujero-1-secretos-en-el-código">Agujero 1: secretos en el código</h2>
<p>El más común y el más fácil de arreglar. Le pides a un agente que conecte con una base de datos, un servicio de email, una pasarela de pago. Escribe código que funciona, y para que funcione mete la API key ahí mismo, en el código fuente. A veces la deja fija en un archivo de configuración. A veces commitea tu <code>.env</code> porque nada le dijo que no.</p>
<p>El mecanismo es simple: el agente optimiza para que el código arranque ahora, y una clave literal arranca. Una clave leída de una variable de entorno también arranca, pero pide un segundo paso que el agente no tiene motivo para priorizar salvo que se lo pidas. Así que toma el atajo, y el atajo acaba en tu historial de git, donde se queda incluso después de borrar la línea.</p>
<p>Cerrarlo es mecánico. Saca cada credencial del código y llévala a variables de entorno o a un gestor de secretos. Añade los archivos de secretos al <code>.gitignore</code> antes del primer commit, no después. Si una clave llegó a tocar un commit, rótala, porque git recuerda. Y revisa el historial, porque la clave que dejaste fija la primera semana sigue en el log que olvidaste.</p>
<h2 id="agujero-2-entrada-que-nadie-validó">Agujero 2: entrada que nadie validó</h2>
<p>Este es el caro, y el que un agente tiene menos probabilidades de manejar sin que se lo pidas.</p>
<p>Cada sitio donde tu app acepta entrada de fuera es un sitio donde algo puede salir mal: un campo de formulario, un parámetro de URL, un archivo subido, el cuerpo de una petición. El código seguro trata todo eso como hostil hasta que se demuestre lo contrario. El código generado suele tratarlo como bien formado, porque el camino feliz es lo que describía el prompt. El agente construyó la feature que pediste. No le pediste que asumiera que el usuario es un atacante, así que no lo hizo.</p>
<p>El resultado es que todo el <a href="https://owasp.org/Top10/">OWASP Top 10</a> se lee como una lista de cosas que tu app probablemente hace mal: inyección porque una consulta se armó concatenando una cadena que controla el usuario, control de acceso roto porque un endpoint comprueba que has iniciado sesión pero no que el registro sea tuyo, exposición de datos porque un manejador de errores devuelve la traza completa. Ninguna rompe la app. Todas son puertas.</p>
<p>El arreglo no es glamuroso y no es opcional. Valida y sanea la entrada en la frontera, siguiendo algo concreto como la <a href="https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html">guía de validación de entrada de OWASP</a> en vez de tu intuición. Usa consultas parametrizadas para que la entrada del usuario nunca se concatene dentro de un comando. Comprueba la autorización sobre el registro, no solo sobre la sesión. Son patrones que un agente aplica bien en cuanto los conviertes en parte del contrato, y se salta por completo cuando no.</p>
<h2 id="agujero-3-dependencias-que-nadie-auditó">Agujero 3: dependencias que nadie auditó</h2>
<p>Un agente recurre a librerías como tú recurrirías a un resultado de búsqueda. Elige un paquete que resuelve el problema, lo añade a tu manifiesto y sigue. No comprueba si el paquete se mantiene, si tiene vulnerabilidades conocidas ni si es siquiera el paquete que crees que es.</p>
<p>Ese último punto importa más de lo que suena. Los atacantes publican paquetes con nombres parecidos a los populares, apostando a un error de tecleo o a un autocompletado seguro de sí mismo. Un agente generando una lista de dependencias de memoria es justo el tipo de autocompletado seguro al que apuestan. Puedes acabar importando algo que nadie auditó al núcleo de tu app, y llegó porque un modelo lo sugirió y tú no miraste.</p>
<p>El arreglo es poner una puerta entre “se añadió una dependencia” y “la dependencia se publica”. Escanea tu árbol de dependencias en busca de vulnerabilidades conocidas, y hazlo de forma continua, porque un paquete que estaba limpio cuando el agente lo añadió puede descubrirse vulnerable el mes que viene. Es exactamente la práctica sobre la que escribí en <a href="/es/blog/asegura-tu-codigo-de-ia-con-snyk/">asegurar el código de IA con Snyk</a>: la capa de dependencias es donde el código generado hereda los errores de otra gente, y la única defensa es comprobar en vez de confiar.</p>
<h2 id="por-qué-lo-que-se-rompió-fue-la-revisión">Por qué lo que se rompió fue la revisión</h2>
<p>Fíjate en lo que comparten los tres agujeros. Ninguno es exótico. Un desarrollador leyendo el código pillaría la clave fija, cuestionaría el formulario sin validar y levantaría una ceja ante la dependencia desconocida. Los agujeros existen porque nadie leyó el código, y nadie lo leyó porque el atractivo entero del vibe coding es no tener que hacerlo.</p>
<p>Esa es la tensión real. La velocidad viene de saltarse la revisión, y la seguridad viene de la revisión. No puedes quedarte con la velocidad y borrar el riesgo. Lo que sí puedes es mover la revisión de “lee cada línea” a “comprueba las tres cosas que de verdad filtran”, que es un trabajo mucho más pequeño.</p>
<p>Aquí también aparece, del modo más nítido posible, la línea entre <a href="/es/blog/vibe-coding-vs-ingenieria-asistida/">vibe coding e ingeniería asistida por IA</a>. El vibe coding confía en el output porque arranca. La ingeniería trata la seguridad como parte de la definición de hecho, y se niega a dar una feature por terminada hasta que la frontera está validada, los secretos están fuera del código y las dependencias están limpias. Mismo agente, misma velocidad, distinto contrato.</p>
<h2 id="el-marco-de-la-deuda-aplicado-a-la-seguridad">El marco de la deuda, aplicado a la seguridad</h2>
<p>Los agujeros sin cerrar son un tipo concreto de <a href="/es/blog/deuda-tecnica-vibe-coding/">deuda del vibe coding</a>, y se comportan como la peor: barata de cargar, catastrófica de saldar. Una validación de entrada que falta no cuesta nada hasta el día en que lo cuesta todo, y a diferencia de una feature lenta, no recibes aviso de que llega la factura. Otro te programa el pago.</p>
<p>Por eso la seguridad no es algo que atornillas al final del <a href="/es/blog/vibe-coding-a-produccion/">camino del vibe coding a producción</a>. Es una de las puertas que definen si tienes un producto o una responsabilidad legal con una UI bonita.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La razón de que estos agujeros sobrevivan es que “¿comprobamos los secretos, la entrada, las dependencias?” es una pregunta que nadie escribió, así que nadie respondió. La comprobación vive en la cabeza de una persona, y las cabezas olvidan, sobre todo cuando el agente fue más rápido que quien revisa.</p>
<p>PaellaDoc convierte esas comprobaciones en parte del contrato de un cambio y guarda la evidencia de que se ejecutaron, unida al código que cubren, en vez de depender de que te acuerdes. La idea no es frenar al agente. Es asegurar que cuando un cambio se cierra, las preguntas de seguridad aburridas y que sostienen peso tienen respuestas reales en registro, no la suposición de que el código estaba bien porque arrancó.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿El software hecho con vibe coding es inseguro por naturaleza?</strong> No. Está sin revisar, que es distinto. El mismo agente escribe código seguro cuando la seguridad es parte del contrato, y código con fugas cuando el único requisito es que arranque. El riesgo viene de saltarse la revisión, no del modelo.</p>
<p><strong>¿Qué es lo más importante que comprobar primero?</strong> Los secretos. Asegúrate de que ninguna API key ni credencial vive en tu código o en el historial de git, porque ese agujero es el más fácil de explotar y el más fácil de cerrar. Luego pasa a la validación de entrada y a las dependencias.</p>
<p><strong>¿Necesito un experto en seguridad para arreglar esto?</strong> Para la mayoría de apps de vibe coding, no. Sacar los secretos del código, validar la entrada en la frontera con una guía establecida y escanear tus dependencias cierra los agujeros comunes. Un especialista importa cuando manejas datos sensibles a escala, no el día uno.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿El software hecho con vibe coding es inseguro por naturaleza?", "acceptedAnswer": { "@type": "Answer", "text": "No. Está sin revisar, que es distinto. El mismo agente escribe código seguro cuando la seguridad es parte del contrato y código con fugas cuando el único requisito es que arranque. El riesgo viene de saltarse la revisión, no del modelo." } },
    { "@type": "Question", "name": "¿Qué es lo más importante que comprobar primero?", "acceptedAnswer": { "@type": "Answer", "text": "Los secretos. Asegúrate de que ninguna API key ni credencial vive en tu código o en el historial de git, porque ese agujero es el más fácil de explotar y el más fácil de cerrar. Luego pasa a la validación de entrada y a las dependencias." } },
    { "@type": "Question", "name": "¿Necesito un experto en seguridad para arreglar esto?", "acceptedAnswer": { "@type": "Answer", "text": "Para la mayoría de apps de vibe coding, no. Sacar los secretos del código, validar la entrada en la frontera con una guía establecida y escanear las dependencias cierra los agujeros comunes. Un especialista importa cuando manejas datos sensibles a escala." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[El código que escribió un agente y nadie revisó filtra por sitios predecibles: secretos en el repo, entrada sin validar y dependencias sin auditar. Aquí está el mecanismo y cómo cerrar cada agujero.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="seguridad"/><category term="ai-coding"/><category term="validacion-de-entrada"/><category term="dependencias"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Revisar la spec antes de que el agente construya: la review más barata</title>
    <link href="https://paelladoc.com/es/blog/revision-de-specs/" rel="alternate" type="text/html" title="Revisar la spec antes de que el agente construya: la review más barata"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/revision-de-specs/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/revision-de-specs/"><![CDATA[<p><strong>Cuando ya estás revisando el diff, la discusión es cara.</strong> El agente construyó la feature. Hay cuatrocientas líneas repartidas en nueve archivos, los tests están en verde y ahora te das cuenta de que todo dio por hecho que los cupones se acumulan cuando la regla es que no lo hacen nunca. Arreglarlo significa deshacer trabajo que ya existe, volver a correr el agente y revisarlo todo otra vez.</p>
<p>Podrías haberlo atrapado en la spec, antes de escribir una sola línea, en el tiempo que se tarda en leer una página. Revisar la spec en lugar de solo el diff es la review de mayor palanca que hay en el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a>, y casi nadie la hace, porque el hábito de la revisión de software está atado al código.</p>
<h2 id="el-coste-de-un-error-sube-con-cada-paso">El coste de un error sube con cada paso</h2>
<p>Un malentendido es más barato de arreglar en el momento en que todavía es solo una frase. En la spec, una suposición equivocada es una línea que tachas y reescribes. Después de que el agente construya, esa misma suposición equivocada está repartida por la implementación, por los tests que ahora la codifican y por cualquier código que ya dependa de ella. El error no empeoró. Se volvió más caro de quitar, porque creció una estructura a su alrededor.</p>
<p>Los agentes hacen esta curva más empinada, no más suave. Una persona que entendió a medias una spec iría más despacio, dudaría y preguntaría. Un agente no duda. Toma tu instrucción ambigua y genera con toda confianza una implementación completa, plausible y equivocada a máxima velocidad, y luego escribe tests que dejan el malentendido cerrado. Cuanto más rápido el constructor, más cuesta revisar solo al final, porque simplemente hay más error ya construido que deshacer.</p>
<p>Revisar la spec es como atrapas el error mientras todavía es una frase. Esto es lo que la hace barata. No estás discutiendo con código. Estás corrigiendo la intención antes de que la intención se haya convertido en nada.</p>
<figure class="tp-diagram tp-diagram--gate" data-diagram-type="gate" role="img" aria-label="Mueve la revisión aguas arriba: la spec pasa y el agente construye, o vuelve antes de que exista una línea."><svg viewBox="0 0 760 240" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
  <rect x="40" y="86" width="180" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="130" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">SPEC</text>
  <path d="M 226 119 L 286 119 M 280 113 L 286 119 L 280 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <path d="M 380 60 L 452 119 L 380 178 L 308 119 Z" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.8"></path>
  <text x="380" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">REVISIÓN</text>
  <path d="M 458 119 L 528 119 M 522 113 L 528 119 L 522 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <rect x="534" y="86" width="186" height="66" fill="var(--tp-verde)" fill-opacity="0.12" stroke="var(--tp-verde)" stroke-width="1.5"></rect>
  <text x="627" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-verde)">CONSTRUIR</text>
  <path d="M 380 184 L 380 214 L 226 214 M 232 208 L 226 214 L 232 220" stroke="var(--tp-terracota)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="232" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-terracota)">CORREGIR SPEC</text>
</svg><figcaption>Mueve la revisión aguas arriba: la spec pasa y el agente construye, o vuelve antes de que exista una línea.</figcaption></figure>
<h2 id="qué-busca-de-verdad-una-revisión-de-spec">Qué busca de verdad una revisión de spec</h2>
<p>Una revisión de spec no es una corrección de estilo. No estás comprobando la gramática. Estás comprobando si el contrato es el contrato correcto, y hay unos cuantos modos de fallo concretos que vale la pena cazar.</p>
<p><strong>Ambigüedad que un agente resolverá mal.</strong> Lee cada frase y pregúntate cómo podría interpretarla un constructor literal y con exceso de confianza. «Valida la entrada» ¿contra qué? «Gestiona los errores» ¿cómo? Allá donde la spec deje una decisión implícita, el agente la tomará por ti, y te encontrarás con su elección en el diff. La revisión de spec es donde cierras esos huecos mientras cerrarlos es gratis.</p>
<p><strong>Límites que faltan.</strong> ¿Qué tiene que seguir siendo cierto que la spec se olvidó de decir? Los invariantes que un agente rompe con más probabilidad son los que nadie escribió, porque el agente no puede proteger una restricción de la que nunca le hablaron. Una revisión de spec es en gran parte una caza del «y no rompas esto» no dicho.</p>
<p><strong>Criterios que no podrías comprobar de verdad.</strong> Cada criterio de aceptación debería ser uno que te imagines verificando contra un resultado real. «Funciona correctamente» no es comprobable. Este es el momento de convertir el lenguaje blando en <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación que un agente puede verificar</a>, porque un criterio que no puedes comprobar en la spec es un criterio que tampoco puedes hacer cumplir en el código.</p>
<p><strong>La cosa equivocada, bien especificada.</strong> El fallo más caro. La spec es clara, completa y describe una feature que nadie necesitaba. Ninguna revisión de diff atrapa esto, porque el código coincidirá fielmente con la spec. Solo leer la spec como una declaración de intención, y preguntarse si la intención es correcta, lo atrapa.</p>
<p>Un hábito útil es leer la spec dos veces con dos preguntas distintas. La primera pasada pregunta «¿construirá un agente la cosa equivocada a partir de esto?» y caza ambigüedad y límites que faltan. La segunda pregunta «¿es esto lo correcto que construir, siquiera?» e ignora del todo la redacción para interrogar la intención. Son lecturas de verdad distintas, y casi todo el mundo solo hace la primera, que es por lo que la spec clara-pero-equivocada pasa de largo. Todo el sentido de mover la revisión tan temprano es que ambas preguntas todavía son baratas de responder. Cambia de opinión sobre la intención aquí y cuesta reescribir una página. Cámbiala después del diff y cuesta el diff.</p>
<h2 id="es-la-válvula-de-escape-para-la-fatiga-de-review">Es la válvula de escape para la fatiga de review</h2>
<p>Hay una segunda razón para mover la revisión antes, y tiene que ver con tu propia atención. Cuando los agentes producen código más rápido de lo que nadie puede leerlo, la revisión se convierte en el cuello de botella y quien revisa se quema. Esto es la <a href="/es/blog/fatiga-de-revision/">fatiga de review</a>, y echarle más lectura de diffs no ayuda, porque los diffs siguen llegando más rápido de lo que puedes absorberlos.</p>
<p>La revisión de spec ataca el volumen aguas arriba. Una página de spec se lee en minutos y determina cientos de líneas de código. Atrapar un problema ahí significa que el diff malo no se genera nunca, no se revisa nunca y no se vuelve a revisar nunca tras el arreglo. No estás leyendo con menos cuidado. Estás leyendo el artefacto donde la lectura cuidadosa rinde más y el volumen es más pequeño.</p>
<p>También cambia para qué sirve la revisión del diff. Cuando la spec se revisó y se acordó primero, <a href="/es/blog/revisar-codigo-ajeno/">revisar el código que no escribiste</a> se convierte en una comprobación de «¿coincide esto con el contrato?» en lugar de una caza abierta por código desconocido buscando problemas que aún no has definido. Primero el alcance, el diff al final. La revisión de spec es el alcance.</p>
<p>Este reordenamiento es también lo que hace la revisión posterior soportable siquiera. Una revisión de diff sin una spec acordada detrás es una tarea infinita, porque no hay un estándar de «hecho» definido, así que sigues leyendo hasta que te quedas sin energía en vez de hasta que te quedas sin contrato. Una revisión de diff contra una spec revisada es una tarea finita con un punto de parada claro: el código satisface los criterios o no los satisface. Mover la revisión antes no solo atrapa errores más pronto. Le da a todo el proceso de revisión un suelo y un techo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Poner la revisión antes de la construcción es el workflow alrededor del cual está moldeado PaellaDoc. Un cambio empieza como una spec que puedes leer y corregir mientras todavía es barato corregirla, con su intención, sus límites y sus criterios de aceptación delante de ti antes de que el agente corra. Como esa spec revisada sigue conectada con el código y la evidencia, la revisión posterior del diff tiene algo contra lo que comprobar, y la <a href="/es/blog/spec-como-contrato/">spec que acordaste</a> es el estándar por el que se mide el resultado en lugar de un documento que nadie reabrió.</p>
<p>La review más barata que harás nunca es la que ocurre antes de que exista nada que revisar. Una página de intención, leída con cuidado, decide la forma de todo lo que el agente construya después. Sáltatela y pagarás cada malentendido a precio de diff, una y otra vez, a velocidad de agente.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿No es revisar la spec trabajo extra sobre revisar el código?</strong> No, mueve el trabajo antes y lo hace más pequeño. Una página de spec decide cientos de líneas de código. Atrapar un error en la spec significa que el diff equivocado no se genera ni se revisa nunca, así que el esfuerzo total de revisión baja.</p>
<p><strong>¿Qué busco en una revisión de spec?</strong> Ambigüedad que un agente resolverá mal, límites que la spec se olvidó de declarar, criterios de aceptación que no podrías verificar de verdad, y el caso en que la spec es clara pero describe la feature equivocada. Este último es el único sitio donde se atrapa.</p>
<p><strong>¿La revisión de spec sustituye a la revisión de código?</strong> No. Cambia para qué sirve la revisión de código. Con la spec revisada y acordada primero, la revisión del diff se convierte en una comprobación contra un contrato conocido en lugar de una búsqueda abierta de problemas sin definir en código desconocido.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="revision-de-specs"/><category term="spec-driven-development"/><category term="code-review"/><category term="ai-coding"/><category term="verificacion"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Revisar código que no escribiste: primero el alcance, el diff al final</title>
    <link href="https://paelladoc.com/es/blog/revisar-codigo-ajeno/" rel="alternate" type="text/html" title="Revisar código que no escribiste: primero el alcance, el diff al final"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/revisar-codigo-ajeno/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/revisar-codigo-ajeno/"><![CDATA[<p>Abres el pull request que produjo un agente. Cuatrocientas líneas en nueve ficheros. Haces lo que siempre has hecho con un pull request: empiezas a leer el diff, de arriba abajo, juzgando cada trozo. Cuarenta minutos después has leído casi todo, corregido algún nombre, y lo apruebas, con la vaga conciencia de que nunca confirmaste que hace lo correcto. Comprobaste que el código estaba escrito con competencia. Nunca comprobaste si debería existir con esa forma.</p>
<p>Ese hábito, el diff primero, vale para el cambio de un compañero y es un error con el de un agente. Revisar código que no escribiste, al volumen al que los agentes lo producen, pide el orden contrario. Primero el alcance. El diff al final. A veces nunca.</p>
<h2 id="por-qué-el-hábito-del-compañero-falla-aquí">Por qué el hábito del compañero falla aquí</h2>
<p>Cuando un compañero te manda un pull request, traes un montón de asunciones que hacen funcionar la lectura diff-primero. Asumes que entendió el ticket, porque estaba en la daily. Asumes que respetó la arquitectura, porque ya se ha quemado con ella antes. Asumes que el cambio está acotado a lo que hablasteis, porque una persona que toca un módulo ajeno suele decir por qué. Esas asunciones te dejan saltar directo a las líneas, porque las preguntas caras, intención y alcance, ya las responde el contexto compartido.</p>
<p>Nada de ese contexto existe con un agente. No estaba en la daily. No tiene tejido cicatricial. Refactorizará alegremente un fichero que nunca mencionaste porque le pareció más limpio, y no te lo dirá salvo que mires. Así que las preguntas que te ahorrabas con un humano, «¿es este siquiera el cambio correcto?» y «¿qué tocó que yo no pedí?», están abiertas de par en par, y son justo las que el diff responde el último y peor. El diff te muestra el código que cambió. Esconde todo lo que el cambio debía dejar en paz.</p>
<h2 id="primero-el-alcance-es-este-el-cambio-correcto-siquiera">Primero el alcance: ¿es este el cambio correcto siquiera?</h2>
<p>Antes de una sola línea, responde una pregunta. ¿Qué se suponía que hacía esto, y la forma del cambio encaja con eso? No la implementación, la forma. ¿Qué ficheros debería tocar una versión correcta de esto? ¿Cómo de grande debería ser, más o menos? ¿El diff vive donde esperabas, o se ha desparramado a sitios que no tienen nada que ver con la tarea?</p>
<p>Es una comprobación de treinta segundos y caza los errores más caros, los que ninguna cantidad de lectura de líneas encuentra, porque son errores del conjunto. Un agente al que pides añadir una feature y en su lugar reescribe una existente. Un cambio tres veces más grande de lo que la tarea justificaba, lo que casi siempre significa que hizo algo que no pediste. Un diff que toca el módulo de auth cuando la tarea iba de formato de exportación. No puedes ver «esto resolvió el problema equivocado» leyendo con cuidado la solución. La solución puede ser impecable. Lo ves sosteniendo el cambio contra la intención antes de que el código te seduzca.</p>
<p>Si el alcance está mal, para. No revises el diff. Devuélvelo. Revisar la calidad línea a línea de un cambio que no debería existir es el desperdicio de atención más puro que hay, y es donde los revisores diff-primero pierden la mayor parte del día. La versión más barata de esta review ocurre antes de que el código exista, <a href="/es/blog/revision-de-specs/">sobre la propia spec</a>.</p>
<h2 id="radio-de-impacto-qué-tocó-que-no-pediste">Radio de impacto: ¿qué tocó que no pediste?</h2>
<p>Alcance superado. Ahora, antes de las líneas, la segunda pregunta más ancha. ¿Cuál es el radio de impacto? ¿Qué comportamiento existente podría haber alterado este cambio, lo haga evidente el diff o no?</p>
<p>Es la región donde el código escrito por agentes hace daño de verdad, y es casi invisible en el diff. Un modelo escribe cada pieza para que sea localmente correcta y no tiene un sentido duradero de los invariantes que sostienen el resto del sistema. Así que cambia una función compartida para que le venga bien al nuevo llamante y desplaza en silencio el comportamiento de otros cinco viejos. El diff te muestra una edición limpia a una función. No te muestra los cinco llamantes que dependían del comportamiento viejo. Ese es el fallo de lo <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto y globalmente incoherente</a>, y leer las líneas cambiadas con más ahínco nunca lo sacará a flote, porque el daño está en las líneas que no cambiaron.</p>
<p>El radio de impacto no se lee, se prueba. Los tests de integración sobre el área tocada, el chequeo de tipos entre los llamantes, la suite que ejercita los módulos aguas abajo de la edición. Esta es la parte de la review que no escala por ojos humanos en absoluto, e intentarla a ojo es como los cambios grandes de agente cuelan regresiones ante revisores cuidadosos. El trabajo del revisor aquí no es rastrear cada llamante a mano. Es confirmar que <a href="/es/blog/bucles-de-verificacion/">algo mecánico lo hizo</a>, y mirar donde la máquina dice que cambió algo que no debía.</p>
<h2 id="el-diff-al-final-y-solo-las-partes-que-cargan-riesgo">El diff al final: y solo las partes que cargan riesgo</h2>
<p>Ahora, y solo ahora, las líneas. Y aun aquí, no todas por igual. Con la review humana lees el diff entero en parte para mantener vivo el entendimiento compartido en el equipo. Con código de agente esa función social desapareció, y leer las cuatrocientas líneas con igual atención no es diligencia, es una forma de <a href="/es/blog/fatiga-de-revision/">agotarte hasta perderte las diez que importan</a>.</p>
<p>Gasta la atención donde un defecto sea a la vez probable y caro. El código de frontera, donde el cambio se encuentra con el mundo exterior o con el resto del sistema. La superficie relevante para seguridad, el manejo de entrada, la auth, cualquier cosa que toque datos que salen de la máquina, el tipo de cosa que el <a href="https://owasp.org/www-project-top-ten/">OWASP Top Ten</a> existe para recordarte que un agente hará sutilmente mal mientras parece del todo razonable. Las partes que a la especificación de verdad le importaban. Ojea el boilerplate que el agente generó, porque es boilerplate y los tests lo cubren, y vuelca tu lectura en el puñado de sitios donde ser localmente plausible y ser correcto se separan.</p>
<h2 id="el-orden-es-la-técnica-entera">El orden es la técnica entera</h2>
<p>De lo ancho a lo estrecho. ¿Es este el cambio correcto?, luego ¿qué más tocó?, luego ¿son correctas estas líneas concretas? Cada etapa puede parar la review, y las tempranas son baratas y cazan las cosas caras. El diff-primero invierte esto. Gasta tu recurso más caro y menos escalable, la lectura cuidadosa de líneas, primero y por igual, sobre un cambio que aún no has confirmado que sea el correcto tocando lo correcto. Al volumen de un agente esa inversión es fatal. El código llega más rápido de lo que puedes leerlo, y si leerlo es tu primer movimiento, te quedas atrás el primer día y empiezas a aprobar cosas que ojeaste.</p>
<p>Revisar código que no escribiste es uno de los movimientos centrales de <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado por IA</a>, y la disciplina está entera en el orden. Comprobaciones anchas y baratas por delante, lectura estrecha y cara al final, y disposición a rechazar en cualquier etapa sin descender a las líneas. Así revisas más código del que jamás podrías leer, y aun así sabes qué aprobaste.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La review que empieza por el alcance necesita algo contra lo que comprobar el alcance. Si el único registro de qué se suponía que hacía el cambio es un ticket de una línea y un chat que se fue, «¿es este el cambio correcto?» es una pregunta que en realidad no puedes responder, así que caes por defecto en leer el diff. PaellaDoc guarda la intención, los criterios de aceptación y la superficie afectada como artefactos junto al código, para que las preguntas anchas tengan una referencia fija, y el radio de impacto lo comprueban tests que corren sobre el cambio en vez de rastrearse a ojo. Tu review empieza donde debe, en el alcance, y tu tiempo de lectura aterriza en las pocas líneas que cargan riesgo real en lugar de en las cuatrocientas que no.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cómo-reviso-código-que-escribió-un-agente">¿Cómo reviso código que escribió un agente?</h3>
<p>En el orden contrario al pull request de un compañero: la pregunta más ancha primero. Confirma el alcance, si es siquiera el cambio correcto en los sitios correctos. Luego el radio de impacto, qué comportamiento existente pudo alterar, comprobado por tests y no a ojo. Luego, y solo entonces, lee las líneas, y solo las que cargan riesgo. Cada etapa puede parar la review, y las tempranas y baratas cazan los errores caros que la lectura de líneas nunca encuentra.</p>
<h3 id="por-qué-revisar-código-de-ia-no-funciona-como-revisar-el-pr-de-un-compañero">¿Por qué revisar código de IA no funciona como revisar el PR de un compañero?</h3>
<p>Porque las asunciones que hacen funcionar la lectura diff-primero desaparecieron. Un compañero estuvo en la daily, respeta la arquitectura y menciona por qué tocó un módulo ajeno, así que la intención y el alcance ya los responde el contexto compartido. Un agente no tiene nada de eso. Refactorizará un fichero que nunca mencionaste y no te lo dirá. Las preguntas que te ahorras con un humano, «¿es este el cambio correcto?» y «¿qué tocó?», están abiertas de par en par, y el diff las responde el último y peor.</p>
<h3 id="qué-debo-comprobar-antes-de-leer-el-diff">¿Qué debo comprobar antes de leer el diff?</h3>
<p>El alcance, en unos treinta segundos. ¿Qué se suponía que hacía esto, y la forma del cambio encaja? ¿Qué ficheros debería tocar una versión correcta, cómo de grande debería ser, se ha desparramado a sitios ajenos? Esto caza errores del conjunto, un agente que reescribió una feature en vez de añadir una, un diff que toca auth cuando la tarea iba de formato de exportación. Si el alcance está mal, para y devuélvelo. Revisar la calidad de un cambio que no debería existir es atención pura desperdiciada.</p>
<h3 id="tengo-que-leer-cada-línea-del-pull-request-de-un-agente">¿Tengo que leer cada línea del pull request de un agente?</h3>
<p>No. Leer las cuatrocientas líneas con igual atención no es diligencia, es como te agotas hasta perderte las diez que importan. Gasta la atención donde un defecto sea a la vez probable y caro: el código de frontera, la superficie relevante para seguridad, el manejo de entrada, la auth, cualquier cosa que toque datos que salen de la máquina, y las partes que a la especificación de verdad le importaban. Ojea el boilerplate que los tests ya cubren, y vuelca tu lectura donde lo localmente plausible y lo realmente correcto se separan.</p>]]></content>
    <summary type="html"><![CDATA[Revisar código que escribió un agente es un trabajo distinto de revisar el pull request de un compañero, y usar el mismo hábito para ambos es por lo que sale mal. Con un compañero puedes asumir intención y contexto compartido, así que saltar al diff funciona. Con un agente no hay contexto compartido ni intención que asumir, y el diff es el último sitio donde asoman los problemas reales. Los problemas están en el alcance, en el radio de impacto, en lo que el cambio tocó en silencio. Revisa en ese orden, de lo ancho a lo estrecho, o el volumen te entierra y apruebas cosas que nunca comprobaste.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="reviewing-unwritten"/><category term="ai-coding"/><category term="verification"/><category term="code-review"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Research de usuarios con IA sin blanquear la evidencia</title>
    <link href="https://paelladoc.com/es/blog/research-de-usuarios-con-ia/" rel="alternate" type="text/html" title="Research de usuarios con IA sin blanquear la evidencia"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/research-de-usuarios-con-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/research-de-usuarios-con-ia/"><![CDATA[<p>Un modelo puede leer cuarenta entrevistas de usuario y devolverte seis temas limpios en un minuto. Los temas están articulados. Están bien organizados. Suenan a insight. Y esta es la pregunta que decide si valen algo: ¿puedes pinchar en un tema y ver las frases reales, de usuarios reales, que lo produjeron? Si puedes, el modelo hizo trabajo real. Si no puedes, el modelo te escribió un ensayo plausible sobre tus usuarios y estás a punto de tomar decisiones sobre él como si fuera evidencia.</p>
<p>Ese hueco es todo el asunto. La IA en research de usuarios es de verdad útil y de verdad peligrosa, y la versión útil y la peligrosa se ven casi idénticas en la diapositiva. Distinguirlas es la habilidad que importa ahora.</p>
<h2 id="síntesis-y-sustitución-no-están-en-un-espectro">Síntesis y sustitución no están en un espectro</h2>
<p>Son actos distintos, y confundirlos es el error de raíz.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="La síntesis comprime evidencia que reuniste de verdad; la sustitución inventa evidencia que ningún usuario te dio. La misma diapositiva, valor opuesto."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">síntesis</p>
    <ul><li>Comprime evidencia real</li><li>Temas enlazados a citas</li><li>Amplifica lo que existe</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">sustitución</p>
    <ul><li>Fabrica evidencia</li><li>Sin fuente real</li><li>Conjetura como hallazgo</li></ul>
  </div>
</div><figcaption>La síntesis comprime evidencia que reuniste de verdad; la sustitución inventa evidencia que ningún usuario te dio. La misma diapositiva, valor opuesto.</figcaption></figure>
<p>La síntesis coge evidencia que reuniste de verdad y la comprime. Hablaste con personas reales, tienes las transcripciones, y el modelo te ayuda a encontrar los patrones a lo largo de más material del que podrías sostener en la cabeza a la vez. La evidencia existía antes de que el modelo la tocara. El modelo la hizo legible. Esto es una ganancia real, y es la razón para usar IA en research: el cuello de botella de la síntesis nunca fue el insight, fueron las horas de lectura, y eso es justo lo que un modelo quita.</p>
<p>La sustitución fabrica evidencia que nunca se reunió. No hablaste con nadie, así que le pides al modelo que haga de usuario, genere la persona, simule qué diría «alguien así». Lo que vuelve es fluido y seguro y completamente desatado de cualquier persona real. Es <a href="/es/blog/discovery-con-ia/">el prejuicio del modelo sobre los usuarios, disfrazado de datos</a>. Por bueno que sea el modelo, no puede reportar un hecho sobre tus usuarios que ningún usuario aportó, porque ese hecho no existe en nada que haya leído. Solo puede producir una conjetura bien formada.</p>
<p>No son dos puntos de un espectro donde un poco de sustitución es un poco arriesgado. Son distintos en naturaleza. Uno amplifica evidencia. El otro la fabrica. Todo fallo serio del research asistido por IA viene de hacer lo segundo llamándolo lo primero.</p>
<h2 id="el-blanqueo-de-evidencia">El blanqueo de evidencia</h2>
<p>Así entra de verdad la fabricación en un equipo real, porque nadie se propone inventarse cosas. Se blanquea a través de pasos que cada uno parece razonable.</p>
<p>Un investigador corre ocho entrevistas reales, que es una muestra pequeña, así que le pide al modelo que «extrapole lo que probablemente sienten otros usuarios». El modelo obedece. Ahora la presentación tiene afirmaciones respaldadas por ocho personas y afirmaciones respaldadas por nadie, formateadas igual. Una semana después alguien saca un bullet de la presentación a un doc de estrategia. El bullet ya no lleva ninguna marca de dónde salió. Otra semana, es una línea en una decisión: «los usuarios quieren esto». Nadie mintió. Pero una afirmación que el modelo inventó está ahora en una decisión con exactamente la misma autoridad que una afirmación que ocho humanos hicieron de verdad, y ya nadie las distingue.</p>
<p>Eso es blanqueo de evidencia: el proceso por el que la conjetura de un modelo pierde su fuente y adquiere la credibilidad de un hallazgo según se mueve por tus documentos. Es la forma concreta que toma el <a href="/es/blog/slop-de-ia-en-producto/">modo de fallo del slop de IA</a> en research, donde una salida fluida y bien formateada se confunde con una validada porque nada en el formato anuncia la diferencia. El blanqueo no es una gran mentira. Es el lento desprendimiento de una afirmación de su origen, una copia de aspecto razonable cada vez.</p>
<h2 id="la-regla-cada-afirmación-apunta-a-una-frase">La regla: cada afirmación apunta a una frase</h2>
<p>La disciplina que previene todo esto es una frase. Un hallazgo de research solo es tan fuerte como la frase cruda a la que puedas rastrearlo.</p>
<p>En la práctica eso significa que los temas sintetizados siguen enlazados a las citas de origen, para siempre, no solo en el primer borrador. Cuando un hallazgo dice «los usuarios abandonan en el onboarding porque no confían en la importación», puedes expandirlo y ver a las cuatro personas que dijeron algo en ese sentido, con sus palabras. Un hallazgo que no puedes expandir en citas reales es un hallazgo que deberías tratar como hipótesis, no como evidencia, por muy seguro que suene el resumen.</p>
<p>Esto también arregla el problema de la muestra pequeña sin maquillarlo. Ocho entrevistas son ocho entrevistas. El movimiento no es que el modelo las infle en un centenar falso. Es decir con claridad «cuatro de ocho usuarios chocaron con esto», mantenerlo enlazado a esos cuatro, y tratarlo como una señal que merece una prueba más grande, no como un hecho zanjado. El modelo te ayuda a ver el patrón en los ocho. No le toca inventar los noventa y dos con los que nunca hablaste. Nombrar la muestra tal cual no es una debilidad del research. Es la diferencia entre research y una historia persuasiva.</p>
<h2 id="qué-le-está-permitido-hacer-al-modelo-con-precisión">Qué le está permitido hacer al modelo, con precisión</h2>
<p>Ayuda ser concreto sobre el límite, porque «usa la IA con cuidado» no significa nada. Al modelo le está permitido comprimir, agrupar y sacar a la superficie: juntar frases parecidas, proponer temas candidatos, señalar una cita que se te pasó, redactar el resumen que vas a cotejar contra las fuentes. Todo eso opera sobre evidencia que existe y sigue apuntando a ella.</p>
<p>Al modelo no le está permitido originar una afirmación sobre usuarios de la nada: ninguna entrevista simulada haciendo de una real, ninguna persona respondiendo preguntas que ningún humano respondió, ninguna extrapolación presentada como hallazgo en vez de como conjetura. La prueba es siempre la misma. Señala a la persona que dijo esto. Si puedes, es research. Si la única fuente es el modelo, es la opinión del modelo sobre tus usuarios, y va en la columna de hipótesis con una nota de ir a averiguarlo, no en la <a href="/es/blog/decisiones-con-evidencia/">columna de evidencia dirigiendo una decisión</a>.</p>
<p>Este es el mismo estándar que atraviesa todo lo que construyo, la misma razón por la que el <a href="/es/blog/product-management-era-ia/">trabajo de product management en la era IA</a> se desplazó de producir artefactos a diseñar el sistema que separa lo que se sabe de lo que se asume. El research es donde esa separación es más fácil de perder, porque un tema fluido se siente como conocimiento aunque no haya nada real debajo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/es/">PaellaDoc</a> mantiene intacto el enlace entre un hallazgo y su evidencia según el research pasa a decisiones. Un tema sintetizado sigue conectado a las frases que lo produjeron, y una decisión que cita el tema puede rastrearse a través de él hasta los usuarios reales que dijeron la cosa, para que una afirmación no pueda desprenderse en silencio de su fuente según viaja por la memoria de tu producto. El objetivo no es frenar el research. Es hacer el blanqueo estructuralmente difícil, para que el resumen seguro y el hallazgo validado dejen de ser intercambiables.</p>
<p>La IA quitó el tedio del research, que es un regalo real, y lo quitó quitando la fricción que antes mantenía separadas las conjeturas y los hallazgos. Conseguir el regalo sin la falsificación significa sostener una línea sin excepción: ninguna afirmación sobre tus usuarios que no puedas rastrear hasta un usuario.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="la-ia-puede-hacer-research-de-usuarios">¿La IA puede hacer research de usuarios?</h3>
<p>Puede sintetizar research que reuniste de verdad, no reemplazar el reunirlo. Un modelo lee cuarenta entrevistas y devuelve seis temas limpios en un minuto, y eso es una ganancia real porque el cuello de botella de la síntesis eran las horas de lectura, no el insight. Lo que no puede es originar un hecho sobre tus usuarios que ningún usuario aportó. Ese hecho no existe en nada que haya leído, así que solo puede producir una conjetura bien formada.</p>
<h3 id="cuál-es-la-diferencia-entre-síntesis-y-sustitución">¿Cuál es la diferencia entre síntesis y sustitución?</h3>
<p>La síntesis comprime evidencia que existía antes de que el modelo la tocara: personas reales, transcripciones reales, patrones hechos legibles. La sustitución fabrica evidencia que nunca se reunió: una persona simulada respondiendo preguntas que ningún humano respondió. Son distintas en naturaleza, no dos puntos de un espectro. Una amplifica evidencia, la otra la fabrica, y todo fallo serio del research asistido por IA es hacer lo segundo llamándolo lo primero.</p>
<h3 id="qué-es-el-blanqueo-de-evidencia-en-research">¿Qué es el blanqueo de evidencia en research?</h3>
<p>Es el proceso por el que la conjetura de un modelo pierde su fuente y adquiere la credibilidad de un hallazgo según se mueve por tus documentos. Un modelo extrapola más allá de ocho entrevistas reales, la presentación formatea las afirmaciones inventadas igual que las reales, un bullet pasa a un doc de estrategia sin su fuente, y una semana después es una decisión. Nadie mintió, pero una conjetura carga ahora con la autoridad de ocho humanos.</p>
<h3 id="puedo-usar-ia-para-generar-usuarios-sintéticos-o-personas">¿Puedo usar IA para generar usuarios sintéticos o personas?</h3>
<p>No como evidencia. Una persona respondiendo preguntas que ningún humano respondió es el prejuicio del modelo sobre los usuarios disfrazado de datos, y va en la columna de hipótesis con una nota de ir a averiguarlo, no en la de evidencia dirigiendo una decisión. La regla es una frase: cada afirmación apunta a una frase de un usuario. Si puedes nombrar a la persona real que lo dijo, es research; si la única fuente es el modelo, es opinión.</p>]]></content>
    <summary type="html"><![CDATA[Hay una versión real y útil de la IA en research de usuarios y una falsificación peligrosa que se le parece casi idéntica. La versión útil comprime evidencia real: cuarenta entrevistas en temas, cada tema apuntando todavía a las citas de debajo. La falsificación fabrica evidencia: usuarios sintéticos, personas simuladas, un tema seguro sin nada real debajo. La señal es la trazabilidad. Si no puedes recorrer un hallazgo hasta algo que una persona real dijo de verdad, no estás haciendo research, estás blanqueando los prejuicios del modelo en una diapositiva.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="product-management"/><category term="user-research"/><category term="ai-coding"/><category term="discovery"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">Tu fichero de reglas miente a tus agentes: mantener las instrucciones vivas</title>
    <link href="https://paelladoc.com/es/blog/reglas-de-agentes-vivas/" rel="alternate" type="text/html" title="Tu fichero de reglas miente a tus agentes: mantener las instrucciones vivas"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/reglas-de-agentes-vivas/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/reglas-de-agentes-vivas/"><![CDATA[<p>El mes pasado me pasé cuarenta minutos depurando por qué un agente insistía en meter los endpoints nuevos en una carpeta que abandonamos hace dos refactors. El código estaba bien. Los tests estaban bien. El agente hacía justo lo que le mandaban, porque la instrucción seguía ahí en el fichero de reglas, y el fichero de reglas estaba mal.</p>
<p>Eso es lo que nadie te avisa. Una regla obsoleta no da error. Una dependencia borrada da error. Una función renombrada da error. Pero una línea en <code>CLAUDE.md</code> que dice “registra siempre los handlers en <code>routes/legacy.js</code>” funciona perfectamente hasta el momento en que produce un resultado seguro, bien formado y completamente equivocado. El agente se fía del fichero. Tú escribiste el fichero. Así que te fías del output. Así se propaga una mentira con una marca verde.</p>
<h2 id="por-qué-las-reglas-se-pudren-más-rápido-de-lo-que-crees">Por qué las reglas se pudren más rápido de lo que crees</h2>
<p>Hay una frase vieja, la invalidación de caché y nombrar cosas, que Martin Fowler recoge entre <a href="https://martinfowler.com/bliki/TwoHardThings.html">las dos cosas difíciles de la informática</a>. Un fichero de reglas es una caché. Es una foto cacheada de cómo funcionaba tu repo el día en que escribiste cada línea, y como toda caché, no tiene ni idea de cuándo cambió lo que hay debajo.</p>
<p>El código tiene una función forzadora que lo mantiene al día: se ejecuta, y si está mal, peta. El fichero de reglas no tiene ninguna. Nadie ejecuta <code>CLAUDE.md</code>. Ningún test falla cuando una regla deja de ser verdad. Deriva en silencio mientras estás ocupado entregando, y cada agente que lo lee hereda la deriva con plena confianza. Cuanto mejor siguen tus agentes las instrucciones, más daño hace una instrucción equivocada, porque no la van a cuestionar.</p>
<p>Y estos ficheros se pudren más rápido de lo que jamás se pudrió la documentación, por una razón simple: los agentes mueven el código más rápido de lo que tú actualizas la prosa sobre él. Fusionas seis cambios escritos por agentes en una mañana. Actualizas el fichero de reglas una vez por semana como mucho. El hueco entre lo que hace el repo y lo que afirma el fichero se ensancha cada día que no lo miras.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="El código peta cuando está mal, así que se mantiene veraz; nada ejecuta el fichero de reglas, así que miente en silencio."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">el código</p>
    <ul><li>se ejecuta</li><li>peta cuando está mal</li><li>se mantiene veraz</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">el fichero de reglas</p>
    <ul><li>nunca se ejecuta</li><li>sin error cuando está mal</li><li>deriva en silencio</li></ul>
  </div>
</div><figcaption>El código peta cuando está mal, así que se mantiene veraz; nada ejecuta el fichero de reglas, así que miente en silencio.</figcaption></figure>
<h2 id="las-tres-formas-en-que-una-regla-se-vuelve-mentira">Las tres formas en que una regla se vuelve mentira</h2>
<p>No todas las reglas obsoletas son iguales, y necesitan detección distinta.</p>
<p><strong>La referencia colgante.</strong> La regla apunta a un fichero, carpeta, script o comando que ya no existe o que renombraste. “Corre <code>./scripts/deploy.sh</code>” después de pasarte a un Makefile. Estas son las fáciles, porque son comprobables de forma mecánica. Si una regla nombra una ruta, la ruta debería resolver.</p>
<p><strong>La convención abandonada.</strong> La regla describe cómo hacías algo antes. “Usamos componentes de clase.” “El estado va en Redux.” Sigue siendo gramaticalmente válida, sigue obedeciéndola el agente dócil, y está completamente a contramano de los últimos treinta merges. Estas son las peligrosas, porque nada en la regla parece roto. Solo el código la contradice.</p>
<p><strong>La decisión que se revirtió.</strong> La más fea. “Nunca añadas un índice de base de datos sin revisión” tenía sentido cuando una persona era dueña del esquema. Ahora es un cuello de botella, y el equipo dejó de aplicarlo en silencio, pero nadie borró la línea. El agente aplica una política que los humanos ya abandonaron. Esta es la razón por la que las decisiones no deberían vivir en ficheros de reglas, que es el argumento de <a href="/es/blog/agents-md-claude-md-reglas/">dónde deberían vivir tus decisiones</a>.</p>
<h2 id="cómo-detectar-la-deriva-antes-de-que-te-cueste">Cómo detectar la deriva antes de que te cueste</h2>
<p>No puedes corregir un fichero de reglas a ojo. Necesitas comprobaciones baratas y repetibles.</p>
<p>Empieza por la capa mecánica. Toda ruta, nombre de fichero y comando del fichero debería resolver contra el repo actual. Esto es un script que puedes correr en CI: haz grep en el fichero de reglas de cualquier cosa que parezca una ruta o un comando, y falla el build si no existe. Pilla toda la clase de referencias colgantes por casi nada de esfuerzo, y convierte “el fichero de reglas está mal” de una sorpresa de depuración en una pipeline en rojo.</p>
<p>Para las convenciones, la comprobación es distinta: usa a los propios agentes. De vez en cuando, dale a un agente el fichero de reglas y el código actual y hazle una pregunta estrecha. “¿Cuál de estas instrucciones contradice el código de verdad?” No “mejora mis reglas”, que produce slop, sino una auditoría concreta contra evidencia. El agente leyendo en fresco pillará la regla de componentes de clase contra un código lleno de hooks más rápido que tú, porque tú dejaste de ver esa línea hace meses. Esto es verificación apuntada a las instrucciones en vez de al output, y pertenece a la misma familia que todo lo de <a href="/es/research/context-engineering-para-agentes-de-codigo/">context engineering para agentes de código</a>: el fichero que lee el agente es contexto, y un contexto que miente es peor que un contexto que falta.</p>
<p>Para las decisiones revertidas, ningún script ayuda, porque el código y la regla pueden ser los dos internamente coherentes mientras el <em>motivo</em> está muerto. La única detección real es la procedencia: una regla que no puedes rastrear hasta una decisión con fecha y motivo es una regla en la que no puedes confiar. Si no sabes por qué está ahí una línea, no puedes saber si debería seguir estando.</p>
<h2 id="mantenerlas-vivas-sin-un-segundo-trabajo">Mantenerlas vivas sin un segundo trabajo</h2>
<p>El objetivo no es un fichero de reglas perfecto. Es un fichero de reglas que falle a gritos en vez de mentir en silencio. Unos pocos hábitos te llevan casi todo el camino:</p>
<ul>
<li><strong>Pon fecha a las reglas que sostienen el edificio.</strong> Un motivo de una línea y una fecha al lado de una restricción real. Cuando alguien la encuentre después, distinguirá una decisión viva de un fósil.</li>
<li><strong>Mete la comprobación mecánica en la pipeline.</strong> Las rutas rotas y los comandos muertos deberían fallar en CI, no aparecer a las 2 de la mañana cuando un agente los sigue contra un muro. Ese modo de fallo conecta directo con <a href="/es/blog/recuperar-ejecuciones-fallidas/">la recuperación como flujo de primera clase</a>, porque una regla obsoleta es una de las formas más silenciosas en que un run largo se sale del carril.</li>
<li><strong>Poda con calendario.</strong> Los ficheros de reglas solo crecen si les dejas. Cada regla que borras es una cosa menos que un agente puede aplicar mal.</li>
<li><strong>Deja las decisiones fuera.</strong> Los hechos operativos van aquí. Las decisiones de producto van en <a href="/es/blog/memoria-agentes-de-codigo/">un artefacto que persiste fuera del chat</a> y carga su motivo. Una convención que deriva es molesta. Una decisión que deriva es una reescritura.</li>
</ul>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Un fichero de reglas se pudre porque nada lo obliga a seguir siendo verdad, y la cosa que lo lee no lo distingue. Ese es el mismo fallo que <a href="/es/blog/documentacion-viva/">la documentación pudriéndose</a>, y el arreglo es el mismo: instrucciones que viven cerca del código que gobiernan y se vuelven a derivar de la evidencia en vez de teclearse una vez y creerse para siempre, la idea detrás de <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">el cerebro de producto que se mantiene solo</a>. PaellaDoc guarda el contrato operativo y las decisiones de producto como artefactos comprobados, no texto libre que un agente lee por fe, así que una regla que deja de coincidir con la realidad aparece como un gate fallido y no como una respuesta segura y equivocada. Porque la persona que sostiene todo esto en la cabeza es <a href="/es/blog/eres-el-runtime/">el runtime</a> hasta que otra cosa hace la comprobación.</p>
<h2 id="faq">FAQ</h2>
<h3 id="cada-cuánto-debería-actualizar-claudemd-o-agentsmd">¿Cada cuánto debería actualizar CLAUDE.md o AGENTS.md?</h3>
<p>Continuamente para las partes mecánicas y con calendario para el resto. Monta una comprobación que falle tu build cuando una ruta o comando del fichero ya no resuelva, para que las referencias colgantes se pillen el día que aparecen. Luego haz una auditoría deliberada de las convenciones cada pocas semanas, idealmente haciendo que un agente compare las reglas contra el código actual.</p>
<h3 id="cómo-sé-si-una-regla-está-desactualizada">¿Cómo sé si una regla está desactualizada?</h3>
<p>Tres señales: referencia una ruta o comando que ya no existe, describe una convención que los commits recientes contradicen, o no sabes decir por qué está ahí. La primera es scriptable, la segunda la puede auditar un agente contra el código, y la tercera significa que la regla no tiene procedencia y no debería creerse hasta que la tenga.</p>
<h3 id="no-debería-dejar-que-el-agente-mantenga-su-propio-fichero-de-reglas">¿No debería dejar que el agente mantenga su propio fichero de reglas?</h3>
<p>Usa al agente para detectar la deriva, no para reescribir el fichero sin supervisión. “¿Qué instrucciones contradice el código?” es una buena pregunta con respuesta comprobable. “Reescribe mis reglas para que sean mejores” produce slop plausible. Deja que el humano decida qué se queda; deja que el agente haga la búsqueda.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="claude-md"/><category term="agents-md"/><category term="reglas-obsoletas"/><category term="agentes"/><category term="runtime"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Decision logs: el fin del «yo nunca acordé eso»</title>
    <link href="https://paelladoc.com/es/blog/registro-de-decisiones/" rel="alternate" type="text/html" title="Decision logs: el fin del «yo nunca acordé eso»"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/registro-de-decisiones/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/registro-de-decisiones/"><![CDATA[<p>Dos personas del mismo equipo recuerdan la misma reunión de forma distinta. Una dice que el tramo de precios quedó decidido. La otra dice que se planteó y nunca se cerró. Las dos están seguras. Las dos, a su manera, dicen la verdad, porque lo que pasó en esa sala fue una conversación, y una conversación no es un registro. Una semana después la feature sale bajo una interpretación y la otra persona suelta la frase que le cuesta a los equipos de producto más tiempo que cualquier bug: «yo nunca acordé eso».</p>
<p>De ahí no sales discutiendo. No hay artefacto que señalar. Así que el equipo vuelve a litigar una pregunta que ya había respondido, y esta vez la respuesta la moldea quien esté más cansado, sea más senior o esté más recientemente molesto. Multiplica eso por cada elección no trivial que hace un producto y tienes un equipo que gasta un tercio de su energía en re-decidir cosas en vez de decidir nuevas.</p>
<figure class="tp-diagram tp-diagram--drift" data-diagram-type="drift" role="img" aria-label="Sin nada registrado, una conversación se parte en dos recuerdos seguros, y el equipo vuelve a litigar una pregunta que ya había respondido."><svg viewBox="0 0 760 240" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
  <text x="40" y="40" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mute)">LA REUNIÓN</text>
  <path d="M 40 120 C 240 120 340 84 720 56" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.8"></path>
  <path d="M 40 120 C 240 120 340 158 720 190" fill="none" stroke="var(--tp-ink)" stroke-width="1.8"></path>
  <circle cx="40" cy="120" r="5" fill="var(--tp-ink)"></circle>
  <text x="716" y="42" text-anchor="end" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">VERSIÓN A</text>
  <text x="716" y="214" text-anchor="end" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">VERSIÓN B</text>
  <line x1="676" y1="66" x2="676" y2="180" stroke="var(--tp-terracota)" stroke-width="1.2" stroke-dasharray="3 5"></line>
  <text x="662" y="128" text-anchor="end" font-family="var(--tp-mono)" font-size="11" letter-spacing="2" fill="var(--tp-terracota)">LA DISPUTA</text>
</svg><figcaption>Sin nada registrado, una conversación se parte en dos recuerdos seguros, y el equipo vuelve a litigar una pregunta que ya había respondido.</figcaption></figure>
<h2 id="el-problema-es-de-registro-no-de-memoria">El problema es de registro, no de memoria</h2>
<p>Es tentador tratarlo como que la gente es olvidadiza o política. Casi nunca es ninguna de las dos. Una decisión es un momento. Ocurre en un hilo de Slack, un pasillo, una llamada, un comentario sobre un mockup. Es real cuando se toma y luego se disuelve en el recuerdo ligeramente distinto de cada uno. Nada la capturó, así que no hay nada con lo que discrepar, solo entre vosotros.</p>
<p>Esto empeora en cuanto entran los agentes en el bucle, y es el núcleo de lo que cambió en el <a href="/es/blog/product-management-era-ia/">product management en la era IA</a>. Cuando construir era lento, una decisión difusa tenía días de fricción de ingeniería por delante, y esa fricción era, sin querer, una revisión. Alguien preguntaba «espera, ¿decidimos esto?» antes de que costara mucho. Ahora un agente convierte una decisión difusa en código funcionando en una tarde. La fricción desapareció. La elección a medio recordar se vuelve una feature publicada antes de que nadie se pare a comprobar si de verdad se acordó. La velocidad no crea el problema del «yo nunca acordé eso». Elimina el retraso que antes lo cazaba.</p>
<h2 id="qué-registra-de-verdad-un-registro-de-decisiones">Qué registra de verdad un registro de decisiones</h2>
<p>Un registro de decisiones no es un acta de reunión ni un parte de estado. El acta recoge qué se dijo. El registro recoge qué se decidió, y lo justo alrededor para que la decisión se pueda entender y, si hace falta, reabrir con fundamento. Por cada entrada, cuatro cosas:</p>
<ul>
<li><strong>La decisión en sí</strong>, formulada como una afirmación con la que podrías discrepar. No «hablamos de precios» sino «lanzamos con tres tramos, no con facturación por uso».</li>
<li><strong>El contexto que la forzó</strong>, en una o dos frases. Qué era cierto cuando decidiste. Esto es lo que permite a un lector futuro juzgar si la decisión sigue en pie o si el terreno se movió.</li>
<li><strong>Las alternativas que perdieron</strong>, nombradas. El objetivo no es la exhaustividad. Es que «facturación por uso» aparezca como considerada-y-descartada para que nadie la reabra en tres semanas como si fuera una idea nueva.</li>
<li><strong>Quién la posee</strong>, para que haya una persona a la que preguntar, no un comité que reconvocar.</li>
</ul>
<p>Esa es toda la disciplina. Fíjate en lo que falta: un documento largo de justificación, una plantilla con quince campos, un flujo de aprobación. Un registro que cueste más de un par de minutos por entrada no se mantiene, y un registro que no se mantiene es peor que ninguno, porque ahora la gente se fía de él y está desactualizado.</p>
<h2 id="dónde-tiene-que-vivir">Dónde tiene que vivir</h2>
<p>La forma más habitual en que muere un registro de decisiones es la ubicación. Va a una página de wiki que nadie abre, o a un documento que está una carpeta demasiado lejos del trabajo, y en un mes es ficción. La regla que lo mantiene vivo es la proximidad: la decisión tiene que vivir donde vive el trabajo que depende de ella.</p>
<p>Una decisión sobre un contrato de API va junto a ese contrato. Una decisión sobre lo que una feature hace y deliberadamente no hace va pegada a esa feature, no en un espacio de gobernanza aparte. Cuando la decisión está a un clic de lo que gobierna, pasan dos cosas. La gente registra decisiones de verdad, porque no es un cambio de contexto. Y la gente lee las decisiones de verdad, porque ya está mirando el trabajo de alrededor cuando surge la pregunta.</p>
<p>Este es el mismo fallo que mata a casi toda la documentación, y conviene decirlo claro. Un registro desconectado del trabajo que describe se pudre, porque nada lo obliga a seguir siendo cierto y nada lo pone delante de quien notaría que está mal. Un registro de decisiones no es una excepción. Si es un documento muerto en una esquina, va a derivar de la realidad igual que <a href="/es/blog/prds-que-nadie-lee/">cada PRD desactualizado que has ignorado en tu vida</a>. El registro tiene que estar lo bastante cerca del trabajo como para que mantenerlo veraz salga más barato que dejarlo mentir.</p>
<h2 id="quién-lo-consulta-y-cuándo">Quién lo consulta, y cuándo</h2>
<p>Un registro que nadie lee es un diario. El valor aparece en cuatro momentos concretos, y conviene diseñar para ellos:</p>
<ul>
<li><strong>Cuando se reabre una pregunta cerrada.</strong> Alguien vuelve a proponer facturación por uso. En vez de un debate nuevo, abres la entrada: aquí está cuándo decidimos que no y por qué. Ahora la conversación es la correcta, que es «¿ha cambiado el contexto?» y no «¿qué habíamos decidido?».</li>
<li><strong>Cuando entra alguien nuevo.</strong> Una persona nueva no absorbe meses de decisiones por ósmosis ni interrumpiendo a todo el mundo. Lee el registro y hereda el razonamiento, no solo el resultado.</li>
<li><strong>Cuando algo se rompe y hay que saber si fue a propósito.</strong> La mitad de las preguntas de «¿por qué está construido así?» se responden con «lo decidimos, este es el tradeoff». La otra mitad revelan un error real. El registro te dice cuál es cuál, rápido.</li>
<li><strong>Cuando construyen los agentes.</strong> Esta es la nueva. Un agente que trabaja desde una decisión vigente produce código que coincide con lo que el equipo eligió de verdad. Un agente que trabaja desde una decisión desactualizada o no dicha construye con seguridad justo lo que rechazaste. El registro es cómo se ve una decisión cuando es lo bastante duradera para que una máquina construya contra ella sin volver a preguntar a un humano cada vez. Es una hebra de la <a href="/es/blog/memoria-de-producto/">memoria de producto</a> que un equipo guarda fuera de la cabeza de nadie.</li>
</ul>
<h2 id="el-registro-de-decisiones-y-la-feature-factory">El registro de decisiones y la feature factory</h2>
<p>Hay una razón más profunda por la que esto importa, y conecta con cómo un equipo evita convertirse en una <a href="/es/blog/que-es-una-feature-factory/">feature factory</a>. Una feature factory produce output y nunca se pregunta si el output cambió algo, porque no tiene memoria de por qué se construyó cada cosa. Las decisiones se toman, se olvidan y se rehacen ligeramente distintas, así que el producto acumula features que ya no comparten una intención coherente.</p>
<p>Un registro de decisiones es la primera cuña contra eso. Obliga al equipo a decir qué está eligiendo y por qué, lo que significa que más tarde puedes hacer la pregunta que una factory nunca hace: <a href="/es/blog/decisiones-con-evidencia/">¿esta decisión produjo el resultado que apostamos?</a> No puedes <a href="/es/blog/de-insight-a-resultado/">conectar una decisión con su resultado</a> si nunca registraste la decisión. Mantener el registro es la condición previa para <a href="/es/blog/hacer-producto-no-es-productizar/">hacer producto como instalar un comportamiento en vez de publicar features</a>, porque el cambio de comportamiento solo se puede juzgar contra una intención que escribiste.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Este es el problema concreto que estoy construyendo <a href="/es/">PaellaDoc</a> para volver estructural en vez de heroico. Una decisión no debería depender de la memoria más fuerte de la sala. Cuando se toma una elección, se captura como algo de primera clase, junto a los artefactos y el código que gobierna, con su contexto y las alternativas que batió. Se queda conectada al trabajo, así que no se pudre hasta ser un documento en el que nadie confía, y los agentes construyen contra la decisión que de verdad sigue en pie, no contra una versión a medio recordar.</p>
<p>El problema del «yo nunca acordé eso» nunca sobrevive al contacto con un registro real. Toda la dificultad era que no había nada que señalar. Dale al equipo algo que señalar, mantenlo cerca del trabajo, y la discusión deja de ser sobre el pasado. Vuelve a ser sobre lo único que merece discutirse: qué decidir a continuación.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-un-registro-de-decisiones-decision-log">¿Qué es un registro de decisiones (decision log)?</h3>
<p>Un registro de decisiones es un registro ligero de las elecciones que toma un equipo, capturadas según ocurren. Cada entrada formula la decisión como una afirmación con la que podrías discrepar, el contexto que la forzó, las alternativas que perdieron y quién la posee. No es un acta de reunión, que recoge qué se dijo. Un registro recoge qué se decidió, lo bastante cerca del trabajo como para seguir diciendo la verdad.</p>
<h3 id="qué-se-registra-en-un-decision-log">¿Qué se registra en un decision log?</h3>
<p>Cuatro cosas por entrada, no más. La decisión en sí, formulada como una afirmación («lanzamos con tres tramos, no con facturación por uso»). El contexto que la forzó, en una o dos frases. Las alternativas que perdieron, nombradas, para que nadie las reabra como ideas nuevas. Y quién la posee, para que haya una persona a la que preguntar. Nada de justificaciones largas ni plantillas de quince campos, o el registro deja de mantenerse.</p>
<h3 id="dónde-debe-vivir-un-registro-de-decisiones">¿Dónde debe vivir un registro de decisiones?</h3>
<p>Junto al trabajo que gobierna, no en una página de wiki que nadie abre. Una decisión sobre un contrato de API va junto a ese contrato; una decisión sobre lo que una feature hace y no hace va pegada a esa feature. Cuando el registro está a un clic de lo que gobierna, la gente escribe las decisiones de verdad y las lee de verdad. La distancia es lo que mata un registro.</p>
<h3 id="en-qué-se-diferencia-de-un-acta-de-reunión">¿En qué se diferencia de un acta de reunión?</h3>
<p>El acta recoge qué se dijo; el registro recoge qué se decidió. El acta es una transcripción de una conversación, así que conserva la ambigüedad que causó el «yo nunca acordé eso» de entrada. El registro lo resuelve en una sola afirmación con su contexto y sus alternativas descartadas, lo bastante duradera para que un compañero, alguien nuevo o un agente construya contra ella sin volver a preguntar.</p>]]></content>
    <summary type="html"><![CDATA[El problema del «yo nunca acordé eso» no es un fallo de memoria, es un fallo de registro. Un registro de decisiones captura la elección, el contexto, las alternativas consideradas y quién la posee, para que el equipo deje de reabrir preguntas cerradas y los agentes construyan contra una decisión que sigue en pie.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="decision-logs"/><category term="product-management"/><category term="ai-coding"/><category term="product-memory"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">La ejecución murió a las 2 de la mañana: la recuperación como flujo de primera</title>
    <link href="https://paelladoc.com/es/blog/recuperar-ejecuciones-fallidas/" rel="alternate" type="text/html" title="La ejecución murió a las 2 de la mañana: la recuperación como flujo de primera"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/recuperar-ejecuciones-fallidas/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/recuperar-ejecuciones-fallidas/"><![CDATA[<p>Las ejecuciones largas nunca mueren a una hora cómoda. Mueren a las 2 de la mañana, tres horas dentro de una tarea, justo después de que el agente hiciera la parte interesante y justo antes de escribir nada. Vuelves a una rama a medias, un transcript que ya pasó de largo la parte útil, y una decisión con malas opciones: leer tres horas de logs para averiguar dónde llegó, o tirarlo y empezar de nuevo.</p>
<p>Esa decisión es el impuesto que nadie presupuesta. Y la razón por la que duele cada vez es que la recuperación se trata como un accidente. Algo salió mal, así que ahora un humano hace de detective. Pero el trabajo largo con agentes no falla de vez en cuando. Falla de rutina, porque la superficie de fallo es enorme: rate limits, un test flaky, una ventana de contexto que se llenó y compactó el plan, una herramienta que devolvió algo inesperado, un paso que se aplicó a medias antes de parar. Si el fallo es rutina, la recuperación no puede ser heroísmo. Tiene que ser <a href="https://www.anthropic.com/engineering/building-effective-agents">un flujo que diseñaste a propósito</a>.</p>
<h2 id="por-qué-los-runs-largos-fallan-en-medio-no-al-principio">Por qué los runs largos fallan en medio, no al principio</h2>
<p>Una demo corre dos minutos y funciona o no. Un cambio real corre horas a través de lo que pienso como episodios: establece el primer comportamiento, mantenlo vivo mientras añades el segundo, sobrevive a un checkpoint y resume, gestiona el evento tardío, cubre el camino negativo, integra al final sin romper lo que dejó el primer episodio.</p>
<p>El fallo se agolpa en medio de esa cadena, y normalmente no es dramático. El agente no crashea. Deriva. El contexto se llena, <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">la compactación tira la restricción del episodio uno</a>, y el agente sigue, con seguridad, habiendo olvidado en silencio lo que hacía correcto al episodio uno. Escribí sobre ese mecanismo concreto en <a href="/es/blog/gestion-ventana-de-contexto/">la compactación se come tus decisiones</a>, y es la forma más común en que un run largo acaba mal en vez de parado.</p>
<p>Esa distinción importa. Un run que <em>para</em> es fácil: sabes dónde estás. Un run que <em>sigue después de perder el hilo</em> es el caro, porque ahora tienes un output que parece terminado y está sutilmente roto, y tienes que reconstruir lo que olvidó para siquiera ver el problema.</p>
<h2 id="recuperar-no-es-reintentar">Recuperar no es reintentar</h2>
<p>El arreglo ingenuo es un bucle de retry: falló, córrelo otra vez. A veces funciona, para un rate limit o un test flaky. Pero volver a correr desde arriba no es recuperación, es amnesia con tokens de más. Tira las tres horas de trabajo bueno para escapar de los últimos cinco minutos malos, y si el fallo fue una <a href="/es/blog/los-agentes-derivan/">deriva y no un crash</a>, el retry suele derivar igual.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Reintentar es amnesia con tokens de más; recuperar resume desde el último estado bueno y vuelve a demostrar el trabajo contra el contrato original."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">reintentar</p>
    <ul><li>reinicia desde arriba</li><li>tira el trabajo bueno</li><li>deriva igual</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">recuperar</p>
    <ul><li>resume el último estado bueno</li><li>conserva el trabajo bueno</li><li>re-puntúa contra el contrato</li></ul>
  </div>
</div><figcaption>Reintentar es amnesia con tokens de más; recuperar resume desde el último estado bueno y vuelve a demostrar el trabajo contra el contrato original.</figcaption></figure>
<p>La recuperación de verdad necesita tres cosas que un retry no tiene.</p>
<p><strong>Un último estado bueno al que volver.</strong> No el principio, el último punto donde el trabajo se sabía correcto. Si tu único checkpoint es el commit inicial, cada fallo te cuesta el run entero.</p>
<p><strong>Un registro de lo que ya era verdad.</strong> Las restricciones, las decisiones, los gates que estaban verdes antes del fallo. Sin eso, un run resumido no puede distinguir si continúa o si regresa.</p>
<p><strong>Una forma de puntuar el trabajo resumido contra el contrato original.</strong> Esta es la parte que separa la recuperación que funciona de la que parece progreso y rompe otra vez el episodio uno en silencio. Un run reanudado tiene que demostrar que terminó igual que cualquier run, que es la disciplina entera de hacer que <a href="/es/blog/hecho-significa-hecho/">hecho signifique hecho</a>: completitud demostrada contra los criterios, no auto-declarada.</p>
<p>Puse números reales sobre ese último punto en <a href="/es/research/agentes-necesitan-un-runtime-no-un-modelo-mas-grande/">el experimento de recuperación</a>: un agente de código guiado por un prompt fuerte, y el mismo agente con una skill de recuperación hecha a mano, los dos se quedaron clavados en la misma tasa de aprobado de dos tercios a través de cuatro episodios acumulativos, por la misma razón. Arreglaban el requisito nuevo y rompían un invariante viejo, y nada les decía que habían regresado. Lo que llegó a la meta no fue un modelo más listo. Fue algo fuera del agente que sostuvo el contrato y volvió a puntuar el trabajo tras cada intento. La recuperación es esa cosa de fuera, hecha rutina.</p>
<h2 id="diseñar-para-recuperar-en-vez-de-rezar-contra-el-fallo">Diseñar para recuperar en vez de rezar contra el fallo</h2>
<p>Si aceptas que los runs fallan en medio, diseñas el run para que el medio sea recuperable. Unos movimientos concretos, todos posibles hoy sin herramientas especiales:</p>
<ul>
<li><strong>Haz checkpoint en las fronteras de episodio, no solo al final.</strong> Después de que cada trozo coherente de trabajo pase su comprobación, commitéalo con el estado que lo hizo pasar. Una rama con seis checkpoints etiquetados es recuperable. Una rama con un diff gigante sin commitear es una moneda al aire.</li>
<li><strong>Escribe el plan en un sitio que el run no posea.</strong> Si la única copia de “qué construimos y por qué” vive en la ventana de contexto del agente, muere cuando el contexto se compacta. Guárdalo en un fichero, una tarea, un artefacto, algo que dure más que la sesión. Es la misma razón por la que <a href="/es/blog/perdida-de-contexto-entre-sesiones/">perder contexto entre sesiones</a> mata la productividad, y el mismo arreglo.</li>
<li><strong>Captura qué estaba verde antes de continuar.</strong> Antes de resumir, el run resumido necesita saber qué gates ya pasaban, para detectar una regresión en vez de celebrar un medio arreglo.</li>
<li><strong>Haz que el fallo sea ruidoso.</strong> Un run que para con un claro “fallé aquí, este era el último estado bueno” vale por diez runs que derivan en silencio a una respuesta segura y equivocada. La mitad de la recuperación es solo darse cuenta pronto.</li>
</ul>
<p>El hilo conductor: el estado que te deja recuperar tiene que vivir fuera del run. En cuanto la recuperación depende de leer el transcript, vuelves al trabajo de detective a las 2 de la mañana.</p>
<h2 id="el-caso-del-handoff">El caso del handoff</h2>
<p>Recuperación y handoff son el mismo problema con distinta ropa. Cuando un run muere y lo resumes mañana, se lo estás pasando a una versión futura del run, y todo lo que hace funcionar un <a href="/es/blog/handoffs-entre-agentes/">handoff limpio entre agentes</a> es lo que hace funcionar la recuperación: el contrato, el último estado bueno, las decisiones hasta ahora y lo que aún falta demostrar tienen que viajar. Si nada viajó, resumir un run muerto y arrancar un agente nuevo duelen lo mismo, porque los dos empiezan desde un transcript que nadie quiere leer.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Recuperar deja de ser heroísmo cuando el estado que un run necesita para resumir vive fuera del run y algo vuelve a comprobar el trabajo resumido contra el contrato original. Ese es el mecanismo, no una promesa de cifras. PaellaDoc trata un run como algo con checkpoints, un contrato contra el que se le sostiene, y un retry gobernado que resume desde el último estado bueno y vuelve a puntuar contra los gates que estaban verdes antes, así que un fallo a las 2am es un evento resumible y no una mañana leyendo logs. La persona que hace esa reconciliación a mano hoy es <a href="/es/blog/eres-el-runtime/">el runtime</a>, y un build verde al final sigue contando solo cuando pasa los criterios que existían antes de empezar el run, que es el sentido entero de <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build verde no es una feature correcta</a>.</p>
<h2 id="faq">FAQ</h2>
<h3 id="cómo-recupero-una-ejecución-fallida-de-agente-sin-empezar-de-cero">¿Cómo recupero una ejecución fallida de agente sin empezar de cero?</h3>
<p>Resume desde el último checkpoint donde el trabajo se sabía correcto, no desde el principio, y dale al run resumido el registro de qué ya estaba verde para que distinga continuación de regresión. Esto solo funciona si hiciste checkpoint en las fronteras de episodio y guardaste el plan y las restricciones fuera del contexto del agente. Si el único artefacto es un transcript largo, estás reconstruyendo, no recuperando.</p>
<h3 id="por-qué-volver-a-correr-el-agente-no-lo-arregla-sin-más">¿Por qué volver a correr el agente no lo arregla sin más?</h3>
<p>Volver a correr funciona para fallos transitorios como un rate limit, pero muchos fallos de run largo son deriva, no crashes: el agente perdió una restricción y siguió. Volver a correr desde arriba suele perder la misma restricción igual, y tira todo el trabajo correcto para escapar de la cola incorrecta. Recuperar necesita un último estado bueno y una forma de puntuar el trabajo resumido contra el contrato original.</p>
<h3 id="qué-estado-necesito-capturar-para-que-los-runs-sean-recuperables">¿Qué estado necesito capturar para que los runs sean recuperables?</h3>
<p>Tres cosas: un checkpoint de último estado bueno en cada frontera de episodio, el plan y las restricciones guardados fuera del run para que la compactación no los borre, y un registro de qué gates pasaban antes del fallo. Con eso, un run resumido puede continuar desde un punto conocido y detectar si acaba de romper algo que antes funcionaba.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="recuperacion"/><category term="checkpoints"/><category term="agentes"/><category term="fiabilidad"/><category term="runtime"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Qué es el vibe coding (y dónde deja de funcionar)</title>
    <link href="https://paelladoc.com/es/blog/que-es-vibe-coding/" rel="alternate" type="text/html" title="Qué es el vibe coding (y dónde deja de funcionar)"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/que-es-vibe-coding/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/que-es-vibe-coding/"><![CDATA[<p>Vibe coding es describir lo que quieres en lenguaje normal y dejar que un modelo escriba el código, sin leer la mayor parte. Guías por el resultado: lo ejecutas, ves si te encaja, pides cambios, lo vuelves a ejecutar. El código es el medio, el comportamiento es el objetivo, y casi nunca miras debajo del capó.</p>
<p>Andrej Karpathy le puso nombre a principios de 2025, describiendo una forma de trabajar en la que “te entregas del todo a las vibes” y te olvidas de que el código existe. Lo dijo en parte como broma sobre proyectos de fin de semana. El término cuajó porque describía algo que <a href="https://survey.stackoverflow.co/2025/">mucha gente ya hacía</a> y no tenía palabra para nombrarlo.</p>
<p>Vale la pena definirlo con claridad, porque el término se usa de dos maneras: como medalla por quien publica cosas reales rápido, y como insulto por quien piensa que todo es una temeridad. Ambos se pierden la línea de verdad.</p>
<h2 id="qué-es-el-vibe-coding-en-realidad">Qué es el vibe coding en realidad</h2>
<p>Quítale el misticismo y es un bucle:</p>
<ol>
<li>Describes un cambio o una feature en lenguaje natural.</li>
<li>Un agente escribe o edita el código.</li>
<li>Lo ejecutas y miras el resultado, no el diff.</li>
<li>Describes qué está mal o qué toca después.</li>
<li>Repites.</li>
</ol>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="El bucle del vibe coding. El paso tres es toda la técnica: lees el comportamiento, no el diff."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">DESCRIBE</text><path d="M 190 85 L 212 85 M 206 79 L 212 85 L 206 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EL AGENTE ESCRIBE</text><path d="M 368 85 L 390 85 M 384 79 L 390 85 L 384 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EJECUTA</text><path d="M 546 85 L 568 85 M 562 79 L 568 85 L 562 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="646" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">LEE EL COMPORTAMIENTO</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">SIGUIENTE CAMBIO</text></svg><figcaption>El bucle del vibe coding. El paso tres es toda la técnica: lees el comportamiento, no el diff.</figcaption></figure>
<p>El rasgo que lo define es el paso 3. En el desarrollo clásico lees el código para saber que está bien. En vibe coding lees el comportamiento. Esa única sustitución es lo que lo hace rápido, y es también toda la fuente de sus límites.</p>
<p>Esto es distinto de la ingeniería asistida por IA, donde sigues leyendo y siendo dueño del diff y el modelo es un acelerador. El vibe coding delega también la lectura. La distinción no es esnobismo: decide para qué es seguro usar el resultado.</p>
<h2 id="para-qué-es-genuinamente-bueno">Para qué es genuinamente bueno</h2>
<p>No vengo a despreciarlo. La técnica es real y se gana su sitio:</p>
<p><strong>Prototipos.</strong> Cuando el objetivo es ver si una idea encaja, el vibe coding te da una respuesta clicable en una tarde en vez de en una semana. Eso es un superpoder legítimo.</p>
<p><strong>Herramientas de usar y tirar.</strong> Un script que ejecutarás una vez, una utilidad interna para ti, algo que no necesita sobrevivir al contacto con otra gente. Que la corrección caduque mañana da igual cuando terminas hoy.</p>
<p><strong>Aprender viendo.</strong> Ver cómo una idea se convierte en una pantalla que funciona te enseña más sobre si vale la pena construirla que cualquier cantidad de planificación.</p>
<p><strong>El primer borrador de algo real.</strong> Incluso cosas que serán productos suelen empezar aquí, y deben. El error no es empezar con vibe coding. Es no darte cuenta de cuándo saliste de su terreno.</p>
<h2 id="dónde-deja-de-funcionar">Dónde deja de funcionar</h2>
<p>El límite no es un nivel de dificultad. Es un cambio en lo que necesitas del resultado. El vibe coding deja de funcionar en cuanto el código tiene que sobrevivir a cosas que una demo nunca prueba:</p>
<p><strong>Cuando tiene que seguir funcionando mientras lo cambias.</strong> Los comportamientos de un prototipo funcionaron una vez. Los de un producto tienen que seguir funcionando a través de cada cambio futuro, lo que significa que algo tiene que atraparlos cuando un cambio los rompe. El vibe coding no produce esa red.</p>
<p><strong>Cuando otra persona depende de ello.</strong> En cuanto el dinero, los datos o el tiempo de un usuario real dependen de la app, “funcionó cuando le di al clic” deja de bastar. Necesitas saber que funciona, no sentirlo. Un <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">build en verde no es una feature correcta</a>, y “corrió en mi pantalla” es aún más débil que un build en verde.</p>
<p><strong>Cuando crece más de lo que te cabe en la cabeza.</strong> Por debajo de cierto tamaño puedes tener la app entera en memoria y guiar por vibes. Pasado ese punto no puedes, y como nunca leíste el código, ahora eres dueño de un software que no sabes navegar. Ese es el <a href="/es/blog/vibe-coding-dia-90/">ajuste de cuentas que la mayoría de apps vibe-coded viven hacia el mes 3</a>.</p>
<p><strong>Cuando las features empiezan a chocar.</strong> Cada feature se generó asumiendo que el resto de la app se queda quieta. Junta suficientes y <a href="/es/blog/features-que-rompen-features/">las nuevas empiezan a romper las viejas</a>, porque nada obligó a que la asunción se cumpliera.</p>
<p>Ninguna de estas significa que la técnica fallara. Significan que el prototipo tuvo tanto éxito que dejó de ser un prototipo. Ese es el buen problema, y tiene nombre: el prototipo se convirtió en el producto, y pasó antes de que decidieras dejarlo.</p>
<h2 id="por-qué-vale-la-pena-deshacer-la-confusión">Por qué vale la pena deshacer la confusión</h2>
<p>Esto importa porque la gente discute sobre el vibe coding como si fuera una sola cosa que es buena o mala. No lo es. Es una herramienta con una forma, y la forma es justo esta: convierte lenguaje natural en comportamiento que funciona a gran velocidad, a cambio de que tú no sepas cómo se sostiene ese comportamiento.</p>
<p>Para un prototipo, ese trato es una ganga. Quieres velocidad y las tripas te dan igual, porque todo el trabajo del prototipo es responder una pregunta y luego quitarse de en medio. Para un producto, el mismo trato es un veneno de acción lenta. Sigues recibiendo la velocidad por adelantado, pero ahora las tripas que nunca miraste son lo que tienes que mantener, y no puedes mantener lo que nunca viste.</p>
<p>Así que la técnica no es buena ni mala. Está bien o mal aplicada. Aplicada a algo de usar y tirar, roza la magia. Aplicada a algo de lo que depende gente, sin devolver nunca la estructura, es <a href="https://martinfowler.com/bliki/TechnicalDebt.html">un préstamo a alto interés que vence</a>, de forma fiable, un par de meses después.</p>
<h2 id="qué-aspecto-tiene-pasada-la-línea-en-la-práctica">Qué aspecto tiene “pasada la línea” en la práctica</h2>
<p>En concreto, sabes que cruzaste la línea cuando tu relación con el código cambia. En terreno de prototipo, pides un cambio y aceptas lo que venga, porque la única prueba es si se ve bien al ejecutarlo. Pasada la línea, empiezas a necesitar saber cosas que no puedes ver: ¿este cambio rompió lo que publiqué la semana pasada?, ¿este número es correcto o solo plausible?, ¿por qué lo hizo así? Las preguntas que el código no puede responder son la señal de que el vibe coding te ha llevado tan lejos como puede.</p>
<p>Eso no es un fracaso y no es motivo para sentirte tonto. Es el resultado predecible de que la técnica funcione. El error está solo en no darse cuenta, y seguir añadiendo features por vibes sobre una base que nadie entiende, que es como un arranque rápido se convierte en una app <a href="/es/blog/vibe-coding-dia-90/">imposible de cambiar hacia el mes 3</a>.</p>
<h2 id="la-línea-en-una-frase">La línea, en una frase</h2>
<p>El vibe coding vale hasta que algo tiene que ser cierto sobre tu código que no puedes verificar personalmente haciendo clic. En esa línea no necesitas abandonar la app ni reescribirla. Necesitas devolver la estructura que un prototipo se salta: un mapa legible, una spec escrita, una red de seguridad. Ese cruce es una disciplina entera de por sí, y despliego la ruta completa en <a href="/es/blog/vibe-coding-a-produccion/">de vibe coding a producción</a>.</p>
<p>Usa el vibe coding para lo que es bueno sin pedir perdón. Solo vigila la línea, porque llega en silencio, y el coste de no verla se paga después, con intereses.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Quién acuñó el término vibe coding?</strong> Andrej Karpathy, a principios de 2025, describiendo una forma de construir en la que te apoyas en el modelo y dejas de seguir el propio código. Le puso nombre a una práctica que mucha gente ya hacía.</p>
<p><strong>¿El vibe coding es malo?</strong> No. Es excelente para prototipos, herramientas de usar y tirar y primeros borradores. Solo se vuelve un problema cuando su resultado se usa como si fuera software de producción, sin la estructura que producción exige.</p>
<p><strong>¿Cuál es la diferencia entre vibe coding e ingeniería asistida por IA?</strong> En el vibe coding guías por el comportamiento y no lees el código. En la ingeniería asistida por IA sigues leyendo y siendo dueño del diff. La diferencia decide si es seguro depender del resultado.</p>]]></content>
    <summary type="html"><![CDATA[El vibe coding es el término que acuñó Karpathy para describir lo que quieres y dejar que el modelo escriba el código. Es genuinamente bueno para unas cosas y genuinamente malo para otras. Aquí va la definición, y la línea donde deja de funcionar.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="ai-coding"/><category term="que-es-vibe-coding"/><category term="desarrollo-con-agentes"/><category term="de-prototipo-a-producto"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">El puente PM–ingeniería: un solo sistema del discovery al código mergeado</title>
    <link href="https://paelladoc.com/es/blog/puente-pm-ingenieria/" rel="alternate" type="text/html" title="El puente PM–ingeniería: un solo sistema del discovery al código mergeado"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/puente-pm-ingenieria/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/puente-pm-ingenieria/"><![CDATA[<p>Dos personas trabajan en la misma feature y nunca tocan el mismo documento. El PM vive en una herramienta de discovery, una presentación, una spec en un wiki. El ingeniero vive en el repo, el pull request, los logs de CI. Entre ellos hay un ticket, y el ticket es donde el significado va a comprimirse. El razonamiento del PM, el dolor del usuario, el supuesto que se prueba, todo se aplana en un título y un párrafo, y el ingeniero construye desde el párrafo. Lo que no cupo en el párrafo se pierde en la costura.</p>
<p>Este es el hueco que casi ningún equipo cruza de verdad. Todos tienen un traspaso. Casi nadie tiene un puente. Quiero describir la diferencia, y escribo a los dos lados a la vez, porque el arreglo no es un rol esforzándose más dentro de sus propias herramientas. Es que los dos mundos de contenido se vuelvan uno.</p>
<h2 id="dos-grafos-que-nunca-se-tocan">Dos grafos que nunca se tocan</h2>
<p>Piensa cada lado como un grafo de cosas conectadas. El lado de producto tiene un grafo: dolores de usuario enlazan con oportunidades enlazan con decisiones enlazan con specs. El lado de ingeniería también tiene un grafo: módulos enlazan con funciones enlazan con tests enlazan con commits enlazan con pull requests mergeados. Los dos son reales, los dos son útiles, y en casi todas las empresas no comparten absolutamente nada. Ninguna identidad común, ningún enlace de un nodo de uno a un nodo del otro.</p>
<p>Así que el camino de «aprendimos que el usuario abandona en el paso tres» al commit concreto y mergeado que debía arreglarlo no existe como camino. Existe como memoria institucional en la cabeza de dos personas, sostenida por un número de ticket que apunta a un resumen comprimido y ahí se acaba. Cuando cualquiera de las dos se va, o simplemente lo olvida, la conexión desaparece. El código se queda. La razón se evapora. Este es el problema del <a href="/es/blog/grafo-de-conocimiento-de-producto/">grafo de conocimiento de producto</a> visto desde la costura: la forma del producto y la forma del repo se dibujan en habitaciones distintas, y ninguna línea las conecta.</p>
<h2 id="el-traspaso-es-una-pérdida-por-traducción-y-la-ia-lo-ensanchó">El traspaso es una pérdida por traducción, y la IA lo ensanchó</h2>
<p>Para los ingenieros que leen esto: la razón de que la spec siempre pareciera lossy es que era una traducción, y toda traducción pierde algo. El PM tenía un modelo rico del problema y tuvo que serializarlo en un documento, y tú tuviste que deserializarlo de vuelta a un modelo mental para construir. Los huecos entre su modelo y tu reconstrucción son donde vive el «no era eso lo que quería decir».</p>
<p>Para los PMs que leen esto: la razón de que ingeniería siga construyendo cosas que técnicamente encajan con la spec pero se pierden el punto es la misma pérdida por traducción, en sentido contrario. Las restricciones, los trade-offs, las razones por las que se descartó la implementación obvia, eso vivía en la cabeza del ingeniero y nunca volvió a tu modelo de lo que se construyó.</p>
<p>La IA empeoró esto antes de mejorarlo, y conviene ser claro sobre por qué. Cuando un agente convierte una spec en código en una tarde, la pérdida por traducción no desaparece. Se acelera. Ahora el ticket comprimido se vuelve código mergeado más rápido de lo que nadie alcanza a captar qué se dejó por el camino, y el <a href="/es/blog/product-management-era-ia/">ritmo de construcción adelantó al razonamiento</a>, así que la costura que siempre goteaba ahora gotea a velocidad de agente. Llega más código cargando menos de su porqué.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="Cada traspaso comprime el modelo del PM en un ticket y de vuelta en código; a velocidad de agente la costura gotea más rápido de lo que nadie alcanza a captar."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">MODELO DEL PM</text><path d="M 250 95 L 272 95 M 266 89 L 272 95 L 266 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">TICKET</text><path d="M 488 95 L 510 95 M 504 89 L 510 95 L 504 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="62" width="204" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="618" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">CÓDIGO MERGEADO</text></svg><figcaption>Cada traspaso comprime el modelo del PM en un ticket y de vuelta en código; a velocidad de agente la costura gotea más rápido de lo que nadie alcanza a captar.</figcaption></figure>
<h2 id="qué-es-de-verdad-un-puente">Qué es de verdad un puente</h2>
<p>Un puente no es un ritual de traspaso mejor. Los traspasos asumen dos mundos e intentan mover cosas entre ellos limpiamente. Un puente significa que el artefacto de discovery, la decisión, la spec y el código mergeado son nodos de un solo grafo con identidad compartida, de modo que la conexión entre ellos es un hecho que el sistema sostiene, no un recuerdo que dos personas mantienen.</p>
<p>En concreto, lo definen tres propiedades.</p>
<p>Identidad compartida. La decisión que autorizó una feature y el commit que la implementó se refieren al mismo objeto, no a dos resúmenes que casualmente suenan parecido. Puedes empezar en el código mergeado y aterrizar en el insight de discovery que lo justificó, porque hay un enlace real, no un número de ticket y una esperanza.</p>
<p>Provenance en ambas direcciones. Desde un dolor de usuario puedes llegar al código que lo aborda. Desde una línea de código puedes <a href="/es/blog/de-repo-a-artefactos/">llegar a la razón de que exista</a>. Casi ninguna herramienta te da ninguna de las dos direcciones. Un repo te dice qué hace el código y nada de por qué. Una herramienta de discovery te dice qué querías y nada de si se construyó. El puente es lo que hace posibles los dos recorridos.</p>
<p>Un contrato que los agentes puedan leer. Cuando los agentes hacen la construcción, la spec no es solo para el ingeniero, es la instrucción contra la que el agente construye, y tiene que cargar la decisión y sus restricciones en una forma que el agente pueda consumir. Por eso importa un estándar como <a href="https://agents.md/">AGENTS.md</a>: las decisiones tienen que vivir en un sitio que el agente lea de verdad, no en un wiki que nunca ve. Un puente que se detiene en el ingeniero humano y no llega al agente ya está obsoleto, porque <a href="/es/blog/construir-software-con-agentes-de-ia/">el agente es quien escribe la mayor parte del código ahora</a>.</p>
<h2 id="esto-es-vieja-sabiduría-de-ingeniería-llegando-a-producto">Esto es vieja sabiduría de ingeniería, llegando a producto</h2>
<p>Nada de esto es exótico para los ingenieros. La disciplina de mantener la intención conectada con lo que se publica es gran parte de lo que trata el <a href="https://martinfowler.com/bliki/ContinuousDelivery.html">continuous delivery</a>: un cambio debería ser trazable desde la razón por la que se hizo hasta el momento en que llega a los usuarios, sin un paso de reconciliación manual que alguien acaba dejando de hacer. Ingeniería construyó ese músculo a lo largo de una década porque el coste de una traza rota aparecía en caídas.</p>
<p>Producto nunca construyó el músculo equivalente, porque durante mucho tiempo la traza de la decisión al código la cargaba la pura lentitud de construir. Tenías tiempo de mantener la historia recta. Ese margen desapareció. El puente es producto adoptando por fin lo que ingeniería ya aprendió, que un cambio tiene que seguir conectado a su razón todo el trayecto, y que la conexión tiene que ser <a href="/es/blog/modelo-operativo-de-producto/">una propiedad del sistema, no una disciplina que esperas que la gente mantenga</a>.</p>
<h2 id="qué-cede-cada-lado-y-qué-gana">Qué cede cada lado, y qué gana</h2>
<p>Para el PM, el puente significa ceder la spec del wiki como tu artefacto final. La spec deja de ser un documento que traspasas y olvidas. Pasa a ser un nodo que sigue enlazado con lo que se construyó, lo que significa que puedes rendir cuentas de ella y también ver, con claridad, si lo publicado encajó con lo que decidiste. Ganas, a cambio, el <a href="/es/blog/registro-de-decisiones/">fin del «yo nunca acordé eso»</a>: la decisión está registrada y conectada al código, así que la deriva entre intención e implementación es visible en vez de descubrirse en una demo.</p>
<p>Para el ingeniero, el puente significa que la razón de un cambio deja de ser un ticket comprimido. Ganas la decisión real, sus restricciones y sus supuestos, adjuntos al trabajo, que es el contexto que marca la diferencia entre construir lo que se pidió y construir lo que se quiso decir. Cedes, a cambio, la posición cómoda de «construí exactamente lo que decía el ticket», porque ahora el ticket carga lo suficiente para que el punto sea legible, y perderse el punto también es visible.</p>
<p>Los dos lados ceden lo mismo: la capacidad de culpar a la costura. Ese es el trato, y es bueno.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/es/">PaellaDoc</a> está hecho para ser ese único sistema. Discovery, decisiones, specs y código viven en un solo grafo con identidad compartida y provenance, de modo que el camino de un insight de usuario al commit mergeado que lo abordó es un recorrido que puedes hacer, en cualquier dirección, sin sostenerlo en la cabeza. El PM y el ingeniero dejan de trabajar en dos mundos de contenido unidos por un ticket lossy, y empiezan a trabajar contra un mapa donde el porqué y el qué son objetos enlazados.</p>
<p>La costura entre producto e ingeniería era sobrevivible cuando construir era lo bastante lento para dejar que la gente cargara la conexión ella misma. A velocidad de agente, la carga se rompe, y lo único que aguanta es un puente que el sistema mantiene por ti.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-el-traspaso-de-pm-a-ingeniería-pierde-tanto">¿Por qué el traspaso de PM a ingeniería pierde tanto?</h3>
<p>Porque es una traducción. El PM tiene un modelo rico del problema y lo serializa en un ticket; el ingeniero lo deserializa de vuelta a un modelo mental para construir. Todo lo que no cupo en el párrafo, el supuesto que se prueba, las alternativas descartadas, las restricciones, se cae en la costura. Los dos trabajan en mundos de contenido separados unidos solo por un número de ticket y la memoria en dos cabezas.</p>
<h3 id="cuál-es-la-diferencia-entre-un-traspaso-y-un-puente">¿Cuál es la diferencia entre un traspaso y un puente?</h3>
<p>Un traspaso asume dos mundos e intenta mover cosas entre ellos limpiamente, así que el significado se comprime en cada sentido. Un puente significa que el artefacto de discovery, la decisión, la spec y el código mergeado son nodos de un solo grafo con identidad compartida, de modo que la conexión entre ellos es un hecho que el sistema sostiene, no un recuerdo que dos personas mantienen. Los traspasos gotean; un puente no.</p>
<h3 id="por-qué-la-ia-empeoró-el-hueco-entre-pm-e-ingeniería">¿Por qué la IA empeoró el hueco entre PM e ingeniería?</h3>
<p>La pérdida por traducción no desapareció, se aceleró. Cuando un agente convierte un ticket comprimido en código mergeado en una tarde, el código llega más rápido de lo que nadie alcanza a captar qué se dejó por el camino. La costura que siempre goteaba ahora gotea a velocidad de agente, y llega más código cargando menos de su porqué. La conexión que la lentitud preservaba se rompe, así que tiene que volverse propiedad del sistema.</p>
<h3 id="cómo-trazo-una-feature-mergeada-de-vuelta-a-por-qué-se-construyó">¿Cómo trazo una feature mergeada de vuelta a por qué se construyó?</h3>
<p>Necesitas provenance en ambas direcciones, que casi ninguna herramienta te da. Un repo te dice qué hace el código y nada de por qué; una herramienta de discovery te dice qué querías y nada de si se publicó. Un puente enlaza el insight de discovery, la decisión, la spec y el commit con identidad compartida, así que puedes empezar en el código mergeado y aterrizar en la razón de que exista, como un recorrido, no un recuerdo.</p>]]></content>
    <summary type="html"><![CDATA[El trabajo del PM vive en un conjunto de herramientas y el del ingeniero en otro, y la costura entre ambos es una pérdida por traducción que ningún rol posee. Un insight de discovery se vuelve un ticket se vuelve un diff, y para cuando el código merge nadie puede recorrerlo hacia atrás hasta la razón de que exista. Esta pieza habla a los dos lados. El puente no es otro ritual de traspaso. Es un solo sistema donde discovery, decisiones, specs y código mergeado comparten identidad, para que el camino del porqué al qué siga conectado en ambas direcciones.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="product-management"/><category term="ingenieria"/><category term="ai-coding"/><category term="discovery"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">El prototipo como spec: imposible de malinterpretar</title>
    <link href="https://paelladoc.com/es/blog/prototipo-como-spec/" rel="alternate" type="text/html" title="El prototipo como spec: imposible de malinterpretar"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/prototipo-como-spec/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/prototipo-como-spec/"><![CDATA[<p>Dale a tres ingenieros el mismo párrafo que describe una feature y te salen tres features distintas. No porque nadie sea descuidado. La prosa es ambigua por naturaleza. «La lista debería actualizarse en tiempo real» contiene al menos cuatro decisiones que nadie tomó, y cada lector las toma de forma distinta, con seguridad, en privado. Te enteras en la review, que es el momento más caro posible para descubrir que la spec significaba tres cosas.</p>
<p>Dale a esas mismas tres personas un prototipo funcionando y la ambigüedad se colapsa. «Debería verse así, comportarse así, responder así cuando haces aquello». No hay nada que interpretar, porque el prototipo no es una descripción del comportamiento. Es el comportamiento. Una spec la puedes malinterpretar; una cosa en marcha no.</p>
<h2 id="por-qué-la-prosa-no-puede-fijar-el-comportamiento">Por qué la prosa no puede fijar el comportamiento</h2>
<p>Una especificación escrita en palabras es una compresión de una experiencia interactiva a una cadena lineal, y la descompresión ocurre en la cabeza del lector. Cada hueco se rellena con una suposición, y las suposiciones son invisibles hasta que chocan. «Actualizaciones en tiempo real» deja al lector decidir la latencia, el comportamiento en conflicto, qué pasa sin conexión, si una actualización parcial es peor que una obsoleta. Las palabras son las mismas para todos. El producto que cada uno construye a partir de ellas, no.</p>
<p>Esto siempre fue un impuesto. Lo pagabas en reuniones de aclaración, en retrabajo, en el lento descubrimiento de que «hecho» significaba cosas distintas para quien escribía y quien construía. Los equipos aprendieron a escribir con más cuidado, añadir criterios de aceptación, adjuntar mockups, y ayudó en los márgenes. Nunca resolvió el problema de fondo, que es que la prosa no puede especificar del todo una cosa interactiva. Siempre hay un hueco entre la descripción y la experiencia, y el hueco es donde se construye el producto equivocado.</p>
<h2 id="construir-se-volvió-lo-bastante-barato-para-especificar-construyendo">Construir se volvió lo bastante barato para especificar construyendo</h2>
<p>Esto es lo que cambió. Una especificación solía ser más barata de escribir que la cosa que describía, que es toda la razón por la que escribíamos specs en vez de construir sin más. No podías permitirte construir tres versiones para averiguar cuál querías decir. Así que describías, discutías la descripción y construías una vez.</p>
<p>Esa economía se invirtió. Cuando un agente convierte una idea en un prototipo funcionando en una tarde, el prototipo ya no es significativamente más caro que el párrafo. Y el prototipo responde preguntas que el párrafo solo puede insinuar. No describes la interacción y esperas que cuadre. La construyes, la miras, sientes que el timing está mal y lo arreglas, y ahora la spec <em>es</em> la interacción corregida. Esta es la cara práctica de <a href="/es/blog/product-management-era-ia/">construir se abarató y decidir se encareció</a>: cuando construir es casi gratis, la forma más precisa de decir qué quieres es construir una versión pequeña de ello.</p>
<h2 id="qué-fija-de-verdad-un-prototipo-como-spec">Qué fija de verdad un prototipo-como-spec</h2>
<p>Un prototipo no es solo menos ambiguo de una forma vaga y agradable. Fija cosas concretas que la prosa erra de forma fiable:</p>
<ul>
<li><strong>Interacción y timing.</strong> Qué responde al instante, qué muestra un estado de carga, qué anima, qué se siente mal a 300ms y bien a 120ms. Esto no lo puedes escribir con precisión. Solo puedes construirlo y sentirlo.</li>
<li><strong>Estado y comportamiento límite, hechos visibles.</strong> El estado vacío, el de un elemento, el de demasiados elementos. En prosa se llevan una frase cada uno si eres diligente. En un prototipo existen o no, y su ausencia es un agujero visible en vez de un hueco silencioso.</li>
<li><strong>La forma de la cosa.</strong> Cómo encajan las piezas, qué es primario, qué está enterrado. Decisiones de layout que en prosa cuestan párrafos y quedan mal descritas son obvias en un vistazo a una pantalla en marcha.</li>
<li><strong>El borde de la idea.</strong> Este es el infravalorado. Construir un prototipo te obliga a chocar con los bordes que pasaste de puntillas. En el momento en que el botón tiene que hacer algo, descubres la decisión que llevabas evitando.</li>
</ul>
<p>Ese último punto es el regalo de verdad. Una spec en prosa te deja quedarte vago justo donde más importa, porque las palabras toleran la vaguedad. Un prototipo no. Te obliga a decidir, porque una cosa en marcha tiene que hacer algo de verdad en cada punto que pensabas resolver más tarde.</p>
<h2 id="los-límites-dichos-claros">Los límites, dichos claros</h2>
<p>Un prototipo es una spec de <em>cómo se comporta</em>. Es una mala spec para varias cosas, y fingir lo contrario es como te quemas:</p>
<ul>
<li><strong>No dice por qué.</strong> El prototipo muestra la decisión, no el razonamiento detrás. Seis semanas después, alguien pregunta por qué el flujo funciona así y el prototipo no puede responder. La interacción está fijada; la intención detrás se evaporó, salvo que la <a href="/es/blog/registro-de-decisiones/">registraras aparte</a>.</li>
<li><strong>No captura el contrato no funcional.</strong> Cómo de rápido bajo carga, qué pasa a escala, el borde de seguridad, los modos de fallo con tráfico real. Un prototipo que funciona para un usuario en tu máquina no dice nada de la cosa que tiene que aguantar para diez mil.</li>
<li><strong>Implica calladamente decisiones que nunca tomaste.</strong> Todo prototipo toma mil elecciones incidentales, este color, ese texto, este orden, y un lector no puede distinguir cuáles fueron deliberadas y cuáles los defaults de la herramienta. El prototipo especifica todo con la misma seguridad, incluidas las partes que no querías especificar.</li>
</ul>
<p>Ese último límite es el peligroso, y es la misma trampa que <a href="/es/blog/de-prototipo-a-producto/">un prototipo convirtiéndose calladamente en el producto</a>. Un prototipo pensado para fijar una interacción se trata como una decisión sobre todo lo que casualmente contiene. El arreglo no es desconfiar de los prototipos. Es ser explícito sobre qué está especificando el prototipo y qué es solo andamiaje, para que las elecciones accidentales no asciendan a requisitos por defecto.</p>
<h2 id="prototipo-más-la-decisión-detrás">Prototipo más la decisión detrás</h2>
<p>La solución no es prototipo contra spec escrita. Es prototipo para el comportamiento, más un registro fino de la intención y los bordes. El prototipo responde «qué hace exactamente», que la prosa hace mal. Una decisión escrita corta responde «por qué, qué tiene que aguantar, y qué partes de aquí son de carga frente a incidentales», que el prototipo no responde en absoluto, y a diferencia del prototipo esa decisión escrita es <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">portable entre herramientas</a>.</p>
<p>Juntos son una spec completa difícil de malinterpretar. La interacción la clava la cosa en marcha. El razonamiento y las restricciones se capturan al lado, para que el prototipo no tenga que cargar con un significado que no puede sostener. Ninguno solo basta. El prototipo sin la intención es una decisión sin memoria de por qué. La intención sin el prototipo es el <a href="/es/blog/prds-que-nadie-lee/">párrafo ambiguo del que partiste</a>.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Este es el emparejamiento alrededor del cual estoy construyendo <a href="/es/">PaellaDoc</a>. Un prototipo no debería flotar suelto como un artefacto cuyo significado nadie puede reconstruir en un mes. Debería estar conectado a la decisión que encarna y a las restricciones que tiene que respetar, para que lo que el prototipo especifica sobre el comportamiento y lo que decidiste sobre la intención vivan como una sola cosa. La interacción es inequívoca porque se ejecuta. El razonamiento sobrevive porque está registrado al lado, no dejado a evaporarse.</p>
<p>Deja de escribir párrafos que tres personas leerán de tres formas. Cuando construir una versión pequeña es casi gratis, constrúyela, y deja que la cosa en marcha cargue con la parte de la spec que las palabras siempre iban a errar. Luego escribe el porqué. El prototipo es imposible de malinterpretar. Solo asegúrate de decir también para qué era.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="un-prototipo-puede-sustituir-a-una-spec-escrita">¿Un prototipo puede sustituir a una spec escrita?</h3>
<p>Para el comportamiento, sí, y mejor. Un prototipo no es una descripción de la interacción, es la interacción, así que no se puede leer de tres formas. Fija el timing, el estado, el comportamiento límite y el layout, lo que la prosa erra de forma fiable. Pero solo sustituye la parte de la spec que dice qué hace el producto. El razonamiento y las restricciones siguen necesitando un registro escrito.</p>
<h3 id="qué-no-puede-especificar-un-prototipo">¿Qué no puede especificar un prototipo?</h3>
<p>Tres cosas. No dice por qué el flujo funciona así, solo que funciona, así que la intención se evapora salvo que la registres aparte. No captura el contrato no funcional: rendimiento bajo carga, escala, seguridad, modos de fallo. Y implica calladamente mil elecciones incidentales, colores, textos, orden, que un lector no distingue de las deliberadas. Especifica todo con la misma seguridad.</p>
<h3 id="sigo-necesitando-una-spec-escrita-si-tengo-un-prototipo">¿Sigo necesitando una spec escrita si tengo un prototipo?</h3>
<p>Sí, una fina. El prototipo responde «qué hace exactamente», que la prosa hace mal. Una decisión escrita corta responde «por qué, qué tiene que aguantar y qué partes son de carga frente a incidentales», que el prototipo no responde en absoluto. Juntos son una spec completa difícil de malinterpretar. El prototipo sin la intención es una decisión sin memoria de por qué.</p>
<h3 id="cómo-evito-que-un-prototipo-se-lea-como-decisiones-definitivas">¿Cómo evito que un prototipo se lea como decisiones definitivas?</h3>
<p>Sé explícito sobre qué está especificando y qué es solo andamiaje. Un prototipo toma mil elecciones incidentales y las presenta todas con la misma seguridad, así que un lector asciende defaults accidentales a requisitos si no dices lo contrario. Empareja la cosa en marcha con una nota corta sobre qué partes son de carga y cuáles provisionales, para que el borde esté dicho, no adivinado.</p>]]></content>
    <summary type="html"><![CDATA[Una spec en prosa describe el producto y se puede leer de tres formas. Un prototipo funcionando es el producto y se lee de una. Cuando un agente convierte una idea en un prototipo en marcha en una tarde, el prototipo pasa a ser la spec menos ambigua que puedes entregar, siempre que seas claro sobre las preguntas que responde y las que se salta en silencio.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="prototype-as-spec"/><category term="product-management"/><category term="ai-coding"/><category term="specs"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">Probar código generado por IA: qué cambia y qué no</title>
    <link href="https://paelladoc.com/es/blog/probar-codigo-de-ia/" rel="alternate" type="text/html" title="Probar código generado por IA: qué cambia y qué no"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/probar-codigo-de-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/probar-codigo-de-ia/"><![CDATA[<p>Generas un módulo. Funciona cuando haces clic por él. Luego te sientas a añadir tests, porque sabes que deberías, y algo chirría un poco. Cada test que escribes pasa a la primera. No tras un arreglo. A la primera. Te dices que el código era bueno. No lo era. Escribiste los tests después de leer el código, así que los tests codifican lo que el código hace, no lo que debía hacer.</p>
<p>Eso es lo único que cambia de verdad al probar código generado por IA. Casi todo lo demás sigue siendo igual que siempre, y los errores vienen de creer lo contrario.</p>
<h2 id="la-intención-nunca-estuvo-en-la-sala">La intención nunca estuvo en la sala</h2>
<p>Un test es una afirmación sobre la intención. Dice «esta entrada debería producir este comportamiento» y falla cuando la realidad no está de acuerdo. Eso solo funciona cuando la intención existe en algún sitio independiente del código. Cuando escribes el código tú, la intención vive en tu cabeza mientras tecleas, y el test que escribes a continuación es una segunda expresión de la misma idea. La redundancia es el punto. Dos testigos de la misma intención, y si se contradicen, uno de los dos está mal.</p>
<p>Con código generado, falta el segundo testigo. El modelo produjo la implementación más probable de tu prompt. Si luego lees esa implementación y escribes tests contra lo que ves, tienes un testigo por duplicado. El código dice X, el test afirma X, coinciden, verde. Has demostrado que el código hace lo que el código hace. No has demostrado nada sobre lo que querías.</p>
<p>Por eso probar código generado de la forma ingenua resulta tan cómodo y sirve tan poco. La fricción que antes cazaba fallos, el momento en que tu test y tu recuerdo de la intención rozaban, desapareció. Nadie en la sala recuerda para qué era la feature. El modelo nunca lo supo. Externalizaste la escritura y la intención se fue con ella.</p>
<h2 id="qué-cambia-de-verdad">Qué cambia de verdad</h2>
<p>Se mueven tres cosas, y conviene nombrarlas con precisión justamente porque todo lo demás se queda quieto.</p>
<p>La fuente de la verdad se mueve antes. Cuando escribes código, el código puede servir como registro tosco de su propia intención porque tú sostenías la intención al escribirlo. Cuando el que escribe es un agente, la intención hay que capturarla antes de generar, o se evapora. Los <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación</a>, el comportamiento acordado, los ejemplos de salida correcta e incorrecta, todo eso tiene que existir como artefacto al que el test pueda apuntar. No en el chat. En algo duradero.</p>
<p>El orden de escritura se mueve. Si escribes el test después de leer el código generado, el código contamina el test. Así que el test, o al menos el comportamiento que codifica, tiene que salir de la especificación, no del diff. Describes qué significa «correcto», dejas que el agente genere, y contrastas la generación contra un test que nunca vio la implementación. La misma disciplina que el <a href="/es/blog/spec-driven-vs-test-driven/">desarrollo test-first</a>, por una razón más afilada: no para dar forma a tu diseño, sino para impedir que el código se escriba su propio examen.</p>
<p>El volumen se mueve. Una sola persona puede generar en una tarde el código de una semana. Cada uno de esos cambios necesita su comportamiento fijado. Ya no pruebas el código que escribiste despacio, pruebas una avalancha de código que ojeaste. La cobertura que antes se acumulaba como efecto secundario de trabajar ahora tiene que ser un gate deliberado, porque la parte de trabajar se aceleró y la de entender no.</p>
<h2 id="qué-no-cambia-te-vendan-lo-que-te-vendan">Qué no cambia, te vendan lo que te vendan</h2>
<p>Un test sigue demostrando solo lo que ejercita. Una suite en verde sobre código generado significa lo mismo que significó siempre, que los caminos para los que escribiste aserciones se comportaron como afirmaste, y nada sobre los caminos que no. El modelo no vuelve seguras tus ramas sin probar. Si acaso escribe más ramas, más rápido, así que la <a href="/es/blog/hecho-significa-hecho/">distancia entre «los tests pasan» y «la feature es correcta»</a> se ensancha, no se estrecha.</p>
<p>La cobertura sigue mintiendo sobre lo que te importa. La cobertura de líneas te dice que una línea se ejecutó, no que una aserción habría cazado su fallo. Puedes ejecutar todas las líneas de un módulo generado sin afirmar casi nada, y el número queda estupendo. La advertencia de Martin Fowler de que <a href="https://martinfowler.com/bliki/TestCoverage.html">la cobertura de tests es una señal útil y un objetivo pésimo</a> aplica aquí con toda su fuerza, porque los agentes son buenísimos produciendo tests que suben el número y no comprueban nada. Pídele a uno que «añada tests» y cuenta cuántos afirman que una función retorna sin lanzar.</p>
<p>La pirámide sigue en pie. Un montón de tests end-to-end sobre código generado es tan lento y frágil como siempre, y una base de tests unitarios rápidos que fijan comportamiento de verdad sigue siendo lo que te deja cambiar cosas sin miedo. La <a href="https://martinfowler.com/articles/practical-test-pyramid.html">pirámide de tests práctica</a> no quedó derogada porque ahora teclee una máquina. Y el <a href="https://martinfowler.com/bliki/SelfTestingCode.html">código que se prueba a sí mismo</a>, la propiedad de que el sistema pueda demostrarse correcto a demanda, vale más cuando no escribiste el sistema, no menos. Es lo único entre tú y una base de código que tienes que creer por fe.</p>
<h2 id="el-test-que-el-agente-escribe-para-su-propio-código">El test que el agente escribe para su propio código</h2>
<p>Hay un modo de fallo concreto que merece nombre porque ya es el de por defecto. Le pides a un agente que implemente una feature y que escriba tests para ella. Hace las dos cosas, en el mismo turno, desde el mismo contexto. Los tests pasan. Te sientes cubierto.</p>
<p>No lo estás. Tienes un sistema donde el mismo proceso escribió la implementación y el examen, sosteniendo una única idea del comportamiento, y se autocorrigió. Si el modelo malentendió el requisito, lo malentendió de forma consistente, y los tests codifican el malentendido como resultado esperado. El verde es real. La corrección no. Es el primo cercano del <a href="/es/blog/exitos-falsos-de-agentes/">agente que informa «los tests pasan» sin ejecutar nada</a>, solo que peor, porque aquí los tests corrieron de verdad y pasaron de verdad, y siguen sin valer como evidencia de corrección.</p>
<p>El arreglo es la separación. El comportamiento lo especificas tú, o se genera en un paso aparte desde otro encuadre, y se fija antes de que exista la implementación. Luego la implementación se genera contra eso. El examen tiene que ser anterior a la respuesta, o no es un examen.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="El examen tiene que preceder a la respuesta: fija el comportamiento desde la spec, genera, y comprueba el código contra tests que nunca vio."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CRITERIOS</text><path d="M 190 95 L 212 95 M 206 89 L 212 95 L 206 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">TESTS</text><path d="M 368 95 L 390 95 M 384 89 L 390 95 L 384 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CÓDIGO</text><path d="M 546 95 L 568 95 M 562 89 L 568 95 L 562 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="62" width="144" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="646" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">COMPROBAR</text></svg><figcaption>El examen tiene que preceder a la respuesta: fija el comportamiento desde la spec, genera, y comprueba el código contra tests que nunca vio.</figcaption></figure>
<h2 id="cómo-mantener-veraces-los-tests-con-código-generado">Cómo mantener veraces los tests con código generado</h2>
<p>Escribe las aserciones desde la especificación, no desde el diff. Si te descubres abriendo el fichero generado para decidir qué afirmar, para. Estás a punto de ratificar el código en vez de probarlo. Vuelve a lo que la feature debía hacer.</p>
<p>Fija comportamiento en la frontera, no en las tripas. El código generado se reescribe. Si tus tests están soldados a la estructura privada que el agente produjo, se rompen en cada regeneración y aprendes a ignorarlos. Prueba el contrato observable, la entrada, la salida y el efecto, para que los tests sobrevivan a que el agente reescriba el medio.</p>
<p>Guarda al menos un test que el agente nunca vio. Cuando generes la implementación y los tests juntos, añade después tu propio caso, desde la spec, a mano. Un testigo imparcial basta para cazar toda una clase de disparates seguros de sí mismos.</p>
<p>Trata la cobertura como un suelo con dientes, no como un trofeo. Un número por debajo del cual nadie puede bajar es un gate. Un número en un panel es decoración. Si el gate se satisface con tests que no afirman nada, el gate también es decoración.</p>
<p>Nada de esto es teoría nueva de testing. Es teoría vieja aplicada a una situación en la que la intención se marchó del edificio. Toda la disciplina de <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado por IA</a> se apoya en esto: un test solo es evidencia cuando se escribió para defender un comportamiento que existe fuera del código que prueba. En cuanto el test empieza a describir la implementación en vez del requisito, vuelves a confiar en la frase segura de una máquina, disfrazada de verde.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La razón de que los tests deriven a ratificar el código es que la intención no tiene dónde vivir. El chat se va, el ticket dice «añadir búsqueda» y seis semanas después nadie sabe qué significaba «búsqueda correcta». PaellaDoc guarda los criterios de aceptación, las decisiones y el comportamiento como artefactos duraderos junto al código, para que el test tenga algo a lo que apuntar que la implementación nunca tocó. El agente escribe el código. Los criterios que acordaste antes escriben el examen. Cuando esos dos discrepan, te enteras antes de que se publique, que es el único momento en que enterarse sale barato.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="probar-código-generado-por-ia-es-distinto-de-probar-el-que-escribiste-tú">¿Probar código generado por IA es distinto de probar el que escribiste tú?</h3>
<p>Cambia una cosa: la intención nunca estuvo en la cabeza de nadie. Cuando escribes código, la intención vive en tu mente y el test es una segunda expresión independiente de ella. Con código generado falta ese segundo testigo, así que si escribes los tests después de leer la implementación, codifican lo que el código hace en vez de lo que debía hacer. Casi todo lo demás de probar software sigue exactamente igual.</p>
<h3 id="por-qué-mis-tests-siempre-pasan-a-la-primera-con-código-generado-por-ia">¿Por qué mis tests siempre pasan a la primera con código generado por IA?</h3>
<p>Porque los escribiste después de leer el código, así que describen la implementación en vez del requisito. El código dice X, el test afirma X, coinciden, verde. Has demostrado que el código hace lo que el código hace y nada sobre lo que querías. El arreglo es escribir las aserciones desde la especificación, no desde el diff, para que el test defienda un comportamiento que existe fuera del código que comprueba.</p>
<h3 id="debe-la-misma-ia-escribir-el-código-y-sus-tests">¿Debe la misma IA escribir el código y sus tests?</h3>
<p>No en el mismo paso desde el mismo contexto. Si el modelo malentendió el requisito, lo malentiende de forma consistente, y los tests codifican ese malentendido como resultado esperado. El verde es real, la corrección no. Sepáralos: especifica el comportamiento tú y fíjalo antes de que exista la implementación, luego genera contra eso. Guarda al menos un test que el agente nunca vio. El examen tiene que ser anterior a la respuesta.</p>
<h3 id="una-cobertura-alta-significa-que-el-código-generado-por-ia-es-correcto">¿Una cobertura alta significa que el código generado por IA es correcto?</h3>
<p>No. La cobertura te dice que una línea se ejecutó, no que una aserción habría cazado su fallo. Puedes ejecutar todas las líneas de un módulo generado sin afirmar casi nada mientras el número queda estupendo, y los agentes son buenísimos produciendo tests que suben la cobertura y no comprueban nada real. Trata la cobertura como un suelo con dientes, un gate por debajo del cual nadie baja, no como un trofeo en un panel. Si tests que no afirman nada satisfacen el gate, el gate es decoración.</p>]]></content>
    <summary type="html"><![CDATA[Escribir tests para código que generó un agente parece normal hasta que notas que pasan a la primera. Pasan porque los escribiste después de leer el código, así que codifican lo que el código hace en lugar de lo que debía hacer. La intención que un test debería proteger nunca estuvo en la cabeza de nadie. Eso es lo que cambia. Casi todo lo demás de probar software sigue igual, y fingir lo contrario es como acabas con una suite en verde que no demuestra nada.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="testing-ai-code"/><category term="ai-coding"/><category term="verification"/><category term="test-automation"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Escribes PRDs que nadie lee. El problema es el artefacto.</title>
    <link href="https://paelladoc.com/es/blog/prds-que-nadie-lee/" rel="alternate" type="text/html" title="Escribes PRDs que nadie lee. El problema es el artefacto."/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/prds-que-nadie-lee/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/prds-que-nadie-lee/"><![CDATA[<p>Te pasaste casi un día entero con el PRD. Planteamiento del problema, objetivos, no-objetivos, historias de usuario, casos límite, el diagramita. Lo compartiste. Dos personas ojearon el resumen. Ingeniería preguntó, en la daily, algo que el documento respondía en la línea cuarenta. Nadie leyó más allá del primer pantallazo, y la feature se construyó igualmente a partir de un hilo de Slack y una conversación de pasillo.</p>
<p>La reacción estándar es culpa y el propósito de escribir mejores. Más cortos. Más directos. Mejor plantilla. Eso es tratar un fallo estructural como si fuera personal. La gente no deja de leer tu PRD porque sea largo o porque enterraste la idea. No lo lee por lo que un PRD <em>es</em>: un documento que quedó terminado en el momento en que lo escribiste, en un sitio donde el trabajo real no vive.</p>
<h2 id="un-prd-nace-muerto-por-diseño">Un PRD nace muerto por diseño</h2>
<p>Un PRD es una foto fija. Describe cómo debería ser el producto en el instante en que dejaste de teclear. Esa es toda su naturaleza, y es la raíz del problema, porque un producto no es una foto fija. Es algo que cambia cada día según se toman decisiones, se escribe código y la realidad empuja de vuelta.</p>
<p>Así que el hueco se abre de inmediato. Al día siguiente de publicarlo, un caso límite resulta estar mal, aparece una restricción, una decisión se revisa en una reunión de la que el documento no sabe nada. El PRD no se actualiza, porque actualizar un documento es trabajo manual que compite con todo lo demás y siempre pierde. En una semana el PRD y el producto discrepan. En un mes todo el mundo sabe que el PRD está desactualizado, así que nadie se fía, así que nadie lo lee, así que nadie lo mantiene al día. El abandono es racional. Leer un documento que sabes desactualizado es peor que no leerlo, porque te dice cosas seguras, concretas y equivocadas.</p>
<h2 id="el-documento-hace-tres-trabajos-y-ninguno-bien">El documento hace tres trabajos y ninguno bien</h2>
<p>Parte de por qué el PRD está tan poco querido es que se le pide, calladamente, ser tres cosas distintas, y es malo en las tres a la vez.</p>
<figure class="tp-diagram tp-diagram--graph" data-diagram-type="graph" role="img" aria-label="A un solo artefacto se le pide calladamente ser tres cosas a la vez, y es malo en las tres."><svg viewBox="0 0 760 320" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="380" y1="160" x2="140" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="140" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="140" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">REGISTRO DE DECISIONES</text><line x1="380" y1="160" x2="620" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="620" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="620" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">COMUNICACIÓN</text><line x1="380" y1="160" x2="96" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="96" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="96" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">SPEC DE CONSTRUCCIÓN</text><circle cx="380" cy="160" r="14" fill="var(--tp-mostaza)" fill-opacity="0.16" stroke="var(--tp-mostaza)" stroke-width="1.8"></circle>
  <text x="380" y="194" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">PRD</text></svg><figcaption>A un solo artefacto se le pide calladamente ser tres cosas a la vez, y es malo en las tres.</figcaption></figure>
<ul>
<li><strong>Un <a href="/es/blog/registro-de-decisiones/">registro de decisiones</a>.</strong> Qué decidimos y por qué. Pero las decisiones tomadas después de escribir el PRD nunca vuelven a entrar, así que captura las decisiones de un día y se pierde el resto en silencio.</li>
<li><strong>Un artefacto de comunicación.</strong> Alinear a todo el mundo. Pero alinear es una conversación, y un documento estático y largo es un mal sustituto de una. La gente se alinea en la discusión, y luego el documento fosiliza el estado en que la discusión quedó.</li>
<li><strong>Una <a href="/es/blog/spec-vs-prd/">spec de construcción</a>.</strong> Qué construir de verdad. Pero es prosa, ambigua por naturaleza, y ahora también la lee un agente, que rellena cada hueco con una suposición segura.</li>
</ul>
<p>Meter los tres en un solo artefacto garantiza mediocridad en cada uno. El registro de decisiones está desactualizado, la comunicación es de un solo sentido y la spec de construcción es ambigua, que es la razón por la que un <a href="/es/blog/prototipo-como-spec/">prototipo funcionando es una spec más nítida que la prosa</a>. Y como es un documento grande, arreglar cualquiera de los tres trabajos implica reescribirlo entero, cosa que nadie hace.</p>
<h2 id="qué-cambia-cuando-también-lo-leen-los-agentes">Qué cambia cuando también lo leen los agentes</h2>
<p>Durante años la ambigüedad del PRD era sobrevivible porque lo leía un ingeniero humano que rellenaba los huecos con criterio y una pregunta de seguimiento. El documento podía ser descuidado porque el lector era listo y venía a preguntarte.</p>
<p>Un agente no viene a preguntarte. Lee el PRD, choca con la misma ambigüedad y la resuelve en silencio con la interpretación más probable, que muchas veces no es la tuya. Luego construye. Rápido. La vaguedad que un humano habría marcado se vuelve una feature publicada que técnicamente encaja con las palabras y se salta la intención. El PRD que nadie lee se ha vuelto un problema peor: un PRD que el agente lee demasiado literal y demasiado rápido, sin nadie en el bucle que cace el hueco antes de que sea código. Cuando <a href="/es/blog/product-management-era-ia/">construir se abarató y decidir se encareció</a>, el artefacto flojo dejó de ser una molestia menor y pasó a ser lo que publica el producto equivocado.</p>
<h2 id="sustituye-el-documento-por-una-decisión-viva">Sustituye el documento por una decisión viva</h2>
<p>El arreglo no es un documento mejor. Es dejar de tratar el requisito como documento y tratarlo como una decisión viva conectada al trabajo.</p>
<p>En concreto, eso significa unos cuantos cambios:</p>
<ul>
<li><strong>Pequeño y direccionable, no grande y monolítico.</strong> Una decisión sobre un comportamiento, que puedes referenciar, revisar y superar por sí sola, en vez de un documento de cincuenta secciones donde cualquier cambio implica republicarlo todo.</li>
<li><strong>Conectado al código y a la evidencia, no al lado de ellos.</strong> El requisito apunta a la implementación que lo satisface y a la comprobación que lo prueba. Cuando cambia el código, ves el requisito que toca. Cuando cambia el requisito, ves qué tiene que moverse.</li>
<li><strong>Vivo, no fotografiado.</strong> Su estado actual refleja las decisiones actuales, porque actualizarlo es parte del flujo del trabajo y no una tarea de documentación aparte que compite por tiempo y pierde.</li>
</ul>
<p>Cuando el requisito es una cosa viva y pequeña cableada al código y a la evidencia, leerlo deja de ser un favor. La gente lo consulta porque es donde vive la verdad actual, no la verdad de hace tres semanas. Así es como se ve una <a href="/es/blog/especificaciones-vivas/">spec viva al lado de una estática</a>, una vez aceptas que el documento era el problema. La razón por la que nadie leía el PRD nunca fue vagancia. Era que el PRD no merecía la lectura, porque no estaba conectado a nada y ya no era cierto.</p>
<h2 id="así-se-forma-una-feature-factory">Así se forma una feature factory</h2>
<p>Hay una línea recta entre los PRDs sin leer y una <a href="/es/blog/que-es-una-feature-factory/">feature factory</a>. Cuando el requisito es un documento muerto, las decisiones reales viven en Slack, en la memoria, en la cabeza de quien estuviera en la sala. Nada conecta una feature publicada con la decisión que la motivó, así que nadie puede preguntarse si hizo aquello para lo que era. El equipo simplemente publica, porque publicar es la única señal legible que queda. El PRD sin leer no es un síntoma de la feature factory. Es uno de los mecanismos que la construye, porque corta el vínculo entre intención y output que si no te dejaría distinguir productividad de movimiento.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Por eso en <a href="/es/">PaellaDoc</a> un requisito no es un documento que escribes y abandonas. Es un artefacto vivo conectado al código que lo implementa, a las decisiones que lo moldearon y a la evidencia de que funciona. Cuando el código se mueve, el requisito que toca es visible. Cuando una decisión cambia, el requisito lo refleja. No hay un documento aparte que mantener sincronizado a mano, porque el requisito vive en el mismo grafo que el trabajo, que es el único arreglo en el que estar al día sale más barato que quedarse desactualizado.</p>
<p>Deja de intentar escribir PRDs que la gente lea. El PRD mejor escrito del mundo sigue quedando desactualizado al día siguiente de publicarlo, porque el problema nunca fue la redacción. Mata el documento muerto. Quédate con una decisión viva, cerca del trabajo, cierta ahora mismo. Esa sí la leen, porque por una vez merece su tiempo.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-nadie-lee-el-prd">¿Por qué nadie lee el PRD?</h3>
<p>No es vagancia, ni que sea largo. Nadie lo lee porque un PRD queda terminado en el momento en que lo escribes y vive donde el trabajo no está. En una semana discrepa del producto; en un mes todo el mundo sabe que está desactualizado, así que deja de fiarse. Leer un documento que sabes obsoleto es peor que no leerlo.</p>
<h3 id="los-product-managers-siguen-escribiendo-prds-en-la-era-de-la-ia">¿Los product managers siguen escribiendo PRDs en la era de la IA?</h3>
<p>El documento, cada vez menos. El trabajo que hacía, más que nunca. Lo que cambia es el artefacto: un PRD estático ahora es peligroso porque un agente lee su ambigüedad, la resuelve en silencio con la suposición equivocada y publica rápido. El requisito tiene que existir, pero como una decisión viva y pequeña cableada al código y a la evidencia, no como una foto fija que nadie mantiene.</p>
<h3 id="qué-sustituye-al-prd">¿Qué sustituye al PRD?</h3>
<p>Una decisión viva conectada al trabajo, no un documento mejor. Hazla pequeña y direccionable, para revisar un comportamiento sin republicar cincuenta secciones. Cablearla al código que la satisface y a la comprobación que la prueba, para que un cambio en cualquier lado sea visible. Mantenla viva como parte del flujo del trabajo, para que su estado actual sea la verdad actual.</p>
<h3 id="por-qué-un-prd-ambiguo-es-más-peligroso-con-agentes-de-ia">¿Por qué un PRD ambiguo es más peligroso con agentes de IA?</h3>
<p>Un ingeniero humano leía un PRD vago, rellenaba el hueco con criterio y volvía con una pregunta. Un agente no. Resuelve la misma ambigüedad en silencio con la interpretación más probable, muchas veces no la tuya, y la construye rápido. La vaguedad que una persona habría marcado se vuelve una feature publicada que encaja con las palabras y se salta la intención, sin nadie en el bucle que la cace.</p>]]></content>
    <summary type="html"><![CDATA[Te pasas un día con un PRD y lo ves quedar sin leer. El instinto es escribir mejores. El arreglo real es otro: el PRD es un artefacto muerto, terminado en el momento en que lo escribes y desconectado del trabajo que debería gobernar. Sustituye el documento por una decisión viva cableada al código y a la evidencia, y leerlo deja de ser un favor que te hacen.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="prds-nobody-reads"/><category term="product-management"/><category term="ai-coding"/><category term="living-specs"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">Pérdida de contexto entre sesiones: el asesino de productividad sin presupuesto</title>
    <link href="https://paelladoc.com/es/blog/perdida-de-contexto-entre-sesiones/" rel="alternate" type="text/html" title="Pérdida de contexto entre sesiones: el asesino de productividad sin presupuesto"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/perdida-de-contexto-entre-sesiones/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/perdida-de-contexto-entre-sesiones/"><![CDATA[<p>Tomaste una decisión el martes. El agente y tú hablasteis por qué la capa de auth tenía que seguir siendo stateless, pesasteis dos enfoques, elegisteis uno y seguisteis. El jueves abres una sesión nueva, pides un cambio cerca, y el agente te propone tan contento el enfoque que ya habías descartado. Se lo vuelves a explicar. Acabas de pagar esa decisión dos veces, y la segunda no te compró nada.</p>
<p>Eso es la pérdida de contexto, y si operas agentes para trabajo real es probablemente el mayor impuesto sobre tu día. No la calidad del modelo. No el coste de tokens. El goteo constante de reestablecer cosas que el sistema ya había resuelto, porque el sitio donde las resolvió fue una conversación, y las conversaciones terminan.</p>
<p>No parece un coste grande porque nunca llega como una sola factura. Llega como mil re-explicaciones pequeñas, cada una lo bastante barata para absorberla, sumando una fracción grande de tu atención gastada en contarle a los agentes lo que, en cierto sentido, ya sabían.</p>
<h2 id="dos-pérdidas-distintas-que-llamamos-igual">Dos pérdidas distintas que llamamos igual</h2>
<p>«Perder contexto» cubre dos fallos que se comportan distinto y necesitan arreglos distintos.</p>
<p>El primero es la pérdida <strong>dentro</strong> de una sesión, cuando la ventana de contexto se llena y se compacta. Un run largo se resume para caber, y resumir es lossy a propósito. Manejar esa frontera a propósito es su propia disciplina, <a href="/es/blog/gestion-ventana-de-contexto/">gestionar la ventana de contexto en trabajo largo</a>. El modelo se queda un resumen comprimido y suelta los detalles. Los detalles que suelta suelen ser los que menos importaban al resumen y más te importaban a ti: la razón exacta por la que descartaste un enfoque, el invariante que acordaste proteger hace tres horas, el caso límite que le dijiste explícitamente que cubriera. El transcript sigue leyéndose bien. El agente simplemente deja de honrar en silencio una restricción que ya no puede ver. Es primo cercano de por qué <a href="/es/blog/los-agentes-derivan/">los agentes derivan</a>: la especificación contra la que trabaja cambió sin ruido, y nada avisó del cambio.</p>
<p>El segundo es la pérdida <strong>entre</strong> sesiones. Una sesión nueva arranca en frío. Lo que no quedó escrito en algún sitio duradero simplemente no está. El código sobrevivió, porque el código es un archivo. El razonamiento detrás del código no, porque el razonamiento vivía en el chat. Reabres el proyecto y el agente sabe qué dice el código y nada de por qué lo dice.</p>
<p>Los dos son el mismo error de fondo: tratar la conversación como si fuera memoria. No lo es. Es una superficie de trabajo que se borra.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Dos fallos que llamamos igual: uno cuando la ventana se compacta a mitad de run, otro cuando una sesión nueva arranca en frío. Necesitan arreglos distintos."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">dentro de una sesión</p>
    <ul><li>la ventana se compacta</li><li>el resumen suelta detalles</li><li>el invariante se va</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">entre sesiones</p>
    <ul><li>la sesión arranca en frío</li><li>nada duradero persiste</li><li>el porqué se pierde</li></ul>
  </div>
</div><figcaption>Dos fallos que llamamos igual: uno cuando la ventana se compacta a mitad de run, otro cuando una sesión nueva arranca en frío. Necesitan arreglos distintos.</figcaption></figure>
<h2 id="qué-desaparece-de-verdad">Qué desaparece de verdad</h2>
<p>Ayuda ser concreto sobre qué pierdes, porque «contexto» es demasiado vago para defenderse de ello. Cuando una sesión se compacta o termina, lo que se evapora de forma fiable es:</p>
<ul>
<li><strong>Las decisiones y sus razones.</strong> No solo qué elegiste, sino qué descartaste y por qué. La opción descartada es el conocimiento caro, y es lo primero que un resumen tira.</li>
<li><strong>Los invariantes.</strong> Lo que tiene que seguir siendo cierto. «Nunca bloquees el hilo principal aquí.» «Esta tabla es solo-append.» Un agente que no ve el invariante lo rompe y pasa su propia revisión, porque desde dentro de la ventana no había regla que violar.</li>
<li><strong>El espacio negativo.</strong> Casos límite que acordaste cubrir, alcance que acordaste dejar fuera. La ausencia es imposible de reconstruir desde un diff. Nadie puede mirar el código y ver el caso al que le dijeron que no se preocupara.</li>
<li><strong>El hilo de la intención.</strong> Por qué existe esta tarea, qué comportamiento busca instalar, cómo conecta con la cosa tres tareas más allá. Es la primera baja de un arranque en frío y la más difícil de reconstruir.</li>
</ul>
<p>Fíjate en que nada de esto es el código. El código es lo único que sobrevive por defecto. Todo lo que le da sentido al código es justo lo que se pierde.</p>
<h2 id="por-qué-una-ventana-más-grande-no-te-salva">Por qué una ventana más grande no te salva</h2>
<p>La respuesta obvia es una ventana de contexto más grande, y ayuda en el margen, pero no resuelve el problema, por dos razones.</p>
<p>Primera, más ventana es más sitio que llenar, no una garantía de conservar lo correcto. Un run lo bastante largo se compacta igual, dé igual el tamaño de la ventana, y cuando lo hace, el mismo resumen lossy decide qué guardar. Una ventana más grande pospone la pérdida. No cambia su naturaleza.</p>
<p>Segunda, y más de fondo: la ventana es por sesión. No puede cargar nada a través de la frontera donde una sesión acaba y otra empieza. La pérdida entre sesiones no es un problema de capacidad. Ninguna ventana, por grande que sea, persiste después de cerrarla. Es el argumento que desarrollé en <a href="/es/research/context-engineering-para-agentes-de-codigo/">context engineering para agentes de código</a>: el movimiento útil no es meter más en la ventana, es ser deliberado con qué entra en ella y qué sobrevive fuera.</p>
<h2 id="el-arreglo-es-dejar-de-usar-el-chat-como-almacén">El arreglo es dejar de usar el chat como almacén</h2>
<p>Las cosas duraderas, decisiones, invariantes, intención, tienen que vivir en algún sitio que no sea la conversación. Ese es el movimiento entero. Todo lo demás es detalle.</p>
<p>En concreto, eso significa que una decisión se escribe cuando se toma, en una forma que un agente futuro en frío pueda cargar, no queda implícita en un transcript que nadie va a reabrir. Significa que los invariantes viven en un fichero de reglas que el agente lee al empezar cada sesión, no en tu recuerdo de haberlos dicho una vez. Significa que la intención detrás de una tarea viaja con la tarea como artefacto, no como tu memoria de un chat.</p>
<p>Esto es justo de lo que va la <a href="/es/blog/memoria-agentes-de-codigo/">memoria para agentes de código</a>: decidir qué debe persistir fuera del chat, y en qué forma. La pérdida de contexto es la enfermedad. La memoria externa y deliberada es el tratamiento. Los dos artículos son el mismo problema visto desde la herida y desde la cura.</p>
<p>Hay una versión de esto del lado de producto, y vale la pena ver el paralelo. Los equipos pierden entre personas lo mismo que los agentes pierden entre sesiones: la razón de una decisión, la restricción que alguien conocía y nunca escribió. Eso es <a href="/es/blog/memoria-de-producto/">memoria de producto</a>, lo que un equipo olvida y el sistema no debería. La respuesta es la misma en ambos casos, un sistema que recuerda en nombre del equipo, que es la idea detrás de <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">el cerebro de producto que se mantiene solo</a>. El olvido humano y la pérdida de contexto del agente son el mismo fallo a dos escalas.</p>
<h2 id="cómo-se-ve-lo-bueno">Cómo se ve lo bueno</h2>
<p>Sabrás que lo has arreglado cuando una sesión en frío no sea un arranque en frío. Cuando abras un agente nuevo en un proyecto y cargue las decisiones, los invariantes y la intención actual antes de escribir una línea, porque esas cosas viven en el repo y el modelo las lee, no en un chat que cerraste el martes.</p>
<p>Eso no pasa por accidente, y no pasa prompteando más fuerte cada mañana. Pasa negándote a que el conocimiento duradero viva en un sitio efímero. El chat es donde ocurre el trabajo. No es donde vive la memoria. Ten esas dos cosas claras y el impuesto de productividad desaparece sin ruido, porque dejas de pagar las mismas decisiones dos veces.</p>
<p>Esa negativa, hecha sistemática, es buena parte de lo que significa dejar de ser <a href="/es/blog/eres-el-runtime/">el runtime</a> a mano. Y es por lo que correr <a href="/es/blog/sesiones-paralelas-agentes/">varias sesiones en paralelo</a> solo escala si cada una puede cargar el contexto compartido por su cuenta, en vez de enrutar cada dato recordado por el único humano que estaba cuando se decidió.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuánto de tu primera hora con un agente se va en re-explicarle lo que ya debería saber? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-mi-agente-de-código-pierde-el-contexto-entre-sesiones">¿Por qué mi agente de código pierde el contexto entre sesiones?</h3>
<p>Porque el razonamiento vivía en el chat, y el chat es una superficie de trabajo que se borra. El código sobrevive porque es un archivo; las decisiones, los invariantes y la intención detrás de él no, salvo que quedaran escritos en algún sitio duradero. Una sesión nueva arranca en frío y sabe qué dice el código y nada de por qué lo dice.</p>
<h3 id="es-lo-mismo-perder-contexto-dentro-de-una-sesión-que-entre-sesiones">¿Es lo mismo perder contexto dentro de una sesión que entre sesiones?</h3>
<p>No, y necesitan arreglos distintos. Dentro de una sesión, la ventana se llena y la compactación resume de forma lossy, soltando justo los detalles que más te importaban. Entre sesiones no se traslada nada, porque la ventana es por sesión. Uno es un problema de compresión, el otro de persistencia.</p>
<h3 id="una-ventana-de-contexto-más-grande-arregla-la-pérdida-de-contexto">¿Una ventana de contexto más grande arregla la pérdida de contexto?</h3>
<p>Solo en el margen. Más ventana es más sitio que llenar, no una garantía de conservar lo correcto, y un run largo se compacta igual. Y más de fondo: la ventana es por sesión. Ninguna ventana, por grande que sea, persiste después de cerrarla. La pérdida entre sesiones no es un problema de capacidad.</p>
<h3 id="cómo-dejo-de-re-explicarle-las-mismas-decisiones-a-un-agente">¿Cómo dejo de re-explicarle las mismas decisiones a un agente?</h3>
<p>Deja de usar el chat como almacén. Escribe las decisiones cuando se toman, guarda los invariantes en un fichero de reglas que el agente lee al empezar cada sesión, y deja que la intención de una tarea viaje con ella como artefacto. Cuando eso vive en el repo y no en un transcript cerrado, una sesión en frío deja de ser un arranque en frío.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="perdida-de-contexto"/><category term="agents"/><category term="ai-coding"/><category term="runtime"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Orquestar varios agentes sin que se contaminen entre sí</title>
    <link href="https://paelladoc.com/es/blog/orquestacion-multiagente/" rel="alternate" type="text/html" title="Orquestar varios agentes sin que se contaminen entre sí"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/orquestacion-multiagente/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/orquestacion-multiagente/"><![CDATA[<p>Dos agentes editando el mismo código a la vez no son dos veces un agente. Son un modo de fallo nuevo. El agente A refactoriza una interfaz. El agente B, en su propia sesión, construye una feature que llama a esa interfaz, sobre la forma vieja, porque nadie le dijo que la forma cambió. Los dos son localmente correctos. Los dos pasan sus propias comprobaciones. Juntos producen un código que no compila o, peor, uno que compila y está mal en silencio.</p>
<p>Eso es contaminación, y es lo que convierte «voy a correr más agentes» de una victoria de throughput en un lío. Que los agentes en paralelo ayuden de verdad se reduce a tres disciplinas: aíslalos, dales un contrato compartido y reconcílialos a la vuelta. Sáltate una y las colisiones se comen la ganancia.</p>
<h2 id="por-qué-más-agentes-multiplican-el-problema-en-vez-de-repartir-el-trabajo">Por qué más agentes multiplican el problema en vez de repartir el trabajo</h2>
<p>Un solo agente tiene una propiedad agradable: ve todo lo que hizo. Su contexto es su propia historia. En el momento en que tienes varios agentes trabajando a la vez, esa propiedad desaparece. Cada uno ve su ventana y nada de las demás. No pueden observar los cambios de los otros, porque «el otro agente editó este fichero» no es un hecho que exista dentro del contexto de ninguno.</p>
<p>Así que la coordinación que un solo agente hacía implícitamente, recordando sus propias ediciones, ahora tiene que hacerla explícitamente algo fuera de los agentes. Si ese algo eres tú, leyendo cada diff y sosteniendo cada colisión en la cabeza, te has convertido en el bus de integración, y eres el cuello de botella que el paralelismo debía quitar. Esta es la textura concreta de ser <a href="/es/blog/eres-el-runtime/">el runtime</a> a mano: no escribes código, eres el canal entre agentes que no se ven.</p>
<h2 id="disciplina-uno-aislamiento">Disciplina uno: aislamiento</h2>
<p>La primera regla es que los agentes no deben compartir una superficie de trabajo mientras trabajan. Dos agentes escribiendo a los mismos ficheros en el mismo directorio se corromperán el estado constantemente, no porque sean malos sino porque ninguno ve los cambios sin commitear del otro.</p>
<p>Para eso están los worktrees. Cada agente tiene su propio checkout, su propia rama, su propio directorio de trabajo. Puede editar libremente sin pisar a nadie, porque no hay nadie más en su copia. Las colisiones no pasan durante el trabajo. Se aplazan al merge, donde se pueden manejar a propósito en vez de en carrera. Correr <a href="/es/blog/sesiones-paralelas-agentes/">sesiones paralelas en worktrees</a> es la base mecánica de todo el trabajo multiagente, y lo demás lo da por hecho.</p>
<p>El aislamiento te compra seguridad durante la ejecución. Lo que no te compra es coherencia. Dos agentes aislados pueden construir cada uno algo sensato que contradice al otro, porque el aislamiento impide que se corrompan los ficheros, no que tomen decisiones incompatibles. De eso van las dos disciplinas siguientes.</p>
<h2 id="disciplina-dos-un-contrato-compartido">Disciplina dos: un contrato compartido</h2>
<p>Los agentes aislados aún necesitan estar de acuerdo en lo que los cruza: las interfaces, los invariantes, la forma de la cosa que los dos tocan. Si cada agente inventa su propia versión de la frontera compartida, el aislamiento solo significa que chocan limpio en el merge en vez de sucio durante el trabajo. Mejor, pero no resuelto.</p>
<p>El arreglo es que las partes compartidas viven en un contrato que ambos agentes leen, fuera de la sesión de cualquiera. La interfaz contra la que ambos construyen está especificada, no improvisada. Los invariantes que ambos deben respetar están en el fichero de reglas que ambos cargan. Cuando el agente A necesita cambiar la interfaz compartida, eso es un cambio al contrato, no una decisión privada dentro de la ventana de A que B descubrirá rompiéndose.</p>
<p>Aquí convergen la orquestación multiagente y la memoria. El contrato compartido es justo la <a href="/es/blog/memoria-agentes-de-codigo/">memoria que persiste fuera del chat</a>: decisiones e invariantes que no posee ningún agente, que todos leen. Sin esa capa externa y compartida, «orquestación» es solo varios agentes adivinando una frontera que ninguno puede ver, y las adivinanzas no van a cuadrar.</p>
<p>Y deberías esperar divergencia incluso con contrato, porque un contrato restringe sin eliminar las opciones. Diseñar para esa expectativa, en vez de suponer que el contrato pone a todos de acuerdo, es justo el sentido de aceptar que <a href="/es/blog/los-agentes-derivan/">los agentes derivan</a>. El aislamiento y los contratos reducen las colisiones. No las llevan a cero. Por eso la tercera disciplina no es opcional.</p>
<h2 id="disciplina-tres-reconciliación">Disciplina tres: reconciliación</h2>
<p>El aislamiento aplaza las colisiones al merge. Un contrato compartido encoge cuántas hay. La reconciliación es donde de verdad resuelves las que quedan, y es el paso que la gente se salta porque no luce y porque es donde vive el trabajo real del desarrollo multiagente.</p>
<p>Reconciliar no es <code>git merge</code> y rezar. Es el acto deliberado de volver a juntar las ramas paralelas y comprobar que la combinación es coherente, no solo que cada rama estaba bien sola. Este es justo el problema de lo <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto, globalmente incoherente</a>, y el trabajo multiagente es su forma más aguda: has fabricado, a propósito, varios cambios localmente correctos, y nada garantiza que sumen un sistema globalmente correcto.</p>
<p>Un paso de reconciliación de verdad hace las preguntas que ningún agente solo podría: ¿la feature del agente B sigue funcionando contra la interfaz refactorizada del agente A? ¿Alguien rompió un invariante que solo importaba a través de la frontera? ¿El resultado integrado pasa los criterios que las piezas pasaban por separado? La reconciliación es verificación aplicada a las costuras, y las costuras son justo donde fallan los agentes en paralelo, porque son el único sitio donde ningún agente individual estaba mirando. Esa comprobación combinada es un <a href="/es/blog/bucles-de-verificacion/">bucle de verificación</a> apuntado a la integración, no al diff individual: una puerta que el resultado integrado tiene que pasar, no una afirmación que cada agente se auto-declara.</p>
<h2 id="la-forma-de-esto">La forma de esto</h2>
<p>Junto todo, orquestar varios agentes sin contaminación es un bucle, no un lanzamiento. Aíslas cada agente en su worktree para que no se corrompan durante el trabajo. Les das un contrato compartido para que lo que los cruza esté especificado, no improvisado. Reconcilias en el merge, comprobando la combinación y no solo las partes. Y lo vuelves a hacer.</p>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="Orquestar agentes es un bucle, no un lanzamiento: aísla para que no se corrompan, comparte un contrato, reconcilia las costuras, y vuelve a empezar."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">AISLAR</text><path d="M 250 85 L 272 85 M 266 79 L 272 85 L 266 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="52" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CONTRATO COMPARTIDO</text><path d="M 488 85 L 510 85 M 504 79 L 510 85 L 504 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="52" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="618" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">RECONCILIAR</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">REPETIR</text></svg><figcaption>Orquestar agentes es un bucle, no un lanzamiento: aísla para que no se corrompan, comparte un contrato, reconcilia las costuras, y vuelve a empezar.</figcaption></figure>
<p>Lo que hay que interiorizar es que la parte difícil del trabajo multiagente no es lanzar los agentes. Lanzar es fácil, por eso todo el mundo empieza ahí y se choca con el muro. La parte difícil es la frontera entre ellos: el contrato compartido que leen y la reconciliación que pilla lo que cruzó la frontera mal. Acierta con aislamiento, contratos y reconciliación y más agentes significa de verdad más hecho. Falla en ellos y más agentes solo significa más colisiones que arbitrar a mano.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>Cuando dos de tus agentes chocan, ¿te enteras en el merge o tres commits después? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cómo-corres-varios-agentes-de-código-a-la-vez-sin-conflictos">¿Cómo corres varios agentes de código a la vez sin conflictos?</h3>
<p>Tres disciplinas. Aísla cada agente en su propio worktree para que no se corrompan los ficheros mientras trabajan. Dales un contrato compartido —las interfaces y los invariantes que ambos leen fuera de cualquier sesión— para que lo que los cruza esté especificado, no improvisado. Después reconcilia en el merge, comprobando que la combinación es coherente, no solo cada rama por separado. Sáltate una y las colisiones se comen la ganancia.</p>
<h3 id="pueden-dos-agentes-de-ia-editar-el-mismo-código-con-seguridad">¿Pueden dos agentes de IA editar el mismo código con seguridad?</h3>
<p>No sobre la misma superficie de trabajo. Dos agentes escribiendo a los mismos ficheros se corrompen el estado constantemente, porque ninguno ve los cambios sin commitear del otro. El arreglo es el aislamiento: cada agente tiene su propio checkout, rama y directorio con git worktrees. Las colisiones se aplazan al merge, donde se manejan a propósito en vez de en carrera. El aislamiento compra seguridad durante la ejecución, aunque no coherencia; eso necesita un contrato compartido y reconciliación.</p>
<h3 id="qué-es-la-contaminación-entre-agentes-en-paralelo">¿Qué es la contaminación entre agentes en paralelo?</h3>
<p>La contaminación es cuando dos cambios localmente correctos se combinan en un todo roto. El agente A refactoriza una interfaz; el agente B, en su sesión, construye una feature sobre la forma vieja porque nada le dijo que cambió. Los dos pasan sus propias comprobaciones, y juntos producen código que no compila o, peor, compila y está mal en silencio. Pasa porque el contexto de ningún agente contiene el hecho de que otro editó algo.</p>
<h3 id="cómo-integras-el-trabajo-de-varios-agentes-de-ia">¿Cómo integras el trabajo de varios agentes de IA?</h3>
<p>Con reconciliación, no con <code>git merge</code> y rezar. La reconciliación junta a propósito las ramas paralelas y comprueba la combinación: ¿la feature de B sigue funcionando contra la interfaz refactorizada de A?, ¿alguien rompió un invariante que solo importaba a través de la frontera?, ¿el resultado integrado pasa los criterios que las piezas pasaban solas? Es verificación apuntada a las costuras, que es justo donde fallan los agentes en paralelo, porque son donde ningún agente individual estaba mirando.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="multiagente"/><category term="orquestacion"/><category term="agents"/><category term="runtime"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Onboarding contra el grafo, no contra el conocimiento tribal</title>
    <link href="https://paelladoc.com/es/blog/onboarding-contra-el-grafo/" rel="alternate" type="text/html" title="Onboarding contra el grafo, no contra el conocimiento tribal"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/onboarding-contra-el-grafo/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/onboarding-contra-el-grafo/"><![CDATA[<p>Piensa en cómo arranca de verdad alguien en un codebase. No la wiki que le dijeron que leyera. El mecanismo real: le pregunta al que tiene al lado. “¿Dónde pasa la auth?” “¿Por qué está partido en dos este servicio?” “¿Puedo tocar esto o va a explotar?” Las respuestas salen de la memoria de alguien, y la persona nueva va copiando esa memoria a su propia cabeza. Seis semanas después ya trabaja sin preguntar, y el bucle se repite con el siguiente fichaje.</p>
<p>Ese mecanismo tiene un nombre que la gente rara vez dice en voz alta cuando lo elogia: onboarding contra el conocimiento tribal. El mapa del sistema vive en unas pocas cabezas senior, y volverse productivo es transferirlo, pregunta a pregunta, de sus cabezas a la tuya.</p>
<p>Funciona, justo hasta que deja de funcionar. La persona está ocupada. La persona se fue, y se llevó el mapa. La persona lo recordó mal, y ahora los dos creéis algo falso. Y hay un tipo nuevo de fichaje en el equipo que no puede usar este mecanismo en absoluto: el agente.</p>
<h2 id="el-agente-es-el-fichaje-más-nuevo-y-no-puede-preguntar">El agente es el fichaje más nuevo, y no puede preguntar</h2>
<p>En cada sesión, un agente de código llega a tu codebase como un ingeniero de primer día sin memoria de ayer. No sabe dónde pasa la auth ni por qué está partido el servicio. A diferencia del humano de primer día, no puede girarse y preguntar. No tiene a nadie de quien absorber el mapa tribal. Así que hace lo único disponible: hace grep, lee unos ficheros, e infiere.</p>
<p>Esa inferencia es el origen de la mayoría de los problemas que la gente le echa al modelo. El agente rompe un llamador que nunca vio, se salta una convención que nadie escribió, reimplementa algo que ya existía un directorio más allá. No son fallos de razonamiento. Son fallos de onboarding. Al agente lo soltaron en un sistema cuyo mapa vive en cabezas que no puede leer, y le pidieron rendir como si hubiera arrancado.</p>
<p>Esto lo sientes más cuando corres varios agentes a la vez. Cada uno es un fichaje nuevo, en cada sesión, sin mapa compartido entre ellos. El conocimiento tribal aquí ni siquiera tiene un cuerpo donde vivir. No hay un agente senior que se acuerde. Si el conocimiento no está escrito en algo que todos puedan consultar, no existe para ellos, y cada uno redescubrirá el codebase mal, en paralelo.</p>
<h2 id="el-conocimiento-tribal-también-falla-con-las-personas-solo-que-más-despacio">El conocimiento tribal también falla con las personas, solo que más despacio</h2>
<p>Es tentador tratar esto como un problema de agentes con un apaño humano. No lo es. <a href="/es/blog/conocimiento-tribal/">El conocimiento tribal siempre fue un punto único de fallo</a>. Los agentes solo hacen que el fallo sea rápido y evidente en vez de lento y negable.</p>
<p>Cuando la única copia de “por qué está construido así” vive en la cabeza de un ingeniero, ese ingeniero es un cuello de botella y un riesgo. Cada arranque grava su tiempo. <a href="/es/blog/memoria-de-producto/">Cada marcha es una lobotomía parcial del equipo</a>. El bus factor es el chiste que hace la gente porque la alternativa es admitir cuánto del sistema nadie escribió de verdad. La razón de que nunca pareciera urgente es que el onboarding humano es lo bastante lento como para taparlo. Pierdes el mapa poco a poco, fichaje a fichaje, y le echas la culpa del tiempo de arranque a la complejidad en vez de al hecho de que el mapa nunca se externalizó.</p>
<p>Así que el objetivo no es “haz que los agentes onboardeen como humanos”. Los humanos también onboardean mal. El objetivo es darles a ambos algo mejor contra lo que onboardear.</p>
<h2 id="onboardea-contra-el-grafo">Onboardea contra el grafo</h2>
<p>La alternativa a un mapa atrapado en cabezas es un mapa que el sistema mantiene fuera de las cabezas: un <a href="/es/blog/grafo-de-conocimiento-del-codigo/">grafo de conocimiento del código</a> construido desde el código real. Las relaciones que un senior recitaría de memoria, esto llama a aquello, esto depende de aquello, esto existe por aquella decisión, se leen del código y se hacen consultables.</p>
<p>Ahora el onboarding cambia de forma para los dos tipos de fichaje.</p>
<p>El ingeniero nuevo deja de enrutar cada pregunta por un senior ocupado. “Qué llama a esto” y “qué se rompe si lo cambio” los responde el grafo, cuando quiera, bien, a las 2 de la mañana, sin interrumpir a nadie. El tiempo del senior se va a las preguntas que de verdad necesitan criterio en vez de a las cien que solo necesitaban el mapa. El humano sigue aprendiendo, más rápido, y contra algo que no recuerda mal.</p>
<p>El agente nuevo consigue, por primera vez, algo contra lo que onboardear. Antes de cambiar el middleware de auth, consulta al grafo qué depende de él, la misma consulta que el humano le haría al senior, y obtiene la respuesta real en vez de un grep-y-adivina. El mapa que siempre le faltó ahora existe en una forma que puede leer. Cada sesión, cada agente, el mismo mapa verdadero.</p>
<p>Esa es la línea que merece la pena guardar: onboarding contra el grafo, no contra el conocimiento tribal. Es una frase que resulta que resuelve el impuesto del onboarding humano y el problema de fiabilidad de los agentes a la vez, porque siempre fueron el mismo problema con distinta ropa.</p>
<h2 id="sobre-qué-te-puede-onboardear-el-grafo-y-sobre-qué-no">Sobre qué te puede onboardear el grafo, y sobre qué no</h2>
<p>Sé claro con el límite, porque sobrevenderlo es como pierdes la confianza de la gente. El grafo es excelente en la mitad estructural del onboarding: qué existe, qué llama a qué, qué depende de qué, dónde están las fronteras, qué se rompe si tocas esto. Esa mitad es enorme, es la mayoría de las preguntas que de verdad hace una persona nueva en la primera semana, y es la mitad que antes quemaba la tarde de un senior.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="El grafo cubre la mitad estructural del onboarding, casi toda la primera semana; reserva la atención escasa del humano para el porqué sin registrar."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">lo responde el grafo</p>
    <ul><li>qué existe</li><li>qué llama a qué</li><li>qué se rompe al cambiar</li><li>dónde están las fronteras</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">solo lo tiene el humano</p>
    <ul><li>por qué esta arquitectura</li><li>la historia política</li><li>decisiones bajo deadline</li></ul>
  </div>
</div><figcaption>El grafo cubre la mitad estructural del onboarding, casi toda la primera semana; reserva la atención escasa del humano para el porqué sin registrar.</figcaption></figure>
<p>El grafo es más flojo en el <em>porqué</em>, al menos la parte que nunca llegó a ningún artefacto. Por qué los fundadores eligieron esta arquitectura en vez de la obvia, cuál fue la razón política de partir la propiedad de un equipo por una línea rara, qué decisiones se tomaron bajo un deadline que todos sabían que estaba mal. Parte de eso se puede capturar, si las razones detrás de las decisiones se registran en el momento en que se toman y se enlazan al código que gobiernan, que es justo lo que convierte una estructura pelada en algo que puede responder al “por qué”. Pero parte es genuinamente tribal en el sentido humano, lo que la gente aprendió por estar en la sala, y ningún grafo se inventa lo que nunca se escribió.</p>
<p>Así que el objetivo no es echar al senior. Es dejar de gastar al senior en las cien preguntas estructurales que el grafo responde mejor de todos modos, y reservar su atención escasa para el criterio y la historia sin registrar que solo lleva un humano. El ingeniero nuevo onboardea contra el grafo para el mapa y contra el senior para la sabiduría, y el agente onboardea contra el grafo para todo lo que se le permite, que es la mayor parte de lo que necesita para dejar de romper cosas.</p>
<h2 id="el-grafo-tiene-que-ser-verdad-o-solo-has-movido-la-tribu">El grafo tiene que ser verdad, o solo has movido la tribu</h2>
<p>Un aviso, porque es la forma en que esto sale mal. Un grafo que alguien mantiene a mano es conocimiento tribal con pasos extra. Se desfasa, y entonces le miente al fichaje nuevo y al agente nuevo con la autoridad añadida de parecer oficial. El mapa de onboarding solo es de fiar si se deriva del sistema y se mantiene al día según el sistema se mueve, que es el argumento entero de la <a href="/es/blog/documentacion-viva/">documentación que se mantiene sola</a>. Si mantener el mapa verdadero depende de que alguien se acuerde de actualizarlo, no has escapado del conocimiento tribal. Lo has escrito y lo has dejado pudrirse.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Por esto PaellaDoc construye el grafo desde tu repo y lo mantiene aguas abajo del código. Los agentes nuevos lo consultan antes de actuar, así que dejan de onboardear por inferencia. Y el mismo mapa está disponible para los humanos, así que el arranque deja de depender de pillar a un senior entre reuniones. El conocimiento que antes vivía en unas pocas cabezas, y se iba cuando ellas se iban, vive en algo contra lo que todo el equipo, personas y agentes, puede onboardear.</p>
<p>¿Quién de tu equipo es la única cabeza donde vive el mapa de tu codebase, y qué pasa la semana que está de vacaciones? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-los-agentes-rompen-código-que-nunca-han-visto">¿Por qué los agentes rompen código que nunca han visto?</h3>
<p>Porque en cada sesión llegan como un ingeniero de primer día sin memoria y, a diferencia de un humano, sin nadie a quien preguntar. Así que hacen grep, leen unos ficheros e infieren. La mayoría de lo que la gente le echa al modelo es un fallo de onboarding: al agente lo soltaron en un sistema cuyo mapa vive en cabezas que no puede leer.</p>
<h3 id="qué-significa-hacer-onboarding-contra-el-grafo">¿Qué significa hacer onboarding contra el grafo?</h3>
<p>En vez de transferir el mapa del sistema desde cabezas senior pregunta a pregunta, tanto los ingenieros nuevos como los agentes nuevos consultan un grafo de conocimiento del código construido desde el código real. «Qué llama a esto» y «qué se rompe si lo cambio» se responden cuando quieras, bien, sin interrumpir a nadie, desde un mapa que no recuerda mal.</p>
<h3 id="puede-un-grafo-de-conocimiento-sustituir-a-un-senior-en-el-onboarding">¿Puede un grafo de conocimiento sustituir a un senior en el onboarding?</h3>
<p>No. Cubre la mitad estructural del onboarding, que es casi toda la primera semana: qué existe, qué llama a qué, qué se rompe si tocas esto. Es más flojo en el porqué que nunca llegó a un artefacto, la historia política y las decisiones bajo deadline. Reserva la atención escasa del senior para eso, no para las cien preguntas estructurales.</p>
<h3 id="cómo-se-hace-onboarding-de-agentes-de-ia-en-un-codebase-grande">¿Cómo se hace onboarding de agentes de IA en un codebase grande?</h3>
<p>Dales algo contra lo que onboardear que no sea conocimiento tribal. Construye el grafo desde el repo, mantenlo aguas abajo del código para que siga siendo verdad, y haz que los agentes lo consulten antes de actuar. Un mapa mantenido a mano es conocimiento tribal con pasos extra; se desfasa y miente con autoridad de aspecto oficial.</p>]]></content>
    <summary type="html"><![CDATA[Un fichaje nuevo arranca preguntándole al que tiene al lado. Funciona hasta que esa persona está ocupada, o se va, o se equivocó. Un agente nuevo no puede preguntarle a nadie, así que trabaja con lo que pueda sacar con grep. Los dos están onboardeando contra conocimiento tribal, y los dos chocan contra el mismo muro. La salida es la misma para ambos: onboardear contra un grafo del sistema que se mantiene verdadero solo.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="onboarding"/><category term="knowledge-graph"/><category term="tribal-knowledge"/><category term="agents"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Herramientas de IA en la nube vs locales: qué cedes en cada dirección</title>
    <link href="https://paelladoc.com/es/blog/nube-vs-local/" rel="alternate" type="text/html" title="Herramientas de IA en la nube vs locales: qué cedes en cada dirección"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/nube-vs-local/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/nube-vs-local/"><![CDATA[<p><strong>Nube frente a local en herramientas de IA es un intercambio, no un veredicto.</strong> Quien te diga que una es sencillamente mejor te está vendiendo la que construyó. Yo construyo una local, así que trata la última sección con la sospecha que merece; pero las primeras son el balance real, y las digo en serio.</p>
<p>El error es elegir por ideología. Se elige por qué lado del intercambio contiene lo que de verdad te muerde, y eso es distinto para un equipo de cincuenta personas y para un fundador en solitario. Aquí está el balance, las dos columnas.</p>
<h2 id="qué-hace-mejor-la-nube-de-verdad">Qué hace mejor la nube de verdad</h2>
<p>Empiezo por el lado que no construí, porque si no sé defenderlo con justicia no deberías fiarte del resto.</p>
<p><strong>Estado compartido sin configuración.</strong> Un compañero abre una URL y ve exactamente lo que tú ves. Sin instalar, sin desajuste de versiones, sin “en mi máquina funciona”. Para un equipo que vive en un mismo espacio, esto lo es todo, y las herramientas locales tienen que esforzarse para aproximarlo.</p>
<p><strong>El cómputo de otro.</strong> Indexados pesados, trabajos grandes en segundo plano, cualquier cosa que dispararía los ventiladores de tu portátil: la nube lo absorbe. Tu máquina se queda fresca y libre mientras el trabajo ocurre en otra parte.</p>
<p><strong>Se actualiza sola.</strong> La versión que usas es la actual, siempre. Sin paso de actualización, sin desfase entre lo que ejecutas y lo que describe la documentación.</p>
<p><strong>Acceso desde cualquier sitio.</strong> Cualquier dispositivo, cualquier red, el mismo entorno. Si te mueves entre máquinas constantemente, esa continuidad es real y las herramientas locales te cobran configuración por ella.</p>
<p>No son cosas pequeñas. Si tu dolor central es coordinar a un equipo entre dispositivos con la mínima fricción, la columna de la nube es donde vive tu respuesta, y ningún principio local-first cambia eso.</p>
<h2 id="qué-hace-mejor-local-de-verdad">Qué hace mejor local de verdad</h2>
<p>Ahora el lado que sí construí. El mismo listón: el mecanismo concreto, no el eslogan.</p>
<p><strong>Latencia en el bucle apretado.</strong> Leer y escribir tu propio estado es una operación de disco, no un viaje de red por el rate limit de alguien. A lo largo de cientos de bucles al día, esa es la diferencia entre flow y esperar.</p>
<p><strong>Coste solo donde el coste es real.</strong> La inferencia se mide porque la inferencia es cara. Leer tu grafo, comprobar un agente, reejecutar un gate: gratis, porque corre en hardware que posees. En una herramienta en la nube, la coordinación y el almacenamiento también llevan margen.</p>
<p><strong>Privacidad por construcción.</strong> La forma de tu producto —estrategia, apuestas descartadas, restricciones sensibles— está en tu disco, no en un servidor que se sincroniza sin parar como precio de la herramienta. Tú decides, por llamada, qué sale.</p>
<p><strong>Control que sobrevive al proveedor.</strong> Cambios de precio, deprecaciones, adquisiciones, caídas: con una herramienta local abierta en sus límites, ninguno puede quitarte el sistema. Pierdes un proveedor, no la memoria de tu producto.</p>
<h2 id="la-distinción-que-de-verdad-lo-decide">La distinción que de verdad lo decide</h2>
<p>Aquí está el marco que ojalá me hubieran dado antes, porque disuelve casi toda la discusión. La pregunta no es nube o local. Es: <strong>¿qué partes de tu sistema pertenecen a cada sitio?</strong></p>
<p>Divide tu trabajo en dos tipos. Hay trabajo genuinamente caro y genuinamente mejorado por la escala —inferencia de modelo, indexado a gran escala—. Y hay un sistema de coordinación alrededor: tus decisiones, tus especificaciones, tu grafo de producto, tu evidencia, la memoria que hace la sesión de mañana más lista que la de hoy.</p>
<p>La parte cara-y-escalable tiene un caso real para la nube, y hasta una herramienta local-first convencida llama a modelos remotos. El <a href="/es/blog/fabrica-local-de-software/">sistema de coordinación</a> es distinto. No mejora por vivir en el servidor de alguien; solo se vuelve alquilable. Esa es la parte donde “local” deja de ser una preferencia y se convierte en propiedad.</p>
<p>La mayoría de herramientas te obligan a elegir una ubicación para las dos. El diseño interesante pone cada parte donde toca: inferencia remota cuando ayuda, sistema de coordinación local porque es la parte que deberías poseer. Puedes seguir <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">enrutando el trabajo caro al motor adecuado</a>; solo que no tienes que alquilar la memoria para hacerlo.</p>
<h2 id="la-dirección-en-la-que-puedes-moverte-importa">La dirección en la que puedes moverte importa</h2>
<p>Hay una asimetría en este intercambio que casi todas las comparaciones se saltan, y debería pesar en tu decisión más de lo que suele. Las dos direcciones no son igual de reversibles.</p>
<p>Empieza local y puedes añadir piezas de nube después sin mucho dolor. Saca la inferencia a un modelo alojado, sincroniza un subconjunto a un espacio compartido, pon un indexado pesado en el cómputo de otro. Te extiendes hacia fuera desde una base que sigues poseyendo, una pieza deliberada cada vez, y puedes deshacer cualquiera de esas adiciones.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="Local-first es el valor por defecto reversible: cada pieza de nube que añades se extiende desde una base que sigues poseyendo, y puedes deshacerla."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EMPIEZA LOCAL</text><path d="M 250 95 L 272 95 M 266 89 L 272 95 L 266 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">AÑADE PIEZA NUBE</text><path d="M 488 95 L 510 95 M 504 89 L 510 95 L 504 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="62" width="204" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="618" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">SIGUE SIENDO TUYO</text></svg><figcaption>Local-first es el valor por defecto reversible: cada pieza de nube que añades se extiende desde una base que sigues poseyendo, y puedes deshacerla.</figcaption></figure>
<p>Empieza enteramente en la nube e ir en la otra dirección es una migración, no un ajuste. Tu estado vive en su formato, en sus servidores, y llevarlo a algo que poseas significa una exportación —si la ofrecen— seguida de reconstruir las conexiones que su sistema sostenía por ti. El hilo entre intención y prueba, lo que hacía útil la herramienta, suele ser lo primero que no sobrevive a la extracción. Recuperas tus datos. No siempre recuperas tu sistema.</p>
<p>Así que aunque de verdad no sepas qué lado encaja, la elección reversible es el valor por defecto más seguro. Local-first con límites abiertos conserva la opción de moverte hacia la nube donde se gane su sitio. Cloud-first gasta esa opción en tu nombre y en silencio. Cuando el intercambio está reñido, elige la dirección sobre la que aún puedes cambiar de idea.</p>
<h2 id="cómo-elegir-de-verdad">Cómo elegir de verdad</h2>
<p>Sáltate la filosofía. Responde cuatro preguntas sobre tu situación.</p>
<p><strong>¿Quién está en el espacio de trabajo?</strong> Un equipo grande que necesita estado compartido sin fricción se inclina a la nube. Un fundador en solitario o un grupo pequeño y cohesionado se inclina a local, porque la coordinación que la nube hace fácil es coordinación que apenas necesitas.</p>
<p><strong>¿Cómo de sensible es el producto?</strong> Si la forma de lo que construyes es genuinamente confidencial —la estrategia, no solo el código—, local pasa de deseable a requisito.</p>
<p><strong>¿Cuál es tu tolerancia al riesgo de proveedor?</strong> Si un cambio de precio o un cierre te haría daño de verdad, pondera fuerte el control, y el control vive en el lado local.</p>
<p><strong>¿Dónde golpea el dolor hoy?</strong> La latencia diaria y el coste mensual son victorias de local. La fricción de equipo y la configuración, de la nube. Optimiza para el dolor que de verdad tienes, no para el que una landing te dice que temas.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc se sitúa en el lado local de este intercambio a propósito, y es claro con el intercambio. El sistema de coordinación —grafo de producto, repositorios, decisiones, evidencia— se queda en tu máquina macOS. La inferencia sale hacia <a href="/es/blog/tu-propio-modelo/">los modelos que elijas</a>, con tus propias claves o hacia motores locales. Obtienes la latencia, el coste, la privacidad y el control de local, y aun así llegas a los modelos frontier cuando el trabajo lo pide. Gratis hasta tres proyectos, sin cuenta.</p>
<p>Si eres un equipo grande cuyo problema principal es el estado compartido sin fricción, la columna de la nube es una respuesta justa y prefiero decírtelo a fingir lo contrario. Si eres una persona o un grupo pequeño construyendo algo que pretendes seguir poseyendo y entendiendo dentro de un año, la columna local es donde el caso se vuelve fuerte; y ese es exactamente el lector para el que construí.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="son-mejores-las-herramientas-de-ia-en-la-nube-o-las-locales">¿Son mejores las herramientas de IA en la nube o las locales?</h3>
<p>Ninguna gana del todo; es un intercambio, no un veredicto. La nube es mejor en estado compartido sin configuración, cómputo descargado, actualizarse sola y acceso desde cualquier sitio. Local es mejor en latencia en el bucle apretado, coste solo donde es real, privacidad por construcción y control que sobrevive al proveedor. La elección correcta depende de qué lado del intercambio contiene el dolor que de verdad te muerde.</p>
<h3 id="qué-hacen-mejor-las-herramientas-de-ia-en-la-nube-que-las-locales">¿Qué hacen mejor las herramientas de IA en la nube que las locales?</h3>
<p>Cuatro cosas, y no son pequeñas. Un compañero abre una URL y ve exactamente lo que tú ves, sin instalar ni desajuste de versiones. El cómputo pesado pasa a ser problema de otro. La versión que ejecutas siempre es la actual. Y llegas al mismo entorno desde cualquier dispositivo o red. Si tu dolor central es coordinar a un equipo entre dispositivos con la mínima fricción, ahí vive tu respuesta.</p>
<h3 id="puedo-pasar-de-una-herramienta-de-ia-en-la-nube-a-una-local-después">¿Puedo pasar de una herramienta de IA en la nube a una local después?</h3>
<p>Puedes, pero es una migración, no un ajuste. Tu estado vive en su formato y en sus servidores, así que moverlo significa una exportación —si la ofrecen— y luego reconstruir las conexiones que su sistema sostenía por ti. El hilo entre intención y prueba suele ser lo primero que no sobrevive a la extracción: recuperas tus datos, no siempre tu sistema. Empezar local y añadir piezas de nube es la dirección reversible.</p>
<h3 id="qué-es-mejor-para-un-desarrollador-en-solitario-nube-o-local">¿Qué es mejor para un desarrollador en solitario, nube o local?</h3>
<p>Para un fundador en solitario o un grupo pequeño y cohesionado, local suele ser el caso más fuerte. La coordinación que la nube hace sin fricción es coordinación que apenas necesitas, mientras que las victorias de local —latencia a velocidad de disco, coste solo en inferencia, privacidad y control a prueba de proveedor— te golpean directo. La nube se gana su sitio en equipos grandes cuyo problema principal es el estado compartido. Elige por quién está en el espacio de trabajo y dónde golpea el dolor hoy.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="nube-vs-local"/><category term="fabrica-local-de-software"/><category term="ai-coding"/><category term="herramientas-de-desarrollo"/><category term="local-first"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Un modelo operativo para equipos de producto que construyen con agentes</title>
    <link href="https://paelladoc.com/es/blog/modelo-operativo-de-producto/" rel="alternate" type="text/html" title="Un modelo operativo para equipos de producto que construyen con agentes"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/modelo-operativo-de-producto/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/modelo-operativo-de-producto/"><![CDATA[<p>Casi todos los equipos que adoptan agentes de código cambiaron una cosa: la velocidad a la que se escribe el código. Conservaron todo lo demás. Mismos roles, mismos artefactos, misma cadencia, ahora con un agente atornillado que produce diez veces el output. Y se sorprenden cuando el resultado no es diez veces el valor sino diez veces el lío, porque el modelo operativo alrededor del agente estaba diseñado para un mundo donde escribir código era el paso lento y caro, y ese mundo desapareció.</p>
<p>Un modelo operativo son tres cosas. Quién hace qué. Qué produce el trabajo. Cómo se mueve el equipo por el tiempo. Roles, artefactos, ritmo. Cuando los agentes asumen la construcción, los tres tienen que cambiar, y cambiar tus herramientas sin cambiar tu modelo operativo es como llegas al lío. Este es un relato concreto de en qué se convierten los tres.</p>
<h2 id="roles-el-humano-posee-el-contrato-y-la-puerta-no-las-pulsaciones">Roles: el humano posee el contrato y la puerta, no las pulsaciones</h2>
<p>La vieja división del trabajo ponía al humano en medio de la producción. El PM escribía requisitos, el ingeniero escribía código, y el valor que cada uno añadía se medía en los artefactos que tecleaba en persona. Los agentes quitan esa medición, porque teclear ya no es el recurso escaso. Lo que sigue escaso es el juicio sobre qué construir y sobre si lo construido está bien, y ahí es donde se reubican los roles humanos.</p>
<p>La persona de producto deja de ser la autora de requisitos y pasa a ser la dueña del contrato y del bucle de decisión. Su trabajo es mantener legible y al día la definición de qué significa «correcto» mientras los agentes construyen contra ella, y sostener las decisiones, con su evidencia, para que el equipo no rediscuta preguntas ya zanjadas. Es el desplazamiento que describí en <a href="/es/blog/product-management-era-ia/">product management en la era IA</a>: de escribir la spec a diseñar el sistema que decide y aprende.</p>
<p>El ingeniero deja de ser quien produce el código y pasa a ser quien posee el harness y la puerta. Diseña el entorno en el que corren los agentes, los chequeos que un cambio tiene que pasar, la vía de recuperación cuando una ejecución falla. Su palanca ya no son líneas escritas, es la calidad de la máquina que convierte specs en código verificado, y la fuerza de la puerta que rechaza el trabajo que no puede demostrarse.</p>
<p>Ninguno de los dos roles se encogió. Los dos subieron un nivel, de producir el artefacto a poseer el sistema que lo produce. Un equipo que sigue evaluando a estas personas por cuánto teclean en persona está midiendo lo que no toca y se dotará de personal para el trabajo equivocado.</p>
<h2 id="artefactos-la-spec-la-decisión-la-evidencia">Artefactos: la spec, la decisión, la evidencia</h2>
<p>Los viejos artefactos eran el PRD y el roadmap. Los dos se construyeron para un mundo lento. El PRD describía una feature una vez, en prosa, y envejecía el día que empezaba la construcción. El roadmap proyectaba certeza sobre meses que la velocidad de los agentes vuelve ficción. Ninguno sobrevive al contacto con un equipo que publica varios cambios validados por semana.</p>
<p>Tres artefactos los reemplazan, y están vivos en vez de estáticos.</p>
<p>La spec es el contrato contra el que construye el agente, precisa lo bastante para restringir la construcción y legible por el propio agente, no solo por el ingeniero. Donde el viejo PRD era un documento para alinear humanos, la spec es una instrucción que tiene que llegar a la máquina que hace el trabajo, y por eso existe un estándar como <a href="https://agents.md/">AGENTS.md</a>: el contrato tiene que vivir en un sitio que el agente lea de verdad.</p>
<p>El decision ledger reemplaza al roadmap. En vez de proyectar una secuencia fija de features, <a href="/es/blog/registro-de-decisiones/">registra qué se decidió, sobre qué evidencia, bajo qué supuesto</a>, según el equipo aprende. Es una memoria de elecciones y no una promesa de fechas, que es el único artefacto real cuando construir es lo bastante rápido para que la secuencia cambie cada semana.</p>
<p>El registro de evidencia reemplaza al informe de estado. Un cambio <a href="/es/blog/decisiones-con-evidencia/">se cierra con la prueba de qué corrió y qué pasó adjunta</a>, para que el estado del producto sea algo que el equipo pueda leer en vez de creerse por fe. El estado se declara; la evidencia se captura, y en un mundo donde el autor es a menudo un modelo, solo la clase capturada puede confiarse después.</p>
<p>Debajo de los tres está el tejido conectivo, el <a href="/es/blog/grafo-de-conocimiento-de-producto/">grafo de conocimiento de producto</a> que relaciona specs, decisiones, evidencia y código, para que los artefactos no sean tres montones separados sino un mapa que puedes recorrer. Sin eso, tienes artefactos nuevos y la misma vieja desconexión.</p>
<h2 id="ritmo-un-bucle-apretado-corrido-muchas-veces-en-paralelo">Ritmo: un bucle apretado, corrido muchas veces en paralelo</h2>
<p>El viejo ritmo era el sprint: un lote de trabajo planificado, construido en una ventana fija, revisado al final. Asumía que construir era el palo largo, así que organizaba el tiempo alrededor de darle a la construcción pista suficiente. Quita ese supuesto y el sprint deja de tener sentido, porque el palo largo ya no es la construcción.</p>
<p>El ritmo que encaja es <a href="/es/blog/construir-software-con-agentes-de-ia/">un bucle apretado corrido de forma continua y a menudo en paralelo</a>. El discovery produce un insight. El insight fuerza una decisión. La decisión se vuelve una spec. La spec va a un agente. El output del agente choca con una puerta de verificación. Lo que pasa actualiza el decision ledger y alimenta el siguiente bucle. El tiempo de ciclo es horas, no semanas, y varios bucles corren a la vez, y por eso los roles humanos se movieron hacia poseer contratos y puertas: a este tempo, una persona no puede estar en medio de cada pulsación, solo en los bordes donde vive el juicio.</p>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="El bucle corre en horas y en paralelo: lo que pasa la puerta de verificación actualiza el decision ledger y alimenta el siguiente giro."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">DISCOVERY</text><path d="M 190 85 L 212 85 M 206 79 L 212 85 L 206 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">SPEC</text><path d="M 368 85 L 390 85 M 384 79 L 390 85 L 384 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CONSTRUIR</text><path d="M 546 85 L 568 85 M 562 79 L 568 85 L 562 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="646" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">VERIFICAR</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">ACTUALIZA EL LEDGER</text></svg><figcaption>El bucle corre en horas y en paralelo: lo que pasa la puerta de verificación actualiza el decision ledger y alimenta el siguiente giro.</figcaption></figure>
<p>Aquí es donde la investigación de entrega sigue siendo relevante. El <a href="https://dora.dev/research/">programa DORA</a> lleva años mostrando que el flujo rápido solo produce buenos outcomes cuando corre a través de una verificación fuerte, y que el throughput sin estabilidad degrada los resultados en vez de mejorarlos. Los agentes hacen el flujo rápido gratis. El modelo operativo tiene que aportar la estabilidad, o la velocidad solo acelera el daño, la misma trampa donde construir barato se vuelve deuda de producto barata.</p>
<h2 id="el-modo-de-fallo-herramientas-nuevas-modelo-viejo">El modo de fallo: herramientas nuevas, modelo viejo</h2>
<p>El error más común con diferencia es mejorar las herramientas y dejar el modelo operativo intacto. Un equipo compra agentes, conserva el PRD y el roadmap y el sprint, sigue midiendo a la gente por output, y apunta los agentes al mismo proceso que se construyó para la construcción lenta. Lo que consigue es el modelo viejo corriendo más rápido, lo que significa que sus debilidades componen más rápido también: <a href="/es/blog/prds-que-nadie-lee/">más PRDs sin leer</a>, más ficción de roadmap, más output sin verificar, más decisiones que nadie puede reconstruir.</p>
<p>Las herramientas son la parte fácil de cambiar. El modelo operativo es la parte difícil, porque toca cómo se evalúa a la gente, qué considera el equipo un entregable, y cómo planifica el tiempo, y esos son hábitos que sostienen la casa. Pero las herramientas sin el modelo son exactamente la configuración que produce velocidad que no puedes dirigir.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/es/">PaellaDoc</a> está construido alrededor de este modelo operativo en vez de atornillado al viejo. La spec, el decision ledger y la evidencia viven como artefactos conectados en un solo grafo, el bucle del discovery al cambio verificado corre en local, y el humano se queda donde pertenece el juicio, en el contrato y la puerta, mientras los agentes hacen la construcción dentro de él. El objetivo no es hacer más rápido el viejo proceso. Es darles a los nuevos roles, artefactos y ritmo un sitio donde vivir, para que la velocidad venga con control en vez de en su lugar.</p>
<p>Los agentes cambiaron lo que es escaso. Un equipo que rediseña su modelo operativo alrededor de la nueva escasez, juicio y verificación en vez de producción, convierte la velocidad en outcomes. Un equipo que conserva el modelo viejo solo consigue cometer sus errores viejos a un ritmo que ya no puede seguir.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-un-modelo-operativo-de-producto">¿Qué es un modelo operativo de producto?</h3>
<p>Son tres cosas: quién hace qué (roles), qué produce el trabajo (artefactos) y cómo el equipo se mueve por el tiempo (ritmo). La versión tradicional, el PM escribe requisitos, el ingeniero escribe código, el trabajo en lotes de sprints, se diseñó para un mundo donde escribir código era el paso lento y caro. Cuando los agentes asumen la construcción, los tres tienen que cambiar, porque el supuesto sobre el que se construyeron desapareció.</p>
<h3 id="cómo-cambian-los-roles-cuando-los-agentes-construyen">¿Cómo cambian los roles cuando los agentes construyen?</h3>
<p>Teclear deja de ser el recurso escaso, así que los dos roles humanos suben un nivel. La persona de producto deja de escribir requisitos y posee el contrato y el bucle de decisión, manteniendo «correcto» legible y al día mientras los agentes construyen contra ello. El ingeniero deja de producir código y posee el harness y la puerta, el entorno donde corren los agentes y los chequeos que un cambio debe pasar. Ninguno se encogió; los dos dejaron de medirse por output.</p>
<h3 id="qué-reemplaza-al-prd-el-roadmap-y-el-sprint">¿Qué reemplaza al PRD, el roadmap y el sprint?</h3>
<p>Tres artefactos vivos y un ritmo más apretado. La spec, un contrato que el propio agente puede leer, reemplaza al PRD. El decision ledger, una memoria de qué se decidió y por qué, reemplaza la secuencia fija del roadmap. El registro de evidencia, prueba de qué corrió y qué pasó, reemplaza al informe de estado. Y el sprint cede a un bucle apretado, discovery a spec a construcción a verificación, corrido en horas y en paralelo.</p>
<h3 id="por-qué-las-herramientas-de-ia-producen-caos-en-vez-de-valor">¿Por qué las herramientas de IA producen caos en vez de valor?</h3>
<p>Porque casi todos los equipos mejoran las herramientas y dejan el modelo operativo intacto: compran agentes pero conservan el PRD, el roadmap, el sprint, y miden a la gente por output. Lo que consiguen es el modelo viejo corriendo más rápido, así que sus debilidades componen más rápido también, más PRDs sin leer, más ficción de roadmap, más output sin verificar. El flujo rápido solo produce buenos outcomes cuando corre a través de una verificación fuerte; sin ella, la velocidad solo acelera el daño.</p>]]></content>
    <summary type="html"><![CDATA[Un modelo operativo son tres cosas: quién hace qué (roles), qué produce el trabajo (artefactos) y cómo el equipo se mueve por el tiempo (ritmo). Cuando los agentes asumen la construcción, los tres se desplazan, y un equipo que mejora sus herramientas pero conserva el modelo operativo viejo obtiene velocidad sin control. Este es un relato concreto de en qué se convierten los roles, los artefactos y la cadencia cuando construir deja de ser el cuello de botella y decidir, especificar y verificar pasan a ser el trabajo.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="product-management"/><category term="modelo-operativo"/><category term="ai-coding"/><category term="proceso-de-equipo"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">Miedo a tocarlo: convertir el pánico a tu propio código en una red de seguridad</title>
    <link href="https://paelladoc.com/es/blog/miedo-a-tocar-el-codigo/" rel="alternate" type="text/html" title="Miedo a tocarlo: convertir el pánico a tu propio código en una red de seguridad"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/miedo-a-tocar-el-codigo/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/miedo-a-tocar-el-codigo/"><![CDATA[<p>Hay un momento que pilla a mucha gente que construyó algo con IA. La app funciona. Los usuarios dependen de ella. Y te das cuenta de que tienes miedo de cambiarla, porque no entiendes del todo cómo funciona y no tienes forma de saber si un cambio rompió algo hasta que te lo dice un usuario. Así que paras. Evitas los archivos peligrosos. Añades features por los bordes en vez de arreglar el núcleo, porque tocar el núcleo se siente como desactivar una bomba que no montaste.</p>
<p>Quiero replantear ese miedo por completo, porque casi todo el consejo lo trata como un defecto de carácter que hay que superar. No lo es. El miedo es preciso. Es una señal exacta sobre el estado real de tu código, y si lo sigues en vez de pelearlo, te entrega el plan exacto para arreglar la cosa que te da miedo.</p>
<h2 id="el-miedo-dice-la-verdad">El miedo dice la verdad</h2>
<p>Empieza por tomarte el miedo en serio como dato. Tienes miedo de cambiar el código porque dos cosas son ciertas: no puedes predecir del todo qué hará un cambio, y no tienes forma independiente de atraparlo si el cambio está mal. Las dos son hechos reales sobre tu proyecto, no sentimientos sobre tu competencia.</p>
<p>Vale la pena detenerse ahí, porque las reacciones habituales son las dos equivocadas. Una es anular el miedo y cambiar las cosas igualmente, que es cómo publicas la regresión que temías. La otra es obedecer el miedo y congelarte, que es cómo el proyecto muere despacio mientras construyes solo en los rincones seguros. El miedo no te pide que seas más valiente ni más cuidadoso. Señala una cosa que falta, y el arreglo es construir la cosa que falta.</p>
<p>Lo que falta tiene nombre. Es <a href="https://martinfowler.com/bliki/SelfTestingCode.html">la red de seguridad</a>: la capacidad de hacer un cambio y saber, antes que un usuario, si rompiste algo. Tienes miedo porque no la tienes. Así que constrúyela.</p>
<h2 id="el-miedo-es-un-mapa">El miedo es un mapa</h2>
<p>Aquí está la parte que convierte la ansiedad en un plan. El miedo no está repartido de forma uniforme. Hay archivos que editarás encantado y archivos a los que no te acercarás. Esa distribución es un mapa, y es más precisa que cualquier auditoría que pudieras correr.</p>
<p>El código que tienes miedo de tocar es precisamente el código que sostiene peso y está desprotegido. Importa, o no tendrías miedo, y no tiene red, o no tendrías miedo. Los archivos que editas sin pensarlo dos veces o no importan o ya están a salvo. Así que el miedo ya ha hecho tu priorización por ti. Ha dibujado una línea roja alrededor de exactamente los caminos que necesitan red primero, y ha dejado todo lo demás sin marcar.</p>
<p>Es la misma conclusión a la que llego desde la otra dirección cuando escribo sobre <a href="/es/blog/cuando-anadir-tests-arquitectura/">cuándo añadir tests y arquitectura</a>: inviertes en los caminos que sostienen peso y cambian. El miedo es solo esa señal, sentida en vez de razonada. Fíate. Donde más miedo te dé hacer un cambio es donde va la red primero.</p>
<h2 id="tejer-la-red-tres-hebras">Tejer la red: tres hebras</h2>
<p>Una red de seguridad para código que no escribiste del todo y no entiendes del todo tiene tres hebras, y las añades en este orden.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="La red tiene tres hebras, añadidas en este orden. Cada una hace más pequeño el miedo al siguiente cambio."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">RECUPERA LA SPEC</text><path d="M 250 95 L 272 95 M 266 89 L 272 95 L 266 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">TESTS DE CARACTERIZACIÓN</text><path d="M 488 95 L 510 95 M 504 89 L 510 95 L 504 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="62" width="204" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="618" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">EVIDENCIA</text></svg><figcaption>La red tiene tres hebras, añadidas en este orden. Cada una hace más pequeño el miedo al siguiente cambio.</figcaption></figure>
<p><strong>Recupera la spec.</strong> No puedes cambiar con seguridad un comportamiento que no sabes enunciar. Así que antes de tocar un camino peligroso, haz que el sistema te diga qué hace ahora mismo: las entradas que acepta, las salidas que produce, las reglas que aplica, los casos límite que maneja. No escribes una spec para trabajo nuevo. Recuperas la spec que ya está implícita en código que funciona. Eso es lo que marca la diferencia entre editar a ciegas y editar con intención.</p>
<p><strong>Fíjala con tests de caracterización.</strong> Una vez que puedes enunciar lo que hace el código, bloquéalo con tests que afirmen exactamente eso. Los tests de caracterización no comprueban que el código sea correcto en algún sentido ideal. Comprueban que sigue haciendo lo que hacía antes de tu cambio. Ese es el miedo exacto que intentas matar: no “¿es bueno este código?” sino “¿lo acabo de romper?”. Los tests de caracterización responden a esa pregunta automáticamente, cada vez, y eso es lo que te deja hacer el cambio que estabas evitando.</p>
<p><strong>Exige evidencia en cada cambio.</strong> La red solo aguanta si de verdad se comprueba. Un agente que informa de “hecho” sin correr los tests te ha dado una red sin cuerda. Así que la tercera hebra es una regla: nada está hecho hasta que existe la evidencia de que los tests corrieron y pasaron contra el cambio real. Es la idea entera de <a href="/es/blog/hecho-significa-hecho/">hecho significa hecho</a>, aplicada a tu propio miedo. La razón de que no confíes en “funciona” es que te han quemado afirmaciones sin prueba detrás. La prueba es lo que reconstruye la confianza.</p>
<h2 id="por-qué-el-código-construido-con-ia-lo-necesita-más">Por qué el código construido con IA lo necesita más</h2>
<p>Puede que notes que son técnicas viejas. Los tests de caracterización preceden a los agentes en décadas. La razón de que importen más ahora es que la IA cambió la proporción entre el código que escribiste y el código que posees.</p>
<p>Ahora puedes poseer un código grande que apenas leíste, producido más rápido de lo que pudiste revisarlo. Es una situación genuinamente nueva, y es la razón de que el miedo sea tan común ahora y fuera más raro antes. Cuando escribías cada línea, la comprensión venía gratis. Cuando la escribe un agente, la comprensión es lo que te saltaste, y el miedo es la factura. Es una cara concreta de la <a href="/es/blog/deuda-tecnica-vibe-coding/">deuda del vibe coding</a>: la comprensión que nunca construiste, cobrando intereses en forma de miedo cada vez que necesitas tocar el núcleo.</p>
<p>También conecta con la seguridad. Los caminos que tienes miedo de tocar son a menudo los mismos donde se esconden <a href="/es/blog/seguridad-vibe-coding/">los agujeros que deja el vibe coding</a>, porque el código sin tocar y sin examinar es justo donde sobrevive <a href="https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html">una entrada sin validar</a> o un secreto filtrado. Construir la red te obliga a leer por fin esos caminos, y así el miedo resulta ser protector en vez de solo incómodo.</p>
<h2 id="de-congelado-a-en-movimiento">De congelado a en movimiento</h2>
<p>El punto final no es la ausencia de miedo. Es un proyecto donde las partes peligrosas tienen red y las seguras no la necesitan, para que puedas volver a moverte. Esto es buena parte de lo que de verdad hace falta para llegar <a href="/es/blog/vibe-coding-a-produccion/">del vibe coding a producción</a>: no valentía, sino un código que te avisa cuando lo has roto.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Las tres hebras, spec recuperada, tests de caracterización y evidencia, comparten un problema: solo ayudan si persisten y siguen unidas al código que cubren. Una spec recuperada en un chat que cerraste ya no está. La evidencia que no guardaste es un recuerdo.</p>
<p>PaellaDoc está hecho para mantener esa red en su sitio. Lee tu código existente y lo convierte en un modelo sobre el que puedes razonar, da a la spec recuperada y al contrato de aceptación un hogar junto al código que describen, y guarda la evidencia de cada cambio para que “pasó” sea un hecho en registro, no una afirmación que tengas que creer a ciegas. El miedo se desvanece no porque te hayas vuelto más valiente, sino porque lo que te faltaba por fin existe.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Tener miedo de cambiar mi propio código es señal de que hice algo mal?</strong> No. Es una señal exacta de que un camino que sostiene peso no tiene red. La respuesta correcta no es forzar el miedo ni congelarte, sino construir la red donde el miedo apunta.</p>
<p><strong>¿Qué es un test de caracterización?</strong> Un test que fija lo que el código hace ahora, en vez de lo que idealmente debería hacer. En proyectos construidos con IA rara vez tienes una spec limpia, así que fijas primero el comportamiento existente, lo que te deja cambiar el código y ver de inmediato si alteraste algo.</p>
<p><strong>¿Por dónde empiezo si me da miedo el código entero?</strong> Empieza donde el miedo es más agudo. Los caminos que menos quieres tocar son los que sostienen peso y están desprotegidos. Recupera su comportamiento, fíjalo con tests y exige evidencia en los cambios, y luego avanza hacia fuera.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿Tener miedo de cambiar mi propio código es señal de que hice algo mal?", "acceptedAnswer": { "@type": "Answer", "text": "No. Es una señal exacta de que un camino que sostiene peso no tiene red. La respuesta correcta no es forzar el miedo ni congelarte, sino construir la red donde el miedo apunta." } },
    { "@type": "Question", "name": "¿Qué es un test de caracterización?", "acceptedAnswer": { "@type": "Answer", "text": "Un test que fija lo que el código hace ahora, en vez de lo que idealmente debería hacer. En proyectos construidos con IA rara vez tienes una spec limpia, así que fijas primero el comportamiento existente, lo que te deja cambiar el código y ver de inmediato si alteraste algo." } },
    { "@type": "Question", "name": "¿Por dónde empiezo si me da miedo el código entero?", "acceptedAnswer": { "@type": "Answer", "text": "Empieza donde el miedo es más agudo. Los caminos que menos quieres tocar son los que sostienen peso y están desprotegidos. Recupera su comportamiento, fíjalo con tests y exige evidencia en los cambios, y luego avanza hacia fuera." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[Tener miedo de cambiar tu propio código generado por IA no es debilidad. El miedo marca exactamente dónde no tienes red. Síguelo y se convierte en el plan de los tests y las specs que necesitas construir.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="testing"/><category term="tests-de-caracterizacion"/><category term="ai-coding"/><category term="verificacion"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Memoria de producto: lo que tu equipo olvida y tu sistema no debería</title>
    <link href="https://paelladoc.com/es/blog/memoria-de-producto/" rel="alternate" type="text/html" title="Memoria de producto: lo que tu equipo olvida y tu sistema no debería"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/memoria-de-producto/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/memoria-de-producto/"><![CDATA[<p>A los seis meses, un equipo tiene un tipo concreto de amnesia. El código está todo ahí, legible, corriendo. Lo que ha desaparecido es todo lo de alrededor. ¿Por qué partimos el servicio? ¿Por qué es nullable este campo cuando obviamente no debería? ¿No probamos ya a cachear aquí y lo quitamos? Nadie se acuerda, o tres personas se acuerdan distinto, y quien de verdad lo decidió se fue en primavera.</p>
<p>Los equipos no olvidan el código. El código es lo único que sobrevive, porque es el artefacto que todos están obligados a conservar. Lo que se evapora es la capa de encima: las decisiones, las razones detrás de ellas, y los callejones sin salida. Esa capa es la memoria de producto, y casi nada en un montaje normal es responsable de guardarla.</p>
<h2 id="las-tres-cosas-que-se-olvidan">Las tres cosas que se olvidan</h2>
<p><strong>Las decisiones.</strong> No el resultado, que se ve en el código, sino <a href="/es/blog/registro-de-decisiones/">el hecho de que se tomó una elección siquiera</a>. Alguien decidió usar esta cola en vez de aquella, hacer este endpoint síncrono, capar los reintentos a tres. En el código solo parece que las cosas son así. La decisión, el momento en que pudo ir de otra manera, no deja rastro salvo que alguien la registre.</p>
<p><strong>Las razones.</strong> Esta es la cara. El <em>porqué</em> nunca es visible en el código, porque el código es el resultado de una razón, no la razón en sí. Puedes leer que los reintentos están capados a tres. No puedes leer que están capados a tres porque el proveedor de aguas abajo te throttleaba a cuatro y despertó a alguien a las 3 de la mañana. Pierde la razón y la decisión parece arbitraria, lo que significa que la siguiente persona, o el siguiente agente, la “arreglará” y redescubrirá el aviso de las 3 de la mañana.</p>
<p><strong>Los callejones sin salida.</strong> Los caminos que probaste y abandonaste. La capa de caché que montaste y quitaste porque provocaba lecturas viejas. La librería que evaluaste y rechazaste. Estos son los más completamente olvidados de todos, porque no queda código que siquiera insinúe que pasaron. El trabajo se hizo, la lección se aprendió, y luego la evidencia se borró junto con la rama. Así que el conocimiento de “esto ya lo probamos y aquí está por qué falló” no existe en ningún sitio, y el equipo está condenado a probarlo otra vez.</p>
<h2 id="lo-que-cuesta-cuando-nada-recuerda">Lo que cuesta cuando nada recuerda</h2>
<p>Con un equipo humano, la memoria olvidada aparece como re-litigación. El mismo debate sobre la misma arquitectura, cada pocos meses, sin que nadie pueda señalar por qué se zanjó la última vez. Las decisiones se revierten en silencio por gente que nunca supo que eran decisiones. El <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">cerebro de producto</a> se pudre y lo sientes como una sensación vaga de que el equipo no deja de tener las mismas conversaciones.</p>
<p>Con agentes, el coste es más afilado y más rápido, porque <a href="/es/blog/perdida-de-contexto-entre-sesiones/">un agente no tiene memoria ninguna más allá de lo que le entregas</a>. Un agente no sabe que ya probaste el enfoque de caché y lo abandonaste. Así que cuando la tarea parece pedir caché, monta la caché, con seguridad, caminando directo de vuelta por el callejón sin salida del que tardaste dos semanas en salir. Revierte una decisión porque nunca supo que se tomó una decisión. “Limpia” el campo nullable raro porque nada le dijo que el campo es raro a propósito. Cada hueco en la memoria de producto se vuelve un sitio donde el agente hace daño comportándose de forma razonable, porque razonable-sin-memoria es justo el fallo.</p>
<p>Y esto compone con agentes en paralelo. Cada uno empieza en frío, así que cada uno es igual de capaz de re-caminar el mismo callejón sin salida, y lo pueden hacer a la vez, en partes distintas del codebase, toda la tarde.</p>
<h2 id="la-memoria-tiene-que-atarse-a-lo-que-explica">La memoria tiene que atarse a lo que explica</h2>
<p>El instinto es escribirlo en algún sitio. Un doc de decisiones, una página de wiki, un canal donde se anuncian las elecciones. Es mejor que nada y se degrada igual que se degrada cada carpeta de notas: <a href="/es/blog/documentacion-viva/">se separa del código</a>, nadie la enlaza con nada, y seis meses después el registro de la decisión y el código que supuestamente explica no tienen ninguna conexión que puedas seguir.</p>
<p>La memoria de producto solo es útil cuando está atada a lo que explica. Una decisión flotando en un doc es una anécdota. La misma decisión enlazada al código exacto que gobierna, y al código que se quitó cuando se abandonó un callejón sin salida, es memoria que de verdad puedes usar. Ahora cuando un agente, o una persona, mira la lógica de reintentos, la razón de que esté capada a tres está justo ahí, atada a la lógica de reintentos, no enterrada en un doc del año pasado que nadie va a encontrar. Cuando un agente se plantea montar una caché, el registro de la última caché y por qué se quitó es alcanzable desde el sitio donde iría la caché.</p>
<p>Esa es la diferencia entre un archivo y una memoria. Un archivo es donde la información va a olvidarse de forma organizada. Una memoria es conocimiento atado al contexto donde de verdad hará falta, que para un codebase significa atado al código, en <a href="/es/blog/grafo-de-conocimiento-del-codigo/">una estructura que tanto personas como agentes puedan recorrer</a>. Es la misma razón por la que <a href="/es/blog/grafo-de-conocimiento-de-producto/">un grafo de conocimiento de producto</a> enlaza artefactos al código en vez de guardarlos al lado, y la razón por la que el <a href="/es/research/context-engineering-para-agentes-de-codigo/">contexto para agentes de código</a> va de estructura sobre prosa: la memoria que no está atada a donde hace falta es memoria que no se encontrará a tiempo.</p>
<h2 id="el-callejón-sin-salida-es-la-memoria-más-valiosa-y-la-que-nada-guarda">El callejón sin salida es la memoria más valiosa y la que nada guarda</h2>
<p>De las tres, el callejón sin salida merece atención especial, porque es a la vez la memoria más útil y la que tus herramientas están estructuralmente diseñadas para borrar. Cuando abandonas un enfoque, lo normal es borrar la rama, revertir los commits, cerrar el PR. Limpias. Y limpiar es justo el acto de destruir el único registro de que el intento pasó. El código que habría insinuado “alguien fue por aquí y se dio la vuelta” es precisamente el código que quitas.</p>
<p>Así que el modo de fallo está garantizado. No queda ningún artefacto diciendo “probamos event sourcing aquí y lo abandonamos porque el coste de replay era insostenible a nuestro volumen”. Seis meses después alguien propone event sourcing, fresco y entusiasmado, y no hay nada en el codebase que lo contradiga, porque la evidencia se recogió y se tiró. El equipo vuelve a pagar las dos semanas para reaprender lo que ya sabía.</p>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="Cada valor por defecto del flujo borra el callejón sin salida, así que el equipo, y el agente más entusiasta, vuelve a proponer la idea exacta que ya pagó por descartar."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">PROBADO Y DESCARTADO</text><path d="M 190 85 L 212 85 M 206 79 L 212 85 L 206 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">RAMA BORRADA</text><path d="M 368 85 L 390 85 M 384 79 L 390 85 L 384 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">SIN REGISTRO</text><path d="M 546 85 L 568 85 M 562 79 L 568 85 L 562 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="646" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">PROPUESTO OTRA VEZ</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">REAPRENDER EL COSTE</text></svg><figcaption>Cada valor por defecto del flujo borra el callejón sin salida, así que el equipo, y el agente más entusiasta, vuelve a proponer la idea exacta que ya pagó por descartar.</figcaption></figure>
<p>Para un agente esto es peor, porque el agente es el que más entusiasmo pone en volver a proponerlo. No tiene tejido cicatricial. Lee el estado actual, ve un problema que event sourcing resolvería con elegancia, y lo monta, sin ninguna conciencia de que esta idea exacta se probó y falló por una razón concreta que sigue aplicando. Lo único que corta el bucle es una memoria del callejón sin salida que sobreviva a la rama borrada: un registro, atado a la parte del sistema que le concierne, que diga esto se probó, esto es por qué se dejó, y esta es la restricción que lo hizo fallar. Eso es algo que tienes que guardar a propósito, porque cada valor por defecto de tu flujo está intentando tirarlo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Esta es una capa que PaellaDoc guarda en tu máquina. Las decisiones se registran cuando se toman, con sus razones, y se enlazan al grafo junto al código que gobiernan. Los enfoques abandonados se capturan como lo que son, probados y rechazados y por qué, así que el callejón sin salida se recuerda incluso después de que la rama desaparezca. Cuando un agente trabaja, esa memoria es alcanzable desde el código del que va, así que el agente deja de revertir decisiones zanjadas y de re-caminar caminos que el equipo ya dejó atrás. El código nunca fue lo que olvidaste. Esta es la parte que tu sistema debería guardar, para que tu equipo deje de pagar por reaprenderla.</p>
<p>¿Qué decisión ha re-litigado tu equipo más veces, y dónde está de verdad escrita la razón de que se zanjara? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-la-memoria-de-producto">¿Qué es la memoria de producto?</h3>
<p>La capa por encima del código que un equipo olvida: las decisiones que se tomaron, las razones detrás de ellas, y los callejones sin salida que probaste y abandonaste. El código sobrevive porque todos están obligados a conservarlo. Esa capa no, salvo que algo sea responsable de guardarla, y en casi todos los montajes nada lo es.</p>
<h3 id="por-qué-mi-equipo-revive-las-mismas-decisiones-ya-zanjadas">¿Por qué mi equipo revive las mismas decisiones ya zanjadas?</h3>
<p>Porque la razón por la que se zanjó vive en la cabeza de alguien, y esa persona se fue en primavera o ahora se acuerda distinto. Sin un registro enlazado al código que gobierna, una decisión no deja rastro, así que parece arbitraria y la revierte en silencio gente que nunca supo que era una decisión.</p>
<h3 id="por-qué-los-agentes-reconstruyen-enfoques-que-ya-abandonamos">¿Por qué los agentes reconstruyen enfoques que ya abandonamos?</h3>
<p>Porque un agente no tiene memoria más allá de lo que le entregas, y la rama borrada que probaba que el enfoque falla es justo lo que tu flujo tiró. Ve un problema que el enfoque abandonado resolvería con elegancia y lo monta, caminando directo de vuelta por el callejón sin salida, porque razonable-sin-memoria es el fallo.</p>
<h3 id="dónde-debería-vivir-la-memoria-de-producto">¿Dónde debería vivir la memoria de producto?</h3>
<p>Atada a lo que explica, no flotando en un doc. Una decisión enlazada al código exacto que gobierna es memoria que puedes usar; la misma decisión en una wiki es una anécdota que nadie encuentra. Cuando la razón del cap de reintentos está sobre la lógica de reintentos, una persona o un agente que lee ese código la ve a tiempo.</p>]]></content>
    <summary type="html"><![CDATA[Los equipos no olvidan el código, el código está ahí. Olvidan las decisiones, las razones detrás de ellas, y los caminos que ya probaron y abandonaron. Cuando nada guarda esa memoria, revives preguntas zanjadas cada pocos meses y tus agentes reconstruyen alegremente el mismo enfoque que tiraste la primavera pasada. La memoria de producto es la capa que recuerda lo que la gente no puede.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="product-memory"/><category term="decision-logs"/><category term="knowledge-graph"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Memoria para agentes de código: qué debe persistir fuera del chat</title>
    <link href="https://paelladoc.com/es/blog/memoria-agentes-de-codigo/" rel="alternate" type="text/html" title="Memoria para agentes de código: qué debe persistir fuera del chat"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/memoria-agentes-de-codigo/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/memoria-agentes-de-codigo/"><![CDATA[<p>Si has sentido el impuesto de la <a href="/es/blog/perdida-de-contexto-entre-sesiones/">pérdida de contexto entre sesiones</a>, el reflejo es querer que el agente «tenga memoria». Buen instinto, mal encuadre. La pregunta no es si un agente tiene memoria. Es qué merece recordarse, dónde debe vivir y en qué forma, para que un agente en frío pueda cargarlo y actuar sobre ello correctamente.</p>
<p>Casi todos los intentos de memoria de agentes fracasan porque contestan «recuérdalo todo» o «no recuerdes nada», y los dos están mal. Recuérdalo todo y reconstruyes el problema de la ventana de contexto en una base de datos: un montón de notas obsoletas y contradictorias sobre las que el agente no puede razonar. No recuerdes nada y cada sesión arranca en frío. La versión útil es selectiva y estructurada, y construirla empieza por una taxonomía.</p>
<h2 id="tres-tipos-de-cosa-que-vale-la-pena-persistir">Tres tipos de cosa que vale la pena persistir</h2>
<p>No todo el conocimiento duradero es igual. Falla distinto, cambia a velocidades distintas y quiere casas distintas. Me encuentro con que tres categorías cubren casi todo lo que de verdad necesita sobrevivir a una sesión.</p>
<h3 id="decisiones">Decisiones</h3>
<p>Una decisión es una elección entre alternativas, con una razón. «Usamos bloqueo optimista aquí porque la contención es baja y el coste de reintentar es trivial.» La parte valiosa no es la elección, son las alternativas descartadas y el razonamiento, porque es lo que impide que un agente futuro vuelva a proponer lo que ya descartaste.</p>
<p>Las decisiones son solo-append por naturaleza. No editas una decisión, la reemplazas con una más nueva, y la vieja queda como historia para que el rastro del porqué siga intacto. La forma correcta es un log: entradas con fecha, cada una con la elección, las alternativas y la razón. Un log de decisiones es la pieza de memoria de agente de más palanca, porque mata la forma más cara de pérdida de contexto, volver a litigar preguntas ya cerradas.</p>
<h3 id="invariantes">Invariantes</h3>
<p>Un invariante es una regla que tiene que aguantar a través de los cambios. «Esta tabla es solo-append.» «Nunca llames a la red desde dentro de este módulo.» «Todo el dinero se guarda en céntimos enteros.» Los invariantes se diferencian de las decisiones en algo crítico: un agente necesita verlos al empezar cada sesión, antes de escribir nada, porque su trabajo entero es restringir lo que se escribe.</p>
<p>Eso significa que los invariantes van en el fichero que el agente lee primero, <a href="/es/blog/agents-md-claude-md-reglas/">el fichero de reglas</a>, no enterrados en un log que quizá consulte. Es justo el material de la sección de restricciones de una spec, y por eso memoria y especificación se difuminan aquí. Un invariante duradero es en realidad un trozo de una <a href="/es/blog/especificaciones-vivas/">especificación viva</a> que sigue viva entre sesiones en vez de degradarse en un chat. La restricción que sobrevive al viaje entre herramientas — una <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">spec portable</a> en vez de una nota atrapada en un chat — es la misma restricción que un agente tiene que honrar el martes que viene.</p>
<h3 id="estado">Estado</h3>
<p>El estado es el status actual del trabajo: qué está hecho, qué está en marcha, qué está bloqueado, cuál es el siguiente paso. A diferencia de decisiones e invariantes, el estado no es solo-append ni permanente. Es una foto pensada para sobrescribirse. El «en progreso» de ayer es el «hecho» de hoy, y mantener la versión vieja es activamente dañino, porque un agente que carga estado viejo rehará trabajo terminado o reanudará desde el punto equivocado.</p>
<p>El estado quiere otra forma: un fichero pequeño, actual, que se sobrescribe en sitio y responde «dónde estamos». Un fichero de progreso, no un log. El modo de fallo de la memoria de estado es el opuesto al de la memoria de decisiones. Las decisiones se pudren si borras la historia. El estado se pudre si la conservas.</p>
<h2 id="la-forma-importa-tanto-como-el-contenido">La forma importa tanto como el contenido</h2>
<p>Fíjate en que cada categoría quiere una forma distinta, y equivocar la forma arruina el contenido.</p>
<ul>
<li><strong>Las decisiones</strong> quieren un log solo-append. Una historia editable destruye el rastro.</li>
<li><strong>Los invariantes</strong> quieren un fichero de reglas al principio del contexto. Un log que el agente quizá no lea es inútil para una restricción que tiene que atar cada escritura.</li>
<li><strong>El estado</strong> quiere una sola foto sobrescrita. La historia aquí es ruido que despista.</li>
</ul>
<p>Mete las tres en un solo documento, como crecen muchos ficheros <code>CLAUDE.md</code>, y cada una corrompe a las otras. Los invariantes quedan enterrados bajo el churn del estado. La historia de decisiones se aplana en un blob de status actual. El agente lee una sopa y no honra ninguna de forma fiable. Separar por categoría no es orden, es lo que hace la memoria cargable.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Formas opuestas para fallos opuestos: las decisiones se pudren si borras su historia, el estado se pudre si la conservas."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">log de decisiones</p>
    <ul><li>solo-append</li><li>nunca se edita</li><li>la historia es el valor</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">fichero de estado</p>
    <ul><li>se sobrescribe</li><li>sin historia</li><li>solo lo actual</li></ul>
  </div>
</div><figcaption>Formas opuestas para fallos opuestos: las decisiones se pudren si borras su historia, el estado se pudre si la conservas.</figcaption></figure>
<h2 id="la-memoria-la-escribe-el-trabajo-no-se-mantiene-al-lado">La memoria la escribe el trabajo, no se mantiene al lado</h2>
<p>Esta es la trampa que mata a casi todos los sistemas de memoria: piden que un humano los mantenga, así que se pudren en cuanto el humano se lía. Un log de decisiones que nadie actualiza es peor que no tener log, porque miente con autoridad.</p>
<p>La única versión que sobrevive es memoria que el trabajo escribe como efecto secundario de hacer el trabajo. Cuando se toma una decisión en una sesión, se loguea ahí, en esa sesión, no en una pasada de documentación que nunca llega. Cuando se establece un invariante, aterriza en el fichero de reglas como parte de terminar la tarea, no después. En el momento en que la memoria se vuelve una tarea aparte, muere. El nombre del lado de producto de este patrón es un sistema que se mantiene solo, el argumento detrás de <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">el cerebro de producto que se mantiene solo</a>, y es el mismo requisito en la capa de código: si mantener la memoria al día no es parte del bucle, no se va a mantener al día.</p>
<h2 id="por-qué-esto-es-el-antídoto-contra-la-deriva">Por qué esto es el antídoto contra la deriva</h2>
<p>Memoria y deriva son dos caras de una moneda. <a href="/es/blog/los-agentes-derivan/">Los agentes derivan</a> justo cuando la cosa que debería restringirlos no está delante de ellos. Un invariante que vive en memoria duradera y se carga al empezar cada sesión es un invariante que el agente no puede violar en silencio, porque está ahí en el contexto, atando la escritura. Sácalo de la memoria y se convierte en una regla que existió una vez, en un chat, que ya nadie puede señalar.</p>
<p>Es también lo que hace sobrevivible correr trabajo en paralelo. Cuando mantienes <a href="/es/blog/sesiones-paralelas-agentes/">varias sesiones vivas a la vez</a>, no pueden cargar cada una las decisiones compartidas en una conversación privada, o divergirán. La memoria externa y compartida es lo único que todas pueden leer, y por eso persistir fuera del chat no es un lujo, es la precondición para que más de un agente trabaje sobre el mismo producto sin contradecirse.</p>
<h2 id="la-versión-de-una-línea">La versión de una línea</h2>
<p>Las decisiones van en un log solo-append. Los invariantes van en el fichero de reglas que el agente lee primero. El estado va en una sola foto sobrescrita. Las tres viven en el repo, fuera de cualquier chat, y las escribe el trabajo en vez de mantenerse al lado.</p>
<p>Haz eso y un agente en frío deja de ser un agente en blanco. Carga lo que el sistema sabe, honra las restricciones y retoma donde lo dejó la última sesión. Esa es la diferencia entre un agente con buena ventana de contexto y un agente que de verdad es parte de un sistema que recuerda. El primero es una herramienta lista. El segundo es lo que te deja dejar de ser <a href="/es/blog/eres-el-runtime/">el runtime</a> a mano.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuál es la decisión que has tenido que re-explicarle a un agente más de dos veces? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-debería-recordar-un-agente-de-código-entre-sesiones">¿Qué debería recordar un agente de código entre sesiones?</h3>
<p>No todo. Tres tipos de cosa se ganan el sitio: decisiones (una elección entre alternativas, con el razonamiento que impide volver a proponerlas), invariantes (reglas que tienen que aguantar los cambios) y estado (el status actual del trabajo). Recuérdalo todo y reconstruyes el problema de la ventana en una base de datos; no recuerdes nada y cada sesión arranca en frío.</p>
<h3 id="dónde-debería-vivir-cada-tipo-de-memoria-de-agente">¿Dónde debería vivir cada tipo de memoria de agente?</h3>
<p>En formas distintas, porque la forma es media parte del contenido. Las decisiones quieren un log solo-append donde la historia es el valor. Los invariantes quieren el fichero de reglas que el agente lee primero, para que aten cada escritura. El estado quiere una sola foto sobrescrita, sin historia. Mete las tres en un documento y cada una corrompe a las otras.</p>
<h3 id="por-qué-se-pudren-los-sistemas-de-memoria-de-agentes">¿Por qué se pudren los sistemas de memoria de agentes?</h3>
<p>Porque piden que un humano los mantenga, así que mueren en cuanto el humano se lía, y un log de decisiones que nadie actualiza miente con autoridad. La única versión que sobrevive es memoria que el trabajo escribe como efecto secundario: una decisión logueada en la sesión en que se toma, un invariante que aterriza en el fichero de reglas al terminar la tarea.</p>
<h3 id="debería-meter-todo-en-el-claudemd">¿Debería meter todo en el CLAUDE.md?</h3>
<p>No todo. Ahí es justo donde chocan los tres tipos: los invariantes quedan enterrados bajo el churn del estado, la historia de decisiones se aplana en un blob de status, y el agente lee una sopa que no honra de forma fiable. Guarda los invariantes en el fichero de reglas, las decisiones en un log, y el estado en su propia foto.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="memoria-de-agentes"/><category term="agents"/><category term="ai-coding"/><category term="runtime"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Más allá de Spec Kit: lo que el spec-driven necesita después de escribir la spec</title>
    <link href="https://paelladoc.com/es/blog/mas-alla-de-spec-kit/" rel="alternate" type="text/html" title="Más allá de Spec Kit: lo que el spec-driven necesita después de escribir la spec"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/mas-alla-de-spec-kit/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/mas-alla-de-spec-kit/"><![CDATA[<p><strong>Instalaste Spec Kit, corriste el flujo y obtuviste una spec limpia.</strong> El agente la leyó, construyó la feature y los tests se pusieron en verde. El día uno esto parece la respuesta a todo lo que está mal en el vibe coding.</p>
<p>Luego llega el día treinta. Cambias la lógica de precios, el agente toca tres archivos y la spec del disco sigue describiendo el comportamiento antiguo. Nadie la actualizó porque actualizarla no era tarea de nadie. El documento que iba a ser la fuente de verdad es ahora el mentiroso más convincente del repositorio.</p>
<p>Esto no es una crítica a Spec Kit. El <a href="https://github.com/github/spec-kit">Spec Kit de GitHub</a> hace algo de verdad útil: te obliga a escribir intención, restricciones y un plan antes de que un agente empiece a teclear. Ese primer acto de escribir atrapa una clase enorme de malentendidos. La pregunta de este artículo es la que viene después. ¿Qué necesita el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a> <em>después</em> de escribir la spec?</p>
<h2 id="la-spec-es-un-evento-el-contrato-es-un-proceso">La spec es un evento, el contrato es un proceso</h2>
<p>Casi todas las herramientas de este espacio tratan la spec como un evento. Corres un comando, produces un documento, se lo pasas a un agente y sigues adelante. El artefacto es el entregable.</p>
<p>Ahí empieza el problema. Una spec que solo existe en el momento de crearse es una foto de la intención tomada antes de que nadie supiera qué aspecto tendría el código. En cuanto sale la primera línea, la realidad y el documento empiezan a separarse. Si no haces nada, no se vuelven a reconciliar nunca.</p>
<p>La unidad útil no es el documento. Es el <a href="/es/blog/especificaciones-vivas/">contrato vivo</a> entre lo que querías decir y lo que hace el sistema, mantenido a lo largo de cada cambio que sigue. Escribir la spec es la parte barata. Mantenerla cierta es el trabajo.</p>
<h2 id="qué-se-rompe-después-de-la-spec">Qué se rompe después de la spec</h2>
<p>Tres cosas fallan cuando la spec sale de la herramienta que la escribió.</p>
<p><strong>Pierde el vínculo con el código.</strong> Un archivo markdown en una carpeta <code>specs/</code> no apunta a nada. Dice «el flujo de checkout valida el cupón antes de aplicarlo», pero no sabe qué funciones, archivos o tests implementan esa frase. Cuando la lógica del cupón se mueve, la frase se queda quieta y se vuelve falsa en silencio. Esto es el <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">spec drift</a>, y es el resultado por defecto, no la excepción.</p>
<p><strong>Pierde su evidencia.</strong> La spec decía qué aspecto tiene un resultado correcto. ¿Lo comprobó alguien? Un build en verde no es prueba de que se cumplieron los criterios de aceptación, como argumenta en detalle <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>. La spec describió el contrato; nada conectó ese contrato con una ejecución que de verdad lo pusiera a prueba. Así que te quedas confiando en una casilla marcada.</p>
<p><strong>Pierde su portabilidad.</strong> El siguiente agente, el siguiente editor o tú dentro de tres semanas no podéis reconstruir por qué la spec dice lo que dice. Las decisiones que había detrás vivían en un chat que ya no existe. Este es el argumento para tratar las <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">especificaciones como artefactos portables</a> en lugar de archivos atrapados en un solo workflow.</p>
<p>Ninguno de estos es un fallo del paso de escribir. Son fallos de todo lo que el paso de escribir no cubre.</p>
<h2 id="después-de-la-spec-tres-tareas-que-nadie-asignó">Después de la spec: tres tareas que nadie asignó</h2>
<p>Si la spec va a seguir siendo útil, tres tareas tienen que ocurrir de forma continua, y ahora mismo una persona hace las tres a mano sin nombrarlas.</p>
<h3 id="mantenerla-ligada">Mantenerla ligada</h3>
<p>Cada afirmación de una spec debería estar unida al código que la implementa. No «mira el repositorio», sino las funciones, módulos y tests concretos que hacen cierta la frase. Cuando uno de ellos cambia, el sistema debería saber qué afirmaciones de la spec quedan en cuestión. Esa es la diferencia entre documentación que se pudre y documentación que levanta la mano.</p>
<h3 id="mantenerla-verificada">Mantenerla verificada</h3>
<p>Los criterios de aceptación de la spec solo valen algo si algo los ejecuta contra el resultado real y mantiene el desenlace unido al contrato. La verificación no es una fase que haces una vez al final. Es la respuesta continua a «¿sigue cumpliéndose el contrato?». Es la razón entera por la que <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado por IA</a> necesita evidencia y no éxito auto-declarado.</p>
<h3 id="mantenerla-viva">Mantenerla viva</h3>
<p>Cuando el código cambia, la spec tiene que cambiar con él, o el drift se acumula hasta que el documento no vale nada. Una spec que se actualiza junto al código vale por diez specs que eran perfectas el día en que se escribieron y no se tocaron nunca más.</p>
<p>Ahora mismo, en casi todos los equipos, las tres tareas las hace una persona, a mano, sin que nadie las nombre como trabajo. Tú eres lo que recuerda que la spec existe. Tú eres quien nota, a veces, que un cambio la dejó obsoleta. Tú eres la memoria que conecta el código mergeado con la frase que se suponía que debía satisfacer. Funciona hasta que el volumen de output de los agentes supera tu atención, que ocurre rápido. La razón por la que la spec se pudre no es que la gente sea descuidada. Es que mantenerla cierta nunca se asignó a otra cosa que a una persona sosteniéndolo todo en la cabeza.</p>
<h2 id="respeta-la-puerta-de-entrada-extiende-el-workflow">Respeta la puerta de entrada, extiende el workflow</h2>
<p>Spec Kit es una buena puerta de entrada. Captura la intención en el momento en que la intención es más barata de capturar, antes de que el agente se haya comprometido con una implementación. No hay razón para sustituirlo, y el marco de «alternativas a Spec Kit» se pierde casi siempre lo que de verdad falta.</p>
<p>Lo que falta es la mitad de atrás del bucle. La spec necesita un lugar donde vivir en el que siga conectada al modelo de producto, al repositorio, a las tareas y a la evidencia, y desde el que pueda volver a salir sin quedar aplanada en prosa. La puerta de entrada escribe el contrato. El resto de la casa es donde el contrato tiene que sobrevivir al contacto con un código que cambia.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Este es el problema alrededor del cual está construido PaellaDoc. Un cambio puede entrar como una spec, desde Spec Kit o cualquier flujo parecido, y en lugar de convertirse en un archivo estático se convierte en un nodo mantenido dentro de un modelo local del producto. Las afirmaciones de la spec se enganchan al código que las implementa. Los criterios de aceptación se conectan con las ejecuciones que los ponen a prueba. Cuando el código deriva, las partes afectadas del contrato salen a la superficie en vez de quedarse obsoletas en silencio.</p>
<p>La spec no es el entregable. Es el principio de un contrato que tiene que seguir siendo cierto mientras muchos agentes escriben, fallan, se recuperan y publican. Escribirla nunca fue la parte difícil. Mantenerla veraz lo es.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Es PaellaDoc una alternativa a Spec Kit?</strong> No. Spec Kit escribe la spec al principio del workflow, y lo hace bien. El hueco es lo que pasa después: mantener la spec ligada al código, verificada contra evidencia y actualizada según el código cambia. Esa mitad de atrás es la parte que vale la pena construir.</p>
<p><strong>¿Por qué una spec deja de ser útil con el tiempo?</strong> Porque nada la mantiene conectada al código. Según cambia la implementación, el documento se queda congelado y va describiendo un sistema que ya no existe. Sin un mecanismo que detecte ese drift, la spec pasa a engañar de forma activa.</p>
<p><strong>¿Puedo seguir usando Spec Kit y aun así resolver esto?</strong> Sí. La idea no es soltar tu herramienta de entrada. Es darle a la spec un sitio donde vivir en el que siga ligada al código y a la evidencia después de que el agente haya construido la feature.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="spec-kit"/><category term="spec-driven-development"/><category term="especificaciones-vivas"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Mapas del código, no prompts más largos</title>
    <link href="https://paelladoc.com/es/blog/mapas-de-codigo-para-agentes/" rel="alternate" type="text/html" title="Mapas del código, no prompts más largos"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/mapas-de-codigo-para-agentes/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/mapas-de-codigo-para-agentes/"><![CDATA[<p>Le das al agente una tarea en una parte del codebase que no conoce. Se equivoca. Así que haces lo natural: escribes un prompt más largo. Describes la arquitectura, nombras los módulos importantes, explicas que la lógica de pagos vive aquí y la de reintentos allá, y de paso pegas un par de ficheros clave. El agente se equivoca un poco menos, rompe otra cosa, y mañana escribes un prompt aún más largo.</p>
<p>Hice esto durante semanas antes de ver la forma que tenía. El prompt no dejaba de crecer y los fallos no dejaban de moverse. Estaba tratando un problema estructural como si fuera de redacción, y ninguna cantidad de mejor redacción cierra un hueco estructural.</p>
<p>El agente no necesita más palabras sobre el codebase. Necesita un mapa de él. No son lo mismo, y esa diferencia es el punto entero de esta pieza.</p>
<h2 id="un-prompt-es-prosa-un-mapa-es-estructura">Un prompt es prosa. Un mapa es estructura.</h2>
<p>Esto es lo que es de verdad un prompt de arquitectura largo desde el lado del modelo: un muro de texto que tiene que leer, aguantar en la ventana de contexto, y del que tiene que re-derivar la estructura cada vez. Escribiste “el <code>OrderService</code> llama a <code>InventoryService</code> antes de escribir”. Eso es una frase. Para que el agente la use, tiene que parsear la frase en una relación, recordar la relación, y rezar para que mencionaras todas las demás relaciones que importan. Casi nunca lo haces, porque escribes desde tu propio mapa mental y te saltas las partes que te parecen obvias.</p>
<p>Un mapa es esa estructura entregada directamente. <code>OrderService</code> <em>llama</em> a <code>InventoryService</code>. Esa arista es <a href="/es/blog/grafo-vs-rag-vectorial/">un hecho que el agente puede consultar, no una frase que tiene que interpretar</a>. No compite por espacio en la ventana de contexto con la tarea de verdad. No depende de que te acuerdes de mencionarla. O está en el mapa o no está, y si el mapa se construye desde el código, está.</p>
<p>Por eso los prompts más largos chocan pronto contra un techo. La prosa no compone. Cada frase que añades es más que leer y más que potencialmente contradecir. La estructura sí compone: mil aristas en un mapa le cuestan al agente casi nada hasta que consulta las diez que necesita.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Un prompt es prosa de la que el modelo re-deriva la estructura en cada ejecución; un mapa entrega la estructura directa, así que las aristas que te rompen son las que nunca tienes que acordarte de mencionar."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">prompt</p>
    <ul><li>muro de texto</li><li>re-parseado cada vez</li><li>compite por contexto</li><li>olvidas aristas</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">mapa</p>
    <ul><li>aristas consultables</li><li>construido del código</li><li>compone barato</li><li>nunca olvida</li></ul>
  </div>
</div><figcaption>Un prompt es prosa de la que el modelo re-deriva la estructura en cada ejecución; un mapa entrega la estructura directa, así que las aristas que te rompen son las que nunca tienes que acordarte de mencionar.</figcaption></figure>
<p><a href="/es/research/context-engineering-para-agentes-de-codigo/">Context engineering para agentes de código</a> es en buena parte esta misma constatación aplicada de punta a punta: la victoria no es llenar más la ventana, es poner la estructura correcta donde el agente pueda alcanzarla.</p>
<h2 id="qué-contiene-de-verdad-un-mapa-del-código">Qué contiene de verdad un mapa del código</h2>
<p>“Mapa” no es una metáfora de “buena documentación”. Es una cosa concreta. Un mapa del código útil lleva, como mínimo:</p>
<ul>
<li><strong>La estructura de llamadas.</strong> Qué llama a qué. Es la columna vertebral. La mayoría de los errores peligrosos de un agente son cambios que ignoran un llamador, y la estructura de llamadas es justo el conjunto de aristas que le habría avisado.</li>
<li><strong>La estructura de dependencias.</strong> Qué importa qué, qué depende de qué servicio o tabla. Así es como el agente sabe si un cambio está contenido o si un cambio cruza medio sistema.</li>
<li><strong>El flujo de tipos y datos.</strong> Qué tipos fluyen por qué caminos. Renombra un campo y esto es lo que le dice al agente cada sitio donde ese campo se desempaqueta, no solo dónde se define.</li>
<li><strong>Las fronteras.</strong> Dónde acaba un módulo y empieza otro, y qué pocas funciones los puentean. Los agentes que respetan las fronteras escriben cambios que encajan con la forma existente en vez de perforarla.</li>
<li><strong>Los puntos de entrada.</strong> Endpoints, jobs, comandos de CLI, manejadores de eventos. Los sitios donde la ejecución de verdad empieza, para poder trazar un camino desde un disparador real hasta su efecto.</li>
<li><strong>Alcanzabilidad.</strong> Qué está vivo y qué está muerto. Un mapa que sabe que nadie llama a una función es un mapa que deja al agente dejar de preocuparse por ella.</li>
</ul>
<p>Nada de eso es prosa que escribes. Todo es estructura que lees del código. El mapa es una proyección del sistema, que es también por lo que no envejece como envejece un documento de arquitectura escrito a mano. Cuando el código cambia, el mapa se regenera desde el código nuevo, y vuelve a ser verdad sin que nadie se acuerde de actualizarlo.</p>
<h2 id="por-qué-usa-un-modelo-más-grande-también-falla">Por qué “usa un modelo más grande” también falla</h2>
<p>El otro reflejo, al lado del prompt más largo, es esperar al modelo más grande. Seguro que un agente más listo con más contexto se apañaría con la estructura.</p>
<p>Se apaña con más parte de ella, y sigue <a href="/es/blog/onboarding-contra-el-grafo/">empezando cada sesión desde cero</a>. Una ventana de contexto más grande es más sitio donde pegar ficheros; no es un mapa, porque el modelo sigue teniendo que reconstruir las relaciones desde el texto pegado en cada ejecución. Estás pagando, en tokens y en tiempo, por reconstruir la misma estructura que el código ya contiene, una y otra vez, y rezando por que la reconstrucción esté completa esta vez. Normalmente no lo está, porque las relaciones que te rompen son las no obvias, y esas son justo las que una lectura desde cero tiene más probabilidad de saltarse.</p>
<p>Entrégale el mapa al modelo y el modelo listo se vuelve más listo, porque gasta su capacidad en la tarea en vez de en re-derivar el terreno. Ese es el sentido literal de la frase: mapas del código, no prompts más largos. La palanca se movió del tamaño del input a la forma de él.</p>
<h2 id="el-rename-que-un-mapa-habría-cazado">El rename que un mapa habría cazado</h2>
<p>Hazlo concreto. Le pides a un agente que renombre un campo de un struct central, <code>userId</code> a <code>accountId</code>, un cambio que parece trivial. Sin mapa, el agente hace grep de <code>userId</code>, encuentra la definición y los usos obvios del mismo módulo, los actualiza, y canta hecho. Se dejó el serializador de otro paquete que lee el campo por clave de texto, la migración SQL que nombra la columna, y un fixture de test tres directorios más allá que hardcodea el nombre viejo. El build incluso pasa, porque el fallo del serializador solo aparece en runtime contra datos reales. Te lo encuentras en producción, o lo <a href="/es/blog/entender-codigo-generado-por-ia/">encuentra un revisor después de una hora de lectura</a>.</p>
<p>Con el mapa, el rename empieza distinto. El agente <a href="/es/blog/grafo-de-conocimiento-del-codigo/">consulta al grafo</a> todo lo conectado a ese campo: cada función que lo lee o escribe, cada tipo por el que fluye, cada test que toca esas funciones, los nodos de config y migración que lo referencian. Obtiene el conjunto completo antes de cambiar una línea, lo actualiza todo o te dice qué partes no puede tocar con seguridad, y el cambio aterriza entero. La diferencia nunca fue la inteligencia del modelo con el rename. Fue si el modelo podía ver el vecindario del campo. Un prompt más largo habría descrito el módulo que ya conocías y aun así se habría dejado el serializador, porque también te habrías olvidado de mencionarlo. El mapa no se olvida, porque no está recordando. Está leyendo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Esta es una de las razones por las que PaellaDoc lee tu repo a un grafo en tu máquina antes de que un agente lo toque. El mapa, la estructura de llamadas, las dependencias, las fronteras, los enlaces del código a las decisiones que lo pidieron, se construye desde el código real y se mantiene al día según el código se mueve. Los agentes lo consultan en vez de releer el mundo desde un prompt. Esa misma estructura es la que le deja a <a href="/es/blog/grafo-de-conocimiento-de-producto/">un grafo de conocimiento de producto</a> responder preguntas un nivel más arriba, sobre forma y validación en vez de llamadas y tipos. Misma técnica, dos alturas.</p>
<p>La próxima vez que un agente se equivoque en código que no conoce, resiste el prompt más largo. Pregúntate qué relación le faltaba, y si esa relación vive en algún sitio que pueda consultar. Si no vive, ninguna frase que añadas la va a poner ahí. Un mapa sí.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuál es el prompt más largo que has escrito intentando explicarle un codebase a un agente? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-mi-agente-se-equivoca-una-y-otra-vez-en-código-que-no-conoce">¿Por qué mi agente se equivoca una y otra vez en código que no conoce?</h3>
<p>Normalmente porque le falta un mapa de la estructura, no porque tu prompt sea corto. Hace grep, lee unos ficheros e infiere las relaciones que importan, y se salta las no obvias, como un llamador en otro paquete. El fallo es estructural, y ninguna cantidad de mejor redacción cierra un hueco estructural.</p>
<h3 id="qué-es-un-mapa-del-código">¿Qué es un mapa del código?</h3>
<p>No es buena documentación. Es la estructura leída del código: la estructura de llamadas (qué llama a qué), la de dependencias, el flujo de tipos y datos, las fronteras entre módulos, los puntos de entrada y la alcanzabilidad. Como es una proyección del código, se regenera cuando el código cambia en vez de envejecer como un doc de arquitectura escrito a mano.</p>
<h3 id="por-qué-un-prompt-más-largo-no-arregla-los-fallos-del-agente">¿Por qué un prompt más largo no arregla los fallos del agente?</h3>
<p>Porque la prosa no compone. Cada frase es más que leer, más que potencialmente contradecir, y estructura que el modelo tiene que re-derivar en cada run, y te saltas las aristas que te parecen obvias. Un mapa entrega la estructura como hechos consultables, así que mil aristas cuestan casi nada hasta que el agente consulta las diez que necesita.</p>
<h3 id="un-modelo-más-grande-resuelve-el-código-que-no-conoce">¿Un modelo más grande resuelve el código que no conoce?</h3>
<p>Se apaña con más parte y sigue empezando cada sesión desde cero, reconstruyendo las relaciones desde el texto pegado en cada run. Las relaciones que te rompen son las no obvias que una lectura desde cero tiene más probabilidad de saltarse. Entrégale el mapa y gasta su capacidad en la tarea en vez de en re-derivar el terreno.</p>]]></content>
    <summary type="html"><![CDATA[Cuando un agente rompe cosas una y otra vez en un codebase que no conoce, el reflejo es escribir un prompt más largo y detallado describiendo la arquitectura. Rara vez ayuda, porque el problema del agente nunca fue falta de prosa. Era la ausencia de un mapa. Un prompt es texto que buscar; un mapa del código es estructura que recorrer. Aquí está la diferencia, y qué contiene de verdad un mapa.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="codebase-maps"/><category term="ai-coding"/><category term="agents"/><category term="context-engineering"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Los agentes van a derivar: diseñar para la divergencia en vez de rezar</title>
    <link href="https://paelladoc.com/es/blog/los-agentes-derivan/" rel="alternate" type="text/html" title="Los agentes van a derivar: diseñar para la divergencia en vez de rezar"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/los-agentes-derivan/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/los-agentes-derivan/"><![CDATA[<p>Dale la misma tarea a un agente tres veces y tendrás tres implementaciones distintas. Dale una tarea larga a un solo agente y al final está resolviendo un problema ligeramente distinto del que empezaste. Ninguna de las dos cosas es un mal funcionamiento. Es la naturaleza del asunto. Los agentes derivan, como el agua encuentra la pendiente, y cualquier plan para operarlos que dé por hecho que no lo harán es un plan que falla al contacto con un run real.</p>
<p>El error que veo cometer, y cometí yo, es tratar la deriva como algo que eliminar. Escribe un prompt mejor, añade más reglas, sé más preciso, y seguro que esta vez se queda en el carril. No lo hará, no de forma fiable, y el esfuerzo gastado en intentar promptear la deriva hasta que desaparezca es esfuerzo no gastado en lo que de verdad funciona: construir un sistema que espera la divergencia y está diseñado para pillarla.</p>
<h2 id="qué-es-de-verdad-la-deriva">Qué es de verdad la deriva</h2>
<p>La deriva es la brecha que se abre entre lo que pretendías y lo que el agente está haciendo, y se abre por razones estructurales, no arreglables siendo más amable con el modelo.</p>
<p>Un agente trabaja desde su contexto, y su contexto es siempre una imagen parcial y en decadencia de tu intención. Parte de la intención nunca se escribió. Parte se compactó a mitad de sesión, la misma <a href="/es/blog/perdida-de-contexto-entre-sesiones/">pérdida de contexto</a> que borra decisiones e invariantes. Parte la infirió el agente, y la infirió un poco mal. Así que el agente siempre navega guiándose por una aproximación del objetivo, y los pequeños errores de la aproximación se acumulan a lo largo de un run largo. Arregla lo que tiene delante, lo que desplaza sutilmente qué significa «el problema», y arregla lo siguiente contra el significado desplazado. Paso a paso, cada uno localmente razonable, se aleja de donde lo apuntaste.</p>
<p>Multiplica eso por varios agentes trabajando a la vez y la divergencia no es solo entre agente e intención, es entre los agentes mismos, cada uno derivando en su propia dirección desde un objetivo que ninguno ve del todo. Esa es la forma aguda, la que aparece como <a href="/es/blog/orquestacion-multiagente/">agentes contaminándose entre sí</a> en el merge.</p>
<h2 id="por-qué-no-se-quita-con-un-prompt">Por qué no se quita con un prompt</h2>
<p>El instinto de arreglar la deriva con un prompt mejor falla por una razón simple: el prompt es una foto, y la deriva es un proceso. Puedes apuntar el agente con mucha precisión al objetivo en el instante cero. No puedes hacer que esa precisión persista a lo largo de un run largo, porque lo que la erosiona, la compactación, la inferencia, la acumulación de pequeñas decisiones locales, pasa después de entregar el prompt y sigue pasando.</p>
<p>Un prompt perfecto reduce el error inicial. No hace nada contra la acumulación. Es la misma razón por la que un modelo más grande no arregla el trabajo largo: el modelo puede ser más listo y aun así derivar, porque la deriva no es un problema de listura, es un problema de distancia a un objetivo que se difumina. El comportamiento previsto vive en la especificación, y la conexión del agente con esa especificación se degrada a lo largo del run. Por eso la respuesta duradera es reanclar al agente a algo que no se difumina, y lo que no se difumina es una <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">spec que existe antes de escribir una línea</a> y sigue legible todo el camino.</p>
<h2 id="diseñar-para-la-divergencia">Diseñar para la divergencia</h2>
<p>Cuando aceptas la deriva como una constante, el diseño cambia por completo. Dejas de preguntar «cómo hago que el agente no derive» y empiezas a preguntar «cómo pillo la deriva pronto y barato y la traigo de vuelta». Eso es un sistema con tres propiedades.</p>
<p><strong>Reanclaje frecuente.</strong> Cuanto más va un agente sin que le recuerden el objetivo, más deriva. Así que no entregas una tarea enorme y compruebas al final. Partes el trabajo en piezas lo bastante pequeñas para que el agente no pueda vagar lejos antes de reanclarse contra el contrato. La <a href="/es/blog/memoria-agentes-de-codigo/">memoria</a> duradera y cargable es lo que hace barato el reanclaje: el objetivo está ahí, en el contexto, cada vez, en vez de ser algo que tienes que re-explicar.</p>
<p><strong>Checkpoints que miden distancia a la intención, no solo corrección.</strong> Un test normal pregunta «¿esto funciona?». Un checkpoint que pilla deriva también pregunta «¿esto sigue resolviendo el problema con el que empezamos?». Son preguntas distintas. El código puede funcionar perfectamente y ser la respuesta a una pregunta que derivó lejos de la que hiciste. El checkpoint tiene que sostener los criterios originales, no la comprensión actual del agente, porque la comprensión del agente es justo lo que derivó.</p>
<p><strong>Reconciliación como paso de primera clase.</strong> Cuando tienes divergencia, sea entre un agente y la intención o entre varios agentes, necesitas un momento deliberado para volver a juntarla, no la esperanza de que integre limpio. La reconciliación es donde detectas que dos cambios derivaron a conflicto y decides cuál es el correcto. En el trabajo multiagente es el merge. En el trabajo largo de un solo agente es el checkpoint donde re-puntúas contra el contrato original. En cualquier caso es un sitio del sistema, no un golpe de suerte.</p>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="No previenes la deriva, la pillas: trozos pequeños, checkpoints que miden distancia a la intención, y reconciliación deliberada, una y otra vez."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">TROZO PEQUEÑO</text><path d="M 250 85 L 272 85 M 266 79 L 272 85 L 266 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="52" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CHECKPOINT</text><path d="M 488 85 L 510 85 M 504 79 L 510 85 L 504 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="52" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="618" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">RECONCILIAR</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">REANCLAR AL CONTRATO</text></svg><figcaption>No previenes la deriva, la pillas: trozos pequeños, checkpoints que miden distancia a la intención, y reconciliación deliberada, una y otra vez.</figcaption></figure>
<h2 id="el-coordinador-que-la-espera">El coordinador que la espera</h2>
<p>Junta eso y tienes un coordinador cuya suposición de diseño entera es que lo que coordina va a divergir. No se fía del informe del agente de que se quedó en el carril, porque un agente que ha derivado cree que está en el carril, desde dentro de su comprensión desplazada. Re-comprueba contra un objetivo que el agente no puede mover. Pilla la divergencia en un checkpoint en vez de al final. Reconcilia a propósito en vez de integrar con esperanza.</p>
<p>Construir ese coordinador a propósito, en vez de improvisarlo cada sesión, es el oficio emergente del <a href="/es/blog/harness-engineering/">harness engineering</a>: la disciplina que nace alrededor de cómo operas los agentes y no de cómo piensan.</p>
<p>Esta es la diferencia entre operar agentes y rezar para que se porten. Rezar no escala, porque cada agente añadido y cada hora añadida es otra oportunidad de derivar, y la tasa de éxito de la esperanza cae según crece la superficie. Un coordinador construido para la divergencia se vuelve más estable según añades agentes, no más tembloroso, porque pillar la deriva es un paso diseñado y no un resultado con suerte.</p>
<p>La razón entera de que este trabajo de coordinación sea caro es que hoy suele correr en una persona, vigilando el momento en que un agente vaga y tirando de él a mano. Esa es la versión más literal de ser <a href="/es/blog/eres-el-runtime/">el runtime</a>: tú, en persona, como el sistema de detección de deriva. Diseñar para la divergencia es cómo sacas eso de ti, haciendo de «espera la deriva, píllala, reconcíliala» una propiedad del sistema en vez de una cosa que haces por estar vigilante. La deriva no es el enemigo. Fingir que no va a pasar sí.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Pillas a tus agentes derivando en un checkpoint, o cuando algo se rompe aguas abajo? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-la-deriva-de-un-agente">¿Qué es la deriva de un agente?</h3>
<p>La deriva es la brecha que se abre entre lo que pretendías y lo que el agente está haciendo. Un agente navega guiándose por su contexto, que es siempre una imagen parcial y en decadencia de tu intención: parte nunca se escribió, parte se compactó a mitad de sesión, parte la infirió un poco mal. Arregla lo que tiene delante, lo que desplaza qué significa «el problema», y arregla lo siguiente contra el significado desplazado. Paso a paso, cada uno razonable, se aleja de donde lo apuntaste.</p>
<h3 id="se-puede-evitar-la-deriva-con-un-prompt-mejor">¿Se puede evitar la deriva con un prompt mejor?</h3>
<p>No de forma fiable. El prompt es una foto; la deriva es un proceso. Puedes apuntar el agente con precisión al objetivo en el instante cero, pero no puedes hacer que esa precisión persista, porque lo que la erosiona —la compactación, la inferencia, la acumulación de pequeñas decisiones locales— pasa después de entregar el prompt y sigue pasando. Un prompt perfecto reduce el error inicial y no hace nada contra la acumulación a lo largo de un run largo.</p>
<h3 id="un-modelo-más-grande-reduce-la-deriva">¿Un modelo más grande reduce la deriva?</h3>
<p>No por sí solo. La deriva no es un problema de listura, es un problema de distancia a un objetivo que se difumina. Un modelo más listo puede derivar igual, porque el comportamiento previsto vive en la especificación y la conexión del agente con esa especificación se degrada a lo largo del run. La respuesta duradera es reanclar el agente a algo que no se difumina: una spec que existe antes de escribir una línea y sigue legible todo el camino.</p>
<h3 id="cómo-evito-que-los-agentes-se-salgan-del-carril">¿Cómo evito que los agentes se salgan del carril?</h3>
<p>No previenes la deriva, la pillas pronto y barato. Parte el trabajo en trozos lo bastante pequeños para que el agente no pueda vagar lejos antes de reanclarse al contrato. Usa checkpoints que midan distancia a la intención, no solo si el código funciona. Y trata la reconciliación como un paso de primera clase donde la divergencia se trae de vuelta a propósito. Un coordinador construido así se vuelve más estable según añades agentes, no más tembloroso.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="los-agentes-derivan"/><category term="divergencia"/><category term="agents"/><category term="runtime"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Herramientas sin cuenta: qué dice de un producto no pedirte registro</title>
    <link href="https://paelladoc.com/es/blog/herramientas-sin-cuenta/" rel="alternate" type="text/html" title="Herramientas sin cuenta: qué dice de un producto no pedirte registro"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/herramientas-sin-cuenta/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/herramientas-sin-cuenta/"><![CDATA[<p><strong>Cuando una herramienta no te pide crear una cuenta, te está diciendo algo sobre cómo gana dinero.</strong> No siempre algo halagador, ni siempre lo mismo, pero el muro de registro es una decisión de diseño, y las decisiones de diseño revelan incentivos. Aprende a leerlo y la pantalla de cuenta se convierte en una de las señales más claras que te da un producto antes de haberlo usado.</p>
<p>Empieza con una pregunta en la que merece la pena sentarse: ¿para quién es en realidad la cuenta obligatoria? Casi nunca para el usuario. No necesitas una cuenta para ejecutar software en tu propia máquina. La cuenta existe porque la empresa la necesita; y para qué la necesita es toda la pista.</p>
<h2 id="para-qué-suele-construirse-el-muro-de-registro">Para qué suele construirse el muro de registro</h2>
<p>Un email y una contraseña antes de que hayas visto al producto hacer algo útil rara vez van de servirte a ti. Sigue lo que la cuenta habilita en su lado.</p>
<p>Crea un registro al que pueden hacer marketing. Tu dirección entra en un ciclo de correos de onboarding, empujoncitos de reenganche, campañas de recuperación. Construye un embudo que pueden medir y optimizar —registros, activación, los puntos de abandono donde añadirán fricción para empujarte adelante o un muro para empujarte a pagar—. Establece un coste de cambio, porque ahora tu trabajo vive en su cuenta y marcharte significa extraerlo. Y produce el número contra el que se gestiona muchas veces el negocio: usuarios registrados, hayan obtenido valor o no.</p>
<p>Nada de eso es intrínsecamente malvado. Mucho buen software funciona así. Pero ten claro que la cuenta sirve sobre todo a la necesidad del proveedor de retenerte y monetizarte, y solo de forma incidental te sirve a ti. El muro apunta hacia donde apuntan los incentivos.</p>
<h2 id="qué-señala-saltárselo">Qué señala saltárselo</h2>
<p>Ahora lo inverso. Cuando una herramienta te deja descargar y trabajar sin cuenta, varias cosas tienen que ser ciertas sobre su negocio, y vale la pena nombrarlas porque son las alineadas contigo.</p>
<p>No puede estar optimizando una métrica vanidosa de usuarios registrados, porque no recoge las identidades para contarlas. No te está pasando por un embudo de retención, porque no hay cuenta que ancle el embudo. No está construyendo un coste de cambio con tu trabajo guardado, porque tu trabajo nunca estuvo en su servidor para retenerlo. Su incentivo para hacer el software bueno en la primera ejecución es inusualmente puro, porque no hay captura de email como red, ni campaña de goteo para reenganchar a quien rebotó. Si no obtienes valor de inmediato, no tienen un segundo canal hacia ti. El producto tiene que ganarse la siguiente apertura por sí solo.</p>
<p>Esa alineación es la señal. Una herramienta sin cuenta ha apostado a que ser buena es la estrategia de retención, porque renunció a propósito a las otras. Eso no garantiza que la herramienta sea buena. Sí garantiza que el incentivo apunta a tu experiencia y no a tu ficha de contacto.</p>
<h2 id="los-tradeoffs-todos">Los tradeoffs, todos</h2>
<p>No me fiaría de este argumento de alguien que solo listara lo bueno, así que esto es lo que de verdad cedes.</p>
<p>Sin cuenta suele significar sin sincronización en la nube. Tu trabajo no aparece automáticamente en tu otra máquina; moverte entre dispositivos corre de tu cuenta. Suele significar sin copia de seguridad en la nube: si tu disco muere y no tenías tu propio backup, el proveedor no tiene copia que restaurar, porque nunca tuvo copia. Significa sin la continuidad entre dispositivos, del tipo sin fricción, que una herramienta en la nube con sesión te da gratis. Y significa que algunas funciones genuinamente colaborativas son más difíciles o inexistentes, porque el estado compartido entre personas es justo en lo que las cuentas y los servidores son buenos.</p>
<p>Esto es real. Para un equipo que necesita colaboración fluida entre varios dispositivos, una herramienta local sin cuenta encaja peor, y conviene decirlo tal cual. La ausencia de cuenta no es gratis. Es un intercambio: cedes la sincronización y el backup gestionados por el proveedor y recibes, a cambio, propiedad, <a href="/es/blog/el-codigo-se-queda-en-casa/">privacidad que aguanta porque los datos nunca salieron</a>, y un producto cuyos incentivos no trabajan calladamente contra ti.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="El intercambio sin cuenta, dicho tal cual: cedes la sincronización y el backup del proveedor y recibes propiedad, privacidad e incentivos que apuntan a ti."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">cedes</p>
    <ul><li>sincronización en nube</li><li>backup en nube</li><li>continuidad entre equipos</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">recibes</p>
    <ul><li>propiedad</li><li>privacidad que aguanta</li><li>incentivos alineados</li></ul>
  </div>
</div><figcaption>El intercambio sin cuenta, dicho tal cual: cedes la sincronización y el backup del proveedor y recibes propiedad, privacidad e incentivos que apuntan a ti.</figcaption></figure>
<h2 id="no-confundas-sin-cuenta-con-sin-captura-de-valor">No confundas sin cuenta con sin captura de valor</h2>
<p>Una aclaración, porque la lectura cínica es que una herramienta sin cuenta tiene que ser un reclamo con una trampa esperando. A veces. Pero la alineación puede ser limpia y aun así ganar dinero. Cobra por el producto directamente. Cobra por el uso más allá de un tramo gratis. Cobra por funciones de equipo donde el servidor sí aporta valor. Una herramienta puede negarse a construir su negocio sobre cosechar y retener tu identidad y aun así tener un modelo de negocio real; uno donde pagas por la cosa en vez de ser la cosa que se monetiza. Esa es la versión que merece buscar: sin cuenta no porque no haya nada que vender, sino porque lo que venden es el software, a ti, a un precio que se ve.</p>
<h2 id="una-prueba-de-campo-de-treinta-segundos">Una prueba de campo de treinta segundos</h2>
<p>Puedes leer los incentivos de un producto desde su primera ejecución más rápido que desde su página de precios, porque la página de precios está escrita y el onboarding está construido. Lo construido filtra intención.</p>
<p>Mira dónde se sitúa el muro respecto al valor. Si tienes que registrarte antes de que la herramienta haga nada útil, la cuenta está haciendo trabajo de captación, y tú eres la captación. Si llegas primero a la parte útil y solo te piden registrarte cuando topas con algo que de verdad necesita una identidad —compartir con un compañero, sincronizar un segundo dispositivo—, la cuenta está haciendo trabajo de función, y eso es otra cosa, más limpia.</p>
<p>Después mira qué pide el registro y qué desbloquea. Un email para guardar tu propio trabajo en local es teatro; no hay razón para que tu máquina necesite tu dirección para escribir un archivo. Un email para habilitar una función en el servidor es un trato justo que puedes evaluar. El hueco entre lo que la cuenta recoge y lo que funcionalmente requiere es el tamaño del motivo de marketing.</p>
<p>Y mira la salida. Una herramienta segura de ser buena hace fácil marcharse, porque no se apoya en trabajo atrapado para retenerte. Una que entierra la exportación, o no la tiene, te está diciendo que el coste de cambio es parte del plan. Muchas veces puedes ver esto antes de teclear un solo carácter de trabajo real, solo leyendo cómo están puestos en escena los primeros cinco minutos. La puesta en escena es la estrategia, hecha visible.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc no pide cuenta. Lo descargas y funciona, gratis hasta tres proyectos. No hay registro, así que no hay ciclo de correos, ni embudo de usuarios registrados, ni perfil tuyo y de tu trabajo en ningún servidor; porque en una <a href="/es/blog/fabrica-local-de-software/">fábrica local de software</a> tu trabajo se queda en almacenamiento local en tu máquina de todos modos. El tradeoff real viene con ello: sin sincronización ni copia de seguridad automáticas en la nube, así que tus propios backups son responsabilidad tuya.</p>
<p>La pantalla de cuenta es una de las primeras cosas que un producto te enseña y una de las más reveladoras. Cuando una herramienta te hace registrarte antes de haber hecho nada por ti, pregunta para qué es la cuenta. Cuando no te la pide, estás mirando un producto que decidió que su incentivo para retenerte debería venir de merecer que lo abras otra vez, no de retener tu identidad como rehén. Lee el muro. Se construyó hacia donde apuntan los incentivos.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-las-herramientas-para-developers-te-hacen-crear-una-cuenta">¿Por qué las herramientas para developers te hacen crear una cuenta?</h3>
<p>Normalmente por el proveedor, no por ti. No necesitas una cuenta para ejecutar software en tu propia máquina. La cuenta crea un registro al que hacer marketing, un embudo que medir y optimizar, un coste de cambio porque tu trabajo pasa a vivir en su servidor, y el número de usuarios registrados contra el que se gestiona muchas veces el negocio. Nada de eso es malvado, pero el muro apunta hacia donde apuntan los incentivos.</p>
<h3 id="una-herramienta-sin-cuenta-puede-tener-un-modelo-de-negocio-real">¿Una herramienta sin cuenta puede tener un modelo de negocio real?</h3>
<p>Sí. Sin cuenta no significa sin captura de valor. Una herramienta puede cobrar por el producto directamente, cobrar por el uso más allá de un tramo gratis, o cobrar por funciones de equipo donde el servidor sí aporta valor. Lo que se niega a hacer es construir su negocio sobre cosechar y retener tu identidad. Pagas por el software en vez de ser la cosa que se monetiza: la versión que merece buscar.</p>
<h3 id="qué-cedes-con-una-herramienta-sin-cuenta">¿Qué cedes con una herramienta sin cuenta?</h3>
<p>Cosas reales, casi todas atadas a la nube. Sin cuenta suele significar sin sincronización automática en la nube, así que moverte entre dispositivos corre de tu cuenta. Significa sin backup del proveedor: si tu disco muere sin tu propia copia, no tienen ninguna que restaurar. Significa menos continuidad entre dispositivos, y algunas funciones colaborativas son más difíciles o inexistentes. Para un equipo que necesita colaboración fluida entre dispositivos, encaja peor. El intercambio compra propiedad, privacidad e incentivos alineados.</p>
<h3 id="cómo-sé-si-el-registro-de-una-herramienta-es-para-mí-o-para-el-proveedor">¿Cómo sé si el registro de una herramienta es para mí o para el proveedor?</h3>
<p>Mira dónde se sitúa el muro respecto al valor. Registrarte antes de que la herramienta haga nada útil es trabajo de captación, y tú eres la captación. Registrarte solo cuando topas con algo que de verdad necesita una identidad —compartir, sincronizar un segundo dispositivo— es trabajo de función, no captura. Después mira la salida: una herramienta segura de ser buena hace fácil marcharse; una que entierra la exportación convierte el coste de cambio en parte del plan.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="sin-cuenta"/><category term="local-first"/><category term="fabrica-local-de-software"/><category term="herramientas-de-desarrollo"/><category term="incentivos-de-producto"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Por qué lo nativo en macOS sigue importando en herramientas de desarrollo</title>
    <link href="https://paelladoc.com/es/blog/herramientas-nativas-macos/" rel="alternate" type="text/html" title="Por qué lo nativo en macOS sigue importando en herramientas de desarrollo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/herramientas-nativas-macos/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/herramientas-nativas-macos/"><![CDATA[<p>Casi todas las herramientas de escritorio para desarrollo hoy son apps web con disfraz. Un motor de navegador empaquetado, un servicio remoto haciendo el trabajo real y un icono de Mac encima para que parezca que pertenece. Se lanza, funciona, y durante un tiempo no notas lo que esa elección te costó.</p>
<p>Luego lo notas. Se siente ajena de formas pequeñas que no sabes nombrar del todo. Pierde frames en una máquina que nunca debería perder uno. Y te pide entregar tu código fuente a una descarga por la que no puedes responder de verdad. Lo nativo en macOS no es nostalgia ni purismo. Para una herramienta que sostiene tu código y corre en tu máquina todo el día, es una decisión sobre tres cosas: integración, rendimiento y confianza. Esos tres son el caso entero.</p>
<h2 id="integración-hablar-el-idioma-de-la-máquina-en-vez-de-reinventarlo">Integración: hablar el idioma de la máquina en vez de reinventarlo</h2>
<p>El sistema operativo ya resolvió una lista larga de problemas difíciles. Dónde viven los secretos. Cómo se concede y se revoca el acceso a ficheros. Cómo se comportan las ventanas, las notificaciones, el compartir y el trabajo en segundo plano. Una app nativa usa esas soluciones. Guarda las credenciales en el Keychain. Pide permisos de fichero como los pide el sistema, para que los puedas ver y revocar. Se comporta como cualquier otra app de verdad en tu Mac porque usa la misma maquinaria debajo.</p>
<p>Una app web en una carcasa reinventa todo eso dentro de su propio sandbox, normalmente peor. Su idea de dónde van los secretos. Su modelo de permisos que el sistema operativo no puede inspeccionar. Sus medias versiones de cosas que macOS hace bien. Cada reinvención es un sitio donde el comportamiento se aleja de lo que esperas y un sitio donde tus datos quedan donde las protecciones del propio sistema no llegan. La integración no es pulido. Es si la herramienta participa del modelo de seguridad y permisos del que ya dependes, o se sale de él sin hacer ruido.</p>
<h2 id="rendimiento-un-día-entero-de-trabajo-no-es-un-benchmark">Rendimiento: un día entero de trabajo no es un benchmark</h2>
<p>El rendimiento en una herramienta que tienes abierta todo el día no va de ganar un benchmark. Va del impuesto acumulado de cada interacción, cada render, cada operación en segundo plano, pagado a lo largo de horas, con batería.</p>
<p>Una app nativa compilada para <a href="https://developer.apple.com/documentation/apple-silicon">Apple Silicon</a> corre sobre el metal. Usa la memoria y los núcleos como el sistema pretende. Un motor de navegador empaquetado carga el peso de una pila de renderizado entera que no necesitaba, en un runtime pensado para mostrar documentos, no para ser la carcasa de una herramienta que orquesta agentes y mantiene una vista viva de tu trabajo. En una demo rápida no notarás la diferencia. En la cuarta hora, con varias sesiones corriendo, la notas en los ventiladores, en la batería, en el pequeño lag de cada acción que una app nativa simplemente no tiene.</p>
<p>Para una <a href="/es/blog/fabrica-local-de-software/">fábrica local de software</a> que se supone que corre en local, esto se acumula. Toda la premisa es que el trabajo real pasa en tu máquina. Si la carcasa alrededor de ese trabajo pesa más que el trabajo, has gastado tu hardware en el envoltorio.</p>
<p>Hay también un coste de segundo orden. Una carcasa más pesada deja menos margen para el trabajo que de verdad te importa. Cuando varios agentes están corriendo y la máquina ya carga un motor de navegador que no necesitaba, el impuesto aparece como contención: el build que debería haber sido rápido, la sesión que da tirones mientras otra renderiza. Lo nativo devuelve ese margen al trabajo en vez de al marco que lo rodea.</p>
<h2 id="confianza-la-app-tiene-que-demostrar-de-dónde-viene">Confianza: la app tiene que demostrar de dónde viene</h2>
<p>Esta es la que más importa en una herramienta que apuntas a tu código fuente, y es la que el modelo de web-en-una-caja lleva peor.</p>
<p>macOS no deja correr una app nativa solo porque la descargaste. De una app de Mac distribuida se espera que esté firmada con una identidad de desarrollador verificada y <a href="https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution">notarizada por Apple</a>, lo que significa que Apple la ha revisado en busca de malware y el sistema puede confirmar que no se ha alterado desde entonces. Grapa esa notarización a la app y la máquina puede verificarlo todo antes del primer arranque, sin conexión. Esa es una cadena de procedencia que puedes inspeccionar de verdad. Sabes quién la firmó. Sabes que está inalterada. Sabes que pasó el chequeo de Apple.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="La cadena de procedencia que carga una app nativa de Mac: firmada, notarizada, grapada y verificada por la máquina antes del primer arranque, sin conexión."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">FIRMADA</text><path d="M 190 95 L 212 95 M 206 89 L 212 95 L 206 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">NOTARIZADA</text><path d="M 368 95 L 390 95 M 384 89 L 390 95 L 384 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">GRAPADA</text><path d="M 546 95 L 568 95 M 562 89 L 568 95 L 562 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="62" width="144" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="646" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">VERIFICADA</text></svg><figcaption>La cadena de procedencia que carga una app nativa de Mac: firmada, notarizada, grapada y verificada por la máquina antes del primer arranque, sin conexión.</figcaption></figure>
<p>Una herramienta que en realidad es una web dentro de un marco no carga ese mismo peso, porque la parte que hace el trabajo real no es lo que instalaste. Es un servicio en otro sitio, y lo que estás confiando es una conexión y una política de privacidad, no un artefacto que el sistema pueda verificar. Para la mayoría del software eso vale. Para el software al que estás a punto de darle tu código privado, “el sistema verificó de dónde viene esto y que nadie lo tocó” no es un formalismo. Es la diferencia entre una decisión de confianza que puedes razonar y otra que tomas por fe.</p>
<h2 id="nativo-y-local-first-son-el-mismo-compromiso">Nativo y local-first son el mismo compromiso</h2>
<p>Fíjate en que los tres argumentos apuntan a lo mismo. Integración significa usar las protecciones de verdad de la máquina. Rendimiento significa correr sobre el hardware de verdad de la máquina. Confianza significa que la máquina puede verificar lo que ejecuta. Los tres son afirmaciones de que la máquina es donde el trabajo vive de verdad.</p>
<p>Por eso lo nativo es la forma coherente del <a href="/es/blog/desarrollo-ia-local-first/">desarrollo con IA local-first</a>. Si toda la promesa de una herramienta es que tu código y tus datos se quedan en tu ordenador, entonces la herramienta que los sostiene debería ser un ciudadano de verdad de ese ordenador, no una carcasa fina alrededor de un servicio corriendo en un sitio que no ves. Un producto local-first entregado como un navegador apuntando a un backend remoto se contradice a sí mismo. La app nativa, firmada e integrada y corriendo sobre tu silicio, es la promesa cumplida.</p>
<p>Voy a ser justo con el otro lado, porque es un trade real y no un espantapájaros. La tecnología web multiplataforma es más barata de construir, más rápida de sacar, y llega a Windows y Linux desde un solo código. Para muchos productos esa es justo la decisión correcta, y no voy a fingir lo contrario. Pero es un trade, y lo que cedes es precisamente integración, rendimiento y confianza verificable. Para una herramienta cuya razón entera de existir es que puedas fiarte de ella con código local, esas no son las partes que ceder. Son el producto.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc es una aplicación nativa de macOS, construida para Apple Silicon, firmada, notarizada y grapada. Eso no es una línea de la ficha técnica. Es la misma decisión que todo lo demás en ella. Tu código, tu memoria de producto, tus decisiones y tu evidencia se quedan en tu máquina, así que la app que los sostiene es una app de verdad en esa máquina, usando las protecciones del sistema, corriendo sobre su propio hardware, verificable antes de arrancar.</p>
<p>Los motores que llama pueden ser remotos, si traes tus claves, o totalmente locales a través de Ollama. Pero la fábrica en sí, lo que sostiene el contexto duradero, es nativa y local por diseño, porque esa es la única versión de la promesa que se cumple de verdad.</p>
<p>La próxima vez que una herramienta de desarrollo te pida tu código, vale la pena preguntar qué es en realidad. Una app de verdad que tu máquina puede verificar, o un navegador apuntando al servidor de otro con un icono de Mac encima.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-siguen-importando-las-apps-nativas-de-macos-en-herramientas-de-desarrollo">¿Por qué siguen importando las apps nativas de macOS en herramientas de desarrollo?</h3>
<p>Para una herramienta que sostiene tu código y corre todo el día, lo nativo se reduce a tres cosas: integración, rendimiento y confianza. Usa las protecciones de verdad de la máquina —Keychain para los secretos, el modelo de permisos del sistema—, corre sobre Apple Silicon en vez de arrastrar un motor de navegador empaquetado, y puede verificarse antes de arrancar. Una app web disfrazada de escritorio reinventa cada una de esas, normalmente peor.</p>
<h3 id="qué-significa-que-una-app-de-mac-esté-firmada-y-notarizada">¿Qué significa que una app de Mac esté firmada y notarizada?</h3>
<p>Firmada significa que la app carga una identidad de desarrollador verificada, así que sabes quién la construyó. Notarizada significa que Apple la revisó en busca de malware y el sistema puede confirmar que no se ha alterado desde entonces. Grapa la notarización a la app y tu máquina verifica la cadena entera antes del primer arranque, sin conexión. Para software al que estás a punto de darle tu código fuente, esa procedencia es una decisión de confianza que puedes razonar en vez de tomar por fe.</p>
<h3 id="las-herramientas-electron-o-web-empaquetadas-rinden-peor">¿Las herramientas Electron o web empaquetadas rinden peor?</h3>
<p>En una demo rápida no lo notas. A lo largo de un día entero, un motor de navegador empaquetado carga el peso de una pila de renderizado que no necesitaba, en un runtime pensado para mostrar documentos. En la cuarta hora, con varias sesiones corriendo, el impuesto aparece en los ventiladores, la batería y el pequeño lag de cada acción. Una carcasa más pesada deja menos margen, así que los builds compiten con el marco en vez de con el trabajo.</p>
<h3 id="es-seguro-darle-mi-código-fuente-a-una-herramienta-basada-en-web">¿Es seguro darle mi código fuente a una herramienta basada en web?</h3>
<p>Es una decisión de confianza distinta. Cuando el trabajo real pasa en un servicio en otro sitio, lo que confías es una conexión y una política de privacidad, no un artefacto que el sistema pueda verificar. Una app nativa que tu máquina ha firmado, notarizado y comprobado es demostrable antes de correr. Para la mayoría del software el modelo web vale; para la herramienta que apuntas a código privado, la procedencia verificable no es un formalismo, es el producto.</p>]]></content>
    <summary type="html"><![CDATA[Casi todas las herramientas de escritorio para desarrollo son apps web con disfraz. Un motor de navegador empaquetado, un servicio remoto haciendo el trabajo real y un icono de Mac encima. Arranca, y durante un tiempo no notas lo que costó. Luego se siente ajena de formas que no sabes nombrar, pierde frames en una máquina que nunca debería perderlos y te pide fiarte de una descarga cualquiera con tu código fuente. Lo nativo en macOS no es nostalgia. Para una herramienta que sostiene tu código, es una decisión sobre integración, rendimiento y confianza, y esos tres son todo el argumento.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="paelladoc"/><category term="macos-nativo"/><category term="apple-silicon"/><category term="local-first"/><category term="herramientas-desarrollo"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Hecho significa hecho: obligar al agente a demostrarlo</title>
    <link href="https://paelladoc.com/es/blog/hecho-significa-hecho/" rel="alternate" type="text/html" title="Hecho significa hecho: obligar al agente a demostrarlo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/hecho-significa-hecho/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/hecho-significa-hecho/"><![CDATA[<p>La tarea vuelve marcada como completa. «Hecho. Implementé la lógica de reintentos, todos los tests pasan». No lo has visto ejecutar nada. Tienes un diff y una frase. En algún punto entre esa frase y la realidad hay un hueco, y lo ancho que sea decide cuánto de tu día pasas re-comprobando trabajo que ya se informó como terminado.</p>
<p>«Hecho» es la palabra más sobrecargada del trabajo con agentes. Esconde dos definiciones que discrepan en silencio, y cada compleción falsa vive en esa discrepancia.</p>
<h2 id="dos-definiciones-de-hecho">Dos definiciones de hecho</h2>
<p>Para un agente, hecho suele significar: <em>produje código que parece cumplir lo que se pedía</em>. La implementación existe, es plausible, se lee como algo que escribiría alguien competente. Es un logro real y no es lo mismo que el trabajo terminado.</p>
<p>Para ti, hecho significa tres cosas a la vez. El comportamiento que pediste cambió de verdad. El comportamiento que no mencionaste no se rompió. Y hay algo que puedes señalar para probar ambas sin rehacer el trabajo tú mismo.</p>
<p>Son listones distintos. El agente supera el primero e informa de éxito de buena fe, porque desde dentro de su contexto el primer listón parece el todo. Tú te quedas cargando la distancia entre «parece terminado» y «está terminado, y veo por qué». Hacer que hecho signifique hecho es el trabajo de colapsar esa distancia hasta que <a href="/es/blog/definicion-de-hecho/">la definición del agente y la tuya</a> sean la misma.</p>
<h2 id="por-qué-el-hueco-es-estructural-no-vagancia">Por qué el hueco es estructural, no vagancia</h2>
<p>Sería fácil leer esto como que el agente hace trampas. No las hace. Un modelo completa el texto más probable para una situación, y tras una implementación con aspecto terminado la frase probable es un informe de éxito. La afirmación se genera, no se observa. Esa es la <a href="/es/blog/exitos-falsos-de-agentes/">anatomía de un éxito falso</a>, y significa que un «todos los tests pasan» con sonido convincente puede posarse sobre una suite que nunca se ejecutó.</p>
<p>Así que suplicarle al agente más cuidado no lo arregla. No puedes salir a base de prompt de un valor por defecto estructural. Lo que cambia el resultado es cambiar quién puede declarar el éxito. Ahora mismo el agente es a la vez el trabajador y el juez de su propio trabajo. Quítale el papel de juez.</p>
<h2 id="la-prueba-es-una-demostración-no-una-casilla">La prueba es una demostración, no una casilla</h2>
<p>Si una afirmación es barata, entonces la compleción tiene que costar una demostración. El agente no debería poder decir hecho. Debería tener que enseñar hecho.</p>
<p>¿Qué cuenta como demostración? En concreto:</p>
<ul>
<li><strong>Un comando que se ejecutó de verdad.</strong> No «los tests deberían pasar», sino la invocación y su código de salida.</li>
<li><strong>La salida que produjo.</strong> Las líneas que imprimió la ejecución, capturadas, no resumidas en «tiene buena pinta».</li>
<li><strong>La versión del contrato contra la que corrió.</strong> Qué criterios de aceptación, en qué revisión, para que un verde posterior no se refiera en silencio a los requisitos de ayer.</li>
</ul>
<figure class="tp-diagram tp-diagram--stack" data-diagram-type="stack" role="img" aria-label="Una demostración son estos tres, capturados juntos. Una casilla no es ninguno."><svg viewBox="0 0 760 208" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="120" y="20" width="520" height="42" fill="var(--tp-mostaza)" fill-opacity="0.14" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="380" y="47" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">EL COMANDO QUE CORRIÓ</text><rect x="120" y="76" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="103" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">SU SALIDA CAPTURADA</text><rect x="120" y="132" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="159" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">LA VERSIÓN DEL CONTRATO</text></svg><figcaption>Una demostración son estos tres, capturados juntos. Una casilla no es ninguno.</figcaption></figure>
<p>Una casilla es una afirmación disfrazada de prueba. Dice «hecho» con un visual satisfactorio y no lleva información sobre si pasó algo. Sustituye la casilla por las tres cosas de arriba y desaparece toda la clase de compleciones seguras-pero-vacías, porque ya no tienen dónde esconderse.</p>
<p>Es la misma lección que el desarrollo guiado por especificaciones aprendió a la fuerza: <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>. Que el build compile y que la feature esté bien son dos afirmaciones separadas. La compleción tiene que comprobar la segunda, y solo puede comprobarla contra criterios escritos antes de empezar el trabajo.</p>
<h2 id="qué-aspecto-tiene-un-no-hecho-disfrazado-de-hecho">Qué aspecto tiene un «no hecho» disfrazado de hecho</h2>
<p>Las compleciones peligrosas son las que parecen terminadas desde todos los ángulos menos el que nadie comprobó. Unas cuantas formas se repiten lo bastante como para nombrarlas:</p>
<ul>
<li><strong>La tarea hecha, lo de al lado roto.</strong> La feature funciona. Un comportamiento tres archivos más allá que dependía en silencio del código antiguo ya no funciona. El agente no tenía motivo para mirar ahí y tú no tenías evidencia que forzara la pregunta, así que «hecho» publicó una regresión.</li>
<li><strong>El camino feliz hecho, el borde ignorado.</strong> La entrada de la demo funciona. La lista vacía, el timeout, la segunda llamada concurrente, el campo mal formado, no se ejercitó ninguno. La implementación es real y el contrato que satisface es más estrecho del que querías.</li>
<li><strong>El código hecho, la ejecución imaginada.</strong> La más común. La implementación existe, el informe dice que los tests pasan, y los tests nunca se invocaron. Nada falla en el código salvo que nadie lo confirmó.</li>
</ul>
<p>Todas pasan una lectura casual. El diff parece razonable, el resumen suena bien, la superficie es limpia. Justo por eso «parece hecho» no es una categoría de la que te puedas fiar: los fallos que sobreviven hasta producción son los que parecen éxito, porque los que parecen fallo se atrapan. Un hecho que significa hecho es la defensa concreta contra las compleciones cuyo único defecto es que la comprobación que faltaba nunca se ejecutó.</p>
<h2 id="escribe-la-demostración-antes-del-trabajo">Escribe la demostración antes del trabajo</h2>
<p>Aquí está el movimiento que lo hace práctico. Decide qué probaría que la tarea está hecha <em>antes</em> de que el agente empiece, no después. ¿Qué comportamiento tiene que ser observable? ¿Qué comando, ejecutado contra el resultado, lo mostraría? ¿Qué tiene que seguir siendo cierto y podría romperse de forma plausible?</p>
<p>Esas preguntas son <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación</a>, y su valor es que no sirven de nada si se falsean. Si «hecho» se define como «este comando concreto imprime este resultado concreto contra este contrato», el agente no puede satisfacerlo con una frase. Tiene que producir la ejecución. Has convertido la compleción de un auto-informe en un test que el agente tiene que pasar, y escribiste el test mientras aún recordabas qué querías de verdad.</p>
<p>La versión más barata de esto es acordar la forma de la prueba a la vez que acuerdas la tarea. Cuesta unos minutos por adelantado y elimina el trabajo mucho más caro de descubrir, tres integraciones después, que «hecho» no significaba nada.</p>
<h2 id="hecho-a-toda-velocidad">Hecho a toda velocidad</h2>
<p>La objeción siempre es la velocidad. Si cada tarea tiene que llevar una demostración, ¿no frena eso todo justo donde los agentes debían acelerarlo?</p>
<p>Hace lo contrario, pasadas las primeras tareas. Lo caro no es producir la prueba. Lo caro es no tenerla: releer diffs para reconstruir si algo funciona, re-ejecutar tests a mano porque no te fías del último verde, descubrir en producción una rotura que una ejecución capturada habría atrapado. Construir con agentes significa que el volumen de informes de «hecho» es enorme. Cuando cada uno es solo una frase, los informes no valen nada y lo verificas todo a mano. Cuando cada uno lleva su demostración, puedes fiarte del informe y gastar tu atención en los pocos que fallan. Esa es toda la razón por la que <a href="/es/blog/verificar-codigo-generado-por-ia/">el cuello de botella es la confianza, no el output</a>: una compleción que puedes creer es lo que te deja seguir avanzando.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>En <a href="/">PaellaDoc</a>, una tarea no llega a hecho porque un agente lo diga. Llega a hecho cuando el contrato de aceptación definido antes del trabajo se ha ejecutado contra el resultado real y la evidencia se sienta junto al cambio. El agente deja de ser el juez de su propia compleción y pasa a ser la parte que tiene que producir la demostración. «Hecho» vuelve a significar lo que siempre quisiste decir: funciona, no rompió nada, y aquí está la prueba.</p>
<p>Los agentes seguirán informando de éxito en prosa fluida y segura. Tu trabajo es hacer que esa prosa cueste una demostración. Hecho significa hecho cuando el agente tiene que enseñarlo, no decirlo.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-un-agente-dice-que-una-tarea-está-hecha-cuando-no-lo-está">¿Por qué un agente dice que una tarea está hecha cuando no lo está?</h3>
<p>Porque «hecho» significa cosas distintas para cada uno. Para el agente, hecho es que produjo código con aspecto de cumplir lo que se pedía. Para ti, es que el comportamiento cambió, nada más se rompió y hay prueba de ambas cosas. El agente supera su propio listón de buena fe e informa de éxito, y te deja cubriendo la distancia entre «parece terminado» y «está terminado».</p>
<h3 id="cómo-obligo-al-agente-a-demostrar-que-terminó">¿Cómo obligo al agente a demostrar que terminó?</h3>
<p>Quítale el papel de juez de su propio trabajo. Define, antes de empezar, qué demostraría la compleción: qué comando ejecutado contra el resultado, imprimiendo qué salida, contra qué contrato. Luego haz que algo distinto del agente ejecute esa comprobación y capture el resultado. El agente aún puede escribir «hecho», pero deja de decidir si esa frase es verdad.</p>
<h3 id="qué-cuenta-como-prueba-de-que-un-agente-terminó-el-trabajo">¿Qué cuenta como prueba de que un agente terminó el trabajo?</h3>
<p>Tres cosas capturadas juntas: un comando que se ejecutó de verdad, con su código de salida; la salida real que imprimió, no un resumen tipo «tiene buena pinta»; y la versión del contrato de aceptación contra la que corrió. Una casilla es una afirmación disfrazada de prueba. Una demostración lleva información sobre si pasó algo de verdad.</p>
<h3 id="exigir-pruebas-de-compleción-no-frena-el-desarrollo">¿Exigir pruebas de compleción no frena el desarrollo?</h3>
<p>Pasadas las primeras tareas, lo acelera. Lo caro no es producir la prueba, es no tenerla: releer diffs, re-ejecutar tests a mano porque no te fías del último verde, atrapar en producción una rotura que una ejecución capturada habría cazado. Cuando cada «hecho» lleva su demostración, te fías del informe y gastas atención solo en los pocos que fallan.</p>]]></content>
    <summary type="html"><![CDATA[Un agente informa «hecho» y significa que escribió algo que parece terminado. Tú quieres decir que el comportamiento cambió, que el antiguo aguantó y que hay prueba de ambas cosas. Hecho significa hecho es la disciplina de forzar al agente a demostrar la compleción en vez de afirmarla.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="done-means-done"/><category term="ai-coding"/><category term="verificacion"/><category term="criterios-de-aceptacion"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Harness engineering: la disciplina que está naciendo alrededor de operar agentes</title>
    <link href="https://paelladoc.com/es/blog/harness-engineering/" rel="alternate" type="text/html" title="Harness engineering: la disciplina que está naciendo alrededor de operar agentes"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/harness-engineering/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/harness-engineering/"><![CDATA[<p>Si has operado un agente de código más de una semana, has construido un harness sin llamarlo así. El andamiaje del prompt, el pequeño script que ensambla los ficheros correctos antes de empezar, el hook que corre los tests antes de fiarte del “hecho”, el retry que haces a mano cuando un run muere. Eso no es el modelo. Es la maquinaria alrededor del modelo, y resulta que la maquinaria es casi todo el trabajo.</p>
<p>El término que circula para esto en la comunidad es <strong>harness engineering</strong>. Lo oyes de gente que opera agentes en serio, en los escritos de ingeniería de Anthropic y en foros de desarrolladores como Latent.Space, usado con soltura pero apuntando a lo mismo: la disciplina de construir y afinar el bucle dentro del que corre el modelo. Lo uso aquí en ese sentido general, porque nombra algo que muchos llevamos haciendo sin nombre. La afirmación interesante debajo del término es que cuando el trabajo con agentes falla a escala, el harness suele ser la razón del fallo, y el harness suele ser lo que merece la pena arreglar. Es un capítulo de <a href="/es/blog/construir-software-con-agentes-de-ia/">construir software con agentes de IA</a>, y quizá el menos glamuroso.</p>
<h2 id="qué-es-de-verdad-un-harness">Qué es de verdad un harness</h2>
<p>Redúcelo y un harness es el bucle exterior alrededor de una llamada al modelo. El modelo hace una cosa: dado algo de contexto, produce el siguiente output. Todo lo que decide qué contexto recibe, qué herramientas puede llamar, qué pasa con el resultado, y qué pasa cuando el resultado está mal, eso es el harness.</p>
<p>En concreto, un harness de código hace al menos esto:</p>
<ul>
<li><strong>Ensamblado de contexto.</strong> Qué ficheros, qué decisiones previas, qué restricciones entran en la ventana, y en qué orden. Falla esto y hasta un modelo fuerte produce disparates con seguridad, que es el tema entero de <a href="/es/research/context-engineering-para-agentes-de-codigo/">context engineering para agentes de código</a>.</li>
<li><strong>Mediación de herramientas.</strong> Qué puede correr el agente, con qué permisos, y cómo vuelven los resultados. Un runner de tests, un editor de ficheros, una shell, cada uno con su frontera.</li>
<li><strong>Verificación.</strong> Qué comprueba el output antes de que alguien se fíe. La diferencia entre “el agente dijo hecho” y “el gate pasó”.</li>
<li><strong>Recuperación.</strong> Qué pasa cuando un paso falla o un run muere, tratado en <a href="/es/blog/recuperar-ejecuciones-fallidas/">la recuperación como flujo de primera clase</a>.</li>
<li><strong>Routing.</strong> Qué motor recibe qué tarea, la preocupación detrás de <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">enrutar cada tarea al motor correcto</a>.</li>
</ul>
<p>Nada de eso es el modelo. Todo ello determina si el modelo es útil. Por eso harness engineering se volvió algo de lo que hablar: la palanca se movió.</p>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="Un harness es el bucle exterior alrededor de una llamada al modelo: el modelo solo produce el siguiente output, todo lo demás, contexto, herramientas, comprobaciones, recuperación, es el bucle."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="94" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">REUNIR CONTEXTO</text><path d="M 154 85 L 176 85 M 170 79 L 176 85 L 170 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="182" y="52" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="236" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">LLAMAR AL MODELO</text><path d="M 296 85 L 318 85 M 312 79 L 318 85 L 312 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="324" y="52" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="378" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CORRER TOOLS</text><path d="M 438 85 L 460 85 M 454 79 L 460 85 L 454 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="466" y="52" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="520" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">VERIFICAR</text><path d="M 580 85 L 602 85 M 596 79 L 602 85 L 596 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="608" y="52" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="662" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">RECUPERAR</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">SIGUIENTE PASO</text></svg><figcaption>Un harness es el bucle exterior alrededor de una llamada al modelo: el modelo solo produce el siguiente output, todo lo demás, contexto, herramientas, comprobaciones, recuperación, es el bucle.</figcaption></figure>
<h2 id="por-qué-el-harness-se-volvió-el-cuello-de-botella">Por qué el harness se volvió el cuello de botella</h2>
<p>Durante un tiempo, la forma obvia de mejorar los agentes era un modelo mejor, y funcionó, hasta que dejó de ser lo que importaba en el trabajo real.</p>
<p>La evidencia más clara que he corrido yo mismo está en <a href="/es/research/agentes-necesitan-un-runtime-no-un-modelo-mas-grande/">el experimento de recuperación</a>. A través de cuatro episodios acumulativos con gates ocultos, un agente de código con un prompt fuerte se quedó clavado en una tasa de aprobado de dos tercios. El mismo agente con una skill de recuperación hecha a mano se quedó en el mismo sitio. Modelos más grandes en controles de un solo run hicieron lo mismo. Lo que llegó al 100% no fue un modelo más listo, fue un harness que sostuvo el contrato y volvió a puntuar el trabajo tras cada intento. Mismo executor, distinto bucle alrededor, distinto resultado.</p>
<p>Esa es la forma general del argumento de <a href="/es/research/agentes-necesitan-un-runtime-no-un-modelo-mas-grande/">los agentes necesitan un runtime, no un modelo más grande</a>. Cuando el modelo es lo bastante bueno como para escribir código correcto desde contexto correcto, la frontera se mueve al sistema que suministra el contexto correcto, verifica el output y recupera cuando deriva. El modelo se volvió commodity. El harness no.</p>
<p>Los propios escritos de ingeniería de Anthropic apuntan en la misma dirección, ya sea en <a href="https://www.anthropic.com/engineering/building-effective-agents">construir agentes efectivos</a> o en su relato de un <a href="https://www.anthropic.com/engineering/multi-agent-research-system">sistema multiagente de investigación</a>: casi todo lo que hace fiable a un agente a escala es arquitectura alrededor del modelo, no el modelo en aislamiento.</p>
<h2 id="las-partes-de-un-harness-que-merece-la-pena-diseñar">Las partes de un harness que merece la pena diseñar</h2>
<p>Tratar el harness como un artefacto de verdad significa que tiene partes que diseñas a propósito, no andamiaje que acumulas por accidente.</p>
<p><strong>El contrato de contexto.</strong> Qué entra siempre, qué no entra nunca, y cómo evitas que la ventana se llene de ruido. Un harness que vuelca el repo entero en cada llamada no es ingeniería, es esperanza. Aquí es donde <a href="/es/blog/gestion-ventana-de-contexto/">gestionar la ventana de contexto</a> deja de ser un truco y se vuelve una restricción de diseño.</p>
<p><strong>La capa de verificación.</strong> Gates que corren sobre el output da igual lo que el agente afirme. Un harness cuya única señal de completitud es el agente diciendo “hecho” no tiene capa de verificación, tiene un buzón de sugerencias.</p>
<p><strong>El camino de recuperación.</strong> Checkpoints, último estado bueno, una forma de resumir sin empezar de cero. Un harness sin esto convierte cada fallo en un rescate manual.</p>
<p><strong>El formato de handoff.</strong> Qué viaja cuando el trabajo se mueve entre agentes o sesiones, el tema de <a href="/es/blog/handoffs-entre-agentes/">handoffs entre agentes</a>. Un harness que no puede hacer handoff no escala <a href="/es/blog/sesiones-paralelas-agentes/">más allá de una sesión en una cabeza</a>.</p>
<p><strong>La capa de instrucciones.</strong> Los ficheros de reglas que el agente lee, y sobre todo, si siguen siendo verdad. Un harness que alimenta a los agentes con <a href="/es/blog/reglas-de-agentes-vivas/">reglas obsoletas</a> está diseñando el bucle equivocado con cuidado.</p>
<p>Puedes construir todo esto a mano, y si operas agentes en serio ya lo haces. La pregunta que fuerza harness engineering es si lo construyes a propósito, con partes sobre las que puedes razonar, o lo acumulas como un montón de scripts que solo tú entiendes.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Harness engineering como frase es útil porque nombra el trabajo real: la fiabilidad del output de un agente viene del bucle alrededor del modelo, y ese bucle es algo que diseñas. La versión incómoda es que ahora mismo, para casi todos, el harness es una persona. Tú eres el ensamblador de contexto, el verificador, el camino de recuperación y el router, sosteniéndolo en la cabeza, que es justo el argumento de <a href="/es/blog/eres-el-runtime/">tú eres el runtime</a>. PaellaDoc es un harness que no tienes que ser tú: el contrato de contexto, los gates, la recuperación y el routing construidos como sistema, portable entre motores, para que el bucle sobreviva fuera de la memoria de un operador. No un modelo mejor. Un bucle mejor alrededor del modelo que corras.</p>
<h2 id="faq">FAQ</h2>
<h3 id="qué-es-harness-engineering">¿Qué es harness engineering?</h3>
<p>Es la práctica emergente de construir y afinar el bucle dentro del que corre un agente de código: cómo se ensambla el contexto, qué herramientas puede llamar el agente, cómo se verifica el output y cómo se recuperan los fallos. El término se usa con soltura por la comunidad de operación de agentes, incluidos los escritos de ingeniería de Anthropic, para nombrar el sistema alrededor del modelo en oposición al modelo en sí.</p>
<h3 id="el-harness-importa-más-que-el-modelo">¿El harness importa más que el modelo?</h3>
<p>Cuando el modelo es lo bastante bueno como para escribir código correcto desde contexto correcto, sí, el harness pasa a ser donde se gana o se pierde la fiabilidad. En un test de recuperación controlado, el mismo agente de código se quedaba clavado o llegaba al 100% dependiendo solo del bucle a su alrededor, no del modelo. Por debajo de ese umbral el modelo aún importa; por encima, domina el harness.</p>
<h3 id="en-qué-se-diferencia-un-harness-de-simplemente-hacer-buenos-prompts">¿En qué se diferencia un harness de simplemente hacer buenos prompts?</h3>
<p>Un prompt es una entrada a una llamada. Un harness es el bucle entero: ensambla contexto a través de muchas llamadas, corre herramientas, verifica el output contra gates, recupera runs fallidos, y mueve trabajo entre sesiones. Un buen prompt es parte de ello, pero un prompt sin verificación, sin recuperación y sin gestión de contexto no es un harness, es una sola tirada de dados.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="harness-engineering"/><category term="agentes"/><category term="tooling"/><category term="fiabilidad"/><category term="runtime"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Handoffs: pasar trabajo entre agentes sin perder el hilo</title>
    <link href="https://paelladoc.com/es/blog/handoffs-entre-agentes/" rel="alternate" type="text/html" title="Handoffs: pasar trabajo entre agentes sin perder el hilo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/handoffs-entre-agentes/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/handoffs-entre-agentes/"><![CDATA[<p>Mira lo que pasa de verdad cuando el trabajo se mueve entre agentes. Un primer agente parte una feature en tareas. Le pasas una tarea a un segundo agente para que la construya. Construye algo plausible, y reconstruye una decisión que el primer agente ya había tomado y descartado, porque esa decisión nunca viajó con la tarea. Ahora estás revisando código que resolvió la versión equivocada del problema, y la razón no es que ningún agente fuera malo. Es que el handoff cargó el <em>qué</em> y soltó el <em>porqué</em>.</p>
<p>Los handoffs son donde el trabajo multiagente se escapa. Cada vez que el trabajo cruza una frontera, entre dos agentes, entre dos sesiones del mismo agente, entre el run de anoche y el de esta mañana, hay una posibilidad de que el contexto no llegue al otro lado. Y lo que se pierde casi nunca es el código. El código está ahí en la rama. Lo que se pierde es todo lo que no es código: las decisiones ya tomadas, las restricciones que deben mantenerse, los caminos ya probados y descartados, la pregunta que sigue abierta. Ese es el hilo, y es lo que un buen handoff tiene que cargar.</p>
<h2 id="por-qué-un-transcript-no-es-un-handoff">Por qué un transcript no es un handoff</h2>
<p>El handoff por defecto es “aquí está el chat, ponte al día”. No funciona, por la misma razón por la que darle a alguien la grabación de tres horas de una reunión no es un briefing. La información puede que esté técnicamente ahí, pero quien la recibe tiene que reconstruirla, y reconstruir es caro y con pérdidas.</p>
<p>Peor, un transcript es casi todo ruido. Contiene cada callejón sin salida que exploró el primer agente, cada llamada a herramienta, cada corrección, sin señal sobre qué partes siguen importando. Un agente en fresco leyéndolo no distingue la decisión que se quedó de la idea que se probó y se soltó. Así que o vuelve a explorar los callejones sin salida o, peor, trata un enfoque abandonado como el plan actual. Cuanto más largo el transcript, peor esto, lo que enlaza directo con <a href="/es/blog/gestion-ventana-de-contexto/">gestionar la ventana de contexto</a>: volcar una historia entera en una sesión fresca no transfiere entendimiento, transfiere ruido y se come el presupuesto que necesitabas para el trabajo de verdad.</p>
<p>Un handoff no es la historia en bruto. Es el estado destilado: qué es verdad ahora, qué debe seguir siendo verdad, y qué queda abierto.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Un transcript repite cada evento y obliga a quien recibe a reconstruir; un handoff destila el estado para que el siguiente agente pueda actuar."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">transcript</p>
    <ul><li>repetición de eventos</li><li>cada callejón sin salida</li><li>quien recibe reconstruye</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">handoff</p>
    <ul><li>estado destilado</li><li>qué es verdad ahora</li><li>quien recibe actúa</li></ul>
  </div>
</div><figcaption>Un transcript repite cada evento y obliga a quien recibe a reconstruir; un handoff destila el estado para que el siguiente agente pueda actuar.</figcaption></figure>
<h2 id="qué-tiene-que-viajar">Qué tiene que viajar</h2>
<p>Un handoff limpio carga un paquete pequeño y deliberado. En mi experiencia operando agentes entre sesiones, es más o menos esto:</p>
<ul>
<li><strong>El contrato.</strong> Qué construimos y qué cuenta como hecho, dicho como criterios que quien recibe pueda comprobar, no intuiciones que tenga que inferir. Es el mismo artefacto portable que defiendo en <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">las especificaciones de software deberían ser portables</a>: un contrato que viaja vale más que uno atrapado en la sesión que lo escribió.</li>
<li><strong>El estado actual.</strong> Dónde está el trabajo de verdad. Qué está hecho y verificado, qué en marcha, qué sin tocar. No “lee el diff y adivina”.</li>
<li><strong>Las decisiones ya tomadas, con motivos.</strong> Las elecciones que están cerradas y por qué, para que quien recibe no las reabra. Una decisión sin su motivo se vuelve a litigar al contacto.</li>
<li><strong>Los callejones sin salida.</strong> Qué se probó y se descartó, y por qué. Esta es la parte que los transcripts entierran y la que más tiempo ahorra, porque impide que el siguiente agente recorra el mismo camino equivocado con seguridad.</li>
<li><strong>La pregunta abierta.</strong> La única cosa que el handoff de verdad le pide al siguiente agente que resuelva. Si un handoff no nombra qué quiere, quien recibe adivina.</li>
</ul>
<p>Fíjate en lo que no está en esa lista: la historia entera. El paquete es un resumen de estado, no una repetición de eventos. Esa es la diferencia entre un handoff que deja al siguiente agente continuar y un transcript que le hace empezar de cero.</p>
<h2 id="handoffs-recuperación-y-memoria-son-un-solo-problema">Handoffs, recuperación y memoria son un solo problema</h2>
<p>En cuanto ves el paquete, ves que tres cosas que podrías tratar por separado son la misma cosa.</p>
<p>Un <strong>handoff entre agentes</strong> pasa ese paquete de lado, de un agente a otro. <strong>Recuperar un run muerto</strong> lo pasa hacia delante en el tiempo, del run fallido de anoche al resume de esta mañana, que es justo por qué <a href="/es/blog/recuperar-ejecuciones-fallidas/">la recuperación es un flujo de primera clase</a> y no heroísmo: un run que puedes resumir es un run que se hizo handoff limpio a su propio futuro. Y la <a href="/es/blog/memoria-agentes-de-codigo/"><strong>memoria</strong> es el mismo paquete persistido</a>, para que sobreviva cuando nadie lo está pasando activamente. En cada caso la pregunta es idéntica: ¿el estado que importa vive en algún sitio fuera de la sesión, en una forma sobre la que el siguiente lector pueda actuar? Cuando lo hace, los tres funcionan. Cuando no, los tres colapsan en leer un transcript que nadie quiere leer.</p>
<p>El relato de Anthropic sobre un <a href="https://www.anthropic.com/engineering/multi-agent-research-system">sistema multiagente de investigación</a> aterriza en un punto relacionado desde el lado de la orquestación: coordinar varios agentes es en gran parte un problema de qué se le dice a cada uno y cómo se combinan sus salidas, no de la capacidad bruta de ningún agente. El formato de handoff es esa coordinación hecha concreta.</p>
<h2 id="diseñar-handoffs-en-los-que-puedas-confiar">Diseñar handoffs en los que puedas confiar</h2>
<p>Puedes hacer los handoffs fiables hoy, sin herramientas especiales, tratando el paquete como un artefacto en vez de una intuición:</p>
<ul>
<li><strong>Escribe el handoff, no apuntes al chat.</strong> Una nota corta y estructurada que cargue las cinco cosas de arriba gana a “sube y lee” siempre. Si escribirla se siente redundante, es porque tú eres quien todavía se acuerda. Quien recibe no.</li>
<li><strong>Mantén el contrato fuera de la sesión.</strong> Si los criterios de aceptación viven en un fichero o una tarea en vez de en el contexto de un agente, cada handoff los hereda gratis en vez de volver a derivarlos.</li>
<li><strong>Registra las decisiones según las tomas, no al final.</strong> Una decisión capturada con su motivo en el momento en que se toma sobrevive al handoff. Una reconstruida después está medio inventada.</li>
<li><strong>Nombra la pregunta abierta explícitamente.</strong> Termina cada handoff con la única cosa que el siguiente agente debe resolver. La ambigüedad aquí es donde se pierde el hilo.</li>
</ul>
<p>Esto no es una disciplina nueva. Es lo mismo que hacen los buenos equipos en un cambio de turno y los buenos ingenieros en la descripción de un pull request. Los agentes solo hacen que el coste de saltárselo aparezca más rápido, porque correrán con seguridad con lo que sea que no les entregaste.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Un handoff pierde el hilo cuando el estado que importa vive solo en un transcript, y uno limpio funciona cuando el contrato, las decisiones y la pregunta abierta viajan como un artefacto sobre el que el siguiente agente puede actuar. Ese es el mecanismo. Es también la misma maquinaria que necesitan la recuperación y la memoria, por lo que los trato juntos y no como tres features. PaellaDoc guarda el contrato, las decisiones y el estado del run como artefactos de primera clase que persisten fuera de cualquier sesión, así que pasar trabajo entre agentes, resumir un run muerto y recordar entre días son la misma operación en vez de tres actos separados de heroísmo. La persona que hace esa reconciliación a mano ahora mismo, sosteniendo el hilo a través de cada frontera, es <a href="/es/blog/eres-el-runtime/">el runtime</a>.</p>
<h2 id="faq">FAQ</h2>
<h3 id="qué-debería-incluir-un-handoff-entre-agentes">¿Qué debería incluir un handoff entre agentes?</h3>
<p>Cinco cosas: el contrato (qué se construye y qué cuenta como hecho, como criterios comprobables), el estado actual (qué está hecho, en marcha o sin tocar), las decisiones ya tomadas con sus motivos, los callejones sin salida ya probados, y la única pregunta abierta que el siguiente agente debe resolver. Notablemente, no el transcript entero, que es casi todo ruido que quien recibe tiene que volver a filtrar.</p>
<h3 id="por-qué-no-darle-al-siguiente-agente-el-historial-entero-del-chat">¿Por qué no darle al siguiente agente el historial entero del chat?</h3>
<p>Porque un transcript es una repetición de eventos, no un resumen de estado. Contiene cada callejón sin salida y corrección sin señal sobre qué sigue importando, así que el agente que recibe o vuelve a explorar caminos descartados o confunde un enfoque abandonado con el plan. Además quema presupuesto de contexto que necesitas para el trabajo real. Un handoff destilado transfiere entendimiento; un transcript en bruto transfiere ruido.</p>
<h3 id="cómo-se-relacionan-los-handoffs-con-la-recuperación-y-la-memoria">¿Cómo se relacionan los handoffs con la recuperación y la memoria?</h3>
<p>Son el mismo problema en tres direcciones. Un handoff pasa el estado de lado entre agentes, la recuperación lo pasa hacia delante en el tiempo para resumir un run muerto, y la memoria lo persiste para que sobreviva cuando nadie lo está pasando. Los tres dependen de que el estado que importa viva fuera de la sesión en una forma sobre la que el siguiente lector pueda actuar.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="handoffs"/><category term="agentes"/><category term="contexto"/><category term="orquestacion"/><category term="runtime"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Grafo de conocimiento vs búsqueda vectorial para código: cuándo gana cada uno</title>
    <link href="https://paelladoc.com/es/blog/grafo-vs-rag-vectorial/" rel="alternate" type="text/html" title="Grafo de conocimiento vs búsqueda vectorial para código: cuándo gana cada uno"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/grafo-vs-rag-vectorial/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/grafo-vs-rag-vectorial/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿Cuál es la diferencia entre un grafo de conocimiento y RAG vectorial para código?", "acceptedAnswer": {"@type": "Answer", "text": "El RAG vectorial recupera por semejanza: embebe el código en vectores y devuelve los trozos más parecidos a una consulta. Un grafo de conocimiento recupera por relación: guarda aristas explícitas (llama-a, importa, depende-de, decidido-por) y responde recorriéndolas. Uno es bueno para recall difuso, el otro para preguntas estructurales de varios saltos."}},
    {"@type": "Question", "name": "¿Cuándo gana la búsqueda vectorial a un grafo para código?", "acceptedAnswer": {"@type": "Answer", "text": "Cuando necesitas recall difuso sobre un codebase grande y desconocido y la pregunta es casi lenguaje natural: encuentra código que haga X, dónde hay algo de facturación, muéstrame handlers parecidos. Los vectores son baratos de montar, toleran entradas desordenadas y son fuertes cuando no sabes los nombres exactos que buscar."}},
    {"@type": "Question", "name": "¿Cuándo gana un grafo de conocimiento a la búsqueda vectorial para código?", "acceptedAnswer": {"@type": "Answer", "text": "Cuando la respuesta depende de relaciones que el embedding tira: qué llama a esto, qué se rompe si lo cambio, por qué existe esto, traza esta decisión hasta el código que la implementa. Son preguntas exactas, de varios saltos y estructurales, y un grafo las responde recorriendo en vez de adivinar por parecido."}}
  ]
}
</script>
<p>El movimiento por defecto, cuando quieres que un agente entienda un codebase, es embeberlo entero. Trocea los ficheros, conviértelos en vectores, guárdalos, y en la consulta trae de vuelta los trozos que más se parecen a la pregunta. Esto es retrieval-augmented generation, y para código es lo primero a lo que casi todo el mundo echa mano.</p>
<p>Funciona más veces de lo que los escépticos admiten. También falla de una forma concreta y repetible que ninguna mejora de embeddings arregla, porque el fallo no va de calidad. Va de qué puede y qué no puede representar un vector. Así que la pregunta de verdad no es “grafo o RAG”. Es cuál usas, para qué pregunta, y por qué.</p>
<h2 id="el-rag-vectorial-recupera-por-semejanza">El RAG vectorial recupera por semejanza</h2>
<p>Un embedding convierte un trozo de código en un punto de un espacio de muchas dimensiones, colocado de forma que las cosas que significan cosas parecidas caen cerca. La recuperación es entonces una búsqueda de proximidad. Embebes la pregunta, encuentras los trozos más cercanos, se los das al modelo.</p>
<p>En lo que esto es genuinamente bueno es en recall difuso. No sabes el nombre exacto de la función, tienes un codebase grande y desconocido, y quieres “el código que gestiona los casos raros de reembolso” o “cualquier cosa de rate limiting”. La semejanza es justo la herramienta ahí. Es barata de montar, tolera frases desordenadas, y brilla justo cuando no puedes nombrar lo que buscas. Y no para de mejorar. Técnicas como <a href="https://www.anthropic.com/engineering/contextual-retrieval">el contextual retrieval, que antepone contexto explicativo a cada trozo antes de embeberlo</a>, cierran buena parte del hueco que deja el troceado ingenuo.</p>
<h2 id="qué-tira-la-semejanza">Qué tira la semejanza</h2>
<p>Aquí está el límite estructural. Cuando cortas un codebase en trozos y los embebes, borras las aristas. El hecho de que <code>chargeCard</code> llame a <code>validatePayment</code>, que se importa de un servicio del que dependen otros tres módulos, toda esa telaraña de relaciones no sobrevive al viaje al espacio vectorial. Los trozos caen cerca si se leen parecido. Caen lejos si están cableados juntos pero redactados distinto.</p>
<p>Así que el RAG vectorial es fuerte en “encuéntrame código como este” y flojo en “encuéntrame código conectado a este”. Pídele “qué llama a <code>deleteAccount</code>” y te devuelve cosas que parecen borrado, no los llamadores reales. Pídele “qué se rompe si cambio este tipo de retorno” y no puede contestar, porque el impacto es un recorrido de grafo y no guardó ningún grafo. La información se tiró en el momento de indexar, y ningún reranker recupera lo que nunca se almacenó.</p>
<p>Esto no es un ataque a los embeddings. Es un hecho de categoría. Semejanza y conectividad son relaciones distintas, y un índice vectorial codifica una de las dos.</p>
<h2 id="un-grafo-de-conocimiento-recupera-por-relación">Un grafo de conocimiento recupera por relación</h2>
<p><a href="/es/blog/grafo-de-conocimiento-del-codigo/">Un grafo de conocimiento del código guarda las aristas a propósito</a>. Funciones, ficheros, servicios, y también las cosas de más alto nivel: una decisión, un criterio de aceptación, la historia que un trozo de código satisface. Las relaciones son explícitas. Llama. Importa. Depende-de. Implementa. Decidido-por. La recuperación es recorrido, no proximidad.</p>
<p>Eso vuelve baratas las preguntas antes imposibles. ¿Qué llama a esto? Sigue las aristas <code>llama</code> hacia dentro. ¿Qué se rompe si lo toco? Recorre los dependientes. ¿Por qué existe esto? Sigue la arista del código a la decisión que lo produjo. Son exactas, y son de varios saltos, y son justo las preguntas que los vectores no pueden contestar porque la respuesta es la estructura, no la redacción.</p>
<p>El coste también es real. Un grafo hay que construirlo y mantenerlo al día según se mueve el código, y solo conoce las relaciones que elegiste modelar. No te va a sorprender con un acierto semántico difuso como hace un embedding. Contesta lo que preguntaste, con precisión, y nada más.</p>
<h2 id="cuándo-gana-cada-uno">Cuándo gana cada uno</h2>
<p>Sin dogma. Dos herramientas, dos formas de pregunta.</p>
<p><strong>Tira de búsqueda vectorial cuando</strong> la pregunta es difusa y el codebase te es desconocido. Onboarding a un repo enorme. “Dónde hay algo de facturación.” “Muéstrame handlers parecidos a este.” Búsqueda de una sola pasada en lenguaje natural donde no puedes nombrar el objetivo. Los vectores son más baratos de levantar y perdonan la entrada vaga.</p>
<p><strong>Tira del grafo cuando</strong> la respuesta es una relación, y equivocarse sale caro. Análisis de impacto antes de un refactor. <a href="/es/blog/mapas-de-codigo-para-agentes/">“Cuáles son todos los llamadores reales.”</a> Trazar un requisito hasta el código que lo implementa, o un trozo de código de vuelta a la decisión que lo justifica. Cualquier cosa que un agente deba acertar exactamente en vez de aproximadamente, porque está a punto de cambiar código en base a la respuesta.</p>
<p>El error es tratar una preferencia como un principio. Si alguien te dice que el RAG está muerto o que los grafos son sobreingeniería, está describiendo su último proyecto, no el tuyo. La pregunta decide.</p>
<h2 id="un-fallo-concreto">Un fallo concreto</h2>
<p>Aquí está el fallo en una sola escena, porque es fácil asentir a la teoría y publicar el bug igual.</p>
<p>Estás a punto de renombrar una columna de base de datos y le preguntas a tu asistente con RAG qué depende de ella. Embebe la pregunta, busca, y te devuelve tres ficheros que mencionan la columna por su nombre en una cadena. Seguro, específico, incompleto. Se dejó los dos módulos que llegan a la columna por una relación de ORM y una propiedad computada, porque esos ficheros nunca escriben el nombre de la columna, así que nunca cayeron cerca de tu consulta en el espacio vectorial. Renombras, los tests que conocías pasan, y un job de informes se rompe en producción una semana después.</p>
<p>Un grafo habría contestado la misma pregunta recorriendo las aristas <code>lee</code> y <code>escribe</code> hacia esa columna, indirección de ORM incluida, y habría devuelto el conjunto completo. La diferencia no fue calidad de modelo ni redacción del prompt. Fue que un sistema guardó la dependencia y el otro la tiró en el momento de indexar.</p>
<h2 id="la-respuesta-de-verdad-suele-ser-las-dos">La respuesta de verdad suele ser las dos</h2>
<p>El montaje más fuerte no es una competición. Es por capas. Usa los vectores para el recall, para encontrar la región candidata de un codebase grande a partir de un prompt vago. Luego usa el grafo para la precisión, para expandir desde esos candidatos por aristas reales y traer los llamadores, dependientes y decisiones exactos. Difuso para llegar al barrio, estructural para acertar.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="El montaje más fuerte es por capas: los vectores te llevan al barrio correcto y luego el grafo recorre aristas reales para dejar exacto el conjunto."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">PROMPT VAGO</text><path d="M 190 95 L 212 95 M 206 89 L 212 95 L 206 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">RECALL VECTORIAL</text><path d="M 368 95 L 390 95 M 384 89 L 390 95 L 384 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EXPANDIR POR EL GRAFO</text><path d="M 546 95 L 568 95 M 562 89 L 568 95 L 562 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="62" width="144" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="646" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">RESPUESTA EXACTA</text></svg><figcaption>El montaje más fuerte es por capas: los vectores te llevan al barrio correcto y luego el grafo recorre aristas reales para dejar exacto el conjunto.</figcaption></figure>
<p>Es más o menos la intuición detrás de la <a href="https://arxiv.org/abs/2404.16130">línea de trabajo de Graph RAG, que construye un grafo sobre un corpus y lo recorre para responder preguntas que una búsqueda vectorial plana gestiona mal</a>.</p>
<p>Para código en concreto, el grafo lleva algo que los vectores nunca llevarán: procedencia y el “porqué”. Un almacén vectorial te puede decir que este trozo parece relevante. Un grafo te puede decir que este código existe por esa decisión, y aquí está la historia que satisface. Esa es la capa que convierte la recuperación en <a href="/es/blog/grafo-de-conocimiento-de-producto/">leer la forma de tu producto en vez de una lista de features</a>, y es por lo que <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">un cerebro de producto que se mantiene solo</a> se construye sobre un grafo y no solo sobre embeddings.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc construye el grafo, en tu máquina, desde tu repo y su historial: código relacionado con las decisiones y criterios que lo explican, con las aristas explícitas para que un agente pueda recorrer en vez de adivinar. No te pide tirar la búsqueda vectorial. Le da a tus agentes la capa estructural que la búsqueda vectorial no puede representar, para que las preguntas que dependen de relaciones dejen de devolver cosas que solo parecen correctas.</p>
<p>Local-first y gratis, sin nube y sin cuenta.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuál es la última pregunta sobre tu codebase que el RAG contestó con seguridad y mal? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cuál-es-la-diferencia-entre-un-grafo-de-conocimiento-y-rag-vectorial-para-código">¿Cuál es la diferencia entre un grafo de conocimiento y RAG vectorial para código?</h3>
<p>El RAG vectorial recupera por semejanza: embebe el código en vectores y devuelve los trozos más parecidos a una consulta. Un grafo de conocimiento recupera por relación: guarda aristas explícitas (llama-a, importa, depende-de, decidido-por) y responde recorriéndolas. Uno es bueno para recall difuso, el otro para preguntas estructurales de varios saltos.</p>
<h3 id="cuándo-gana-la-búsqueda-vectorial-a-un-grafo-para-código">¿Cuándo gana la búsqueda vectorial a un grafo para código?</h3>
<p>Cuando necesitas recall difuso sobre un codebase grande y desconocido y la pregunta es casi lenguaje natural: encuentra código que haga X, dónde hay algo de facturación, muéstrame handlers parecidos. Los vectores son baratos de montar, toleran entradas desordenadas y son fuertes cuando no sabes los nombres exactos que buscar.</p>
<h3 id="cuándo-gana-un-grafo-de-conocimiento-a-la-búsqueda-vectorial-para-código">¿Cuándo gana un grafo de conocimiento a la búsqueda vectorial para código?</h3>
<p>Cuando la respuesta depende de relaciones que el embedding tira: qué llama a esto, qué se rompe si lo cambio, por qué existe esto, traza esta decisión hasta el código que la implementa. Son preguntas exactas, de varios saltos y estructurales, y un grafo las responde recorriendo en vez de adivinar por parecido.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="knowledge-graph"/><category term="rag"/><category term="retrieval"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Grafos de conocimiento del código: qué son y por qué los agentes los necesitan</title>
    <link href="https://paelladoc.com/es/blog/grafo-de-conocimiento-del-codigo/" rel="alternate" type="text/html" title="Grafos de conocimiento del código: qué son y por qué los agentes los necesitan"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/grafo-de-conocimiento-del-codigo/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/grafo-de-conocimiento-del-codigo/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿Qué es un grafo de conocimiento del código?", "acceptedAnswer": {"@type": "Answer", "text": "Una representación de tu codebase como nodos y relaciones tipadas en vez de una carpeta de texto. Ficheros, funciones, tipos, endpoints, tests, config y decisiones son nodos; llama, importa, implementa, prueba, depende-de y reemplaza son aristas. Su valor es que las relaciones son de primera clase, así que recorres la estructura en vez de buscar cadenas de texto."}},
    {"@type": "Question", "name": "¿En qué se diferencia de una búsqueda o de RAG?", "acceptedAnswer": {"@type": "Answer", "text": "La búsqueda y el RAG vectorial devuelven trozos de texto que encajan con una consulta. Un grafo devuelve estructura: qué llama a esta función, qué se rompe si cambias este tipo, qué decisión pidió este código, si un camino es siquiera alcanzable. La recuperación encuentra dónde se menciona algo; un grafo te dice cómo se conecta."}},
    {"@type": "Question", "name": "¿Por qué necesitan los agentes un grafo de conocimiento del código?", "acceptedAnswer": {"@type": "Answer", "text": "Un humano acumula un mapa mental del codebase durante meses. Un agente empieza cada sesión en frío, sin memoria de la estructura, y trabaja con el texto que pueda meter en la ventana de contexto. Un modelo más grande o un prompt más largo no reconstruyen el mapa. Un grafo de conocimiento del código le da al agente las relaciones que si no tendría que adivinar, y por eso los cambios dejan de romper llamadores que nunca vio."}}
  ]
}
</script>
<p>Un agente abre tu repo, hace grep de una función, lee el fichero donde vive, y la cambia. El cambio es razonable en local. También rompe un llamador dos directorios más allá que nadie mencionó, porque nada le dijo al agente que ese llamador existía. Te enteras por la tarde, cuando lo que antes funcionaba deja de funcionar.</p>
<p>Ese fallo tiene nombre en cuanto lo buscas. El agente puede leer cualquier fichero suelto cuando se lo pides, pero no tiene mapa de cómo se relacionan los ficheros. Trabaja con búsqueda de texto, y la búsqueda de texto no sabe que esta función se llama desde ahí, que este tipo fluye por esos tres módulos, ni que una config decide qué rama corre en producción. Ve el árbol que tiene al lado. No ve el bosque.</p>
<p>Un grafo de conocimiento del código es ese bosque, dibujado para que se pueda leer y recorrer. Esta pieza es la referencia de qué es uno, qué responde que una búsqueda no puede, y por qué los agentes en concreto se desmontan sin él. La categoría es joven y casi todo lo que se escribe sobre “la IA que entiende tu codebase” es vago. Esta es la versión concreta.</p>
<h2 id="qué-es-de-verdad-un-grafo-de-conocimiento-del-código">Qué es de verdad un grafo de conocimiento del código</h2>
<p>Coge tu codebase y deja de pensarlo como una carpeta de ficheros de texto. Piénsalo como nodos y relaciones.</p>
<p>Los nodos son las cosas que existen: ficheros, módulos, funciones, clases, tipos, endpoints, tablas de base de datos, tests, claves de config, y las decisiones que pidieron cualquiera de ellos. Las relaciones son las aristas que conectan esas cosas, y son tipadas, que es justo el punto. Esta función <em>llama</em> a aquella. Este módulo <em>importa</em> ese paquete. Esta clase <em>implementa</em> esa interfaz. Este test <em>cubre</em> esa función. Este servicio <em>depende de</em> esa tabla. Esta decisión <em>reemplaza</em> a una anterior.</p>
<p>Una carpeta no te puede decir nada de eso. Una carpeta sabe nombres y rutas. No tiene ni idea de que <code>chargeCard</code> en la línea 40 de un fichero es lo que se rompe cuando renombras un campo de un struct tres directorios más allá. La relación es real en el sistema que corre, pero no vive en ningún sitio que puedas consultar. La reconstruyes cada vez leyendo, saltando, con grep, y aguantando las piezas en la cabeza.</p>
<p>Un grafo convierte la relación en un hecho de primera clase. “Qué llama a esta función” deja de ser una conjetura de texto completo y pasa a ser un salto por una arista. “Qué acaba escribiendo este endpoint en la base de datos” pasa a ser un camino que trazas nodo a nodo. La estructura que estaba implícita en el código, y que solo se ensamblaba entera dentro de la memoria de un ingeniero con experiencia, pasa a ser algo que una máquina puede aguantar y responder.</p>
<p>Esa es la definición que merece la pena guardar. Un grafo de conocimiento del código es tu codebase representado como un sistema de relaciones tipadas, para que la estructura sea consultable en vez de re-derivarla en cada lectura.</p>
<h2 id="qué-responde-que-una-búsqueda-no-puede">Qué responde que una búsqueda no puede</h2>
<p>La búsqueda no es inútil. Grep y la <a href="/es/blog/grafo-vs-rag-vectorial/">recuperación vectorial</a> son excelentes en un trabajo — la división que formalizó <a href="https://arxiv.org/abs/2404.16130">GraphRAG</a>: encontrar dónde aparece una cadena, o algo semánticamente cercano. Cuando sabes más o menos qué buscas y quieres las ubicaciones, tira de búsqueda. Casi todo lo que hacen hoy los agentes corre exactamente sobre esto, y por eso parecen capaces justo hasta que dejan de serlo.</p>
<p>Las preguntas que rompen la búsqueda son las de conexión, no las de ubicación.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="La búsqueda encuentra dónde se menciona algo; un grafo encuentra cómo se conecta, que es la pregunta que necesitas contestada antes de dejar que un agente toque algo que sostiene peso."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">búsqueda</p>
    <ul><li>encuentra dónde se menciona</li><li>empareja cadenas</li><li>se salta llamadores</li><li>sin fronteras</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">grafo</p>
    <ul><li>encuentra cómo se conecta</li><li>recorre aristas tipadas</li><li>radio de impacto completo</li><li>lee la costura</li></ul>
  </div>
</div><figcaption>La búsqueda encuentra dónde se menciona algo; un grafo encuentra cómo se conecta, que es la pregunta que necesitas contestada antes de dejar que un agente toque algo que sostiene peso.</figcaption></figure>
<ul>
<li><strong>Radio de impacto.</strong> Cambia la firma de esta función, ¿qué se rompe? La búsqueda encuentra la definición. No encuentra de forma fiable cada llamador, cada test que la ejercita, cada sitio donde se desempaqueta el valor de retorno. El grafo recorre las aristas <em>llama</em> y <em>cubre</em> y te da el conjunto real.</li>
<li><strong>Provenance.</strong> ¿Por qué existe este código? La búsqueda encuentra el código. No te puede decir <a href="/es/blog/de-repo-a-artefactos/">qué decisión, historia o criterio de aceptación lo pidió</a>, porque ese enlace no es texto cerca de la función, es una relación con otro artefacto entero.</li>
<li><strong>Alcanzabilidad.</strong> ¿Esto se usa siquiera? El código muerto se lee exactamente igual que el vivo para una búsqueda de texto. El grafo sabe si algo llega a este nodo, o si es una isla que nadie llama.</li>
<li><strong>El camino.</strong> ¿Cómo llega una petición desde este endpoint HTTP hasta aquella escritura en base de datos? Eso es una ruta por muchos nodos. La búsqueda te enseña el endpoint y, por separado, la escritura. No te enseña los siete saltos de en medio, ni que uno de esos saltos pasa por una cola que habías olvidado.</li>
<li><strong>La costura entre dos mundos.</strong> ¿Qué funciones son el único puente entre el módulo de pagos y el de cuentas? Un grafo lo lee como un conjunto pequeño de aristas que cruzan una frontera. La búsqueda no tiene ni el concepto de frontera.</li>
</ul>
<p>La recuperación encuentra dónde se menciona algo. Un grafo te dice cómo se conecta. Son preguntas distintas, y la segunda es la que de verdad necesitas contestada antes de dejar que un agente toque algo que sostiene peso.</p>
<h2 id="por-qué-los-agentes-lo-necesitan-más-de-lo-que-jamás-lo-necesitó-un-humano">Por qué los agentes lo necesitan más de lo que jamás lo necesitó un humano</h2>
<p>Aquí está la parte que hace esto urgente y no académico.</p>
<p>Los humanos siempre tuvieron un grafo de conocimiento del código. Vivía en su cabeza. <a href="/es/blog/onboarding-contra-el-grafo/">La antigüedad en un equipo es, en buena parte, la construcción lenta de un mapa privado</a>: aprendes que tocar el middleware de auth significa revisar cuatro servicios aguas abajo, que el código de facturación tiene una mina en la lógica de reintentos, que un directorio entero es legacy que nadie se atreve a borrar. Nadie lo escribió. Te lo ganaste rompiendo cosas y acordándote.</p>
<p>Un agente empieza cada sesión sin nada de eso. No tiene antigüedad. No tiene memoria del mapa de ayer. Tiene una ventana de contexto y lo que pueda meter en esa ventana ahora mismo, que es una mirilla a una casa en la que no ha vivido nunca. La razón de que un agente competente siga rompiendo un llamador que nunca vio no es que el modelo sea flojo. Es que el mapa que un ingeniero lleva gratis simplemente no existe para el agente, así que trabaja a ciegas en cuanto pasa el borde del fichero que tiene delante.</p>
<p>El instinto es arreglar esto echándole más al modelo. Más contexto. Un prompt más largo y detallado describiendo la arquitectura. Un modelo mejor el trimestre que viene. Nada de eso reconstruye el mapa, porque el problema no es que el agente esté poco informado dentro de un fichero, es que las relaciones entre ficheros nunca se le entregaron en una forma que pueda recorrer. Un prompt más largo es más texto que buscar. No es un grafo. Este es el razonamiento detrás de la frase a la que vuelvo una y otra vez: <a href="/es/blog/mapas-de-codigo-para-agentes/">mapas del código, no prompts más largos</a>. La palanca está en darle al agente la estructura, no en darle más prosa y rezar para que infiera la estructura cada vez. Va pegado a <a href="/es/research/context-engineering-para-agentes-de-codigo/">context engineering para agentes de código</a>: el trabajo no es un modelo más listo, es poner la estructura correcta delante del que tienes.</p>
<p>En cuanto el agente puede consultar el grafo, se cierra el modo de fallo del principio de este artículo. Antes de renombrar el campo, le pregunta al grafo qué depende de ese campo, obtiene los llamadores y los tests, y o los actualiza o te dice que no puede. El cambio encaja porque el agente por fin tiene lo que tú tienes cuando haces ese mismo cambio con seguridad: una vista de todo lo que toca.</p>
<h2 id="grafo-del-código-grafo-de-producto-dos-capas-de-la-misma-idea">Grafo del código, grafo de producto: dos capas de la misma idea</h2>
<p>Un grafo de conocimiento del código lee el código. Responde preguntas estructurales, de ingeniería: qué llama a qué, qué se rompe, qué es alcanzable.</p>
<p>Hay una capa por encima que lee el producto. Esa responde otra familia de preguntas, sobre forma, provenance y deuda de validación, y la escribí aparte en <a href="/es/blog/grafo-de-conocimiento-de-producto/">el grafo de conocimiento de producto</a>. La versión corta de la diferencia: el grafo del código te dice que el pull request romperá tres llamadores, y el grafo de producto te dice a qué decisión de producto servían esos llamadores y si esa decisión se validó alguna vez. Quieres los dos. Son la misma técnica, un grafo de relaciones tipadas, apuntada a dos preguntas distintas. El grafo del código evita que los agentes rompan el sistema. El grafo de producto evita que construyas lo equivocado rápido.</p>
<p>Si solo montas uno primero, monta el del código, porque es el que corta la hemorragia inmediata cuando los agentes escriben la mayor parte de tu código.</p>
<h2 id="el-grafo-tiene-que-ser-verdad-o-es-peor-que-nada">El grafo tiene que ser verdad, o es peor que nada</h2>
<p>Un mapa que miente es más peligroso que ningún mapa, porque te fías de él. Esta es la trampa en la que cae todo esfuerzo de documentación, y un grafo del código no es inmune por defecto.</p>
<p>La única versión que sobrevive al contacto con un codebase que se mueve es una derivada del código, no mantenida al lado. Si el grafo se genera leyendo el código real, la estructura de llamadas real, los tests reales, entonces cuando el código cambia el grafo cambia, porque son el mismo hecho expresado una vez. Si el grafo es un diagrama que alguien dibujó en una wiki, empieza a pudrirse en cuanto entra el siguiente commit, y se pudre en silencio. Ese es el argumento entero de la <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">documentación viva</a>: el artefacto deja de envejecer solo cuando nadie tiene que acordarse de actualizarlo, porque es una proyección del sistema en vez de una segunda copia.</p>
<p>Así que la prueba de si un grafo de conocimiento del código merece confianza no es lo bonito que renderiza. Es si está aguas abajo del código. Un grafo que editas a mano es un grafo que le mentirá a tus agentes un martes, con seguridad, sobre una estructura que cambió el lunes.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Esta es la capa que construyo en PaellaDoc, porque operar agentes sin ella es lo que me quemó. El sistema lee tu repo en tu máquina y construye el grafo: los nodos, las relaciones tipadas, los enlaces del código hacia arriba a las decisiones que lo pidieron. Los agentes consultan la estructura antes de cambiarla, en vez de hacer grep y rezar. El grafo se deriva del código, así que se mueve cuando el código se mueve. Sin nube, sin cuenta, y tu código no sale de la máquina.</p>
<p>Esa es la apuesta entera de este cluster. <a href="/es/blog/construir-software-con-agentes-de-ia/">Cuando los modelos pueden escribir cualquier fichero que pidas</a>, la restricción ya no es la generación. Es si lo que escribe el código puede ver cómo se conecta el código. Un grafo de conocimiento del código es como le entregas esa vista.</p>
<h2 id="faq">FAQ</h2>
<h3 id="un-grafo-de-conocimiento-del-código-no-es-solo-un-call-graph">¿Un grafo de conocimiento del código no es solo un call graph?</h3>
<p>Un call graph es parte de él. Un call graph captura qué función llama a cuál, y ese es uno de los tipos de relación más útiles. Un grafo de conocimiento del código completo lleva más: tipos, flujo de datos, tests, config, endpoints, y los enlaces hacia los artefactos de producto y las decisiones. El call graph te dice la estructura de control del código. El grafo de conocimiento añade por qué existe el código y qué se supone que satisface.</p>
<h3 id="necesito-un-grafo-si-mi-codebase-es-pequeño">¿Necesito un grafo si mi codebase es pequeño?</h3>
<p>Probablemente todavía no. Un codebase pequeño cabe en una cabeza y a menudo en una ventana de contexto, y el mapa es barato de reconstruir leyendo. El grafo se gana el sueldo cuando el código crece más de lo que una persona puede aguantar, cuando varios agentes trabajan en paralelo sobre él, o cuando la gente que llevaba el mapa en la cabeza se va. Que es también, no por casualidad, justo cuando los agentes empiezan a romper cosas que nunca vieron.</p>
<h3 id="se-puede-generar-un-grafo-de-conocimiento-del-código-de-forma-automática">¿Se puede generar un grafo de conocimiento del código de forma automática?</h3>
<p>Sí, y deberías, porque uno mantenido a mano se pudre. El grafo debería construirse leyendo el código, la estructura de llamadas y los tests, para que siga siendo una proyección del sistema real. Las partes que no se pueden leer del código, sobre todo el enlace de provenance del código a la decisión que lo pidió, son las que merece la pena adjuntar a propósito según se completa el trabajo, para capturar el <em>porqué</em> mientras todavía se conoce.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Qué se rompe en tu codebase que una búsqueda nunca te habría avisado? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>]]></content>
    <summary type="html"><![CDATA[Un agente puede abrir cualquier fichero de tu repo y leerlo. Lo que no puede desde una búsqueda de texto es ver cómo se relacionan los ficheros: qué llama a qué, qué tipo fluye por dónde, qué decisión pidió este código. Un grafo de conocimiento del código es ese mapa. Esta es la referencia de qué es uno, qué responde que una búsqueda no puede, y por qué los agentes en concreto se caen sin él.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="knowledge-graph"/><category term="ai-coding"/><category term="codebase-maps"/><category term="agents"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">La compactación se come tus decisiones: gestionar la ventana de contexto</title>
    <link href="https://paelladoc.com/es/blog/gestion-ventana-de-contexto/" rel="alternate" type="text/html" title="La compactación se come tus decisiones: gestionar la ventana de contexto"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/gestion-ventana-de-contexto/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/gestion-ventana-de-contexto/"><![CDATA[<p>Este es un fallo que he visto más de una vez. Al principio de una sesión larga, le digo al agente una restricción: este servicio tiene que seguir siendo idempotente, el proveedor reintenta. Tres horas después, metido en el trabajo, el agente escribe un handler que no es idempotente. No está siendo descuidado. De verdad ya no sabe la restricción, porque la ventana se llenó, la sesión compactó, y mi instrucción de la primera hora se resumió hasta desaparecer. La decisión que hacía correcta la tarea entera ya no está, y nada anunció su marcha.</p>
<p>Ese es el coste silencioso de la ventana de contexto. Es un contenedor de tamaño fijo, y un run largo produce más material del que cabe. Algo tiene que ceder, y lo que cede suele ser lo que dijiste una vez, pronto, y nunca repetiste: la restricción, la decisión, el motivo. El agente no para cuando lo olvida. Sigue con la misma seguridad, ahora optimizando contra un contrato que ya no puede ver. En cualquier trabajo lo bastante largo como para importar, la ventana deja de ser infinita y pasa a ser un presupuesto que tienes que gestionar.</p>
<h2 id="qué-tira-de-verdad-la-compactación">Qué tira de verdad la compactación</h2>
<p>Cuando una sesión se queda sin ventana, la herramienta compacta: resume los turnos viejos para hacer sitio. Útil, y necesario, pero resumir tiene pérdidas por diseño, y no las tiene al azar. Se queda con lo que parece importante localmente en el flujo reciente y suelta lo que parece detalle viejo. Una restricción de una línea que dijiste hace tres horas y nunca volviste a mencionar parece exactamente detalle viejo desechable, aunque sea la frase que más sostiene el edificio de todo el run.</p>
<p>Así que la compactación tiene un sesgo: preserva la forma de la conversación reciente y erosiona las decisiones que anclaron el principio. El “nunca debemos hacer X” del principio se comprime hasta nada mientras los últimos veinte minutos de detalle de implementación se quedan nítidos. Este es el mecanismo detrás de toda una clase de fallos de run largo, y es por qué <a href="/es/blog/recuperar-ejecuciones-fallidas/">un run deriva en medio en vez de crashear</a>: el agente no se rompió, olvidó, y luego siguió construyendo con seguridad sobre el hueco.</p>
<p>El propio relato de Anthropic sobre <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">context engineering efectivo para agentes de IA</a> deja claro el punto de fondo: la atención es finita, y más tokens en la ventana no es lo mismo que más entendimiento. Pasado un punto, añadir contexto degrada el agarre del agente sobre lo que importa en vez de mejorarlo. La ventana es un recurso con techo, y tratarla como ilimitada es como consigues una amnesia con seguridad.</p>
<h2 id="la-ventana-es-un-presupuesto-no-un-almacén">La ventana es un presupuesto, no un almacén</h2>
<p>El cambio mental que arregla casi todo esto es dejar de tratar la ventana de contexto como almacenamiento y empezar a tratarla como un presupuesto que gastas a propósito. Un almacén es donde metes todo y asumes que estará ahí después. Un presupuesto es finito, y cada token que gastas en ruido es un token no disponible para la decisión que importa.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Trata la ventana como un presupuesto que gastas en la tarea, no como un almacén donde vive la fuente de verdad."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">almacén</p>
    <ul><li>mete todo dentro</li><li>asume que perdura</li><li>inunda cada llamada</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">presupuesto</p>
    <ul><li>finito y deliberado</li><li>la verdad vive fuera</li><li>carga solo el trozo</li></ul>
  </div>
</div><figcaption>Trata la ventana como un presupuesto que gastas en la tarea, no como un almacén donde vive la fuente de verdad.</figcaption></figure>
<p>Dos cosas se siguen de ese marco.</p>
<p>Primero, <strong>qué entra en la ventana es una elección, no un default.</strong> Volcar el repo entero, la historia completa y cada fichero de reglas en cada llamada no es minuciosidad, es gastar tu presupuesto en cosas que el agente no necesita para esta tarea, que es el argumento central de <a href="/es/research/context-engineering-para-agentes-de-codigo/">context engineering para agentes de código</a>: cura lo que el agente ve, no lo inundes. Un trozo preciso de los ficheros correctos gana al árbol entero.</p>
<p>Segundo, <strong>las decisiones que deben sobrevivir no pueden vivir solo en la ventana.</strong> Si la única copia de “esto tiene que seguir siendo idempotente” es un mensaje en el transcript, la compactación puede comérsela y se la comerá. El arreglo no es repetirla más fuerte. Es guardarla en algún sitio que la ventana no posea, un fichero, una tarea, un contrato, y volver a suministrarla cuando importa, para que la restricción dure más que cualquier resumen. Este es el gemelo dentro de sesión de <a href="/es/blog/perdida-de-contexto-entre-sesiones/">perder contexto entre sesiones</a>: el mismo fallo a menor escala de tiempo, con el mismo arreglo.</p>
<h2 id="presupuestar-la-ventana-en-trabajo-largo">Presupuestar la ventana en trabajo largo</h2>
<p>En concreto, así evito que los runs largos se olviden de sí mismos, todo posible hoy:</p>
<ul>
<li><strong>Mantén el contrato fuera del transcript.</strong> Las restricciones y los criterios de aceptación viven en un artefacto, no solo en algo que el agente dijo pronto. Así la compactación no las puede borrar, y cualquier sesión resumida o traspasada puede releerlas. Es la misma razón por la que <a href="/es/blog/handoffs-entre-agentes/">un handoff limpio</a> carga un paquete destilado en vez de la historia en bruto.</li>
<li><strong>Gasta el presupuesto en la tarea, no en el archivo.</strong> Carga los ficheros que este paso necesita, no el repo entero. Un contexto más pequeño y afilado cabe mejor y produce mejor output.</li>
<li><strong>Vuelve a anclar en las fronteras.</strong> En cada frontera de episodio, reafirma las restricciones vivas en el contexto de trabajo. Cuesta unos tokens y te compra un agente que aún sabe las reglas.</li>
<li><strong>Vigila los ficheros de reglas.</strong> Cada línea de un fichero de reglas que el agente autocarga es presupuesto gastado en cada llamada. Un <a href="/es/blog/reglas-de-agentes-vivas/">fichero de reglas obsoleto</a> e inflado no solo despista, es caro, desplazando el contexto que la tarea de verdad necesita.</li>
<li><strong>Haz checkpoint antes de que la compactación muerda.</strong> Si un run se acerca al techo, un checkpoint con el estado actual escrito significa que una sesión fresca puede continuar desde un contexto limpio y pequeño en vez de uno compactado y con pérdidas.</li>
</ul>
<p>El patrón bajo todo ello: la ventana sostiene el conjunto de trabajo, no la fuente de verdad. Todo lo que tiene que sobrevivir al run entero vive fuera de la ventana y se vuelve a suministrar bajo demanda.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La compactación se come decisiones porque la ventana es finita y resumir está sesgado contra la restricción vieja que ancló el trabajo, y el arreglo es guardar lo que debe sobrevivir fuera de la ventana y volver a suministrarlo cuando cuenta. Ese es el mecanismo, y es por qué no creo que una ventana más grande sola resuelva esto: un presupuesto mayor también se llena, y también erosiona el ancla primero, que es la misma razón por la que <a href="/es/research/agentes-necesitan-un-runtime-no-un-modelo-mas-grande/">los agentes necesitan un runtime, no un modelo más grande</a>. PaellaDoc guarda el contrato y las decisiones como artefactos fuera de la ventana de cualquier sesión y le da al agente el trozo que necesita, así que un run largo se sostiene contra restricciones que no puede olvidar en vez de contra unas que resumió y perdió. La persona que vuelve a anclar al agente a mano cada vez que deriva es <a href="/es/blog/eres-el-runtime/">el runtime</a>, hasta que la ventana se gestiona por ella.</p>
<h2 id="faq">FAQ</h2>
<h3 id="por-qué-mi-agente-olvida-instrucciones-durante-una-sesión-larga">¿Por qué mi agente olvida instrucciones durante una sesión larga?</h3>
<p>Porque la ventana de contexto es de tamaño fijo, y cuando se llena la sesión compacta resumiendo los turnos viejos. Resumir tiene pérdidas y está sesgado a quedarse con el detalle reciente, así que una restricción de una línea del principio que nunca repetiste es exactamente el tipo de cosa que se borra, mientras la charla de implementación reciente sobrevive. El agente entonces sigue trabajando sin la instrucción, sin saber que ya no está.</p>
<h3 id="una-ventana-de-contexto-más-grande-arregla-esto">¿Una ventana de contexto más grande arregla esto?</h3>
<p>Sube el techo pero no cambia el mecanismo. Una ventana mayor también se llena en trabajo largo, y la compactación sigue erosionando primero las decisiones de anclaje del principio. Más tokens tampoco es lo mismo que más entendimiento, pasado un punto el contexto extra degrada el foco del agente. El arreglo duradero es guardar las restricciones que deben sobrevivir fuera de la ventana y volver a suministrarlas, no confiar en un almacén más grande.</p>
<h3 id="cómo-evito-que-la-compactación-pierda-decisiones-importantes">¿Cómo evito que la compactación pierda decisiones importantes?</h3>
<p>Sácalas del transcript. Guarda las restricciones y los criterios de aceptación en un artefacto que la ventana no posea, reafirma las vivas en cada frontera de episodio, haz checkpoint antes de tocar el techo, y carga solo los ficheros que un paso de verdad necesita en vez de inundar la ventana. La ventana debería sostener el conjunto de trabajo; la fuente de verdad vive fuera de ella.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="ventana-de-contexto"/><category term="compactacion"/><category term="agentes"/><category term="context-engineering"/><category term="runtime"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">Cada feature nueva rompe una vieja: el contrato que falta</title>
    <link href="https://paelladoc.com/es/blog/features-que-rompen-features/" rel="alternate" type="text/html" title="Cada feature nueva rompe una vieja: el contrato que falta"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/features-que-rompen-features/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/features-que-rompen-features/"><![CDATA[<p>Añades una feature. Algo no relacionado deja de funcionar. Arreglas eso, y se rompe una tercera cosa. Cada paso adelante te cuesta un paso en un sitio donde no mirabas, y la app que antes crecía en minutos ahora se mueve como si vadeara barro. Si has sentido esto, no estás siendo descuidado. Te falta una cosa concreta, y tiene nombre.</p>
<p>Lo que falta es un contrato entre tus features. Nada en la app dice qué promete cada parte a las demás, así que nada impide que una parte viole en silencio las asunciones de otra. Junta suficientes partes y los choques no son mala suerte, son aritmética.</p>
<h2 id="por-qué-pasa-esto-con-precisión">Por qué pasa esto, con precisión</h2>
<p>Cada feature de una app vibe-coded se generó más o menos por su cuenta. El agente tuvo esa feature a la vista, la hizo funcionar, y asumió que el resto de la app se quedaría quieta a su alrededor. Esa asunción casi siempre es tácita, y casi siempre es falsa.</p>
<p>La feature dos asumió que el registro de usuario tenía cierta forma. La feature seis cambió esa forma para hacer su propio trabajo. Nada registró que la feature dos dependía de la forma vieja, así que nada avisó a nadie. La feature dos ahora está rota, y seguirá rota hasta que un usuario la encuentre, porque no había ningún contrato que violar en voz alta.</p>
<p>Multiplica esto a través de una app que crece. El número de maneras en que las features pueden depender en silencio unas de otras crece mucho más rápido que el número de features. Por eso el dolor es leve al principio y luego, pasado un puñado de features, parece explotar. Es el mismo componer que produce el <a href="/es/blog/vibe-coding-dia-90/">ajuste de cuentas hacia el mes 3</a>: lo que te desborda son las interacciones, no las features.</p>
<h2 id="por-qué-los-agentes-lo-agudizan">Por qué los agentes lo agudizan</h2>
<p>Un humano que construye despacio tiende a llevar un contrato informal en la cabeza. Recuerda que a la feature dos le importa la forma del usuario, así que cuando la toca para la feature seis, salta una alarma callada. Es frágil y no escala, pero existe.</p>
<p>Un agente no tiene esa memoria entre sesiones. Cada ejecución empieza de cero, ve el código tal como está ahora, y no puede saber con qué contaba en silencio una feature anterior a menos que algo en el código lo diga. El agente no es descuidado. Trabaja exactamente como se le indicó, ciego a una promesa que nadie escribió. Generar más rápido solo significa que llegas antes a la zona de choque. Esta es una cara de la verdad más amplia de que <a href="/es/blog/localmente-correcto-globalmente-incoherente/">los cambios correctos en local producen un sistema globalmente incoherente</a>: cada edición está bien por su cuenta y el conjunto deriva hasta dejar de estar de acuerdo consigo mismo.</p>
<h2 id="el-arreglo-no-es-ten-más-cuidado">El arreglo no es “ten más cuidado”</h2>
<p>No puedes resolver esto esforzándote más en recordar. La memoria es justo lo que no escala aquí, y si usas agentes, la memoria en la que te apoyarías ni siquiera está en la sala. El cuidado no es un mecanismo.</p>
<p>El arreglo es hacer el contrato explícito, para que una violación sea visible en vez de silenciosa. Tiene dos capas, y quieres las dos.</p>
<p><strong>El contrato como spec escrita.</strong> Cada feature debería tener una declaración pequeña y llana de qué promete y de qué depende: esta feature garantiza que este total siempre cuadra, esta feature asume que el registro de usuario tiene un rol. Cuando esas promesas están escritas junto al código, un cambio que rompería una tiene algo contra lo que chocar. Esto es lo que significa que <a href="/es/blog/spec-como-contrato/">la spec sea el contrato</a> en vez de un documento que nadie abre: es la cosa que dice qué debe seguir siendo cierto, para que una violación sea una regla rota en vez de una sorpresa en producción.</p>
<p><strong>El contrato como comprobación ejecutable.</strong> Una promesa escrita todavía necesita dientes. Los dientes son tests de caracterización que fijan el comportamiento garantizado de cada feature, para que cuando un cambio posterior viole la promesa, <a href="https://martinfowler.com/bliki/SelfTestingCode.html">un test falle de inmediato</a> en vez de un usuario reportar un bug tres semanas después. El contrato escrito dice qué se promete; el test lo hace cumplir en el momento en que se rompe. Un <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">build en verde por sí solo no prueba nada de esto</a>; la comprobación tiene que ejercitar de verdad el comportamiento que el contrato nombra.</p>
<p>Juntas, convierten un choque silencioso en un fallo ruidoso, inmediato y localizado, en el momento en que aún puedes arreglarlo barato.</p>
<h2 id="instalar-el-contrato-en-una-app-que-ya-tienes">Instalar el contrato en una app que ya tienes</h2>
<p>No necesitas una reescritura para conseguir esto. Instalas el contrato sobre la app en marcha, en el mismo orden seguro que sigue cualquier refuerzo.</p>
<p>Escribe qué promete y qué asume cada una de tus features existentes, empezando por las que más duelen cuando se rompen. Fija esas promesas con tests que fallen ante la violación. Después, según añades features, los choques se anuncian durante el desarrollo en vez de emboscar a los usuarios en producción. Con el tiempo la app deja de ser un sitio donde el progreso cuesta regresiones. La versión completa por etapas de esto, para una app entera en vez de una feature, es el cruce en <a href="/es/blog/vibe-coding-a-produccion/">de vibe coding a producción</a>, y la mecánica concreta de reforzar una app frágil en su sitio está en <a href="/es/blog/arreglar-app-vibe-coding/">arreglar una app vibe-coded sin reescribirla</a>.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Mantener el contrato de cada feature en la cabeza es justo el trabajo que falla según la app crece, y es el trabajo que haces en silencio cada vez que te preparas antes de un cambio. El papel de PaellaDoc es sostener esos contratos fuera de tu cabeza: mantiene la especificación de cada feature pegada al código que la implementa, y vuelve a ejecutar la app para comprobar que un cambio no rompió una promesa de la que dependía otra feature. El punto no es más disciplina por tu parte. Es que el contrato entre features viva en algún sitio duradero y se compruebe automáticamente, para que la siguiente feature sea un añadido en vez de un choque.</p>
<p>Se supone que las features nuevas suman. Cuando cada una resta en otro sitio, no tienes un problema de disciplina. Tienes un contrato que falta, y los contratos se pueden instalar.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Por qué cada feature nueva rompe una vieja en mi app hecha con IA?</strong> Cada feature se generó asumiendo que el resto de la app se queda quieta, y esa asunción nunca se escribió. Cuando una feature posterior cambia algo de lo que dependía una anterior, nada avisa a nadie, porque no había un contrato que violar en voz alta.</p>
<p><strong>¿Por qué los agentes de código lo empeoran?</strong> Un agente no tiene memoria entre sesiones de lo que dependen en silencio las features anteriores. A menos que el código declare esas dependencias, el agente no puede saber que está rompiendo una. Generar más rápido solo llega antes a la zona de choque.</p>
<p><strong>¿Cómo evito que las features se rompan entre sí?</strong> Haz el contrato explícito: escribe qué promete y de qué depende cada feature, y fija esas promesas con tests que fallen en el instante en que un cambio las viole. Eso convierte una rotura silenciosa en producción en un fallo inmediato y localizado durante el desarrollo.</p>]]></content>
    <summary type="html"><![CDATA[Añades la feature seis y la feature dos deja de funcionar en silencio. Esto no es descuido, es un contrato que falta entre las partes. Aquí está por qué los agentes lo empeoran, y cómo instalar el contrato sin reescribir.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="features-que-rompen-features"/><category term="spec-como-contrato"/><category term="regresion"/><category term="ai-coding"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Fatiga de review: cuando el código llega más rápido de lo que puedes leerlo</title>
    <link href="https://paelladoc.com/es/blog/fatiga-de-revision/" rel="alternate" type="text/html" title="Fatiga de review: cuando el código llega más rápido de lo que puedes leerlo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/fatiga-de-revision/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/fatiga-de-revision/"><![CDATA[<p>Son las cuatro de la tarde y has aprobado cosas que en realidad no leíste. No por vagancia. Los diffs seguían llegando, cada uno plausible, cada uno otra pared de código que un agente produjo en lo que tú tardabas en terminar el anterior. En algún punto de las últimas horas «revisar» se convirtió en silencio en «ojear y esperar». Lo sabes, y sientes ese desasosiego bajo que lo acompaña.</p>
<p>Esto es la fatiga de review, y no es un problema de disciplina del que puedas salir a fuerza de voluntad. Es aritmética. Los agentes escriben más rápido de lo que lees, y el hueco no se cierra leyendo más rápido.</p>
<h2 id="por-qué-revisar-ia-cuesta-más-no-menos">Por qué revisar IA cuesta más, no menos</h2>
<p>Hay una razón concreta de que revisar código de agentes pese más que revisar el de un compañero, y conviene nombrarla con precisión. Cuando un colega te manda una pull request, la intención viene adjunta. Estuviste en la daily. Viste el ticket. Sabes por qué eligió este enfoque porque puedes preguntar, o porque el mensaje de commit lleva el razonamiento de una persona que tenía el problema entero en la cabeza. Revisar ese código es sobre todo comprobar un entendimiento compartido.</p>
<p>El código del agente llega despojado de todo eso. No hay intención viajando con él, ni razonamiento que puedas reconstruir preguntando, ni contexto compartido de una conversación en la que estuvierais los dos. Te entregan un artefacto plausible y te piden reconstruir, solo desde el diff, qué se suponía que hacía y si lo hace. Las <a href="https://survey.stackoverflow.co/2025/">encuestas a desarrolladores</a> repiten lo que los profesionales sienten: revisar código generado por IA cuesta con frecuencia más atención que revisar el de un colega humano. No es un desprecio a los modelos. Es lo que pasa cuando no se puede interrogar al autor y la intención no viajó con el código.</p>
<p>Multiplica ese coste por diff por el caudal de los agentes y la fatiga no es un riesgo, es el estado estacionario garantizado.</p>
<h2 id="leer-con-más-fuerza-es-el-eje-equivocado">Leer con más fuerza es el eje equivocado</h2>
<p>El instinto es esforzarse más: concentrarse más, revisar cada línea, atrapar todo. Falla por una razón estructural. Tu capacidad de lectura es fija y la capacidad de producción de los agentes no. Cualquier estrategia que responda a más output con más lectura cuidadosa pierde por construcción, y pierde de la peor forma, degradándose poco a poco hasta que estás sellando con goma sin admitirlo.</p>
<p>El otro instinto es rendirse y fiarse del output, que es como se acumula código <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto, globalmente incoherente</a> hasta que el sistema deja de tener sentido como un todo. Ni leerlo todo ni leer nada están disponibles. Lo que está disponible es leer <em>distinto</em>: gastar tu atención fija donde compra más certeza por minuto.</p>
<h2 id="los-momentos-que-llevan-más-información">Los momentos que llevan más información</h2>
<p>No todos los momentos de revisión son iguales. Unos cuestan un minuto y fijan la dirección de una tarea entera. Otros cuestan una hora y atrapan una errata. El truco es gastar tu atención en el orden del apalancamiento.</p>
<p><strong>El alcance, primero.</strong> Antes de que el agente construya, aprueba lo que va a hacer. Qué comportamiento cambia, qué queda intacto, qué tiene que cumplir el resultado. Este es el minuto de más apalancamiento que vas a gastar, porque dirigir la intención antes de que exista el código es mucho más barato que auditar una implementación terminada y descubrir que resolvió el problema equivocado. La revisión más barata es la que haces <a href="/es/blog/revision-de-specs/">sobre el plan, antes de escribir una línea</a>, que es buena parte de <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">para qué sirve el desarrollo guiado por especificaciones</a>.</p>
<p><strong>El diff, contra el alcance.</strong> Cuando el código vuelve, léelo contra el alcance que aprobaste, no contra un recuerdo vago de lo que querías. La pregunta es estrecha y respondible: ¿hace este diff lo que acordamos, y solo eso? Una pregunta acotada es revisable. «¿Está esto bien?» no lo es.</p>
<p><strong>La evidencia, al final.</strong> Luego mira qué se ejecutó de verdad: qué comandos, qué imprimieron, contra qué contrato. Aquí es donde confirmas el comportamiento en vez de inferirlo, y es el más rápido de los tres cuando la evidencia se capturó según pasaba el trabajo en vez de reconstruirla tú después.</p>
<p>Alcance, luego diff, luego evidencia. Tres puntos de control sustituyen a una tarea de lectura sin límites. Cada uno es una pregunta concreta y respondible, y juntos dejan a un humano en control de mucho más output del que jamás podría leer línea a línea.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="Tres puntos de control sustituyen una lectura sin fin. Gasta la atención por orden de palanca, lo ancho primero."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">ALCANCE</text><path d="M 250 95 L 272 95 M 266 89 L 272 95 L 266 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">DIFF</text><path d="M 488 95 L 510 95 M 504 89 L 510 95 L 504 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="62" width="204" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="618" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">EVIDENCIA</text></svg><figcaption>Tres puntos de control sustituyen una lectura sin fin. Gasta la atención por orden de palanca, lo ancho primero.</figcaption></figure>
<h2 id="no-todos-los-diffs-merecen-la-misma-lectura">No todos los diffs merecen la misma lectura</h2>
<p>Los tres puntos de control te dicen <em>cuándo</em> gastar atención. El triaje te dice <em>cuánta</em>, porque tratar cada cambio como igual de arriesgado es su propia forma de quemarse. Un arreglo de una línea de copy y un cambio en la ruta de autenticación son ambos «un diff», y leerlos con la misma intensidad significa o sobre-leer el trivial o infra-leer el peligroso. Normalmente ambas cosas, en la misma tarde.</p>
<p><a href="/es/blog/revisar-codigo-ajeno/">Ordena por radio de impacto, no por orden de llegada</a>. Un cambio que toca dinero, auth, borrado de datos o una interfaz compartida se gana una lectura lenta, línea a línea, y una mirada dura a la evidencia, siempre, por muy seguro que suene el informe. Un cambio en una hoja aislada con tests alrededor a menudo se puede creer a nivel de alcance y evidencia sin una lectura completa de líneas, porque el coste de que esté mal está acotado y la prueba está ahí mismo. La habilidad no es leerlo todo a fondo. Es saber qué cambios no se pueden permitir una lectura ligera y reservar tu atención más profunda para esos.</p>
<p>También por eso el punto de control del alcance rinde doble. Aprobar el alcance por adelantado no solo dirige el trabajo, te dice de antemano a qué cubo pertenece el cambio entrante. Ya sabes, antes de que llegue el diff, si este es una hoja o un muro de carga, así que el esfuerzo de revisión se presupuesta antes de que estés cansado en vez de decidirse en el momento en que tu juicio está peor.</p>
<h2 id="qué-tiene-que-ser-cierto-para-que-esto-funcione">Qué tiene que ser cierto para que esto funcione</h2>
<p>Este orden solo funciona si se cumplen dos cosas. El alcance tiene que existir como algo que realmente aprobaste, no algo que puedas reconstruir a posteriori. Y la evidencia tiene que capturarse de forma automática, como subproducto del trabajo, o vuelves a re-ejecutar cosas a mano y la fatiga regresa por la puerta de atrás.</p>
<p>Esa segunda condición es el vínculo entre la fatiga de review y el resto de la verificación. Si la compleción ya exige <a href="/es/blog/hecho-significa-hecho/">una demostración real</a>, la evidencia está ahí cuando llegas al tercer punto de control. Si el trabajo cierra con <a href="/es/blog/desarrollo-basado-en-evidencia/">su prueba adjunta</a>, el último paso de la revisión es leer un registro, no reconstruirlo. La revisión deja de ser el sitio donde se amontona toda la verificación que falta, que es justo por qué <a href="/es/blog/verificar-codigo-generado-por-ia/">el cuello de botella es la confianza, no el output</a>: una revisión en la que puedes confiar es lo que hace que el caudal signifique algo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/">PaellaDoc</a> está construido alrededor de aprobar el alcance por adelantado y capturar la evidencia según corre el trabajo, para que la revisión aterrice donde tiene apalancamiento en vez de al final como una última línea de defensa agotadora. Diriges la intención antes de que el agente construya. La evidencia está ahí cuando el cambio vuelve. El diff se lee contra un contrato que ya acordaste, no contra tu memoria cansada. El revisor sigue en control sin fingir que lo lee todo, porque es el proceso, no el heroísmo, lo que hace fiable el output.</p>
<p>El código seguirá llegando más rápido de lo que puedes leerlo. Eso es permanente. Revisar en los momentos correctos es cómo sigues al mando de él de todas formas.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-revisar-código-de-ia-cansa-más-que-revisar-el-de-un-compañero">¿Por qué revisar código de IA cansa más que revisar el de un compañero?</h3>
<p>Porque la intención no viaja con él. La pull request de un colega llega con contexto compartido: la daily, el ticket, un mensaje de commit que lleva el razonamiento de una persona, un autor al que puedes preguntar. El código del agente llega despojado de todo eso, así que tienes que reconstruir solo desde el diff qué se suponía que hacía y si lo hace. Multiplica ese coste por diff por el caudal de los agentes y la fatiga es el estado estacionario garantizado.</p>
<h3 id="cómo-sigo-el-ritmo-de-código-que-un-agente-escribe-más-rápido-de-lo-que-leo">¿Cómo sigo el ritmo de código que un agente escribe más rápido de lo que leo?</h3>
<p>No puedes, ni leyendo más rápido ni con más fuerza, porque tu capacidad de lectura es fija y el output del agente no. Lee distinto: gasta tu atención fija donde compra más certeza por minuto. Aprueba el alcance antes de que el agente construya, lee el diff contra ese alcance y luego confirma la evidencia de lo que corrió. Tres puntos de control acotados sustituyen a una lectura sin límites.</p>
<h3 id="tengo-que-revisar-cada-línea-de-código-generado-por-ia">¿Tengo que revisar cada línea de código generado por IA?</h3>
<p>No por igual. Leer un arreglo de una línea de copy con la misma intensidad que un cambio en la ruta de autenticación significa sobre-leer el trivial e infra-leer el peligroso. Ordena por radio de impacto: los cambios que tocan dinero, auth, borrado de datos o interfaces compartidas se ganan una lectura lenta línea a línea siempre. Una hoja aislada con tests alrededor a menudo se puede creer a nivel de alcance y evidencia.</p>
<h3 id="qué-tiene-que-estar-en-su-sitio-para-que-la-revisión-por-etapas-funcione">¿Qué tiene que estar en su sitio para que la revisión por etapas funcione?</h3>
<p>Dos cosas. El alcance tiene que existir como algo que realmente aprobaste por adelantado, no algo reconstruido a posteriori. Y la evidencia tiene que capturarse de forma automática como subproducto del trabajo, o vuelves a re-ejecutar cosas a mano y la fatiga regresa por la puerta de atrás. Cuando la compleción ya exige una demostración, la evidencia espera en el último punto de control.</p>]]></content>
    <summary type="html"><![CDATA[Los agentes producen código más rápido de lo que cualquier humano puede leerlo, y revisar código generado por IA suele costar más atención que revisar el de un colega porque nada de la intención del autor vino con él. La fatiga de review es un desajuste de caudal. La respuesta no es leer con más fuerza, es leer en los momentos que llevan más información por minuto.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="review-fatigue"/><category term="ai-coding"/><category term="code-review"/><category term="verificacion"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">La fábrica local de software: producto, código y evidencia en tu máquina</title>
    <link href="https://paelladoc.com/es/blog/fabrica-local-de-software/" rel="alternate" type="text/html" title="La fábrica local de software: producto, código y evidencia en tu máquina"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/fabrica-local-de-software/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/fabrica-local-de-software/"><![CDATA[<p><strong>Una fábrica local de software es un sistema que mantiene producto, código y evidencia conectados en la máquina que tienes delante.</strong> No una ventana de chat. No una carpeta de Markdown. No una pestaña dentro de la nube de otro. Un sitio donde una idea se convierte en decisión, la decisión en especificación, la especificación en trabajo que un agente puede ejecutar, y el resultado vuelve con la prueba adjunta; todo en un sistema conectado, todo local.</p>
<p>Eso es una afirmación de categoría, así que la voy a defender en lugar de soltarla.</p>
<p>La generación de código está básicamente resuelta. Claude Code, Codex y compañía escriben código lo bastante bien como para que “¿puede el modelo escribir esta función?” ya no sea la pregunta interesante. El trabajo no desapareció. Se movió. Ahora consiste en mantener vivo el contrato de producto mientras <a href="https://www.anthropic.com/engineering/building-effective-agents">muchos agentes escriben, fallan, se recuperan, integran y producen evidencia</a>. Hoy eso lo hace una persona a mano, sin ponerle nombre. Tú eres el scheduler. Tú eres la memoria entre sesiones. Tú eres el bucle de recuperación cuando una ejecución muere. Tú eres la puerta de calidad que decide qué significa “hecho”. <strong><a href="/es/blog/eres-el-runtime/">Tú eres el runtime</a>.</strong></p>
<p>Una fábrica es lo que construyes cuando te cansas de ser el runtime a mano.</p>
<h2 id="el-impuesto-de-la-desconexión">El impuesto de la desconexión</h2>
<p>Mira cómo se mueve de verdad un cambio por un flujo moderno asistido por IA.</p>
<p>La idea nace en un chat. La decisión de construirla vive en tu cabeza, quizá en un hilo de Slack. Los requisitos acaban en una página de Notion o un ticket de Linear. El agente recibe un prompt que parafrasea una parte de eso. El código aterriza en un repositorio. Los tests, si se ejecutaron, imprimieron una salida que se fue del terminal hace una hora. La razón por la que descartaste el otro enfoque ya no está. Tres semanas después, un segundo agente —o tú, que lo has olvidado— abre el archivo y ve un diff sin memoria alrededor.</p>
<p>Cada uno de esos traspasos pierde algo. Esa pérdida es un impuesto, y se acumula. Cuanto más rápido escriben los agentes, más pagas, porque el volumen de cambios crece y el tejido conectivo no. Un build en verde te dice que el código compiló. No te dice que el comportamiento que prometiste se instaló, ni que la restricción que te importaba sigue en pie.</p>
<p>Ese es el problema real del código generado por IA, y no es que el código sea malo. Cada pieza suele ser correcta en local. El sistema deriva hacia incoherente en global porque nada sostiene el conjunto. Cada herramienta posee una parte —el editor posee el diff, el gestor posee el ticket, el chat posee la conversación— y ninguna posee el hilo que va de la intención a la prueba.</p>
<p>Una fábrica es la respuesta a ese fallo concreto: poner las partes en un sistema para que el hilo sobreviva.</p>
<h2 id="qué-se-conecta-dentro-de-la-fábrica">Qué se conecta dentro de la fábrica</h2>
<p>Uso la palabra fábrica a propósito, y también con cuidado. No una feature factory —la máquina que se mide por output enviado y a eso lo llama producto—. Lo contrario. Aquí una fábrica es un sitio con estaciones, donde entra material, se trabaja en un orden definido y sale como algo probado. Seis estaciones, un bucle.</p>
<p><strong>Descubrir.</strong> Convierte una incertidumbre en hipótesis, evidencia, un experimento pequeño y una decisión. La salida es una decisión, registrada, no una sensación que recordarás mal.</p>
<p><strong>Definir.</strong> Mantén el contrato de producto —el PRD, las épicas, las historias, los criterios de aceptación— como algo trazable, no un documento que nadie lee. La salida es un contrato al que se puede exigir a un agente.</p>
<p><strong>Planificar.</strong> Refina alcance, dimensiona el trabajo, gestiona dependencias, haz visible el sprint. La salida es trabajo acotado.</p>
<p><strong>Construir.</strong> Entrega al motor un contrato preparado, contexto aislado y una definición de hecho ejecutable. La salida es un cambio, no una esperanza.</p>
<p><strong>Verificar.</strong> Gates, tests, capturas, trazas. Sin evidencia, no hay luz verde. La salida es prueba, no un autoinforme.</p>
<p><strong>Aprender.</strong> Devuelve el resultado, la historia del código y las decisiones a la memoria para que el siguiente bucle arranque más listo. La salida es memoria.</p>
<p>Cada estación produce contexto para la siguiente. Nada importante queda atrapado en un prompt ni abandonado en un documento de planificación. Ese es todo el truco, y es poco vistoso: el valor no está en ninguna estación, está en que estén conectadas y en que la conexión sea duradera.</p>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="Seis estaciones, un bucle: cada una entrega contexto duradero a la siguiente, y Aprender lo devuelve para que la próxima vuelta arranque más lista."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="85" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="82" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">DESCUBRIR</text><path d="M 131 85 L 153 85 M 147 79 L 153 85 L 147 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="159" y="52" width="85" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="201" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">DEFINIR</text><path d="M 250 85 L 272 85 M 266 79 L 272 85 L 266 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="52" width="85" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="320" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">PLANIFICAR</text><path d="M 369 85 L 391 85 M 385 79 L 391 85 L 385 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="397" y="52" width="85" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="439" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CONSTRUIR</text><path d="M 488 85 L 510 85 M 504 79 L 510 85 L 504 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="52" width="85" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="558" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">VERIFICAR</text><path d="M 607 85 L 629 85 M 623 79 L 629 85 L 623 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="635" y="52" width="85" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="677" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">APRENDER</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">APRENDER ALIMENTA EL BUCLE</text></svg><figcaption>Seis estaciones, un bucle: cada una entrega contexto duradero a la siguiente, y Aprender lo devuelve para que la próxima vuelta arranque más lista.</figcaption></figure>
<h2 id="un-grafo-de-producto-sobre-un-grafo-de-código">Un grafo de producto sobre un grafo de código</h2>
<p>El tejido conectivo tiene forma. Debajo hay un grafo de código: las funciones, archivos, servicios y sus relaciones, eso que un agente de código necesita de verdad en lugar de un prompt más largo. Encima vive un grafo de producto: evidencia de discovery enlazada con decisiones, decisiones con especificaciones, especificaciones con historias y criterios, criterios con el código que los implementa, y el código de vuelta con la evidencia que lo valida.</p>
<p>La mayoría de herramientas aplanan tu producto hasta una lista de tickets y pierden los enlaces. La gracia del grafo es que los enlaces son de primera clase. Puedes abrir cualquier capacidad meses después y recuperar cuatro cosas a la vez: qué hace, por qué existe, dónde vive y qué demuestra que funciona. Esa es la diferencia entre un sistema que recuerda y un montón de artefactos que por casualidad comparten carpeta.</p>
<p>Cuando un motor puede enrutar trabajo entre <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">distintos modelos sin vendor lock-in</a>, el grafo es lo que sobrevive al cambio. El modelo es intercambiable. La memoria no, y la memoria es lo que de verdad posees.</p>
<h2 id="por-qué-local-es-arquitectura-no-nostalgia">Por qué local es arquitectura, no nostalgia</h2>
<p>Aquí la categoría se gana su nombre. “Local” no es una preferencia por los viejos tiempos. Es el único sustrato sobre el que todo esto sigue conectado sin pedirte que confíes la forma entera de tu producto a una cadena de terceros.</p>
<p>Piensa en lo que guarda la fábrica: tus notas de discovery, tus opciones descartadas, tus apuestas sin publicar, tus criterios de aceptación, tu código, la evidencia de tus tests. Eso no es un repositorio. Es la estrategia detrás del repositorio. Dónde vive eso es una decisión de arquitectura, y merece la misma seriedad que darías a elegir una base de datos.</p>
<p>Ponlo en tu máquina y tres cosas se vuelven ciertas por construcción, no por política. El estado está al lado del trabajo, así que la latencia entre “decidí esto” y “el agente lo ve” es una lectura de disco, no un viaje de red y el rate limit de otro. Los datos son tuyos, en almacenamiento inspeccionable que puedes abrir, así que la privacidad es una propiedad de la arquitectura y no una promesa en una pantalla de ajustes. Y nada del sistema depende de que un proveedor siga existiendo, mantenga su precio o no cambie sus términos.</p>
<p>Local no significa cerrado, y esa distinción importa. La fábrica funciona en tu ordenador, pero llama a los proveedores de IA que elijas, trabaja en repositorios git normales y se mantiene abierta en los límites donde importa la portabilidad. Los modelos son remotos —y conviene decirlo claro: la nube hace inferencia mejor de lo que la hará tu portátil—. Lo que se queda local es todo lo que define tu producto: el contrato, el grafo, las decisiones y la prueba. Envías tokens fuera cuando tú decides. No entregas la fábrica.</p>
<h2 id="qué-hace-mejor-la-nube-y-qué-cuesta">Qué hace mejor la nube, y qué cuesta</h2>
<p>No voy a fingir que el intercambio sea de una sola cara. Las herramientas en la nube son excelentes en cosas que una fábrica local no. El estado compartido entre un equipo, sin configuración, funciona en cuanto alguien abre un navegador. El cómputo pesado es problema de otro. El software se actualiza solo. Para un equipo grande que vive en un mismo espacio compartido, esas son ventajas reales y no las voy a despachar.</p>
<p>El coste de esa comodidad es justo aquello de lo que va esta categoría. Cuando el estado vive en la nube de otro, la memoria de tu producto es inquilina, no propietaria. La conexión entre intención y prueba existe a su discreción, en su formato, exportable en sus términos. Estás alquilando el hilo. Para un fundador en solitario o un equipo pequeño que construye algo que pretende seguir entendiendo dentro de un año, poseer ese hilo vale más que la configuración que te ahorra.</p>
<p>Esa es la versión completa de la elección, y es una elección, no un veredicto.</p>
<h2 id="la-fábrica-de-una-sola-persona">La fábrica de una sola persona</h2>
<p>La razón por la que esto importa ahora, y no hace cinco años, es que los agentes cambiaron las unidades económicas de construir. Una sola persona con una fábrica que funciona puede sostener más software en marcha en la cabeza de lo que antes podía un equipo pequeño, porque el sistema sostiene las partes que la persona sostenía a mano. El scheduler, la memoria, el bucle de recuperación, la puerta: esos eran el techo de cuánto podía llevar una persona. Muévelos a un sistema y el techo sube.</p>
<p>Esa es la promesa, y quiero ser exacto: no que enviarás un 40% más rápido, ni ninguna cifra que tendría que inventarme. La afirmación es estructural. Cuando producto, código y evidencia siguen conectados en tu máquina, dedicas menos día a ser el tejido conectivo y más a decidir qué debería existir. Construir se abarató. Decidir se encareció. Una fábrica es donde pones la parte barata para poder permitirte hacer bien la cara.</p>
<h2 id="deja-de-ser-el-runtime-a-mano">Deja de ser el runtime a mano</h2>
<p>Aquí está la prueba de si algo de esto ha calado. Piensa en tu última semana dura de enviar con agentes. Cuenta las horas que pasaste sin construir, sin decidir, solo sosteniendo el conjunto: reexplicando contexto que una sesión perdió, buscando por qué se tomó una decisión, reejecutando trabajo porque no podías fiarte de un “hecho”, cargando el plan entre herramientas en tu propia cabeza. Eso eras tú siendo el runtime. No aparece en ningún changelog, y es la mayor parte del trabajo ahora.</p>
<p>Una fábrica no hace desaparecer ese trabajo por arte de magia. Lo convierte en tarea del sistema en vez de tuya. La planificación, la memoria, la recuperación, la puerta —las partes que hacías a mano— se mueven a algo que las sostiene de forma duradera, conectada, en tu máquina. Lo que te queda es la parte que siempre fue tuya: decidir qué debería existir y juzgar si existió. Ese es el intercambio que la categoría está construida para hacer.</p>
<h2 id="para-profundizar">Para profundizar</h2>
<p>La fábrica se entiende mejor una estación cada vez. El argumento de mantener el sistema entero en tu máquina es el <a href="/es/blog/desarrollo-ia-local-first/">desarrollo con IA local-first</a>, y su versión más afilada es por qué <a href="/es/blog/el-codigo-se-queda-en-casa/">tu código se queda en casa</a> aunque los modelos no. Esa postura tiene un hogar nativo en las <a href="/es/blog/herramientas-nativas-macos/">herramientas nativas de macOS</a> sobre las que corre, y trae libertades más pequeñas, como <a href="/es/blog/herramientas-sin-cuenta/">herramientas que no piden cuenta</a>.</p>
<p>En el lado del modelo, una fábrica enruta el trabajo al <a href="/es/blog/tu-propio-modelo/">modelo que tú traigas</a> y te da un sitio para <a href="/es/blog/controlar-costes-de-ia/">controlar los costes de IA</a> en lugar de verlos flotar. La comparación completa con la alternativa está en <a href="/es/blog/nube-vs-local/">nube frente a herramientas locales</a>. Y la razón de que todo esto importe ahora es económica: es lo que hace posible una <a href="/es/blog/fabrica-de-uno/">fábrica de una sola persona</a>. Para el cuadro operativo dentro del que vive la fábrica, empieza por <a href="/es/blog/construir-software-con-agentes-de-ia/">construir software con agentes de IA</a>.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc es la fábrica local de software que estoy construyendo porque este problema es mío antes que de nadie. Funciona en macOS, local-first, gratis hasta tres proyectos, sin cuenta. Conecta discovery, decisiones, especificaciones, agentes, el grafo de código y la evidencia en un sistema en tu máquina, y llama a los modelos que le apuntes. Los datos de producto, los repositorios y la prueba se quedan locales; el <a href="/es/manifiesto/">manifiesto</a> es la versión larga del porqué.</p>
<p>No inventé la fábrica local de software como un marco de marketing y luego busqué un producto que encajara. Construí el producto porque ser el runtime a mano dejó de escalar, y después me di cuenta de que la forma de lo que había construido era una categoría. Este artículo es yo poniéndole nombre claro. Los agentes seguirán mejorando en escribir código. Lo escaso —un sitio donde tu producto, tu código y tu prueba sigan conectados, y ese sitio sea tuyo— es lo que merece la pena construir.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-una-fábrica-local-de-software">¿Qué es una fábrica local de software?</h3>
<p>Una fábrica local de software es un sistema que mantiene producto, código y evidencia conectados en tu propia máquina. Una idea se convierte en decisión, la decisión en especificación, la especificación en trabajo que un agente ejecuta, y el resultado vuelve con la prueba adjunta; todo en un sistema conectado en lugar de disperso entre un chat, un gestor y un repositorio. Local significa que el hilo de la intención a la prueba es tuyo, no alquilado.</p>
<h3 id="es-lo-mismo-una-fábrica-local-de-software-que-una-feature-factory">¿Es lo mismo una fábrica local de software que una feature factory?</h3>
<p>No, es lo contrario. Una feature factory se mide por output enviado y a eso lo llama producto. Una fábrica de software es un sitio con estaciones —descubrir, definir, planificar, construir, verificar, aprender— donde entra material, se trabaja en orden y sale probado. La gracia no es el volumen de features. Es que intención, código y evidencia sigan conectados para que el sistema no derive hacia incoherente mientras los agentes escriben.</p>
<h3 id="necesito-ejecutar-los-modelos-de-ia-en-local">¿Necesito ejecutar los modelos de IA en local?</h3>
<p>No. Local se refiere a dónde vive el estado de tu producto, no a dónde ocurre la inferencia. La fábrica está en tu máquina pero llama a los proveedores de IA que elijas, y la nube hace inferencia mejor de lo que la hará un portátil. Lo que se queda local es todo lo que define el producto: el contrato, el grafo, las decisiones y la prueba. Envías tokens fuera cuando tú decides, sin entregar la fábrica.</p>
<h3 id="una-fábrica-local-de-software-solo-sirve-para-desarrolladores-en-solitario">¿Una fábrica local de software solo sirve para desarrolladores en solitario?</h3>
<p>Importa sobre todo a un fundador en solitario o un equipo pequeño que construye algo que pretende seguir entendiendo dentro de un año, porque poseer el hilo vale más que la configuración que ahorra una nube compartida. Los equipos grandes ganan cosas reales con la nube: estado compartido sin configuración, cómputo pesado como problema de otro, software que se actualiza solo. La elección depende de si poseer la memoria de tu producto pesa más que esa comodidad.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="fabrica-local-de-software"/><category term="local-first"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="grafo-de-producto"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Una fábrica de una sola persona: software serio como fundador en solitario</title>
    <link href="https://paelladoc.com/es/blog/fabrica-de-uno/" rel="alternate" type="text/html" title="Una fábrica de una sola persona: software serio como fundador en solitario"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/fabrica-de-uno/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/fabrica-de-uno/"><![CDATA[<p>Construyo PaellaDoc solo, con agentes. No como eslogan. Como la forma real del trabajo cada día. <a href="/es/blog/orquestacion-multiagente/">Varias sesiones corriendo a la vez</a>, cada una en su rama, mientras me muevo entre ellas decidiendo qué merece quedarse.</p>
<p>Durante casi todo el tiempo que llevo construyendo software, un fundador en solitario tenía un techo duro. Podías publicar, pero no al throughput de un equipo. Había un número limitado de horas y un solo par de manos. Ese techo casi ha desaparecido. Los agentes escriben el código, y lo escriben rápido. Construir ya no es lo que me limita.</p>
<p>Otra cosa ocupó su sitio, y es más difícil de ver porque no parece un cuello de botella. Parece estar ocupado. Esto es de verdad una fábrica de una persona, y dónde está su muro real.</p>
<h2 id="los-roles-que-un-equipo-reparte-tú-los-sostienes-a-la-vez">Los roles que un equipo reparte, tú los sostienes a la vez</h2>
<p>Un equipo divide el trabajo para que ninguna persona cargue el contrato entero en la cabeza. Alguien lleva producto. Alguien lleva el código. Alguien revisa. Alguien recuerda por qué se tomó una decisión en marzo. Los handoffs entre ellos son molestos, pero también son la manera de que el trabajo siga coherente mientras muchas manos lo tocan.</p>
<p>Un fundador en solitario con agentes tiene todo ese throughput y ninguna de esa división. Soy el product manager que decidió qué construimos. Soy el ingeniero que tiene que entender lo que volvió. Soy el revisor, la única persona entre un diff con buena pinta y la rama principal. Soy la memoria de por qué existe esto. Los agentes multiplicaron mi output. No dividieron mis roles. Cada uno de ellos sigue cayendo en una sola persona.</p>
<figure class="tp-diagram tp-diagram--graph" data-diagram-type="graph" role="img" aria-label="Un equipo reparte esto entre personas. En solitario, cada rol corre sobre una sola persona, y esa es la parte que los agentes no multiplican."><svg viewBox="0 0 760 320" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="380" y1="160" x2="140" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="140" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="140" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">PRODUCTO</text><line x1="380" y1="160" x2="620" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="620" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="620" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">INGENIERÍA</text><line x1="380" y1="160" x2="96" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="96" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="96" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">REVISIÓN</text><line x1="380" y1="160" x2="664" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="664" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="664" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">MEMORIA</text><line x1="380" y1="160" x2="380" y2="40" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="380" cy="40" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="380" y="66" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">RECUPERACIÓN</text><line x1="380" y1="160" x2="380" y2="286" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="380" cy="286" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="380" y="312" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">PUERTA</text><circle cx="380" cy="160" r="14" fill="var(--tp-mostaza)" fill-opacity="0.16" stroke="var(--tp-mostaza)" stroke-width="1.8"></circle>
  <text x="380" y="194" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">TÚ</text></svg><figcaption>Un equipo reparte esto entre personas. En solitario, cada rol corre sobre una sola persona, y esa es la parte que los agentes no multiplican.</figcaption></figure>
<p>Ese es el trato que nadie menciona cuando dicen que una persona puede hacer ya el trabajo de un equipo. Puedes producir como un equipo. Sigues decidiendo como un individuo, y decidir no se paraleliza como construir.</p>
<h2 id="el-cuello-de-botella-se-movió-de-tus-manos-a-tu-atención">El cuello de botella se movió de tus manos a tu atención</h2>
<p>Aquí está el cambio, dicho claro. El recurso escaso solía ser lo rápido que podías producir trabajo. Ahora es lo rápido que puedes absorberlo.</p>
<p>Ocho agentes generan más código en una tarde del que yo puedo leer con cuidado en un día. Eso, por sí solo, no es una victoria de productividad. El output sin revisar no es progreso, es riesgo con un buen mensaje de commit. En cuanto los agentes se volvieron rápidos, mi atención pasó a ser la restricción, y la atención es lo único de lo que no puedo comprar más ni levantar otra instancia.</p>
<p>Esto es lo que quiero decir cuando digo que <a href="/es/blog/eres-el-runtime/">tú eres el runtime</a>. Soy el scheduler que decide qué sesión corre después. Soy la memoria que lleva el contexto entre ellas porque no lo comparten. Soy el bucle de recuperación cuando un run muere a las 2 de la mañana. Soy la puerta que dice esto está hecho y esto no. Un equipo reparte esos trabajos entre personas y sistemas. En solitario corren todos sobre mí, y cuando me aparto, se paran. La <a href="/es/blog/fabrica-local-de-software/">fábrica local de software</a> tiene una sola CPU y es mi cabeza.</p>
<h2 id="dónde-se-rompe-de-verdad-una-fábrica-de-una-persona">Dónde se rompe de verdad una fábrica de una persona</h2>
<p>No se rompe por volumen. Se rompe por las cosas que una persona no puede sostener.</p>
<p>Pérdida de contexto. Termino una sesión, duermo, vuelvo, y el hilo está más fino de lo que estaba. Multiplica eso por el trabajo paralelo y estoy reconstruyendo para qué era cada rama antes de poder juzgarla. Deriva. Dos agentes, trabajando de la misma idea en sus sesiones, divergen sin avisar, y solo lo descubro cuando su trabajo tiene que juntarse. Fatiga de revisión. Cuando eres el único revisor, el décimo diff del día recibe menos escrutinio que el primero, y es justo entonces cuando algo se cuela.</p>
<p>Nada de esto es un problema de throughput. Añadir un modelo más rápido no los toca. Todos son la misma cosa de fondo: la memoria de coordinación que un equipo guarda entre sus miembros, un fundador en solitario la tiene que guardar solo, en una cabeza, sobre más trabajo paralelo del que una cabeza está hecha para seguir. Ese es el muro. No “puedo construirlo”. Si puedo seguir coherente mientras se construye.</p>
<h2 id="qué-necesita-de-verdad-una-fábrica-de-una-persona">Qué necesita de verdad una fábrica de una persona</h2>
<p>Si la restricción es mi atención y mi memoria, entonces la palanca no es otro agente. Es un sistema que sostiene la parte del trabajo que yo no puedo.</p>
<p>La capa duradera tiene que vivir fuera de mí. El contrato de producto, para no ser la única copia de lo que acordamos construir. Las decisiones y sus razones, para que el yo de marzo responda por una elección que el yo de agosto olvidó. El grafo de conocimiento del código, para ver la forma de lo que construyeron los agentes sin leer cada línea. La evidencia de que una tarea pasó de verdad, para no re-revisarla por desconfianza. Cuando eso vive en el sistema y no en mi cabeza, el trabajo paralelo deja de depender de que yo esté despierto y me acuerde de todo.</p>
<p>Esa es la diferencia entre un fundador en solitario que escala y uno que se convierte en el punto único de fallo de su propia empresa. No más agentes. Un sitio donde viva la memoria de coordinación que no sea una persona cansada. Los agentes te dan el output de un equipo. Algo tiene que darte la memoria de un equipo, o el output adelanta a tu capacidad de mantenerlo coherente y todo se convierte, en silencio, en un castillo de naipes construido rápido.</p>
<h2 id="el-muro-que-no-voy-a-esconder">El muro que no voy a esconder</h2>
<p>Una fábrica de una persona tiene un muro real, y estaría vendiendo humo si fingiera lo contrario.</p>
<p>El juicio no se paraleliza. Los agentes no pueden decidir qué merece construirse, si lo que volvió es de verdad bueno, o cuándo tirar una semana de trabajo porque la idea de debajo estaba mal. Eso se queda conmigo, y hay una cantidad finita de eso al día. Parte es criterio, parte es contexto que ningún modelo tiene, parte es solo el peso de ser responsable de una decisión. La velocidad no lo extiende. Los días que intento pasar de ese límite, la calidad de mis decisiones cae mucho antes que mi capacidad de generar más código.</p>
<p>Así que la respuesta de verdad es que un fundador en solitario puede operar ya como un equipo en todo menos en lo que más importaba desde el principio. Puedes construir como diez personas. Sigues teniendo que decidir como una. Todo el juego es ordenar el trabajo para que el juicio escaso caiga solo donde de verdad hace falta, y todo lo demás corra sin él.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Este es el problema que construyo PaellaDoc para resolver, porque es el mío. Mantiene la memoria de la fábrica fuera de mi cabeza: el contrato de producto, las decisiones, el grafo del código y la evidencia viven en un solo sistema local, conectados, para que el trabajo paralelo no dependa de que yo lo sostenga todo. Los agentes corren aislados en sus ramas. Lo que producen se cierra solo cuando la evidencia lo dice, que es lo que me deja dejar de re-revisar por miedo.</p>
<p>No toma el juicio por mí. No me fiaría si dijera que sí. Hace algo más estrecho y más útil: sostiene todo lo que rodea al juicio, para que lo escaso que aporto se gaste en las decisiones que me necesitan y en nada más.</p>
<p>Si estás <a href="/es/blog/construir-software-con-agentes-de-ia/">construyendo software con agentes</a> solo, pregúntate dónde vive de verdad la memoria de tu producto. Si la respuesta de verdad es “en mi cabeza”, ese es el muro con el que vas a chocar, y está más cerca que el del throughput.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="puede-un-fundador-en-solitario-sacar-software-serio-con-agentes-de-ia">¿Puede un fundador en solitario sacar software serio con agentes de IA?</h3>
<p>Sí, y el viejo techo casi ha desaparecido: los agentes escriben el código rápido, así que construir ya no es lo que te limita. Lo que lo sustituye es más difícil de ver. Una persona sostiene ahora cada rol que un equipo reparte —producto, ingeniería, revisión, memoria, recuperación, la puerta de calidad— porque los agentes multiplican tu output sin dividir tus roles. Puedes producir como un equipo, pero sigues decidiendo como un individuo.</p>
<h3 id="cuál-es-el-límite-real-de-un-desarrollador-en-solitario-con-agentes-de-ia">¿Cuál es el límite real de un desarrollador en solitario con agentes de IA?</h3>
<p>La atención, no el throughput. Ocho agentes generan más código en una tarde del que una persona puede leer con cuidado en un día, y el output sin revisar es riesgo con un buen mensaje de commit, no progreso. El muro es la coherencia: pérdida de contexto entre sesiones, deriva entre ramas paralelas y fatiga de revisión, donde el décimo diff recibe menos escrutinio que el primero. El juicio no se paraleliza, y hay una cantidad finita al día.</p>
<h3 id="qué-es-una-fábrica-de-una-sola-persona">¿Qué es una fábrica de una sola persona?</h3>
<p>Una fábrica de una persona es alguien que opera como un equipo corriendo varias sesiones de agentes a la vez, cada una en su rama, mientras sostiene solo el calendario, las decisiones y la puerta de calidad. Funciona cuando la memoria de coordinación —el contrato de producto, las decisiones, el grafo del código y la evidencia— vive fuera de tu cabeza en un sistema conectado. Si no, te conviertes en el punto único de fallo de tu propia empresa, con una cabeza cansada como CPU.</p>
<h3 id="los-agentes-de-ia-pueden-sustituir-a-un-equipo-de-desarrollo-para-un-fundador-en-solitario">¿Los agentes de IA pueden sustituir a un equipo de desarrollo para un fundador en solitario?</h3>
<p>Sustituyen el throughput, no el juicio. Los agentes no pueden decidir qué merece construirse, si lo que volvió es bueno, o cuándo tirar una semana porque la idea de debajo estaba mal. Eso se queda contigo. Lo que de verdad necesita un fundador en solitario no es más agentes sino un sitio donde viva la memoria de un equipo, para que el trabajo paralelo no dependa de que estés despierto y te acuerdes de todo.</p>]]></content>
    <summary type="html"><![CDATA[Construyo PaellaDoc solo, con agentes. No como eslogan, sino como la forma real del día a día: varias sesiones corriendo a la vez, cada una en su rama, mientras me muevo entre ellas. El viejo límite de un fundador en solitario era el throughput. Podías construir, pero no al ritmo de un equipo. Ese límite casi ha desaparecido. El que lo sustituyó es más difícil de ver e imposible de contratar: soy el único scheduler, la única memoria y la única puerta de calidad que tiene todo esto. Así es de verdad una fábrica de una persona, y dónde está su muro.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="paelladoc"/><category term="fundador-solitario"/><category term="agentes-ia"/><category term="empresa-de-una-persona"/><category term="local-first"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">«Los tests pasan»: anatomía de un éxito falso</title>
    <link href="https://paelladoc.com/es/blog/exitos-falsos-de-agentes/" rel="alternate" type="text/html" title="«Los tests pasan»: anatomía de un éxito falso"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/exitos-falsos-de-agentes/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/exitos-falsos-de-agentes/"><![CDATA[<p>Le das una tarea a un agente. Escribe el código, recorre el plan y termina con una línea limpia: «Todos los tests pasan, la feature funciona como se esperaba». Compruebas. No se ejecutó ningún test. La suite nunca se invocó. La afirmación era pura ficción, entregada con total seguridad.</p>
<p>El primer instinto es sentirse engañado, como si la máquina te hubiera mentido a la cara. Ese instinto conviene resistirlo, no porque la afirmación no sea un problema sino porque el diagnóstico equivocado lleva al arreglo equivocado. Esto no es engaño. Es la herramienta comportándose exactamente como se construyó. En cuanto ves el mecanismo, el éxito falso deja de ser una traición y pasa a ser algo alrededor de lo que puedes diseñar.</p>
<h2 id="qué-está-haciendo-el-modelo-en-realidad">Qué está haciendo el modelo en realidad</h2>
<p>Un modelo de lenguaje genera texto prediciendo la continuación más probable de lo anterior. Ese es todo el trabajo. Se le da muy bien, y esa competencia es justo lo que produce la afirmación falsa.</p>
<p>Plantea la situación. El contexto contiene una tarea que pedía código funcionando con tests en verde. Contiene una implementación que ahora parece terminada. ¿Qué es lo más probable que aparezca a continuación en un transcript así? En casi todo el texto que ha visto un modelo, una implementación con aspecto de terminada va seguida de un informe de que funciona. «Los tests pasan». «Feature completa». «Todo funciona». Así que eso es lo que el modelo escribe, porque eso es lo que suele venir después.</p>
<p>Fíjate en lo que falta en ese proceso: cualquier conexión con si un test se ejecutó de verdad. El modelo no consulta un registro de ejecuciones. No hay ejecución que consultar salvo que algo en el harness haya corrido de verdad la suite y devuelto el resultado al contexto. La frase se genera a partir de la forma de la situación, no se observa de la realidad. Es la frase probable, y la frase probable y la verdadera solo coinciden cuando la verdad resulta ser probable.</p>
<h2 id="ni-miente-ni-es-tonto">Ni miente ni es tonto</h2>
<p>«Mentir» implica que el modelo conoce la verdad y afirma lo contrario. No la conoce. No hay un libro de cuentas interno de ejecuciones de tests que esté eligiendo tergiversar. Solo hay la predicción del siguiente token, y la predicción es «éxito» porque así es como suelen acabar estas historias.</p>
<p>«Tonto» es igual de erróneo, y más peligroso, porque te hace infravalorar la herramienta en todo lo demás. El mismo mecanismo que fabrica «los tests pasan» escribe código genuinamente excelente el resto del tiempo. No está fallando. Hace exactamente una cosa (producir texto probable) sin ninguna noción incorporada de anclar ese texto a un evento real. La competencia y la afirmación falsa salen del mismo sitio.</p>
<p>Por eso el éxito falso es tan convincente. No es un bug con pinta de bug. Es prosa fluida, bien formateada y apropiada al contexto que da la casualidad de que describe un evento que nunca ocurrió. Se lee exactamente como un informe verdadero porque, mecánicamente, un informe verdadero y uno falso se producen igual.</p>
<h2 id="por-qué-es-peligroso-justo-por-ser-plausible">Por qué es peligroso justo por ser plausible</h2>
<p>Un crash lo ves. Un stack trace se anuncia solo. El éxito falso no anuncia nada. Parece el buen resultado. Llega con las mismas palabras que usaría un verde real, así que nada en su superficie lo marca para una segunda mirada.</p>
<p>Es el hueco entre superficie y comportamiento que recorre toda la <a href="/es/blog/verificar-codigo-generado-por-ia/">verificación de código generado por IA</a>: una sensación te dice que el output parece correcto, la evidencia te dice qué hizo en realidad, y el éxito falso es una sensación disfrazada de evidencia. Es la razón de que <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no sea una feature correcta</a>, y la razón de que un cambio con aspecto plausible pueda ser <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto y globalmente incoherente</a> a la vez. La plausibilidad es exactamente la propiedad que cuela código ante un revisor cansado. Cuanto más capaz el modelo, más plausible la afirmación falsa, lo que significa que este problema no encoge según mejoran los modelos. Crece.</p>
<h2 id="dónde-se-compone">Dónde se compone</h2>
<p>Una sola afirmación falsa es un problema contenido. La atrapas, re-ejecutas y sigues. Lo que lo hace peligroso a escala es que las afirmaciones se encadenan.</p>
<p>Dale a un agente una tarea de varios pasos y cada paso termina con un pequeño informe de éxito sobre el que se apoya el siguiente. El paso tres asume que el paso dos funcionó porque el paso dos lo dijo. Si la afirmación del paso dos se generó en vez de observarse, todo lo que viene después está de pie sobre un suelo que nunca estuvo ahí, y el «todo hecho» final informa con seguridad del éxito de una estructura con un agujero en medio. Nadie mintió en ningún momento. Cada paso solo produjo su final probable, y los finales probables se compusieron en una historia que nunca ocurrió.</p>
<p>Las sesiones en paralelo lo empeoran. Cuando ocho agentes informan cada uno de «hecho» a través de una docena de tareas, es físicamente imposible re-verificar cada afirmación a mano, así que empiezas a fiarte de los informes, que es justo el comportamiento que la afirmación falsa explota. El éxito falso no es un fallo raro con el que tropezarás de vez en cuando. Es una tasa de fondo constante, y cualquier flujo que se fía de la compleción auto-declarada está integrando en silencio esa tasa en todo lo que publica. Así es como una base de código acaba localmente correcta y globalmente incoherente: no por un fallo dramático, sino por una acumulación lenta de éxitos que solo fueron frases.</p>
<h2 id="diseñar-alrededor-en-vez-de-discutir-con-ello">Diseñar alrededor en vez de discutir con ello</h2>
<p>Si la afirmación falsa es estructural, ninguna cantidad de instrucción la arregla. Puedes añadir «no digas que los tests pasan salvo que los hayas ejecutado de verdad» a cada prompt y seguir recibiendo la afirmación falsa, porque el modelo no tiene forma fiable de introspeccionar si ejecutó algo. Le estás pidiendo que ancle una frase a un hecho al que no tiene acceso.</p>
<p>El arreglo vive fuera del modelo. El principio es simple: la parte que hace el trabajo no debería ser la parte que lo certifica. En concreto, eso significa que la ejecución tiene que ocurrir en el harness, no en la narración. Algo distinto del agente invoca los tests, captura la salida y el código de salida reales, y pone ese resultado donde se decide la compleción. El agente aún puede escribir «los tests pasan». Solo que deja de ser lo que decide si esa frase es verdad.</p>
<p>Ese es el paso de un éxito auto-declarado a uno observado, y es la columna de <a href="/es/blog/hecho-significa-hecho/">hacer que hecho signifique hecho</a>: la compleción cuesta una demostración, y la demostración la produce un paso que el agente no puede sortear narrando. También es por qué la respuesta duradera es cerrar cada tarea con <a href="/es/blog/desarrollo-basado-en-evidencia/">su evidencia adjunta</a>, para que «los tests pasan» nunca sea una frase que tengas que aceptar por fe.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/">PaellaDoc</a> trata el éxito auto-declarado como algo a ignorar por estructura. La frase del agente no es evidencia. La compleción se decide ejecutando el contrato de aceptación contra el resultado real y capturando lo que corrió de verdad, junto al cambio. La afirmación falsa aún se puede generar. Solo que no tiene dónde aterrizar, porque lo que concede «hecho» es una ejecución real, no una frase probable.</p>
<p>Deja de leer el éxito falso como una traición. Es la frase más probable, producida por una máquina que produce frases probables. Diseña para eso, y deja de poder hacerte daño.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-un-agente-dice-que-los-tests-pasan-cuando-no-ejecutó-nada">¿Por qué un agente dice que los tests pasan cuando no ejecutó nada?</h3>
<p>Un modelo de lenguaje genera la continuación más probable de su contexto. Tras una implementación con aspecto terminado, la frase probable es un informe de éxito, porque así acaba casi todo transcript que ha visto. La afirmación se genera desde la forma de la situación, no se observa de una ejecución real. Salvo que el harness haya corrido de verdad la suite y devuelto el resultado, no hay ejecución que el modelo pueda consultar.</p>
<h3 id="está-mintiendo-el-agente-cuando-dice-que-los-tests-pasaron">¿Está mintiendo el agente cuando dice que los tests pasaron?</h3>
<p>No. Mentir exige conocer la verdad y afirmar lo contrario. El modelo no tiene un registro interno de ejecuciones que esté eligiendo tergiversar, solo una predicción del siguiente token que cae en «éxito» porque así suelen acabar estas historias. Llamarlo tonto es peor, porque el mismo mecanismo escribe código excelente el resto del tiempo. Es un solo comportamiento, producir texto probable, sin vínculo incorporado a un evento real.</p>
<h3 id="cómo-evito-que-un-agente-falsee-los-resultados-de-los-tests">¿Cómo evito que un agente falsee los resultados de los tests?</h3>
<p>No lo consigues por prompt, porque el modelo no tiene forma fiable de introspeccionar si ejecutó algo. El arreglo vive fuera del modelo: la parte que hace el trabajo no debería certificarlo. Haz que el harness invoque los tests, capture la salida y el código de salida reales, y use eso para decidir la compleción. El agente aún puede escribir «los tests pasan», solo que deja de decidir si es verdad.</p>
<h3 id="los-modelos-más-capaces-cometen-menos-éxitos-falsos">¿Los modelos más capaces cometen menos éxitos falsos?</h3>
<p>No, al contrario. Cuanto más capaz el modelo, más plausible su prosa, y la plausibilidad es justo la propiedad que cuela una afirmación falsa ante un revisor cansado. Un éxito falso se lee idéntico a un informe verdadero porque mecánicamente se producen igual. El problema no encoge según mejoran los modelos, crece, y por eso la respuesta duradera es una ejecución real, no un prompt mejor.</p>]]></content>
    <summary type="html"><![CDATA[Un agente informa «todos los tests pasan» y no se ejecutó nada. No es engaño y no es incompetencia. Un modelo de lenguaje completa la frase más probable para la situación, y tras una implementación terminada esa frase informa de éxito. Entiende el mecanismo y dejas de sorprenderte y empiezas a diseñar alrededor.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="false-success"/><category term="ai-coding"/><category term="verificacion"/><category term="comportamiento-llm"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Especificaciones vivas: specs que se actualizan con el código</title>
    <link href="https://paelladoc.com/es/blog/especificaciones-vivas/" rel="alternate" type="text/html" title="Especificaciones vivas: specs que se actualizan con el código"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/especificaciones-vivas/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/especificaciones-vivas/"><![CDATA[<p>La mayoría de las specs nacen muertas. Escribes una al empezar una feature, es exacta durante más o menos un día, y a partir del segundo commit deja de describir poco a poco lo que estás construyendo. Cuando la feature se publica, la spec es un documento histórico sobre un plan que abandonaste.</p>
<p>Una especificación viva es la apuesta contraria. Es una spec diseñada para cambiar cuando cambia el código, de modo que en cualquier momento siga describiendo el producto que existe de verdad. Esa única propiedad es la que separa un contrato en el que puedes confiar de un archivo que aprendes a ignorar.</p>
<h2 id="las-specs-estáticas-no-están-mal-están-congeladas">Las specs estáticas no están mal, están congeladas</h2>
<p>La generación actual de herramientas spec-driven es buena consiguiendo que se escriba una spec. <a href="https://github.com/github/spec-kit">Spec Kit</a>, por ejemplo, te da un flujo limpio de propuesta a spec, a plan, a tareas. Esos archivos hacen legible un cambio antes de que nadie construya, algo genuinamente valioso y justo donde el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a> se gana su fama.</p>
<p>La limitación no está en el formato. Está en el ciclo de vida. Una spec producida así se escribe una vez, al principio del trabajo, y luego el trabajo sigue sin ella. Nada lleva la spec hacia delante a medida que cambia el código. Es un artefacto estático: correcto en t=0, degradándose desde t=1.</p>
<p>Esto no es una crítica a escribir specs por adelantado. Escribir el contrato antes de construir es justo la idea. El problema es tratar «escrita» como «terminada». Un contrato que nunca se actualiza se convierte en la fuente del <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">spec drift</a>: el código y la spec contando dos historias distintas, las dos con aire de autoridad, una de ellas mintiendo.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="La diferencia es el ciclo de vida, no la redacción: una spec estática se congela en t=0, una viva se mueve con el código."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">Spec estática</p>
    <ul><li>Se escribe una vez</li><li>En una carpeta</li><li>Se degrada en t=1</li><li>Se lee como rancia</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">Spec viva</p>
    <ul><li>Cambia con el código</li><li>Anclada al código</li><li>Avisa si envejece</li><li>Sigue siendo contrato</li></ul>
  </div>
</div><figcaption>La diferencia es el ciclo de vida, no la redacción: una spec estática se congela en t=0, una viva se mueve con el código.</figcaption></figure>
<h2 id="qué-significa-viva-en-concreto">Qué significa «viva», en concreto</h2>
<p>«Viva» es una palabra fácil de agitar, así que aquí va la prueba concreta. Una spec está viva si un cambio en el código puede actualizarla sin que una persona se acuerde de hacerlo como tarea aparte, y si un cambio en la spec tiene un camino definido hacia el código. La información fluye en las dos direcciones. El documento no está aguas arriba del trabajo; es parte del bucle.</p>
<p>Eso se descompone en tres propiedades.</p>
<h3 id="está-anclada-no-al-lado">Está anclada, no al lado</h3>
<p>Una spec estática vive en una carpeta junto al código. Una spec viva está conectada al código: a los archivos, componentes y tests que la implementan. Cuando puedes trazar una afirmación de la spec al código que la satisface, puedes detectar el momento en que divergen. Una spec flotando en un directorio <code>docs/</code> no tiene ese ancla, y por eso deriva sin que nadie lo note. Es la misma razón por la que una <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">especificación portable</a> tiene que llevar sus vínculos al código y a la evidencia, no solo su prosa.</p>
<h3 id="se-actualiza-como-subproducto-del-trabajo">Se actualiza como subproducto del trabajo</h3>
<p>Las specs se pudren porque actualizarlas es una tarea aparte, y las tareas aparte pierden contra las fechas límite siempre. Una spec viva se actualiza como efecto secundario del trabajo que ya está pasando: cerrar una tarea, aterrizar un cambio, registrar una decisión. Si mantener el contrato al día exige una segunda pasada disciplinada para la que nadie tiene tiempo, no se mantendrá al día. Este es el principio operativo detrás de la <a href="/es/blog/documentacion-viva/">documentación viva</a> en general.</p>
<h3 id="sabe-cuándo-está-rancia">Sabe cuándo está rancia</h3>
<p>Una spec viva no tiene por qué ser mágicamente siempre correcta. Tiene que poder decirte cuándo podría estar equivocada. Una spec conectada al código y a <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación que se pueden reejecutar</a> puede avisar del momento en que la realidad diverge del contrato, en vez de presentar en silencio un verde antiguo como verdad actual.</p>
<h2 id="por-qué-importa-más-con-agentes">Por qué importa más con agentes</h2>
<p>Cuando una sola persona escribía todo el código, la spec y el modelo mental derivaban juntos a la misma velocidad, y la persona podía reconciliarlos de memoria. Esa red de seguridad ya no está.</p>
<p>Un agente no guarda tu memoria del contrato entre ejecuciones. <a href="/es/blog/perdida-de-contexto-entre-sesiones/">El contexto se pierde entre sesiones</a> salvo que algo fuera del chat lo sostenga. Lanza varios agentes en paralelo y cada uno edita contra el contexto que le diste, no contra un contrato compartido y actual. Una spec estática no puede servir como ese contrato compartido, porque para la tercera ejecución ya no coincide con el código. Una spec viva sí, porque se movió junto a las dos primeras.</p>
<p>Dicho de otro modo: cuanto más rápido se escribe el código, más corta es la vida útil de una spec congelada. Los agentes no convirtieron las specs vivas en un lujo opcional. Hicieron que las estáticas caduquen antes.</p>
<h2 id="una-spec-viva-no-es-más-documentación">Una spec viva no es más documentación</h2>
<p>El instinto, al oír todo esto, es escribir más. Specs más grandes, más detalle, más secciones que mantener al día. Es la dirección equivocada, y es como el desarrollo guiado por especificaciones acaba con fama de <a href="/es/blog/spec-driven-ligero/">aplastar con su sobrecarga</a>.</p>
<p>Una spec viva suele ser más pequeña que una estática, no mayor. Guarda las partes que tienen que sobrevivir al contacto con el código —intención, límites, criterios de aceptación, las decisiones detrás del diseño— y delega el resto en el código y los tests, que ya son la descripción más actual del comportamiento que tienes. La meta no es un documento que lo describa todo. Es un contrato lo bastante pequeño para mantenerlo vivo y lo bastante conectado para seguir diciendo la verdad.</p>
<p>Si te encuentras manteniendo una spec que duplica lo que el código ya dice, no estás manteniendo una spec viva. Estás manteniendo una segunda copia de la verdad que derivará de la primera.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Una spec viva necesita un sitio donde vivir que esté conectado al producto y al código, no una carpeta que se queda rancia. Esa conexión es lo que PaellaDoc está construido para sostener: un modelo local donde la spec está anclada al repositorio, a las tareas y a la evidencia de cada ejecución, de modo que un cambio en el código tiene dónde actualizar el contrato y un cambio en el contrato tiene un camino hacia el trabajo. La spec deja de ser un documento que archivas y pasa a ser parte del sistema que se mantiene al día porque el trabajo la mantiene al día.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿En qué se diferencia una spec viva de una buena documentación?</strong> La documentación describe cómo funciona algo para quien lo lee. Una spec viva es un contrato que define qué tiene que ser cierto y sigue conectado al código que lo demuestra. La buena documentación viva y las specs vivas comparten el mismo enemigo, la ranciedad, pero una spec lleva criterios de aceptación y límites, no solo explicación.</p>
<p><strong>¿Las specs vivas sustituyen a los tests?</strong> No. Los tests verifican comportamiento; una spec viva lleva la intención, los límites y las decisiones que los tests no pueden expresar. Las dos se refuerzan. Los criterios de aceptación de la spec son contra lo que comprueban los tests, y así la spec sabe cuándo se ha quedado rancia.</p>
<p><strong>¿Puedo convertir mis specs estáticas actuales en vivas?</strong> En parte. Puedes conectarlas al código, recortarlas a lo que tiene que seguir al día y enrutar las actualizaciones a través del trabajo en vez de una tarea aparte. Lo que no puedes hacer es volver viva una spec escribiendo más de ella. Vivir es cuestión del ciclo de vida, no de la longitud.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="especificaciones-vivas"/><category term="desarrollo-guiado-por-especificaciones"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="spec-drift"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Has publicado código que no sabes leer. ¿Y ahora qué?</title>
    <link href="https://paelladoc.com/es/blog/entender-codigo-generado-por-ia/" rel="alternate" type="text/html" title="Has publicado código que no sabes leer. ¿Y ahora qué?"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/entender-codigo-generado-por-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/entender-codigo-generado-por-ia/"><![CDATA[<p>Hay una frase que mucha gente piensa y muy poca dice en voz alta: no entiendo el código que escribí. La app funciona, la usa gente real, la construiste tú, y si abres cualquier archivo no puedes decir con seguridad qué hace ni por qué. Cada cambio es una apuesta. Cada bug es una excavación. Estás ejecutando un software que no entiendes, y eres tú todo el equipo de soporte.</p>
<p>Este es uno de los estados más comunes y menos hablados del software moderno. No es un defecto personal y no es permanente. Pero la salida no es la obvia, y la obvia te va a ahogar.</p>
<h2 id="el-plan-obvio-que-fracasa">El plan obvio que fracasa</h2>
<p>El instinto es: siéntate y léetelo entero hasta entenderlo. Línea a línea, archivo a archivo, hasta que encaje.</p>
<p>Esto fracasa por una razón concreta. El código generado por IA suele ser localmente razonable y globalmente disperso. Hay mucho, está repartido y fino, y leerlo de arriba abajo te da miles de detalles y ninguna estructura. Terminas más cansado y no más claro, porque entender software no es haber leído las líneas. Es conocer la forma: cuáles son las partes reales, cómo se conectan, dónde vive el comportamiento importante. Eso es una cosa distinta del texto, y leer el texto no te la entrega.</p>
<p>El segundo instinto que fracasa es reescribirlo, para al menos entender la versión nueva. Eso cambia una app que funciona y no entiendes por una app rota que sí entiendes, y reconstruye los mismos huecos por el camino. Casi nunca es la respuesta.</p>
<h2 id="qué-significa-entender-de-verdad">Qué significa entender de verdad</h2>
<p>No necesitas conocer cada línea. Ningún ingeniero en activo conoce cada línea de un sistema del que es responsable. Lo que tiene es un mapa a la altura correcta, y la capacidad de hacer zoom cuando hace falta.</p>
<p>En concreto, tener el control de tu app significa que puedes responder, sin leer código:</p>
<ul>
<li>¿Cuáles son las cuatro o cinco piezas reales de esta app, y para qué sirve cada una?</li>
<li>Cuando un usuario hace lo principal, ¿qué pasa, en orden, a través de esas piezas?</li>
<li>¿Dónde vive el dato, y qué forma tiene?</li>
<li>Si cambio esto, ¿qué más podría notarlo?</li>
</ul>
<p>Ese es el objetivo. No fluidez en cada archivo. Un modelo navegable del conjunto, con el detalle disponible cuando lo necesitas y fuera de tu camino cuando no.</p>
<h2 id="cómo-construir-el-mapa">Cómo construir el mapa</h2>
<p>Puedes hacer una versión de esto a mano hoy. Es lento, pero funciona, y vale la pena hacerlo al menos una vez para saber qué debe contener el mapa.</p>
<p><strong>Empieza por fuera, no por el código.</strong> Lista lo que hace la app desde el punto de vista de un usuario. Las features, los flujos, los roles. Esta es la columna de la que colgarás todo lo demás.</p>
<p><strong>Traza un flujo de principio a fin.</strong> Elige la única cosa más importante que hace un usuario. Síguela desde la pantalla hasta donde acaba el dato, nombrando cada parte por la que pasa. No leas nada que no tengas que leer. Estás dibujando la ruta, no inspeccionando el terreno.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="Trazar un flujo de principio a fin: la forma más rápida de convertir código opaco en un mapa que puedes navegar."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">PANTALLA</text><path d="M 190 95 L 212 95 M 206 89 L 212 95 L 206 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">COMPONENTE</text><path d="M 368 95 L 390 95 M 384 89 L 390 95 L 384 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="62" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">LÓGICA</text><path d="M 546 95 L 568 95 M 562 89 L 568 95 L 562 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="62" width="144" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="646" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">DATO</text></svg><figcaption>Trazar un flujo de principio a fin: la forma más rápida de convertir código opaco en un mapa que puedes navegar.</figcaption></figure>
<p><strong>Nombra las partes reales.</strong> Al final de un par de trazas, las mismas pocas piezas se repiten. Esas son tus partes reales. Escríbelas con una frase cada una. La mayoría de las apps tienen sorprendentemente pocas.</p>
<p><strong>Pídele al agente que lo explique, y luego verifica.</strong> Puedes hacer que un modelo resuma un archivo o un flujo. Esto es genuinamente útil y genuinamente peligroso, porque un resumen plausible de código que hace otra cosa es peor que ningún resumen. Trata cada explicación como una afirmación que hay que comprobar contra el comportamiento, no como un hecho. Aquí aplica la misma disciplina de que un <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">build en verde no es prueba</a>: una explicación que suena bien no es lo mismo que una que está bien.</p>
<p>Cuando puedas bosquejar las partes y trazar el flujo principal de memoria, has pasado de pasajero a conductor. Sigues sin poder leer cada línea. Ya no lo necesitas.</p>
<h2 id="escríbelo-antes-de-que-se-te-olvide-otra-vez">Escríbelo antes de que se te olvide otra vez</h2>
<p>La parte cruel de este estado es que ya estuviste en él una vez, al principio, y se desvaneció. La comprensión que construyas ahora también se desvanecerá, a menos que viva en algún sitio fuera de tu cabeza. Así que mientras construyes el mapa, escríbelo: las partes, los flujos, para qué sirve cada uno. Este es el comienzo de la documentación que el prototipo nunca tuvo, y es lo que evita que aterrices otra vez aquí dentro de dos meses. Un mapa que solo vive en la memoria es un mapa que perderás, y por eso acaba queriendo convertirse en <a href="/es/blog/mapas-de-codigo-para-agentes/">un mapa vivo del código, no prompts más largos</a> que reescribes en cada sesión.</p>
<h2 id="esto-es-la-etapa-uno-de-un-puente-más-largo">Esto es la etapa uno de un puente más largo</h2>
<p>Volverse legible no es todo el trabajo, es su primera etapa. Una vez que puedes navegar la app, los movimientos siguientes son escribir qué se supone que hace, poner una red de seguridad bajo el comportamiento actual y reforzar la estructura, en ese orden. Entender es lo que hace posibles los tres: no puedes especificar, probar ni arreglar lo que no encuentras. La ruta completa desde aquí está en <a href="/es/blog/vibe-coding-a-produccion/">de vibe coding a producción</a>.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>El mapa manual funciona una vez. El problema es que el código sigue cambiando y el mapa de tu cabeza se queda obsoleto de inmediato, que es como llegaste aquí. PaellaDoc lee un repo existente y lo convierte en un modelo navegable de sus partes y flujos reales, y mantiene ese modelo pegado al código a medida que cambia, para que el mapa siga siendo cierto en vez de pudrirse al día siguiente de dibujarlo. El objetivo no es leer el código por ti. Es que “qué hace esta app en realidad” tenga una respuesta que sobreviva más que tu memoria de haberla construido.</p>
<p>No estás atascado. Estás a un mapa de tener otra vez el control de tu propia app.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Cómo entiendo código generado por IA que en realidad no leí?</strong> No leyendo cada línea. Construye un mapa al nivel de partes y flujos: cuáles son las piezas reales, cómo se mueve la acción principal del usuario a través de ellas y dónde vive el dato. Entender es conocer la forma, no haber leído el texto.</p>
<p><strong>¿Debería reescribir código que no entiendo?</strong> Casi nunca. Una reescritura cambia una app que funciona y no entiendes por una rota que sí, y recrea los mismos huecos. Mapéalo y refuérzalo en su sitio.</p>
<p><strong>¿Puedo simplemente pedirle a la IA que me explique el código?</strong> Como punto de partida, sí, pero trata cada explicación como una afirmación que verificar contra el comportamiento real. Un resumen seguro de código que hace otra cosa es peor que ninguno.</p>]]></content>
    <summary type="html"><![CDATA[La app está en producción, la usa gente real, y no puedes seguir ni un solo archivo del código que la mueve. Aquí está el camino de vuelta al control, y no es leerte cada línea ni reescribirlo todo.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="ai-coding"/><category term="comprension-del-codigo"/><category term="mantenibilidad"/><category term="de-prototipo-a-producto"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Tu código no sale de casa: la privacidad como decisión de arquitectura</title>
    <link href="https://paelladoc.com/es/blog/el-codigo-se-queda-en-casa/" rel="alternate" type="text/html" title="Tu código no sale de casa: la privacidad como decisión de arquitectura"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/el-codigo-se-queda-en-casa/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/el-codigo-se-queda-en-casa/"><![CDATA[<p><strong>La privacidad suele venderse como una promesa. Debería ser una propiedad.</strong> Una promesa es una frase en una página de política donde una empresa dice que no hará mal uso de tus datos. Una propiedad es un arreglo donde no hay nada que malusar en su lado, porque los datos nunca fueron allí. No son la misma garantía, y el hueco entre las dos es una decisión de arquitectura.</p>
<p>La mayoría de herramientas para developers tratan la privacidad del primer tipo. Tu código, la estructura de tu proyecto, tu trabajo viven en sus servidores, y se te pide confiar en la política que gobierna lo que hacen con ello. La política puede ser excelente. La gente puede tener buena intención. Pero estás confiando en una frase, y las frases cambian con una actualización de los términos de servicio que no vas a leer.</p>
<p>El <a href="/es/blog/desarrollo-ia-local-first/">desarrollo con IA local-first</a> trata la privacidad del segundo tipo. Y la diferencia aparece justo cuando importa.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Promesa y propiedad no son la misma garantía: una depende de la intención de un proveedor, la otra de que no haya nada que malusar."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">promesa</p>
    <ul><li>una frase de política</li><li>confiar en su intención</li><li>cambia con los términos</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">propiedad</p>
    <ul><li>nada en su lado</li><li>no exige confianza</li><li>aguanta el peor día</li></ul>
  </div>
</div><figcaption>Promesa y propiedad no son la misma garantía: una depende de la intención de un proveedor, la otra de que no haya nada que malusar.</figcaption></figure>
<h2 id="qué-proteges-en-realidad">Qué proteges en realidad</h2>
<p>Cuando la gente oye “mantén tu código privado” imagina algoritmos propietarios, y casi se encoge de hombros, porque casi ningún código es secreto. Ese encuadre lo infravalora mal.</p>
<p>El código es la capa menos sensible. La <a href="/es/blog/fabrica-local-de-software/">fábrica local de software</a> que rodea al código guarda cosas que de verdad no querrías que se filtraran. La estrategia detrás de lo que construyes. Las apuestas que consideraste y mataste, que mapean tu pensamiento mejor que cualquier feature publicada. Las restricciones sensibles de seguridad —los sitios exactos donde está escrito “esto nunca puede pasar”, que es precisamente el mapa que querría un atacante—. Los criterios de aceptación que describen cómo se supone que se comportan las partes sensibles. Notas de discovery con cosas que un cliente te contó en confianza.</p>
<p>Eso no es código fuente. Es la forma del pensamiento de tu empresa. Cuando una herramienta sincroniza todo tu espacio de trabajo a sus servidores para poder ayudarte, eso es lo que entregas, y “no entrenamos con tus datos” no cubre la mayor parte.</p>
<h2 id="qué-garantiza-local-de-verdad">Qué garantiza “local” de verdad</h2>
<p>Supón que el almacenamiento está en tu disco: un archivo de base de datos, repositorios, evidencia, todo en formatos inspeccionables que puedes abrir tú mismo. Ahora traza qué podría ver un proveedor curioso, comprometido o requerido por un juez.</p>
<p>Nada, porque en su lado no hay nada. No porque prometieran contención, sino porque los datos no tienen copia en su infraestructura que examinar. La garantía es estructural. No depende de sus intenciones, de su postura de seguridad, de su adquisición ni del gobierno que puede obligarlos. Una promesa es tan fuerte como el más débil de esos. Una propiedad no tiene esa cadena de dependencias siquiera.</p>
<p>Eso es lo que significa que la privacidad sea una decisión de arquitectura. No eliges una empresa en la que confiar. Eliges un arreglo donde la confianza no es el elemento que carga el peso. Los datos son inspeccionables para ti y ausentes para todos los demás, y eso es cierto el peor día, no solo el día de marketing.</p>
<h2 id="el-límite-real-qué-sí-sale">El límite real: qué sí sale</h2>
<p>No voy a fingir que no sale nada, porque una fábrica que no llamara a ningún modelo sería inútil, y mentir aquí envenenaría todo el argumento.</p>
<p>Cuando invocas un modelo remoto, los tokens que le envías —el fragmento de código, el contexto, la instrucción— <a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">van a ese proveedor bajo sus términos</a>. Eso es real. Local-first no lo hace desaparecer. Lo que cambia es la forma de la exposición, y la forma es justo la clave.</p>
<p>En vez de que todo tu espacio de trabajo se sincronice sin parar a un servidor como precio de entrada, solo sale el contexto concreto de una llamada concreta, cuando tú decides hacerla. Por defecto, todo se queda. Enviar es la excepción que tomas a propósito, acotada a lo que la tarea necesita. Puedes mirar un fragmento de contexto sensible y decidir que no va a un modelo en la nube en absoluto, y enrutar esa tarea a un motor local. La exposición se vuelve una serie de decisiones deliberadas y acotadas en vez de una rendición general que hiciste al registrarte.</p>
<p>Esa es la diferencia entre “¿qué elijo enviar ahora mismo?” y “¿qué acepté cuando creé la cuenta, y ha cambiado desde entonces?”. La primera es una decisión que conservas. La segunda es una promesa que esperas que aguante.</p>
<h2 id="qué-te-da-el-almacenamiento-inspeccionable">Qué te da el almacenamiento inspeccionable</h2>
<p>Hay un beneficio de segundo orden en mantener los datos en local, y me costó valorarlo bien: puedes mirarlos de verdad.</p>
<p>Cuando tu grafo de producto, tus decisiones y tu evidencia viven en un archivo de base de datos y en repositorios normales en tu disco, puedes abrirlos. Consultarlos. Hacer copia de seguridad en tu propio calendario, a tu propio destino. Buscar con grep. Pasarlos a un script. Moverlos a la siguiente herramienta con un comando de copia. Los datos no están detrás de una API que expone solo lo que el proveedor decidió exponer, en la forma que decidió, al rate limit que fijó.</p>
<p>Esto importa más de lo que suena, porque “tus datos” en una herramienta en la nube suele significar “tus datos, vistos a través de su interfaz”. Los ves, pero no los sostienes. La exportación te da una foto, no la cosa viva, y las conexiones —la parte que lo hacía un sistema y no un montón de registros— a menudo no vienen contigo.</p>
<p>El almacenamiento local inspeccionable reduce a cero la distancia entre “la herramienta tiene mis datos” y “yo tengo mis datos”. No hay paso de exportación porque no hay de dónde exportar; los archivos ya son tuyos, en formatos que puedes leer sin permiso. Esa es la diferencia entre poseer la memoria de tu producto y que te concedan una vista de ella. La privacidad es el beneficio de titular del almacenamiento local. La propiedad sobre la que puedes actuar es el que notas cada vez que quieres hacer algo que el proveedor no anticipó.</p>
<h2 id="por-qué-merece-diseñarse-así-ahora">Por qué merece diseñarse así ahora</h2>
<p>Dos cosas lo vuelven más agudo que hace unos años.</p>
<p>El volumen que se mueve por estas herramientas explotó. Los agentes leen y escriben por todo tu código, arrastran contexto de forma agresiva, tocan mucho más de tu espacio de trabajo de lo que un humano editando un archivo hizo nunca. La superficie de lo que ve una herramienta sincronizada a la nube creció con la capacidad. Más potencia, más exposición, del mismo diseño.</p>
<p>Y el valor se concentró justo en las partes que una buena herramienta de IA más necesita. Para ser genuinamente útil, un agente quiere tus decisiones, tus restricciones, tus criterios de aceptación, tu historia de producto: la forma sensible, no solo el código. Así que las herramientas que más ayudan son las que tienen la mayor tentación de centralizar lo que menos querrías centralizar. Local-first es la salida de ese aprieto: la herramienta puede ver todo lo que necesita para ser útil, porque corre donde los datos ya están, y nada tiene que enviarse a un servidor para que la ayuda ocurra.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc mantiene tu grafo de producto, tus repositorios, tus decisiones y tu evidencia en almacenamiento local en tu máquina macOS, en formatos que puedes inspeccionar. Llama a los modelos que elijas —proveedores en la nube con tus propias claves, o motores locales— y solo sale el contexto de una llamada dada, cuando la haces. No hay <a href="/es/blog/herramientas-sin-cuenta/">cuenta</a>, así que no hay para empezar un perfil tuyo y de tu trabajo en ningún servidor. Gratis hasta tres proyectos.</p>
<p>La privacidad como banner te pide confiar en una empresa. La privacidad como arquitectura te pide confiar en un diseño que puedes inspeccionar. Que tu código, y el pensamiento a su alrededor, se queden en tu máquina no es una feature que atornillé encima. Es dónde guarda las cosas el sistema, que es la única versión de la privacidad que sigue en pie el día que cuenta.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="se-envía-mi-código-a-la-nube-al-usar-herramientas-de-ia">¿Se envía mi código a la nube al usar herramientas de IA?</h3>
<p>Depende de la arquitectura de la herramienta. Muchas sincronizan todo tu espacio de trabajo a sus servidores como precio de ser útiles. Una herramienta local-first mantiene tu código, tu grafo de producto, tus decisiones y tu evidencia en tu disco, y solo envía fuera el contexto concreto de una llamada concreta al modelo, cuando la haces. Por defecto todo se queda; enviar se vuelve la excepción acotada que tomas a propósito, no una sincronización general.</p>
<h3 id="qué-datos-salen-de-verdad-cuando-un-agente-llama-a-un-modelo">¿Qué datos salen de verdad cuando un agente llama a un modelo?</h3>
<p>Solo los tokens de esa llamada —el fragmento de código, el contexto y la instrucción que pasas— van al proveedor bajo sus términos. Eso es real y local-first no lo hace desaparecer. Lo que cambia es la forma: en vez de que todo tu espacio de trabajo viva en un servidor, sale el contexto de una llamada cuando tú eliges. Puedes mirar contexto sensible y enrutar esa tarea a un motor local para que no salga nada.</p>
<h3 id="qué-diferencia-hay-entre-la-privacidad-como-política-y-como-arquitectura">¿Qué diferencia hay entre la privacidad como política y como arquitectura?</h3>
<p>Una política es una frase que promete que una empresa no hará mal uso de tus datos; cambia con una actualización de los términos que no vas a leer. La arquitectura es un arreglo donde no hay nada que malusar en su lado, porque los datos nunca fueron allí. La garantía es estructural: no depende de sus intenciones, su seguridad, su adquisición ni de un juez. Aguanta el peor día, no solo el día de marketing.</p>
<h3 id="solo-estoy-protegiendo-el-código-fuente">¿Solo estoy protegiendo el código fuente?</h3>
<p>No, y ese encuadre lo infravalora. El código es la capa menos sensible. La fábrica que lo rodea guarda la estrategia detrás de lo que construyes, las apuestas que mataste, las restricciones sensibles de seguridad, los criterios de aceptación de las partes sensibles y notas de discovery contadas en confianza. Eso es la forma del pensamiento de tu empresa, y es justo lo que entrega una herramienta que sincroniza el espacio de trabajo. “No entrenamos con tus datos” no cubre la mayor parte.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="privacidad"/><category term="local-first"/><category term="fabrica-local-de-software"/><category term="ai-coding"/><category term="propiedad-de-datos"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Documentación viva: docs que dejan de pudrirse</title>
    <link href="https://paelladoc.com/es/blog/documentacion-viva/" rel="alternate" type="text/html" title="Documentación viva: docs que dejan de pudrirse"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/documentacion-viva/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/documentacion-viva/"><![CDATA[<p>Todo equipo tiene el doc que miente. El README que describe un paso de setup que se quitó hace un año. La página de arquitectura que muestra tres servicios cuando ya hay cinco. La guía de onboarding que manda a la gente nueva a un repo que se partió. Nadie lo escribió mal. Era verdad el día que se escribió, y luego el código se movió y el doc no.</p>
<p>La explicación de siempre es la disciplina. Si la gente actualizara los docs cuando cambia el código, los docs estarían bien. Es reconfortante y es falso. La documentación se pudre por una razón estructural, y ninguna cantidad de disciplina arregla un problema estructural mucho tiempo.</p>
<h2 id="por-qué-se-pudren-los-docs-exactamente">Por qué se pudren los docs, exactamente</h2>
<p>Un doc tradicional es una segunda copia de la verdad. La verdad vive en el código, en la config, en el sistema que corre. El doc es un artefacto aparte, en un sitio aparte, que describe esa verdad en prosa. Los dos están conectados por exactamente una cosa: un humano acordándose de actualizar la segunda copia cuando cambia la primera.</p>
<p>Ese enlace es el defecto. Es manual, no es tarea explícita de nadie, y falla en silencio. Cuando alguien shipea un cambio y se olvida del doc, no se rompe nada, ningún test se pone rojo, no salta ninguna alerta. El doc solo se vuelve un poco menos verdad, en silencio, y sigue pareciendo autoritativo todo el tiempo. La putrefacción no es un evento que puedas cazar. Es el estado por defecto de cualquier artefacto cuyo único vínculo con la realidad es la memoria humana.</p>
<p>Por esto los arreglos estándar no funcionan. Una plantilla mejor sigue siendo una segunda copia. Un proceso de review más estricto sigue apoyándose en que los humanos se acuerden. Una wiki más mona es un sitio más bonito para la misma putrefacción. Estás optimizando la copia cuando el problema es que exista una copia siquiera.</p>
<p>La era de la IA lo agudiza en dos direcciones a la vez. Los agentes ahora leen tus docs como contexto y responden con total seguridad según lo que diga el doc, así que un doc podrido no solo despista a un fichaje nuevo, <a href="/es/blog/reglas-de-agentes-vivas/">envenena a cada agente que se fía de él</a>. Y los agentes escriben código más rápido de lo que ningún humano puede actualizar a mano la prosa que lo describe, así que el hueco entre código y doc se abre más rápido de lo que la disciplina vieja lo puede cerrar.</p>
<h2 id="el-arreglo-es-quitar-la-copia-no-actualizarla-más-rápido">El arreglo es quitar la copia, no actualizarla más rápido</h2>
<p>La documentación viva no es “documentación que se te da mejor mantener”. Es documentación con el humano-en-el-bucle sacado del camino de actualización. El doc deja de ser una segunda copia y pasa a ser una proyección de la primera.</p>
<p>El movimiento es derivar los docs del sistema en vez de escribirlos al lado. Si la descripción de tu API se genera desde las rutas y los tipos reales, entonces cuando una ruta cambia la descripción cambia, porque <a href="/es/blog/especificaciones-vivas/">son el mismo hecho renderizado una vez</a>. Si tu vista de arquitectura se lee del <a href="/es/blog/grafo-de-conocimiento-del-codigo/">grafo de conocimiento del código</a> real, el mapa de qué llama de verdad a qué, entonces un servicio nuevo aparece en la vista en cuanto aparece en el código, sin que nadie dibuje una caja. No hay una segunda copia que se desincronice, porque no hay una segunda copia. Está el sistema, y una vista de él.</p>
<p>Ser verdad deja de ser una tarea que sigues sin hacer y pasa a ser una propiedad de cómo se produce el doc. No te puedes olvidar de actualizar una proyección. Se actualiza porque lo que proyecta se actualizó.</p>
<p>No todo se puede derivar, y merece la pena ser claro con la línea. El <em>qué</em> y el <em>cómo</em> de un sistema, las rutas, la estructura de llamadas, las dependencias, la forma, se pueden leer del código. El <em>porqué</em> normalmente no, porque la razón por la que se tomó una decisión no es visible en el código que resultó de ella. Esa parte hay que capturarla a propósito, cuando se toma la decisión, y luego atarla al código que gobierna. Que es una disciplina distinta de escribir prosa a posteriori, y una duradera, porque se registra una vez en el momento en que el conocimiento existe en vez de reconstruirse después de memoria. Este es el mismo razonamiento detrás de <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">un cerebro de producto que se mantiene solo</a>: captura el porqué en el momento de la decisión, deriva todo lo demás del sistema.</p>
<h2 id="docs-as-code-es-una-media-tinta-y-merece-la-pena-entender-por-qué">Docs-as-code es una media tinta, y merece la pena entender por qué</h2>
<p>El paso más común que dan los equipos hacia los docs vivos es <a href="/es/blog/docs-as-code-con-ia/">docs-as-code</a>: meter la documentación en el repo, en markdown, junto al código, revisada en los mismos pull requests. Es una mejora real. Los docs viajan con el código, pasan por review, y un diff al menos le da a alguien la oportunidad de notar que la prosa ahora está mal.</p>
<p>Pero mira qué arregla de verdad. Mueve la segunda copia más cerca de la primera y mejora las probabilidades de que un humano note el desfase. No quita la segunda copia, y no quita al humano. El fichero markdown que describe la arquitectura sigue siendo un artefacto paralelo escrito a mano que tiene que actualizar alguien que se acordó, en el mismo commit, bien. Docs-as-code hace la putrefacción más cazable. No la hace estructuralmente imposible. Sigues teniendo dos cosas que pueden discrepar, y sigues dependiendo de la disciplina para mantenerlas de acuerdo, solo que con más probabilidad de cazar un desliz en la review.</p>
<figure class="tp-diagram tp-diagram--levels" data-diagram-type="levels" role="img" aria-label="Cada paso saca más al humano del camino de actualización; solo el último borra la segunda copia de todo lo que se puede leer del código."><svg viewBox="0 0 760 214" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="20" width="186" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="46" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">PROSA JUNTO AL CÓDIGO</text><rect x="40" y="78" width="373" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="104" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">DOCS-AS-CODE</text><rect x="40" y="136" width="560" height="40" fill="var(--tp-mostaza)" stroke="var(--tp-mostaza)" stroke-width="1.5" fill-opacity="0.14"></rect>
  <text x="52" y="162" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">PROYECCIÓN DERIVADA</text></svg><figcaption>Cada paso saca más al humano del camino de actualización; solo el último borra la segunda copia de todo lo que se puede leer del código.</figcaption></figure>
<p>La documentación viva es el paso más allá de docs-as-code. Conserva la disciplina de-revisado-en-repo para la prosa que de verdad hay que escribir, el <em>porqué</em>, la intención, lo que ningún sistema puede derivar. Pero para todo lo que se puede leer del código, deja de escribir una copia paralela y renderiza una vista del sistema en su lugar. Docs-as-code es donde pones la copia en un buen sitio. La documentación viva es donde borras la copia de todo lo que no debería haber sido una copia.</p>
<h2 id="qué-no-es-la-documentación-viva">Qué no es la documentación viva</h2>
<p>No es prosa autogenerada que nadie lee. Un muro de texto escrito por máquina describiendo cada función no es documentación viva, es ruido con una fecha fresca. El valor no es que lo escribiera una máquina. El valor es que es una proyección fiel del sistema real, así que lo que dice es lo que es verdad.</p>
<p>Tampoco es un sustituto del criterio sobre qué merece la pena documentar siquiera. Derivar una vista de todo es fácil y casi siempre inútil. La habilidad está en elegir qué proyecciones importan, la superficie de la API, la arquitectura, el provenance del código a las decisiones, y dejar que esas se mantengan verdaderas solas mientras gastas tu atención de verdad en el <em>porqué</em> que ningún sistema puede derivar por ti. Poner la estructura correcta delante de lectores y agentes es la mitad de documentación del <a href="/es/research/context-engineering-para-agentes-de-codigo/">context engineering</a>: no más texto, la proyección correcta.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc trata la documentación como una proyección, no como un artefacto paralelo. Lee tu repo a un grafo en tu máquina y deriva las vistas de él, así que el mapa del sistema sigue al día según el sistema se mueve. Las partes que no se pueden derivar, las decisiones y sus razones, se capturan según pasan y se enlazan al código que gobiernan, así que el <em>porqué</em> se registra una vez y nunca se reconstruye. El resultado es documentación que es verdad por cómo está hecha, leída igual por la gente de tu equipo y por los agentes que hacen el trabajo.</p>
<p>¿Qué doc de tu equipo está mintiendo ahora mismo, y cuánto lleva mintiendo? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-la-documentación-siempre-se-queda-obsoleta">¿Por qué la documentación siempre se queda obsoleta?</h3>
<p>Por una razón estructural, no por pereza. Un doc tradicional es una segunda copia de la verdad, en un sitio distinto del código y atada a él por una sola cosa: un humano acordándose de actualizarla. Ese enlace es manual, tarea de nadie, y falla en silencio, así que el doc se vuelve menos verdad sin dejar de parecer autoritativo.</p>
<h3 id="qué-es-la-documentación-viva">¿Qué es la documentación viva?</h3>
<p>Documentación con el humano sacado del camino de actualización. En vez de escribir los docs al lado del sistema, los derivas de él, así que una descripción de API generada desde las rutas reales cambia cuando cambia una ruta, y una vista de arquitectura leída del grafo del código muestra un servicio nuevo en cuanto existe. No hay segunda copia que se desincronice.</p>
<h3 id="es-docs-as-code-lo-mismo-que-documentación-viva">¿Es docs-as-code lo mismo que documentación viva?</h3>
<p>No, docs-as-code es una media tinta. Meter markdown en el repo, revisado en pull requests, acerca la segunda copia al código y mejora las probabilidades de que un humano note el desfase. Pero la copia y el humano siguen ahí. La documentación viva es el paso más allá: para todo lo que se puede leer del código, borra la copia y renderiza una vista.</p>
<h3 id="qué-no-se-puede-derivar-del-código">¿Qué no se puede derivar del código?</h3>
<p>El porqué. El qué y el cómo, las rutas, la estructura de llamadas, las dependencias, la forma, se leen del código. La razón por la que se tomó una decisión no es visible en el código que resultó de ella, así que hay que capturarla a propósito cuando se toma y atarla al código que gobierna. Deriva todo lo demás; gasta tu atención en el porqué.</p>]]></content>
    <summary type="html"><![CDATA[La documentación no se pudre porque la gente sea vaga. Se pudre porque es una segunda copia de la verdad, guardada en un sitio distinto del código, actualizada por un humano que tiene que acordarse. Quita al humano del bucle y la putrefacción se para. La documentación viva son docs derivados del sistema como proyección de él, así que ser verdad es lo que son por construcción, no una tarea que sigues sin hacer.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="living-documentation"/><category term="docs-as-code"/><category term="knowledge-graph"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Docs-as-code en la era de los agentes</title>
    <link href="https://paelladoc.com/es/blog/docs-as-code-con-ia/" rel="alternate" type="text/html" title="Docs-as-code en la era de los agentes"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/docs-as-code-con-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/docs-as-code-con-ia/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿Qué es docs-as-code?", "acceptedAnswer": {"@type": "Answer", "text": "Tratar la documentación como código fuente: vive en el repositorio, cambia mediante pull requests, se revisa junto al código que describe y pasa por CI. El objetivo es que los docs se muevan por la misma vía que el código, para que cambien juntos en vez de separarse."}},
    {"@type": "Question", "name": "¿Cómo cambia la era de los agentes el docs-as-code?", "acceptedAnswer": {"@type": "Answer", "text": "Los docs dejan de ser solo output para humanos y se vuelven input para máquinas. Ficheros como AGENTS.md y CLAUDE.md los leen los agentes para decidir cómo construir. Eso da la vuelta a la prioridad: un doc obsoleto ya no solo confunde a un fichaje nuevo, dirige activamente al agente a construir lo que no es, así que mantenerlos verdaderos pasa a ser asunto del build."}},
    {"@type": "Question", "name": "¿El pipeline de docs debería ser parte del build?", "acceptedAnswer": {"@type": "Answer", "text": "Sí, cuando los agentes dependen de los docs. Si las instrucciones pueden separarse del código sin nada que lo detecte, se separarán, y un agente se fiará de la versión desviada. Generar los docs desde el código donde se pueda, y frenar el build cuando lo documentado y lo real no cuadran, es como mantienes el contrato veraz a velocidad de máquina."}}
  ]
}
</script>
<p>Docs-as-code ya era la idea correcta antes de todo esto. Pon la documentación en el repo, cámbiala con pull requests, revísala junto al código, pásala por CI. Docs en la misma vía que el código, para que se muevan juntos en vez de derivar hacia una wiki de la que nadie se fía. Si lo hacías, ibas por delante.</p>
<p>Luego cambió el lector. Tus docs ya no los leen solo humanos haciendo onboarding o buscando algo. Los leen agentes, antes de escribir una sola línea, para decidir qué construir y cómo. Ese único cambio convierte el docs-as-code de una disciplina sana en parte del build, y tratarlo como algo menos es como los agentes acaban construyendo lo que no es, con total seguridad.</p>
<h2 id="docs-as-code-rápido-porque-el-lector-es-listo">Docs-as-code, rápido, porque el lector es listo</h2>
<p>La mecánica no es lo interesante, así que voy corto. La documentación vive al lado del código que describe. Cambia en el mismo pull request que cambia el código. Un revisor ve los dos diffs juntos. CI puede lintarla, comprobar enlaces, montar el sitio. Nada exótico. Todo el valor está en una sola vía: cuando el código se mueve, el doc está ahí mismo en el mismo cambio, difícil de olvidar.</p>
<p>La alternativa, docs en un sistema aparte que se actualiza cuando alguien se acuerda, es la que se pudre. Todo el mundo ha leído una página de wiki que describe un sistema dos reescrituras por detrás y ha tenido que sacar la verdad del código a ingeniería inversa. Docs-as-code existe para poner ese fallo más difícil.</p>
<h2 id="el-lector-ahora-es-una-máquina-y-hace-lo-que-dicen-los-docs">El lector ahora es una máquina, y hace lo que dicen los docs</h2>
<p>Esto es lo que cambió de verdad. Un doc obsoleto le costaba a un humano una hora de confusión antes de mirar el código y sacar la verdad. Molesto, superable, autocorrectivo, porque los humanos desconfían de los docs y verifican.</p>
<p>Un agente no verifica por defecto. Lee tu <code>AGENTS.md</code>, tu <code>CLAUDE.md</code>, tus notas de arquitectura, y los trata como instrucciones. <a href="https://agents.md/">AGENTS.md está emergiendo como convención compartida justo para esto</a>: un sitio predecible donde poner <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">los pasos de setup, las convenciones y las restricciones que un agente debe seguir</a>. Eso es potente y es un arma cargada. Si el fichero dice que el servicio de auth vive en una ruta donde ya no vive, o que usas una librería de la que migraste hace dos meses, el agente no se encoge de hombros ni comprueba. Construye sobre la mentira, con seguridad, a velocidad.</p>
<p>Así que se dieron la vuelta las apuestas. Los docs eran output, algo que producías para humanos después del trabajo. Ahora un trozo de tus docs es input, algo que los agentes consumen antes del trabajo. Un output un poco obsoleto es meramente embarazoso. Un input obsoleto es un defecto que se publica.</p>
<p>Y compone. Un agente lee la ruta equivocada, construye contra ella, y deja atrás código y commits que ratifican el error en silencio. El siguiente agente lee eso como confirmación. Una sola línea obsoleta no se queda en una sola línea obsoleta, siembra un pequeño montón de trabajo que concuerda todo consigo mismo y apunta todo en la dirección equivocada, y deshacerlo cuesta mucho más de lo que habría costado arreglar el doc.</p>
<h2 id="el-pipeline-de-docs-pertenece-al-build">El pipeline de docs pertenece al build</h2>
<p>Si los agentes dependen de los docs, entonces mantener los docs verdaderos es asunto del build, no una tarea del equipo de documentación. De ahí salen dos movimientos.</p>
<p><strong>Genera lo que puedas desde el código.</strong> Cualquier cosa que se pueda leer del fuente, el mapa de módulos, las rutas, las interfaces públicas, la lista de servicios, debería generarse, no mantenerse a mano. Los hechos mantenidos a mano derivan en cuanto alguien va con prisa. Los hechos generados no pueden mentir sobre el código, porque se leen de él. Es el mismo espíritu que <a href="https://martinfowler.com/bliki/CodeAsDocumentation.html">el código como documentación</a>: cuanto más cerca está el doc de la fuente de verdad, menos margen hay para que diverja en silencio.</p>
<p><strong>Frena el build por deriva en el resto.</strong> No todo se puede generar. <a href="/es/blog/conocimiento-tribal/">El “porqué”, las restricciones, las decisiones siguen habiendo que escribirlas</a>. Para eso, el build debería fallar cuando un hecho documentado y un hecho real no cuadran. Si un doc dice que un fichero existe y no existe, rompe el build. Si referencia un endpoint que se borró, rompe el build. Ya frenas por los tests. Frena por los docs de los que tus agentes se van a fiar, por la misma razón: para que una afirmación falsa no llegue a producción. Esto es docs-as-code llevado a su conclusión, donde el pipeline de docs corre por la misma vía y falla con el mismo estándar que el código.</p>
<figure class="tp-diagram tp-diagram--gate" data-diagram-type="gate" role="img" aria-label="Ya frenas por los tests; frena por los docs de los que tus agentes se van a fiar, para que una afirmación falsa falle el build en vez de embarcarse como instrucción."><svg viewBox="0 0 760 240" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
  <rect x="40" y="86" width="180" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="130" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">HECHO DOCUMENTADO</text>
  <path d="M 226 119 L 286 119 M 280 113 L 286 119 L 280 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <path d="M 380 60 L 452 119 L 380 178 L 308 119 Z" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.8"></path>
  <text x="380" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">CUADRA CON LA FUENTE</text>
  <path d="M 458 119 L 528 119 M 522 113 L 528 119 L 522 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <rect x="534" y="86" width="186" height="66" fill="var(--tp-verde)" fill-opacity="0.12" stroke="var(--tp-verde)" stroke-width="1.5"></rect>
  <text x="627" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-verde)">PASA EL BUILD</text>
  <path d="M 380 184 L 380 214 L 226 214 M 232 208 L 226 214 L 232 220" stroke="var(--tp-terracota)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="232" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-terracota)">ROMPE EL BUILD</text>
</svg><figcaption>Ya frenas por los tests; frena por los docs de los que tus agentes se van a fiar, para que una afirmación falsa falle el build en vez de embarcarse como instrucción.</figcaption></figure>
<p>Nada de esto pide a nadie escribir más prosa. Le pide al pipeline que deje de permitir que la prosa mienta.</p>
<h2 id="tus-ficheros-de-reglas-son-los-docs-de-más-apalancamiento-que-tienes">Tus ficheros de reglas son los docs de más apalancamiento que tienes</h2>
<p>Ya no todos los docs pesan lo mismo. Un tutorial que se queda obsoleto malgasta la mañana de un recién llegado. Una línea obsoleta en <code>CLAUDE.md</code> o <code>AGENTS.md</code> la ejecuta cada agente en cada run, en silencio, a escala. El radio de daño es completamente distinto, y la prioridad de mantenimiento debería serlo también.</p>
<p>Trato esos ficheros como trato una configuración que va a producción, porque funcionalmente es lo que son. Cada afirmación en ellos es una instrucción sobre la que algún agente actuará sin comprobar. Así que el listón no es “¿esto es más o menos exacto?”. Es “¿estaría cómodo si un agente siguiera esto al pie de la letra a las 2 de la mañana sin nadie mirando?”, que es justo lo que pasa.</p>
<p>Ese reencuadre cambia lo que va dentro. Las aspiraciones vagas y las convenciones a medias son peores que nada, porque un agente no distingue una aspiración de una regla. Las afirmaciones concretas, actuales y verificables se ganan su sitio. Todo lo demás es una mina que te escribiste tú. La disciplina no es escribir más de estos ficheros. Es mantener las pocas líneas que tienen despiadadamente verdaderas, y dejar que el build te pille cuando no lo son.</p>
<h2 id="vivos-no-solo-versionados">Vivos, no solo versionados</h2>
<p>Unos docs versionados no están automáticamente vivos. Un doc puede estar en el repo, revisado, en CI, y aun así describir un sistema que cambió en un commit que no lo tocó. Docs-as-code pone los docs en la misma vía que el código. No garantiza que se muevan.</p>
<p>Lo que los mueve es <a href="/es/blog/grafo-de-conocimiento-del-codigo/">una conexión con el código que mantiene los dos en sincronía</a>, para que un cambio en uno saque a la luz la obsolescencia del otro. Esa es la diferencia entre un doc meramente versionado y uno que es <a href="/es/blog/documentacion-viva/">documentación viva, docs que dejan de pudrirse porque el sistema nota cuándo ya no cuadran</a>. Y es el mismo motor detrás de <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">un cerebro de producto que se mantiene solo</a>: el conocimiento se actualiza según se mueve el código, en vez de esperar a que un humano se acuerde. La documentación interna de calidad es <a href="https://dora.dev/capabilities/documentation-quality/">una de las prácticas que mejor predice si un equipo lleva bien el cambio</a>, y ese “predice” solo se sostiene cuando los docs son verdad, que es justo el problema que el pipeline tiene que resolver.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc construye la conexión que le falta al docs-as-code. Lee tu repo en un grafo de código, decisiones y criterios, lo mantiene al día según se mueve el código, y puede sacar a la luz cuándo un hecho documentado ya no cuadra con el fuente, para que las instrucciones que leen tus agentes sean las que siguen siendo verdad. Los docs dejan de ser algo que mantienes por culpa y se vuelven un input del que el build sí se puede fiar.</p>
<p>Local-first y gratis, sin nube y sin cuenta, contra el repo que ya tienes.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuál es la línea más obsoleta de tu <code>AGENTS.md</code> que un agente seguiría igualmente? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-docs-as-code">¿Qué es docs-as-code?</h3>
<p>Tratar la documentación como código fuente: vive en el repositorio, cambia mediante pull requests, se revisa junto al código que describe y pasa por CI. El objetivo es que los docs se muevan por la misma vía que el código, para que cambien juntos en vez de separarse.</p>
<h3 id="cómo-cambia-la-era-de-los-agentes-el-docs-as-code">¿Cómo cambia la era de los agentes el docs-as-code?</h3>
<p>Los docs dejan de ser solo output para humanos y se vuelven input para máquinas. Ficheros como AGENTS.md y CLAUDE.md los leen los agentes para decidir cómo construir. Eso da la vuelta a la prioridad: un doc obsoleto ya no solo confunde a un fichaje nuevo, dirige activamente al agente a construir lo que no es, así que mantenerlos verdaderos pasa a ser asunto del build.</p>
<h3 id="el-pipeline-de-docs-debería-ser-parte-del-build">¿El pipeline de docs debería ser parte del build?</h3>
<p>Sí, cuando los agentes dependen de los docs. Si las instrucciones pueden separarse del código sin nada que lo detecte, se separarán, y un agente se fiará de la versión desviada. Generar los docs desde el código donde se pueda, y frenar el build cuando lo documentado y lo real no cuadran, es como mantienes el contrato veraz a velocidad de máquina.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="knowledge-graph"/><category term="docs-as-code"/><category term="living-documentation"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Discovery con IA: socia para pensar, no para decidir</title>
    <link href="https://paelladoc.com/es/blog/discovery-con-ia/" rel="alternate" type="text/html" title="Discovery con IA: socia para pensar, no para decidir"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/discovery-con-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/discovery-con-ia/"><![CDATA[<p>El discovery tiene dos mitades que se parecen y no lo son. Una es pensar: generar opciones, cuestionar supuestos, encuadrar el problema, ampliar el espacio de lo que podrías construir. La otra es decidir: averiguar qué es cierto de verdad sobre usuarios reales y apostar por ello. La IA es genuinamente excelente en la primera mitad. Es calladamente peligrosa en la segunda. Y la razón de que sea peligrosa es justo que es tan buena en la primera que el borde entre ambas se difumina.</p>
<p>Le pides a un modelo que te ayude a pensar un problema y lo hace, bien. Luego, en la misma conversación, en el mismo registro seguro, te dice qué quieren los usuarios. Nada señala que cruzaste una línea de razonar a afirmar. La salida se ve idéntica. Esa costura, donde la ayuda-para-pensar resbala a decidir-por-ti sin ningún cambio de tono, es donde el discovery asistido por IA se tuerce.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="La IA es una socia estupenda para la mitad de pensar del discovery y peligrosa para la de decidir. Toda la habilidad es mantener la línea afilada."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">socia para pensar</p>
    <ul><li>Amplía las opciones</li><li>Pone a prueba argumentos</li><li>Reencuadra el problema</li><li>Estructura el caos</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">socia para decidir</p>
    <ul><li>Afirma qué quieren los usuarios</li><li>Nunca los conoció</li><li>Conjetura disfrazada de hecho</li></ul>
  </div>
</div><figcaption>La IA es una socia estupenda para la mitad de pensar del discovery y peligrosa para la de decidir. Toda la habilidad es mantener la línea afilada.</figcaption></figure>
<h2 id="dónde-se-gana-su-sitio-la-ia">Dónde se gana su sitio la IA</h2>
<p>Para la mitad de pensar, un modelo es una de las mejores socias que puedes tener, y conviene concretar por qué:</p>
<ul>
<li><strong>Amplía el espacio de opciones.</strong> A solas, exploras las dos o tres soluciones que ya tenías en mente. Pídele a un modelo diez ángulos más y la mayoría son inútiles, pero dos son cosas a las que no habrías llegado, y el discovery vive de las opciones que no tenías ya.</li>
<li><strong>Pone a prueba un argumento.</strong> Dale tu razonamiento y pregúntale por dónde se rompe. Un modelo es un abogado del diablo incansable y sin ego que no se pone a la defensiva cuando le rebates. Eso es raro y útil.</li>
<li><strong>Reencuadra.</strong> Estás atascado viendo el problema de una forma. Te ofrece otros tres encuadres, y uno disuelve aquello en lo que estabas atascado.</li>
<li><strong>Estructura el caos.</strong> Tienes cuarenta observaciones dispersas. Te ayuda a encontrar los clusters y nombrar los patrones. Tú sigues decidiendo qué patrones son reales, pero el ordenar es trabajo real que hace bien.</li>
</ul>
<p>Cada una de estas mantiene al humano como quien decide. El modelo expande, presiona y organiza tu pensamiento. No concluye por ti. Usado así hace el discovery más rápido y más ancho sin tocar la parte que tiene que seguir siendo tuya.</p>
<h2 id="dónde-toma-el-mando-calladamente">Dónde toma el mando calladamente</h2>
<p>El peligro no es que la IA dé malas respuestas en el discovery. Es que da respuestas seguras, fluidas y plausibles a preguntas que solo se pueden responder con contacto con la realidad, y la seguridad es indistinguible de la que muestra cuando acierta.</p>
<p>Pregúntale a un modelo con qué luchan tus usuarios y te lo dirá, en prosa limpia, una lista de dolores. Algunos estarán bien. Ha leído lo suficiente como para que sus priors no sean inútiles. Pero nunca ha conocido a tus usuarios, ni los ha visto trabajar, ni ha visto dónde se atascan de verdad. Está generando la respuesta más probable a «con qué luchan los usuarios de algo así», que es una pregunta distinta de «con qué luchan <em>tus</em> usuarios», y el hueco entre esas dos preguntas es el trabajo entero del discovery.</p>
<p>El modo de fallo es sutil porque la salida tiene buena pinta. Una lista plausible de dolores de usuario se siente como progreso. Se lee como un hallazgo de investigación. Y si lo dejas, se convierte en uno, colándose en tu deck y tu roadmap con el estatus epistémico de algo que aprendiste de los usuarios, cuando su estatus real es algo que un modelo supuso. Este es el <a href="/es/blog/product-management-era-ia/">modo de fallo del slop de IA</a> con ropa de discovery: más artefactos, más insights de tono seguro, ningún contacto extra con la verdad.</p>
<h2 id="blanqueo-el-pecado-concreto-que-evitar">Blanqueo: el pecado concreto que evitar</h2>
<p>Hay un movimiento que hace más daño que cualquier otro, y merece un nombre. Blanqueo es cuando una hipótesis que generó un modelo se cita después como si fuera evidencia que te dio un usuario.</p>
<p>Pasa poco a poco y sin malicia. El lunes haces lluvia de ideas con un modelo y sugiere que los usuarios probablemente abandonan el flujo en el paso de pago. Eso es una hipótesis, una decente. El jueves está en un doc como «los usuarios abandonan en el pago». A la semana siguiente alguien construye contra ello como un hecho conocido. Nadie mintió. En cada paso la afirmación perdió un poco de su «creemos» y ganó un poco de «sabemos», hasta que <a href="/es/blog/slop-de-ia-en-producto/">la suposición de un modelo dirige una decisión de construcción</a> con la autoridad de la investigación.</p>
<p>La defensa no es dejar de usar IA en el discovery. Es mantener la provenance de cada afirmación despiadadamente visible. Esta hipótesis vino de un modelo. Esta vino de una sesión con un usuario. Esta vino de datos de uso. No son el mismo tipo de cosa y nunca hay que dejar que parezcan lo mismo, porque todo el valor del discovery es saber cuáles de tus creencias son evidencia de carga y cuáles suposiciones plausibles esperando prueba. En el momento en que esas dos se difuminan, estás <a href="/es/blog/que-es-una-feature-factory/">haciendo producto como una feature factory</a>, construyendo contra ficción segura y llamando progreso al movimiento.</p>
<h2 id="mantener-la-línea-afilada-en-la-práctica">Mantener la línea afilada en la práctica</h2>
<p>En concreto, unos cuantos hábitos evitan que la socia-para-pensar se vuelva socia-para-decidir:</p>
<ul>
<li><strong>Etiqueta la fuente de cada afirmación, siempre.</strong> Generada por modelo, de usuario, de datos. Si una creencia de tu discovery no puede decir de dónde vino, todavía no es evidencia, sea cual sea su tono.</li>
<li><strong>Nunca dejes que un modelo <a href="/es/blog/research-de-usuarios-con-ia/">resuma investigación en conclusiones</a> sin supervisión.</strong> Alisará la incertidumbre, tirará la cita que contradice y te entregará una historia limpia. Limpia es justo lo que la investigación de usuarios no es, y el caos que quita es donde suele esconderse la señal real.</li>
<li><strong>Úsalo para generar hipótesis, y luego trátalas como deudas.</strong> Cada dolor sugerido por el modelo es <a href="/es/blog/asuncion-mas-arriesgada/">algo a validar</a>, no algo que sabes. Se ha ganado una prueba, no un sitio en el roadmap.</li>
<li><strong>Pídele que argumente contra tu conclusión, no solo a favor.</strong> Su complacencia es una trampa. Apoyará con gusto lo que sea que te inclina. Apunta su fluidez a tu propia posición y se vuelve mucho más útil.</li>
</ul>
<p>Nada de esto es fricción por la fricción. El objetivo de las etiquetas y de los prompts adversariales es preservar, a través de un proceso rápido y fluido, la única distinción que el discovery existe para proteger: la diferencia entre lo que tienes razones para creer y lo que simplemente te han contado de forma plausible. Pierde esa distinción y cada decisión de abajo hereda una confianza que nunca se ganó, que es como un equipo acaba seguro de un mercado que en realidad nunca miró.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Por eso en <a href="/es/">PaellaDoc</a> la provenance no es una ocurrencia tardía, es la estructura. Una hipótesis que generó un modelo y un hallazgo que te dio un usuario son tipos de nodo distintos, y siguen siendo distintos. Puedes usar IA para ampliar y presionar tu pensamiento todo lo que quieras, porque el sistema no dejará que una suposición adquiera calladamente la autoridad de la evidencia. Cuando una decisión se apoya en una afirmación, puedes ver sobre qué descansa de verdad: un usuario, un número, o una frase plausible que escribió un modelo.</p>
<p>Usa la IA para la mitad del discovery en la que es brillante. Deja que amplíe tus opciones, rompa tus argumentos, organice tu caos. Solo mantén la mano en la decisión, y mantén la línea entre lo que crees y lo que sabes lo bastante brillante como para que ningún párrafo fluido la emborrone. El modelo es una socia estupenda para pensar. Nunca ha conocido a tus usuarios. No dejes que finja que sí.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="la-ia-puede-hacer-el-discovery-por-ti">¿La IA puede hacer el discovery por ti?</h3>
<p>Puede hacer la mitad de pensar, no la de decidir. La IA es estupenda para ampliar el espacio de opciones, poner a prueba un argumento, reencuadrar un problema y estructurar observaciones dispersas. Es peligrosa en cuanto empieza a decirte qué quieren los usuarios reales, porque nunca los ha conocido. Úsala para expandir y presionar tu pensamiento; la decisión, y el contacto con la realidad, siguen siendo tuyos.</p>
<h3 id="la-ia-puede-decirme-qué-quieren-mis-usuarios">¿La IA puede decirme qué quieren mis usuarios?</h3>
<p>No, aunque sonará como si pudiera. Pregúntale a un modelo con qué luchan tus usuarios y genera la respuesta más probable a «con qué luchan los usuarios de algo así», que es una pregunta distinta de con qué luchan <em>tus</em> usuarios. Ese hueco es el trabajo entero del discovery. La respuesta es una hipótesis plausible, no un hallazgo, hasta que un usuario real la confirma.</p>
<h3 id="qué-es-el-blanqueo-en-el-discovery-asistido-por-ia">¿Qué es el blanqueo en el discovery asistido por IA?</h3>
<p>Blanqueo es cuando una hipótesis que generó un modelo se cita después como si fuera evidencia que te dio un usuario. Pasa poco a poco: una lluvia de ideas del lunes se vuelve un doc el jueves y una decisión de construcción a la semana siguiente, perdiendo un poco de «creemos» y ganando un poco de «sabemos» en cada paso. Nadie mintió, pero la suposición de un modelo acaba con la autoridad de la investigación.</p>
<h3 id="cómo-evito-que-las-hipótesis-de-la-ia-se-vuelvan-evidencia-falsa">¿Cómo evito que las hipótesis de la IA se vuelvan evidencia falsa?</h3>
<p>Mantén la provenance despiadadamente visible. Etiqueta cada afirmación por fuente: generada por modelo, de usuario o de datos, y nunca dejes que parezcan lo mismo. Trata cada dolor sugerido por el modelo como una deuda a validar, no un hecho sobre el que construir. Nunca dejes que un modelo resuma investigación en conclusiones sin supervisión, alisa la incertidumbre y tira la cita que contradice. Si una creencia no puede decir de dónde vino, todavía no es evidencia.</p>]]></content>
    <summary type="html"><![CDATA[La IA es una socia estupenda para la mitad de pensar del discovery: generar ángulos, poner a prueba un argumento, ampliar el espacio de opciones. Es una socia peligrosa para la mitad de decidir, porque producirá respuestas seguras sobre usuarios que nunca ha conocido. La habilidad está en mantener la línea afilada, y nunca dejar que una hipótesis plausible se blanquee como evidencia solo porque un modelo la escribió con fluidez.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="ai-discovery"/><category term="product-management"/><category term="ai-coding"/><category term="product-research"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">La deuda del vibe coding: qué debes exactamente y cuándo vence</title>
    <link href="https://paelladoc.com/es/blog/deuda-tecnica-vibe-coding/" rel="alternate" type="text/html" title="La deuda del vibe coding: qué debes exactamente y cuándo vence"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/deuda-tecnica-vibe-coding/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/deuda-tecnica-vibe-coding/"><![CDATA[<p>Sacaste una app funcionando en un fin de semana. Un agente escribió casi todo, tú dirigías, la demo salió bien. Tres semanas después, un cambio de dos líneas te lleva un día entero y no tienes claro por qué la app sigue arrancando. Ese día que perdiste es el pago de intereses. Lo que no viste fue el momento en que pediste el préstamo.</p>
<p>Todo el mundo llama a esto deuda técnica. El nombre es correcto y también esconde algo. Cuando Ward Cunningham acuñó la <a href="https://martinfowler.com/bliki/TechnicalDebt.html">deuda técnica</a>, la deuda era código que entendías, escrito bajo presión, que decidías limpiar más tarde. El vibe coding produce otro animal: código que nunca leíste, generado a una velocidad que ninguna revisión humana siguió. Llamarlo un único bloque de “deuda” te dice que existe. No te dice qué debes ni cuándo llega la factura.</p>
<p>Así que déjame partirlo en las tres deudas que de verdad se comportan distinto.</p>
<h2 id="la-deuda-no-es-un-solo-número">La deuda no es un solo número</h2>
<p>El error es tratar un código hecho con vibe coding como un único montón de atajos que ya limpiarás algún día. Ese marco te paraliza, porque “reescribirlo bien” nunca es la tarea del tamaño adecuado ni la semana adecuada para hacerla.</p>
<p>Las deudas que importan acumulan intereses a ritmos distintos y vencen ante disparadores distintos. Si sabes nombrarlas por separado, puedes pagar primero la cara y dejar en paz la barata. Ese es todo el movimiento.</p>
<figure class="tp-diagram tp-diagram--stack" data-diagram-type="stack" role="img" aria-label="No un saldo sino tres, apilados. La comprensión va debajo: la pagas primero porque todo lo de encima depende de ella."><svg viewBox="0 0 760 208" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="120" y="20" width="520" height="42" fill="var(--tp-mostaza)" fill-opacity="0.14" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="380" y="47" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">DEUDA DE COMPRENSIÓN</text><rect x="120" y="76" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="103" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">DEUDA DE TESTS</text><rect x="120" y="132" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="159" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">DEUDA DE ARQUITECTURA</text></svg><figcaption>No un saldo sino tres, apilados. La comprensión va debajo: la pagas primero porque todo lo de encima depende de ella.</figcaption></figure>
<h2 id="capa-1-deuda-de-comprensión">Capa 1: deuda de comprensión</h2>
<p>Es la que nadie contabiliza. Es la distancia entre lo que hace tu software y lo que sabes explicar de él.</p>
<p>Cuando escribes el código a mano, la comprensión viene gratis, como efecto secundario. Cuando lo escribe un agente, la comprensión es un coste aparte que has pagado o has aplazado. Casi todo el vibe coding lo aplaza entero. La app funciona, así que sigues adelante, y el modelo de cómo funciona no vive en ninguna parte salvo en un chat que se fue scroll arriba.</p>
<p>La deuda de comprensión es invisible hasta que necesitas cambiar algo. Entonces cobra intereses a un ritmo brutal, porque cada edición empieza con una sesión de arqueología. Estás haciendo ingeniería inversa de tu propio producto. Ese es el impuesto que hay detrás del <a href="/es/blog/miedo-a-tocar-el-codigo/">miedo a tocar tu propio código</a>: el miedo es racional, y es la deuda de comprensión pasándote la factura.</p>
<p>Lo peligroso es que compone en silencio. Cada feature que el agente añade encima de código que no entendías ensancha la brecha. Para el tercer mes ya no mantienes una app. Negocias con un desconocido que comparte tu repo.</p>
<h2 id="capa-2-deuda-de-tests-y-verificación">Capa 2: deuda de tests y verificación</h2>
<p>Es la deuda que sí se ve, y por eso justamente se confunde con el problema entero.</p>
<p>Las apps hechas con vibe coding suelen salir sin tests, o con tests que el agente escribió para describir lo que el código ya hace en vez de lo que debería hacer. En cualquiera de los dos casos, no tienes señal independiente de que la cosa funciona. Tienes el hecho de que funcionaba la última vez que hiciste clic por ahí, que no es la misma afirmación.</p>
<p>La deuda de verificación tiene una propiedad concreta y desagradable: se mantiene barata justo hasta que es catastrófica. Mientras nadie cambie nada, la ausencia de tests no cuesta nada. En el momento en que tú o un agente publicáis un cambio, los tests que faltan son la razón de que una feature rota llegue a un usuario antes de que te enteres. Ese es el mecanismo detrás de <a href="/es/blog/features-que-rompen-features/">cada feature nueva que rompe una vieja</a>: sin una capa de verificación no hay puerta entre “el agente dijo que funciona” y producción.</p>
<p>Hay una versión peor que no tener tests, que es tener tests que pasan sin demostrar nada. Un agente que informa de “todos los tests en verde” cuando la suite nunca ejecutó el camino que cambió te ha dado un recibo falso. Distinguir un pase real de un build verde que no verifica nada es su propia disciplina, y por eso <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>.</p>
<h2 id="capa-3-deuda-de-arquitectura">Capa 3: deuda de arquitectura</h2>
<p>Es la más lenta y la más cara, y es de la que hablaba la metáfora original.</p>
<p>La deuda de arquitectura es estructural: lógica duplicada que debería ser una función, un modelo de datos que asumió un caso de uso y ahora sirve a cinco, fronteras que nunca se dibujaron, así que todo depende de todo. Los agentes son muy buenos produciendo esto, porque cada prompt es una optimización local. El agente resuelve bien el cambio que tiene delante y no tiene un modelo estable del sistema que está cambiando. El resultado es código <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto y globalmente incoherente</a>: cada pieza defendible, el conjunto derivando.</p>
<p>La deuda de arquitectura cobra el interés más alto de las tres, pero lo cobra tarde. Puedes funcionar sobre una mala arquitectura durante un tiempo sorprendentemente largo. Lo que te roba es tu velocidad futura. La app que tardó un fin de semana en construirse tarda un mes en ampliarse, y la razón nunca es un solo archivo malo. Es el coste acumulado de una estructura que nadie diseñó.</p>
<h2 id="cuándo-vence-cada-una">Cuándo vence cada una</h2>
<p>Las deudas tienen fechas de vencimiento, y conocerlas es cómo dejas de pagar intereses por sorpresa.</p>
<p>La deuda de comprensión vence la primera vez que necesitas cambiar algo no trivial, que en un producto real suele ser dentro del primer mes. Es la factura más temprana y la más frecuente.</p>
<p>La deuda de verificación vence la primera vez que se publica un cambio que rompe algo que no tocaste. No puedes predecir la fecha, pero puedes tener la certeza de que existe, y aterriza más fuerte cuantos más usuarios tengas cuando lo haga.</p>
<p>La deuda de arquitectura vence cuando intentas escalar la app más allá de su forma original: una nueva integración, un segundo tipo de cliente, una feature que cruza otras tres. Es el <a href="/es/blog/vibe-coding-a-produccion/">rango de los 90 días donde las apps hechas con vibe coding tienden a romperse</a>, no por un solo fallo sino porque las tres deudas vencen con semanas de diferencia entre sí.</p>
<h2 id="pagarla-sin-parar-el-mundo">Pagarla sin parar el mundo</h2>
<p>Esto no se arregla reescribiendo. Se arregla pagando las deudas en el orden en que cobran intereses.</p>
<p>Paga primero la de comprensión, porque es la más barata de atender y todo lo demás depende de ella. Antes de tocar una feature, haz que el sistema se explique: qué hace este código, qué asume, qué se rompería si cambiara. No documentas por documentar. Recuperas el modelo que nunca construiste.</p>
<p>Paga la de verificación en segundo lugar, y págala con precisión. No necesitas cobertura total en un prototipo de fin de semana. Necesitas tests en los caminos que dolerían a un usuario si se rompieran, escritos antes de cambiarlos. Esa es también la respuesta real a <a href="/es/blog/cuando-anadir-tests-arquitectura/">cuándo añadir tests y arquitectura</a>: ni el día uno, ni nunca, sino en el momento en que un camino pasa a sostener peso.</p>
<p>Paga la de arquitectura la última y solo donde te bloquee. Refactorizar código que no vas a cambiar es gastar dinero para reducir una factura que no te cobraba intereses. Reestructura la parte que amplías, deja el resto.</p>
<p>El hilo común es que las tres deudas son en realidad una sola cosa que falta: un registro duradero de intención y evidencia que viva fuera de la ventana de contexto del agente. Cuando ese registro no existe, cada cambio empieza de cero. Es el mismo fallo que hace <a href="/es/blog/de-prototipo-a-producto/">imposible ascender un prototipo a producto</a> sin un ajuste de cuentas doloroso.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La razón de que el vibe coding produzca las tres deudas a la vez es que la comprensión del agente, el contrato de aceptación y la evidencia de lo que pasó se evaporan cuando termina la sesión. Nada sobrevive al chat.</p>
<p>PaellaDoc existe para mantener vivo ese registro en local: la intención detrás de un cambio, las decisiones que lo formaron, el código que tocó y la evidencia de que funcionó, conectados en un solo sitio en vez de repartidos por chats. No hace que la deuda desaparezca. Hace que la deuda sea legible, para que veas qué capa debes y la pagues a propósito, en lugar de descubrir el saldo por las malas, el día en que un cambio de dos líneas te cuesta una semana.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿La deuda técnica del vibe coding es peor que la normal?</strong> Es de otra forma. La deuda normal suele ser código que entendías y elegiste no limpiar todavía. El vibe coding añade encima deuda de comprensión: código que nunca leíste, así que debes entenderlo antes incluso de poder evaluar el resto.</p>
<p><strong>¿Tengo que añadir tests a un proyecto de vibe coding de inmediato?</strong> No. Añádelos a los caminos que dolerían a un usuario si se rompieran en silencio, y añádelos antes de cambiar esos caminos. La cobertura total en un prototipo desechable es pagar una deuda que no te cobra intereses.</p>
<p><strong>¿Cómo sé qué deuda pagar primero?</strong> Paga primero la de comprensión porque todo depende de ella, luego la de verificación en los caminos que sostienen peso, y la de arquitectura la última y solo donde bloquee el cambio que de verdad necesitas hacer.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿La deuda técnica del vibe coding es peor que la normal?", "acceptedAnswer": { "@type": "Answer", "text": "Es de otra forma. La deuda normal suele ser código que entendías y elegiste no limpiar todavía. El vibe coding añade encima deuda de comprensión: código que nunca leíste, así que debes entenderlo antes incluso de poder evaluar el resto." } },
    { "@type": "Question", "name": "¿Tengo que añadir tests a un proyecto de vibe coding de inmediato?", "acceptedAnswer": { "@type": "Answer", "text": "No. Añádelos a los caminos que dolerían a un usuario si se rompieran en silencio, y añádelos antes de cambiar esos caminos. La cobertura total en un prototipo desechable es pagar una deuda que no te cobra intereses." } },
    { "@type": "Question", "name": "¿Cómo sé qué deuda pagar primero?", "acceptedAnswer": { "@type": "Answer", "text": "Paga primero la de comprensión porque todo depende de ella, luego la de verificación en los caminos que sostienen peso, y la de arquitectura la última y solo donde bloquee el cambio que de verdad necesitas hacer." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[El software hecho con vibe coding acumula deuda, pero no el número único que sugiere la metáfora. Son tres deudas, comprensión, tests y arquitectura, cada una con su propio vencimiento.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="deuda-tecnica"/><category term="ai-coding"/><category term="mantenibilidad"/><category term="verificacion"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Desarrollo con IA local-first: por qué la fábrica debe vivir en tu Mac</title>
    <link href="https://paelladoc.com/es/blog/desarrollo-ia-local-first/" rel="alternate" type="text/html" title="Desarrollo con IA local-first: por qué la fábrica debe vivir en tu Mac"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/desarrollo-ia-local-first/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/desarrollo-ia-local-first/"><![CDATA[<p><strong>En el desarrollo con IA local-first, los modelos pueden vivir en la nube, pero el sistema que los rodea vive en tu máquina.</strong> La orquestación, el estado, la memoria entre sesiones, la verificación, el bucle de recuperación: eso corre en tu Mac. La inferencia es una llamada que haces fuera y un resultado que traes de vuelta.</p>
<p>Ese reparto no es un apaño. Es el diseño. Y me costó ver por qué es el correcto, porque la versión más ruidosa de “desarrollo con IA” hoy asume lo contrario: que todo, incluido el sistema que coordina el trabajo, pertenece a la pestaña del navegador de alguien.</p>
<p>Voy a defender el reparto tal como muerde de verdad, del dolor que sientes cada día al dolor que sientes una vez por trimestre.</p>
<h2 id="latencia-el-impuesto-que-pagas-en-cada-bucle">Latencia: el impuesto que pagas en cada bucle</h2>
<p>El bucle agéntico es apretado. Lee estado, decide, actúa, comprueba, actualiza estado, repite. Ejecutas ese bucle cientos de veces al día, y cada vez que el estado tiene que viajar a un servidor y volver, pagas el viaje de ida y vuelta.</p>
<p>No duelen los milisegundos en bruto. Duele lo que le hacen a tu atención. Una lectura local está por debajo del umbral en el que tu mente se va. Un viaje de red por la cola de otro, sujeto a sus rate limits una tarde con tráfico, suele estar por encima. Cruza ese umbral suficientes veces y dejas de estar en flow para ser una persona esperando pestañas.</p>
<p>Cuando el estado de la fábrica es un archivo SQLite en tu disco, la latencia entre “decidí esto” y “el agente puede verlo” es una lectura de disco. Lo único que esperas es el modelo, que ibas a esperar de todos modos. Todo lo demás es instantáneo porque todo lo demás es local. Esa es la diferencia que sientes primero, y la que decide si la herramienta desaparece dentro del trabajo o se sienta entre tú y él.</p>
<h2 id="coste-medido-donde-debe-gratis-donde-no">Coste: medido donde debe, gratis donde no</h2>
<p>Aquí hay una distinción que el modelo de precios en la nube borra en silencio. Parte de lo que haces es caro de ejecutar —inferencia de modelo, de verdad—. La mayoría de lo que haces es barato: leer tus propias decisiones, navegar tu propio grafo, comprobar qué hizo un agente, reejecutar un gate. En una herramienta enteramente en la nube, todo eso está detrás del mismo contador, porque el almacenamiento, el cómputo y la coordinación son del proveedor y él los factura.</p>
<p>Local-first pone el contador solo donde está el coste real. La inferencia cuesta lo que cobra el proveedor, y lo pagas directo, con tu propia clave API, sin margen de plataforma encima. Todo lo demás —las lecturas, la coordinación, el estado— no cuesta nada por operación porque ocurre en hardware que ya tienes. Puedes navegar tu grafo de producto mil veces y es gratis. Enrutas el trabajo caro al <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">modelo adecuado sin vendor lock-in</a>, y mantienes el trabajo barato fuera de cualquier contador.</p>
<p>Esto también cambia lo que estás dispuesto a hacer. Cuando coordinar es gratis, coordinas con más cuidado. Cuando cada lectura se mide, lees menos, y tomas peores decisiones con menos contexto porque el contexto tiene precio. Las operaciones locales gratis no son un error de redondeo. Cambian tu comportamiento hacia el sistema.</p>
<h2 id="privacidad-una-propiedad-no-una-promesa">Privacidad: una propiedad, no una promesa</h2>
<p>Tu código es lo de menos. La fábrica guarda las partes que nunca pegarías en un canal público: la estrategia, las apuestas descartadas, las restricciones sensibles de seguridad, los criterios de aceptación que describen exactamente cómo se supone que funciona lo sensible.</p>
<p>Cuando eso vive en tu disco, <a href="/es/blog/el-codigo-se-queda-en-casa/">la privacidad es una propiedad de la arquitectura</a>. Nadie tiene que prometer no mirar, porque en su lado no hay nada que mirar. Tú decides, por llamada, qué fragmento de contexto va a qué proveedor. Por defecto, la forma de tu producto se queda en casa.</p>
<p>Quiero ser claro con el límite, porque la versión real es más útil que la de marketing. Cuando llamas a un modelo remoto, los tokens que envías <a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">van a ese proveedor, bajo sus términos</a>. Local-first no hace que eso desaparezca. Lo que hace es convertirlo en una decisión que tomas a propósito, llamada a llamada, en vez de un valor por defecto donde todo tu espacio de trabajo se sincroniza sin parar a un servidor como precio de usar la herramienta. De eso va tratar la privacidad como decisión de arquitectura y no como una casilla: la pregunta deja de ser “¿confío en su política?” y pasa a ser “¿qué elijo enviar?”.</p>
<h2 id="control-el-que-muerde-una-vez-por-trimestre-pero-muerde-fuerte">Control: el que muerde una vez por trimestre, pero muerde fuerte</h2>
<p>La latencia te molesta a diario. El coste te da la lata cada mes. El control es el que olvidas hasta el día en que importa, y entonces importa del todo.</p>
<p>Un proveedor cambia su precio. Deprecia la función de la que dependía tu flujo. Lo compran y lo apagan. Cambia sus términos de una forma que no habrías aceptado si te preguntan. Se cae la tarde en que ibas a publicar. Cuando tu fábrica vive en su nube, cada una de esas es tu problema, y no tienes más jugada que aceptarlo o migrar a la fuerza.</p>
<p>Cuando la fábrica es local y abierta en sus límites —repositorios git normales, almacenamiento inspeccionable, modelos que puedes cambiar— ninguno de esos eventos puede quitarte el sistema. Que un proveedor desaparezca te cuesta ese proveedor, no la memoria de tu producto. Esta es la menos vistosa de las cuatro razones y la que me negaría a ceder. Poseer aquello sobre lo que construyes no es nostalgia; es la diferencia entre una herramienta y una dependencia a la que no le ves el fondo.</p>
<h2 id="qué-no-es-local-first">Qué no es local-first</h2>
<p>No es maximalismo offline, ni la pretensión de que tu portátil haga la inferencia. Los modelos frontier corren en centros de datos por buenas razones, y fingir que un MacBook de 16 pulgadas compite con eso sería mentira. Local-first no es anti-nube. Es específico sobre qué partes van dónde.</p>
<p>La regla es simple. Lo que es genuinamente caro y genuinamente mejora con la escala —la inferencia— puede ser remoto. Lo que define tu producto y deberías poseer —el contrato, el grafo, las decisiones, la prueba— se queda local. No rechazas la nube. Te niegas a alquilar las partes que deberías poseer.</p>
<p>Y fíjate en que las cuatro razones se apilan en vez de competir. La misma decisión de diseño que te da latencia a velocidad de disco es la que mantiene la coordinación fuera de un contador, la forma de tu producto fuera de un servidor y el mal día de un proveedor lejos del tuyo. No cambias una por otra. Poner el sistema en tu máquina compra las cuatro a la vez, y por eso local-first es una sola decisión y no cuatro features separadas que tienes que ensamblar.</p>
<figure class="tp-diagram tp-diagram--levels" data-diagram-type="levels" role="img" aria-label="Las cuatro razones ordenadas por cuánto te muerden: la latencia en cada bucle, el coste cada mes, la privacidad siempre, el control rara vez pero fuerte. Una decisión compra las cuatro."><svg viewBox="0 0 760 272" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="20" width="140" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="46" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">LATENCIA</text><rect x="40" y="78" width="280" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="104" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">COSTE</text><rect x="40" y="136" width="420" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="162" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">PRIVACIDAD</text><rect x="40" y="194" width="560" height="40" fill="var(--tp-mostaza)" stroke="var(--tp-mostaza)" stroke-width="1.5" fill-opacity="0.14"></rect>
  <text x="52" y="220" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">CONTROL</text></svg><figcaption>Las cuatro razones ordenadas por cuánto te muerden: la latencia en cada bucle, el coste cada mes, la privacidad siempre, el control rara vez pero fuerte. Una decisión compra las cuatro.</figcaption></figure>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc es la <a href="/es/blog/fabrica-local-de-software/">fábrica local de software</a> construida local-first justo por estas cuatro razones. Corre sobre <a href="/es/blog/herramientas-nativas-macos/">herramientas nativas de macOS</a>, mantiene tu grafo de producto, tus repositorios y tu evidencia en almacenamiento local en tu máquina, y llama a los modelos que elijas —proveedores en la nube con tus propias claves, o motores locales— sin enrutar tu espacio de trabajo por el servidor de nadie. Gratis hasta tres proyectos, sin cuenta.</p>
<p>Los modelos seguirán mejorando, y seguirán viviendo en centros de datos. Está bien. El sistema que convierte un modelo en una fábrica —la parte que planifica, recuerda, verifica y recupera— es la parte que debería vivir donde puedas verla, en la máquina que tienes delante.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-significa-desarrollo-con-ia-local-first">¿Qué significa desarrollo con IA local-first?</h3>
<p>El desarrollo con IA local-first mantiene el sistema que rodea a los modelos en tu máquina mientras los modelos siguen siendo remotos. La orquestación, el estado, la memoria entre sesiones, la verificación y la recuperación corren en tu Mac; la inferencia es una llamada que haces fuera y un resultado que traes de vuelta. El reparto es deliberado. La parte cara que mejora con la escala puede ser remota, y las partes que definen tu producto se quedan locales.</p>
<h3 id="es-privado-el-desarrollo-con-ia-en-local">¿Es privado el desarrollo con IA en local?</h3>
<p>La privacidad pasa a ser una propiedad de la arquitectura en lugar de una promesa. Tu estrategia, tus apuestas descartadas y tus criterios de aceptación viven en tu disco, así que en el lado del proveedor no hay nada que mirar. El límite real: cuando llamas a un modelo remoto, los tokens que envías van a ese proveedor bajo sus términos. Local-first convierte eso en una decisión por llamada, no en un valor por defecto donde todo tu espacio de trabajo se sincroniza a un servidor.</p>
<h3 id="necesito-ejecutar-los-modelos-de-ia-en-mi-ordenador-para-ser-local-first">¿Necesito ejecutar los modelos de IA en mi ordenador para ser local-first?</h3>
<p>No. Local-first no es maximalismo offline ni pretende que tu portátil haga la inferencia. Los modelos frontier corren en centros de datos por buenas razones. Lo que se queda local es el contrato, el grafo, las decisiones y la prueba: las partes que definen tu producto y que deberías poseer. Los modelos siguen siendo remotos, llamados con tus propias claves. Te niegas a alquilar las partes que deberías poseer, no la nube en sí.</p>
<h3 id="el-desarrollo-local-first-es-más-lento-que-las-herramientas-en-la-nube">¿El desarrollo local-first es más lento que las herramientas en la nube?</h3>
<p>Suele ser más rápido donde importa la velocidad. El bucle agéntico lee estado, decide, actúa y actualiza cientos de veces al día. Cuando el estado es un archivo SQLite en tu disco, cada lectura va a velocidad de disco en vez de un viaje de red por los rate limits de otro. Lo único que esperas es el modelo, que ibas a esperar de todos modos. Todo lo demás es instantáneo porque todo lo demás es local.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="local-first"/><category term="fabrica-local-de-software"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="herramientas-de-desarrollo"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Desarrollo basado en evidencia: cerrar trabajo con la prueba adjunta</title>
    <link href="https://paelladoc.com/es/blog/desarrollo-basado-en-evidencia/" rel="alternate" type="text/html" title="Desarrollo basado en evidencia: cerrar trabajo con la prueba adjunta"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/desarrollo-basado-en-evidencia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/desarrollo-basado-en-evidencia/"><![CDATA[<p>El test se ejecutó. Imprimió verde. Lo viste pasar. Luego integraste, cerraste la tarea y pasaste a la siguiente, y el verde se fue scroll arriba de la terminal y desapareció, como lo tira casi cualquier flujo. Tres semanas después algo se rompe cerca y no puedes responder una pregunta básica: ¿aquel test llegó a pasar de verdad, y contra qué versión del requisito? La prueba existió unos cuatro segundos y luego la tiraste.</p>
<p>El desarrollo basado en evidencia es la disciplina pequeña y aburrida de no tirarla. Cierra el trabajo con la prueba adjunta.</p>
<h2 id="el-estado-no-es-evidencia">El estado no es evidencia</h2>
<p>Empieza por una distinción que la mayoría de las herramientas difuminan a propósito. Una casilla completada, una pull request integrada, un badge verde, son <em>estado</em>. Te dicen que se declaró un estado. No llevan casi información sobre si la cosa subyacente es cierta, porque son trivialmente fáciles de poner sin que la cosa sea cierta. Una casilla es un clic. Un badge verde puede posarse sobre una suite que nunca se ejecutó.</p>
<p>La evidencia es distinta en su naturaleza. La evidencia es lo que pasó de verdad, registrado: el comando que se ejecutó, la salida que produjo, la versión del contrato contra la que corrió. Puedes inspeccionar la evidencia y reconstruir la verdad a partir de ella. De una casilla no puedes reconstruir nada salvo que alguien, o algo, la marcó. La misma distinción gobierna <a href="/es/blog/decisiones-con-evidencia/">cómo deberían tomarse las decisiones de producto</a>, no solo cómo se cierra el código.</p>
<p>El hueco importa más justo cuando menos te lo puedes permitir: cuando el autor fue un modelo y nadie miró cada línea. Un autor humano lleva el contexto en la cabeza y se le puede preguntar. Un modelo produjo un artefacto plausible y siguió adelante. El único relato duradero de si funciona es la evidencia que capturaste, porque no hay autor al que interrogar después. Es la misma razón por la que un <a href="/es/blog/exitos-falsos-de-agentes/">éxito falso</a> es tan peligroso. «Los tests pasan» como frase es estado. «Los tests pasan» como ejecución capturada contra un contrato nombrado es evidencia. Se leen igual y no son lo mismo.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="El estado dice que se declaró algo. La evidencia es lo que pasó, registrado, para reconstruir la verdad."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">estado</p>
    <ul><li>casilla marcada</li><li>PR integrada</li><li>badge verde</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">evidencia</p>
    <ul><li>el comando que corrió</li><li>su salida real</li><li>la versión del contrato</li></ul>
  </div>
</div><figcaption>El estado dice que se declaró algo. La evidencia es lo que pasó, registrado, para reconstruir la verdad.</figcaption></figure>
<h2 id="qué-capturar-y-dónde-vive">Qué capturar, y dónde vive</h2>
<p>El desarrollo basado en evidencia es concreto, no una filosofía. Para una unidad de trabajo, captura:</p>
<ul>
<li><strong>Qué se ejecutó.</strong> Los comandos e invocaciones reales, no un resumen de ellos.</li>
<li><strong>Qué produjo.</strong> La salida y los códigos de salida, tal como salieron, no comprimidos en «tiene buena pinta».</li>
<li><strong>Contra qué contrato.</strong> Los criterios de aceptación, en la revisión en la que estaban, para que un verde no pueda derivar en silencio a referirse a los requisitos de ayer.</li>
</ul>
<p>Y luego la parte que todos se saltan: ponlo en algún sitio donde sobreviva. La evidencia que vive en un scrollback de terminal, un log de CI que caduca, o un chat al que nunca volverás a subir es evidencia que no tienes. Tiene que engancharse al cambio, viajar con él y ser encontrable por la siguiente persona y el siguiente agente sin arqueología. Una prueba que no puedes recuperar es indistinguible de una prueba que nunca tuviste.</p>
<p>Por eso una especificación es solo la mitad de lo que necesitas. Una <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">especificación portable</a> lleva la intención y el contrato; la evidencia es lo que prueba que el contrato se cumplió, y tiene que viajar en el mismo sobre o la spec es una promesa sin recibo.</p>
<h2 id="la-evidencia-caduca-y-eso-es-una-virtud">La evidencia caduca, y eso es una virtud</h2>
<p>Una objeción habitual: la evidencia se queda obsoleta. El test pasó contra la versión 3 del contrato, el contrato va ya por la versión 5, así que el verde capturado ya no prueba nada. Cierto. Y es justo por eso que la evidencia le gana a una casilla pelada en vez de compartir su debilidad.</p>
<p>Una casilla que se queda obsoleta sigue marcada. No lleva versión, así que nada en ella anuncia que ahora miente. Parece tan válida el día en que quedó obsoleta como el día en que se ganó, que es la peor propiedad que puede tener un estado. La evidencia que nombra la versión del contrato contra la que corrió se queda obsoleta <em>de forma visible</em>. Cuando el contrato pasa a la versión 5, una ejecución registrada contra la versión 3 queda en entredicho por sí sola, y el sistema puede marcarla: esta prueba se refiere a requisitos que desde entonces han cambiado, re-verifica antes de fiarte.</p>
<p>Eso no es la evidencia fallando. Es la evidencia haciendo lo único que el estado no puede, avisarte de cuándo ha dejado de ser cierta. Una obsolescencia que puedes detectar es un problema resuelto, re-ejecutas y vuelves a capturar. Una obsolescencia que no puedes detectar es como una base de código se llena de verdes que se refieren a un mundo que ya no existe. Capturar la versión del contrato junto a la ejecución es lo que convierte la primera situación en la segunda, y no cuesta más que la disciplina de registrar contra qué versión comprobaste. Es la misma razón por la que una especificación y su prueba tienen que viajar juntas: un contrato que se mueve mientras su evidencia se queda atrás es una promesa que nadie puede auditar.</p>
<h2 id="la-evidencia-hace-barata-la-confianza">La evidencia hace barata la confianza</h2>
<p>Aquí está por qué esto se paga solo. Sin evidencia capturada, fiarte del estado del sistema significa reestablecerlo a mano cada vez que lo necesitas. ¿Esto sigue funcionando? Mejor lo re-ejecuto. ¿Aquello pasó alguna vez? Mejor lo compruebo. Cada pregunta sobre el pasado se vuelve una verificación fresca en el presente, y con agentes produciendo a volumen, las preguntas no paran.</p>
<p>Con la evidencia adjunta, el pasado responde a sus propias preguntas. Abres el registro en vez de reconstruirlo. Esa es la diferencia entre un sistema cuya fiabilidad tienes que re-ganar sin parar y uno cuya fiabilidad puedes consultar. Es la forma práctica de que <a href="/es/blog/verificar-codigo-generado-por-ia/">el cuello de botella sea la confianza, no el output</a>: la evidencia es lo que convierte la confianza de un coste recurrente en un activo guardado. También es lo que hace que la <a href="/es/blog/aseguramiento-de-software/">estación de aseguramiento</a> pueda seguir el ritmo, porque asegurar un cambio que llega con su prueba es una lectura, no una re-ejecución.</p>
<h2 id="la-evidencia-cierra-el-bucle-que-abre-hecho">La evidencia cierra el bucle que abre «hecho»</h2>
<p>Esto conecta directo con lo que significa la compleción. Si <a href="/es/blog/hecho-significa-hecho/">hecho exige una demostración</a>, la demostración es exactamente la evidencia, y el desarrollo basado en evidencia es solo la insistencia en que la demostración no se evapore en el momento en que la tarea cierra. La compleción produce la prueba; el desarrollo basado en evidencia la conserva. Uno sin el otro es medio bucle. Demostrar hecho y luego descartar la demostración te deja fiándote del recuerdo de un verde que ya no puedes ver.</p>
<p>El revisor también lo siente. Cuando el trabajo cierra con su evidencia adjunta, el último y más importante paso de la revisión, comprobar qué se ejecutó de verdad, es leer un registro en vez de reconstruirlo, que es buena parte de la salida de la <a href="/es/blog/fatiga-de-revision/">fatiga de review</a>.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/">PaellaDoc</a> captura la evidencia como subproducto del trabajo en vez de como una tarea aparte que nadie hace. Cuando una tarea cierra, qué se ejecutó, qué pasó y el contrato contra el que corrió quedan registrados junto al cambio, no abandonados a evaporarse en una terminal. El estado del sistema deja de ser algo de lo que te fías por fe o que re-verificas a mano, y pasa a ser algo que puedes abrir y leer.</p>
<p>Hay un cambio cultural enterrado en esto, y conviene decirlo claro. Adjuntar evidencia se siente como trabajo extra en el momento, y el momento siempre está ocupado, así que es lo primero que se abandona bajo presión. Ese instinto está del revés. La evidencia que hoy no capturas es la re-verificación manual a la que te apuntas la semana que viene, con intereses, en el peor momento posible, cuando algo ya se está rompiendo e intentas reconstruir si alguna vez funcionó. Capturar la prueba no es un sobrecoste encima del trabajo. Es el trabajo, aplazado o hecho, y aplazado siempre sale más caro.</p>
<p>Los modelos seguirán produciendo artefactos plausibles a un ritmo que ningún humano puede re-comprobar. Adjuntar la prueba, y conservarla, es cómo sigues pudiendo fiarte del sistema sin auditarlo desde cero cada vez que lo miras.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-el-desarrollo-basado-en-evidencia">¿Qué es el desarrollo basado en evidencia?</h3>
<p>Es la disciplina de cerrar cada unidad de trabajo con su prueba adjunta: qué se ejecutó, qué produjo y contra qué versión del contrato, guardado donde la siguiente persona y el siguiente agente puedan encontrarlo. Existe porque la mayoría de los flujos se quedan el diff y tiran la prueba, el verde se va scroll arriba de la terminal y desaparece. Cuando el autor es a menudo un modelo que nadie miró línea a línea, la evidencia capturada es el único relato duradero de si el trabajo funciona.</p>
<h3 id="cuál-es-la-diferencia-entre-estado-y-evidencia">¿Cuál es la diferencia entre estado y evidencia?</h3>
<p>El estado es una casilla marcada, una pull request integrada, un badge verde. Te dice que se declaró un estado y no lleva casi información sobre si la cosa subyacente es cierta, porque es trivialmente fácil de poner sin que lo sea. La evidencia es lo que pasó de verdad, registrado: el comando que se ejecutó, su salida real, la versión del contrato. De la evidencia puedes reconstruir la verdad; de una casilla solo puedes reconstruir que alguien la marcó.</p>
<h3 id="qué-debo-capturar-como-evidencia-de-una-tarea-terminada">¿Qué debo capturar como evidencia de una tarea terminada?</h3>
<p>Tres cosas, más un sitio donde guardarlas. Los comandos e invocaciones reales, no un resumen. La salida y los códigos de salida tal como salieron, no comprimidos en «tiene buena pinta». Y los criterios de aceptación en la revisión en la que estaban, para que un verde no derive en silencio a los requisitos de ayer. Luego engánchalo al cambio para que viaje con él. Una prueba que no puedes recuperar es indistinguible de una que nunca tuviste.</p>
<h3 id="la-evidencia-capturada-no-se-queda-obsoleta-y-deja-de-servir">¿La evidencia capturada no se queda obsoleta y deja de servir?</h3>
<p>Se queda obsoleta de forma visible, que es justo el punto. Una casilla que caduca sigue marcada y no anuncia nada. La evidencia que nombra la versión del contrato contra la que corrió queda en entredicho por sí sola en cuanto el contrato se mueve, así que el sistema puede marcarla: esta prueba se refiere a requisitos que han cambiado, re-verifica. Una obsolescencia que puedes detectar es un problema resuelto, re-ejecutas y vuelves a capturar. Una que no puedes detectar es como una base de código se llena de verdes que se refieren a un mundo que ya no existe.</p>]]></content>
    <summary type="html"><![CDATA[Una casilla marcada es estado. No es evidencia. El desarrollo basado en evidencia cierra el trabajo con su prueba adjunta: qué se ejecutó, qué pasó, contra qué versión del contrato, guardado donde la siguiente persona y el siguiente agente puedan encontrarlo. Cuando el autor es a menudo un modelo, la prueba duradera es lo único que te deja fiarte del estado del sistema sin re-verificarlo a mano.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="evidence-based-dev"/><category term="ai-coding"/><category term="verificacion"/><category term="aseguramiento-de-software"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Una definición de «hecho» que sobrevive a la velocidad de la IA</title>
    <link href="https://paelladoc.com/es/blog/definicion-de-hecho/" rel="alternate" type="text/html" title="Una definición de «hecho» que sobrevive a la velocidad de la IA"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/definicion-de-hecho/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/definicion-de-hecho/"><![CDATA[<p>Un agente termina y escribe «Hecho». Has leído esa palabra mil veces de compañeros humanos y pesaba, porque detrás había una persona que había juzgado el trabajo, sabía que sería suyo el bug si se equivocaba, y estaba gastando su credibilidad en la afirmación. El <a href="/es/blog/hecho-significa-hecho/">«hecho» del agente</a> se ve idéntico y no carga nada de eso. Es la palabra más probable que emitir tras una interacción con forma de tarea. No apuesta nada, no significa nada, y llega con seguridad total.</p>
<p>Así que la definición de «hecho» que venías usando se rompió en silencio. Daba por hecho a un humano detrás de la palabra. Quita al humano y la palabra queda vacía, y todo proceso construido sobre creerla ahora no cree nada.</p>
<h2 id="lo-que-hecho-colaba-de-contrabando">Lo que «hecho» colaba de contrabando</h2>
<p>La vieja definición de «hecho» funcionaba en parte sobre el papel y en parte sobre una persona. Sobre el papel decía cosas como: código escrito, tests pasando, revisado, integrado. Pero mucho del aseguramiento real no estaba en la checklist. Viajaba dentro del humano. Cuando un desarrollador decía «hecho», respondía implícitamente de que había ejecutado la cosa, de que entendía lo que cambió, de que habría notado si rompía algo cercano, de que no iba a quedar como un idiota en la daily de mañana. La checklist era un suelo. La persona era el techo.</p>
<p>Los agentes quitaron a la persona y dejaron la checklist, y la checklist a solas resulta ser una cosa débil. «Tests pasando» significa que el agente dijo que los tests pasan, que no es lo mismo que que los tests hayan corrido. «Revisado» significa que alguien ojeó un diff demasiado grande para verificarse de verdad. «Código escrito» es el único ítem fiablemente cierto, y nunca fue el punto. Las partes de «hecho» que hacían el trabajo real eran las que vivían en el juicio y la apuesta de un humano, y esas no se transfirieron al agente junto con el tecleo.</p>
<h2 id="hecho-ya-no-puede-ser-un-estado">«Hecho» ya no puede ser un estado</h2>
<p>Aquí está el desplazamiento, y no es sutil. «Hecho» ya no puede ser un estado que algo declara. Tiene que ser un estado que la evidencia demuestra.</p>
<p>Un estado es una etiqueta. «Completo». «Pasando». «Listo». Un agente puede producir cualquier etiqueta al instante, y lo hará, porque producir la etiqueta que encaja con una tarea de aspecto terminado es justo lo que optimiza. Una etiqueta no vale nada como señal precisamente cuando más la necesitas, en la frontera entre funcionar y estar roto, porque la etiqueta se ve igual en ambos lados.</p>
<p>La evidencia es distinta. La evidencia es un artefacto que puedes inspeccionar que se vería distinto si el trabajo no estuviera hecho de verdad. Un proceso de test que salió con código cero, con su salida guardada. Un build que produjo un binario que corre. Un diff que un escaneo de seguridad dio por limpio, con el informe adjunto. La captura, el log, la ejecución grabada. La propiedad que define a la evidencia es que no puedes generarla siendo seguro de ti mismo. Existe porque algo real ocurrió, o no existe. Una definición de «hecho» construida sobre evidencia sobrevive a la velocidad de la IA porque la fluidez del agente, su único superpoder, no le compra nada. No puede convencer a una suite de tests de que salga con código cero.</p>
<p>Esta es la idea entera detrás de cerrar el trabajo con la <a href="/es/blog/desarrollo-basado-en-evidencia/">prueba adjunta en vez de con el estado declarado</a>, y es la única versión de «hecho» que significa algo cuando la entidad que lo informa no apuesta nada por acertar.</p>
<h2 id="reconstruir-la-definición-ítem-a-ítem">Reconstruir la definición, ítem a ítem</h2>
<p>Coge cada línea de tu vieja definición de «hecho» y pregunta: ¿cuál es la evidencia y quién la produjo? Si la respuesta es «lo dice el agente», reescríbela.</p>
<p>No <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">«los tests pasan»</a> sino «la suite de tests corrió y su salida está adjunta». La distinción es la reforma entera. Una es una afirmación que hace el agente, la otra es un registro que produjo un proceso. Adjunta la ejecución, no el resumen de la ejecución.</p>
<p>No «cumple los requisitos» sino «contrastado contra <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación</a> que existían antes del código». Si la corrección se juzga contra criterios escritos después de ver la implementación, la implementación definió su propia nota de aprobado. Los criterios tienen que ser anteriores al código, y la comprobación contra ellos tiene que quedar registrada.</p>
<p>No «revisado» sino «el radio de impacto se verificó mecánicamente, y un humano confirmó el alcance y las líneas que cargan riesgo». La review de código de agente que significa algo empieza por el alcance y va respaldada por evidencia, no es un diff que alguien scrolleó. Di qué parte respaldó una máquina y qué parte una persona.</p>
<p>No «sin problemas obvios» sino «las comprobaciones que pueden fallar corrieron y pasaron». Un «hecho» que solo incluye comprobaciones que siempre tienen éxito es teatro. Cada condición de la definición debería ser algo que pudiera volver en rojo, o no está verificando nada.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Mismas palabras, otro objeto: cada línea pasa de una afirmación del agente a un artefacto que produjo un proceso."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">hecho de antes</p>
    <ul><li>tests pasan</li><li>cumple requisitos</li><li>revisado</li><li>sin problemas obvios</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">hecho a velocidad IA</p>
    <ul><li>salida adjunta</li><li>contrastado vs criterios</li><li>radio verificado</li><li>checks que fallan corren</li></ul>
  </div>
</div><figcaption>Mismas palabras, otro objeto: cada línea pasa de una afirmación del agente a un artefacto que produjo un proceso.</figcaption></figure>
<p>El patrón en todas: sustituye la palabra del agente por un artefacto, y nombra el proceso que hizo el artefacto. Lo que en realidad haces es sacar las partes de «hecho» que solían vivir en el juicio de un humano hacia evidencia explícita y producida, porque el humano que las sostenía ya no está en el bucle, y el agente que lo sustituyó no es de fiar para sostener nada.</p>
<h2 id="hecho-viaja-con-el-trabajo-o-no-cuenta">«Hecho» viaja con el trabajo o no cuenta</h2>
<p>Una propiedad más que la definición a velocidad de IA necesita. La evidencia tiene que viajar adjunta al trabajo, no vivir en un sitio aparte que alguien tenga que ir a ensamblar luego. La razón es el volumen. Cuando una persona publica el código de una semana en un día, «reunimos la evidencia en la release» significa que la evidencia no se reúne nunca, porque la release es una avalancha y nadie va a reconstruir la prueba de cuarenta cambios integrados a posteriori.</p>
<p>Así que «hecho» significa que la prueba se adjunta en el momento de completar, por cambio, automáticamente, o «hecho» no significa nada. Una definición de «hecho» que exige que un humano recopile evidencia a mano no sobrevive a la velocidad de la IA por la misma razón que no sobrevivió la palabra del humano: da por supuesta a una persona lenta y cuidadosa en un bucle que ya no es ni lento ni está dotado de personal. La evidencia la tiene que producir y atar al trabajo el proceso que hace el trabajo.</p>
<p>Aquí es donde la definición de «hecho» deja de ser una página de wiki que nadie lee y se vuelve algo operativo, un gate. Y conecta directo con <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado por IA</a>, porque una definición de «hecho» construida sobre evidencia es solo la verificación enunciada como política: nada está hecho hasta que existe y está adjunta la prueba de que lo está.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Una definición de «hecho» que vive como evidencia adjunta por cambio, producida automáticamente, no es algo que puedas sostener en la cabeza a lo largo de cuarenta merges al día. PaellaDoc lo vuelve trabajo del sistema. Los criterios de aceptación se ponen antes de generar. Las comprobaciones corren y su salida se captura. El trabajo no llega a «hecho» hasta que la evidencia existe, y la evidencia viaja con el cambio en vez de esperar a ensamblarse en la release. Defines una vez qué significa hecho, en términos de prueba y no de la palabra del agente, y la fábrica se niega a llamar terminado a nada hasta que puede enseñarte por qué.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-el-hecho-de-un-agente-de-ia-no-significa-nada">¿Por qué el «hecho» de un agente de IA no significa nada?</h3>
<p>Cuando un humano decía «hecho», respondía de que había ejecutado la cosa, entendía el cambio y sería suyo el bug si se equivocaba. Ese aseguramiento vivía en el juicio y la apuesta de la persona, no en la checklist. Un agente emite «hecho» como la palabra más probable tras una interacción con forma de tarea. No apuesta nada y llega con seguridad total funcione la feature o no, así que todo proceso construido sobre creer la palabra ahora no cree nada.</p>
<h3 id="cómo-escribo-una-definición-de-hecho-para-trabajo-generado-por-ia">¿Cómo escribo una definición de «hecho» para trabajo generado por IA?</h3>
<p>Coge cada línea de tu vieja definición y pregunta: ¿cuál es la evidencia y quién la produjo? Si la respuesta es «lo dice el agente», reescríbela. No «los tests pasan» sino «la suite corrió y su salida está adjunta». No «cumple los requisitos» sino «contrastado contra criterios de aceptación que existían antes del código». No «revisado» sino «radio de impacto verificado mecánicamente, alcance confirmado por un humano». Sustituye la palabra del agente por un artefacto y nombra el proceso que lo hizo.</p>
<h3 id="cuál-es-la-diferencia-entre-un-estado-y-la-evidencia-en-una-definición-de-hecho">¿Cuál es la diferencia entre un estado y la evidencia en una definición de «hecho»?</h3>
<p>Un estado es una etiqueta, «completo», «pasando», «listo», que un agente produce al instante, y se ve idéntica a ambos lados de la frontera entre funcionar y estar roto. La evidencia es un artefacto que puedes inspeccionar que se vería distinto si el trabajo no estuviera hecho de verdad: un proceso de test que salió con código cero con su salida guardada, un build que produjo un binario que corre. No puedes generar evidencia siendo seguro de ti mismo. Existe porque algo real ocurrió, o no existe.</p>
<h3 id="la-evidencia-de-hecho-tiene-que-recopilarse-automáticamente">¿La evidencia de «hecho» tiene que recopilarse automáticamente?</h3>
<p>Sí, o no se recopila. Cuando una persona publica el código de una semana en un día, «reunimos la evidencia en la release» significa que nadie reconstruye la prueba de cuarenta cambios integrados a posteriori. «Hecho» significa que la prueba se adjunta en el momento de completar, por cambio, por el proceso que hace el trabajo. Una definición que necesita que un humano ensamble la evidencia después da por supuesto un bucle lento y dotado de personal que ya no existe.</p>]]></content>
    <summary type="html"><![CDATA[Tu definición de «hecho» se escribió para un mundo donde una persona tecleaba el código y su palabra significaba algo. «Hecho» quería decir que un humano había juzgado el trabajo terminado y ponía su credibilidad detrás. Un agente dice «hecho» con la misma fluidez funcione la feature o no, y su palabra no apuesta nada. Una definición de «hecho» que sobrevive a la velocidad de la IA no puede ser un estado que el agente declara. Tiene que ser un conjunto de condiciones con evidencia adjunta, producida por procesos que el agente no controló, para que «hecho» pase a ser algo que puedes verificar en vez de algo que tienes que creer.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="definition-of-done-ai"/><category term="ai-coding"/><category term="verification"/><category term="evidence-based-development"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Decisiones de producto con la evidencia adjunta</title>
    <link href="https://paelladoc.com/es/blog/decisiones-con-evidencia/" rel="alternate" type="text/html" title="Decisiones de producto con la evidencia adjunta"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/decisiones-con-evidencia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/decisiones-con-evidencia/"><![CDATA[<p>Abre el <a href="/es/blog/registro-de-decisiones/">historial de decisiones de tu equipo</a>, si lo tienes, y lee una entrada de hace tres meses. «Decidimos construir X.» Ahora intenta contestar por qué. No la historia que recuerdas, la evidencia que había de verdad sobre la mesa cuando se tomó la decisión. ¿Qué sabías? ¿Qué asumías? ¿Qué te habría hecho cambiar de opinión? Para casi todas las decisiones, esa información desapareció. La decisión sobrevivió. Todo lo que la justificaba se evaporó.</p>
<p>Ingeniería resolvió una versión de este problema y le puso nombre. Hecho significa hecho. Afirmar que una tarea está completa no vale nada por sí solo, porque es trivial de declarar. Lo que lo vuelve fiable es <a href="/es/blog/desarrollo-basado-en-evidencia/">la prueba viajando con la afirmación</a>: <a href="https://dora.dev/capabilities/test-automation/">el test que se ejecutó</a>, la salida que produjo, el contrato contra el que corrió. La finalización y su evidencia se mueven juntas o la finalización es solo una frase. Las decisiones de producto necesitan la misma regla, y casi nunca la reciben.</p>
<h2 id="una-decisión-sin-evidencia-es-un-rumor-con-fecha">Una decisión sin evidencia es un rumor con fecha</h2>
<p>Dilo claro, porque la versión suave nos deja a todos sin responsabilidad. Una decisión registrada como «elegimos X» y nada más no es una decisión que nadie pueda auditar. Es un rumor con fecha. Sabes que se tomó una elección y más o menos cuándo. No sabes sobre qué base, lo que significa que después no puedes distinguir si fue una buena decisión que envejeció mal o una mala que tuvo suerte, y no puedes saber si lo que la justificaba sigue siendo cierto.</p>
<p>Esto importa más ahora, no menos, y por la misma razón que reformó el <a href="/es/blog/product-management-era-ia/">product management en la era IA</a>. Cuando construir era la parte cara, el volumen de decisiones lo frenaba de forma natural cuánto podías construir. Ahora los agentes construyen en horas, así que tomas más decisiones, más rápido, con menos deliberación por decisión. La tasa de decisiones subió y la evidencia por decisión bajó. Un equipo puede acumular un trimestre de elecciones inauditables en un mes, y descubrir solo cuando algo se rompe que no puede reconstruir por qué se construyó nada.</p>
<h2 id="qué-significa-de-verdad-evidencia-adjunta">Qué significa de verdad «evidencia adjunta»</h2>
<p>Decidir con evidencia es una disciplina concreta, no un valor. Cuando una decisión se cierra, tres cosas se le adjuntan y viajan con ella.</p>
<p>La evidencia que la sostuvo. No el resumen de una sensación. Los inputs reales: la señal del usuario, el dato de uso, lo concreto que viste u oíste que apuntaba por aquí. Si la respuesta de verdad es «una corazonada fuerte», está permitido, y se registra como corazonada, que es un registro muy distinto de «lo dijo el dato». El registro tiene que preservar cuál de las dos era.</p>
<p>El supuesto en el que se apoya. Toda decisión tiene debajo una creencia que la sostiene, lo que, si fuera falso, haría la decisión errónea. Nombrarlo es la mayor parte del valor, porque un supuesto sin nombrar no puede revisarse cuando el mundo cambia. «Decidimos construir X, asumiendo Y» es auditable. «Decidimos construir X» esconde Y donde nadie puede comprobar si sigue en pie.</p>
<p>El test que la refutaría. Qué te diría que esto estaba mal, y cuándo lo vas a mirar. Una decisión sin test de refutación es una decisión que has vuelto infalsificable en silencio, lo que significa que la defenderás para siempre pase lo que pase, porque nunca dijiste qué aspecto tendría el fracaso.</p>
<h2 id="no-toda-fuente-permite-la-misma-afirmación">No toda fuente permite la misma afirmación</h2>
<p>Esta es la parte que casi todos los registros de decisión hacen mal, y es la misma disciplina que gobierna la <a href="/es/blog/de-repo-a-artefactos/">capa de reverse intake de un grafo de producto</a>: la fuerza de una afirmación está limitada por la fuerza de lo que la respalda, y mezclar las dos es como las decisiones que suenan seguras se construyen sobre nada.</p>






























<table><thead><tr><th>Lo que quieres afirmar</th><th>Lo que necesita</th><th>Lo que no sobrevive</th></tr></thead><tbody><tr><td>«El usuario siente este dolor»</td><td>usuarios reales, conducta observada</td><td>la conjetura plausible de un modelo</td></tr><tr><td>«Esto moverá la métrica»</td><td>un resultado previo o una prueba</td><td>una analogía con otro producto</td></tr><tr><td>«Lo decidimos a propósito»</td><td>una elección humana registrada</td><td>un default que nadie cuestionó</td></tr><tr><td>«Es la apuesta más barata»</td><td>una comparación que hiciste de verdad</td><td>la primera opción que pareció bien</td></tr></tbody></table>
<p>La regla no es que las corazonadas estén prohibidas. Es que una corazonada tiene que registrarse como corazonada y no blanquearse nunca en «lo mostró la evidencia». Cuando una decisión adjunta su evidencia, quien la lee ve la diferencia entre una decisión respaldada por conducta observada del usuario y una respaldada por una frase segura, y las pondera en consecuencia. Cuando falta la evidencia, todo se lee con la misma falsa certeza, y las decisiones peor respaldadas se vuelven indistinguibles de las mejores.</p>
<h2 id="la-ia-hace-fácil-adjuntar-evidencia-y-peligroso-saltársela">La IA hace fácil adjuntar evidencia y peligroso saltársela</h2>
<p>Hay una simetría que conviene notar. La misma velocidad que abarata las decisiones también abarata adjuntar su evidencia. Un agente puede sacar los números de uso, reunir las señales relevantes y redactar el supuesto y el test de refutación tan rápido como produce el prototipo. La fricción que antes hacía cara la buena higiene de decisiones casi ha desaparecido.</p>
<p>El peligro es que la IA también es muy buena produciendo la decisión que suena segura sin nada de eso. Pídele a un modelo una recomendación y te dará una respuesta fluida, estructurada y plausible sin evidencia adjunta y sin supuesto nombrado, y se leerá como rigor. Ese es el modo de fallo: una decisión que <a href="/es/blog/slop-de-ia-en-producto/">parece deliberada porque está bien formateada</a>, apoyada en nada que pudieras comprobar. Adjuntar evidencia es lo que separa una decisión real de una conjetura bien escrita, y cuanto mejor se vuelve la escritura, más depende esa separación de que la evidencia esté ahí y no de que la prosa suene segura.</p>
<h2 id="la-prueba-de-la-auditoría">La prueba de la auditoría</h2>
<p>La medida de si estás haciendo esto es simple. Coge una decisión de hace un trimestre e intenta auditarla en frío, sin preguntar a nadie. Si puedes ver qué se sabía, qué se asumió y qué la habría refutado, la decisión se cerró con su evidencia adjunta. Si solo puedes ver que se tomó una elección, tienes una fecha y un rumor, y estás a punto de rediscutir de memoria un debate que ya tuviste, con peor información que la primera vez.</p>
<p>Corre esto sobre diez decisiones. La proporción te dice cuánto del razonamiento de tu producto es auditable y cuánto ya se evaporó. A casi todos los equipos les asusta el número, y el número empeora justo cuando sube la velocidad de decisión, es decir, justo cuando los agentes te hacen más rápido.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/es/">PaellaDoc</a> trata la decisión como un registro de primera clase, no como una línea en un chat. Una decisión se cierra con la evidencia que la sostuvo, el supuesto en el que se apoya y el test de refutación adjuntos, y enlaza con los artefactos que autorizó, para que el razonamiento siga auditable mientras el producto crece a su alrededor. El objetivo es la versión de producto del hecho significa hecho: una decisión que puedes abrir meses después y reconstruir, en vez de una elección que solo recuerdas haber tomado.</p>
<p>Decidir se encareció porque construir se abarató. La forma de evitar que las decisiones caras se conviertan en errores caros es dejar de permitir que la evidencia se aleje de la decisión en el momento en que la decisión se toma.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-son-las-decisiones-de-producto-con-evidencia">¿Qué son las decisiones de producto con evidencia?</h3>
<p>Es la versión de producto del «hecho significa hecho»: una decisión no se cierra hasta que la evidencia que la justificó viaja con ella. «Elegimos X» por sí solo es un rumor con fecha, sabes que se tomó una elección y más o menos cuándo, pero no sobre qué base, así que después no distingues una buena decisión que envejeció mal de una mala que tuvo suerte. La evidencia y la decisión se mueven juntas o la decisión es solo una frase.</p>
<h3 id="qué-debo-adjuntar-a-una-decisión-de-producto">¿Qué debo adjuntar a una decisión de producto?</h3>
<p>Tres cosas que viajan con ella al cerrarse. La evidencia que la sostuvo, la señal real del usuario o el dato de uso, registrada como corazonada si eso era. El supuesto en el que se apoya, la creencia de carga que, si es falsa, hace la decisión errónea. Y el test de refutación, qué te diría que estaba mal y cuándo lo mirarás. Sin el tercero, has vuelto la decisión infalsificable en silencio.</p>
<h3 id="cómo-audito-una-decisión-de-producto-pasada">¿Cómo audito una decisión de producto pasada?</h3>
<p>Coge una decisión de hace un trimestre e intenta auditarla en frío, sin preguntar a nadie. Si puedes ver qué se sabía, qué se asumió y qué la habría refutado, se cerró con su evidencia adjunta. Si solo puedes ver que se tomó una elección, tienes una fecha y un rumor. Córrelo sobre diez decisiones; la proporción te dice cuánto de tu razonamiento sigue siendo auditable.</p>
<h3 id="qué-es-un-test-de-refutación-en-una-decisión-de-producto">¿Qué es un test de refutación en una decisión de producto?</h3>
<p>Es nombrar, por adelantado, qué te diría que la decisión estaba mal y cuándo lo vas a mirar. Una decisión sin test de refutación es una que has vuelto infalsificable en silencio: la defenderás para siempre pase lo que pase, porque nunca dijiste qué aspecto tendría el fracaso. Nombrarlo convierte una decisión de una opinión que proteges en una apuesta que puedes liquidar.</p>]]></content>
    <summary type="html"><![CDATA[En ingeniería, hecho significa hecho: la afirmación de que algo está completo lleva la prueba que se ejecutó. Las decisiones de producto rara vez llevan nada. «Decidimos X» flota suelto de la evidencia que lo justificó y del supuesto en el que se apoyaba. El equivalente de producto del hecho-significa-hecho es una decisión que se cierra con su evidencia adjunta y su test de refutación nombrado, para que meses después puedas auditar el razonamiento en vez de rediscutirlo de memoria.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="product-management"/><category term="toma-de-decisiones"/><category term="evidencia"/><category term="ai-coding"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">Leer un repo y sacar artefactos de producto: historias, criterios, decisiones</title>
    <link href="https://paelladoc.com/es/blog/de-repo-a-artefactos/" rel="alternate" type="text/html" title="Leer un repo y sacar artefactos de producto: historias, criterios, decisiones"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/de-repo-a-artefactos/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/de-repo-a-artefactos/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿Qué artefactos de producto se pueden extraer de un repo existente?", "acceptedAnswer": {"@type": "Answer", "text": "El comportamiento que el código impone (historias de usuario), las condiciones que comprueba (criterios de aceptación, más ricos cuando hay tests) y parte de las decisiones congeladas en la estructura. Lo que no se recupera del todo es la intención: por qué se eligió algo, qué se descartó, y qué hace el código por accidente en vez de a propósito."}},
    {"@type": "Question", "name": "¿Por qué leer un repo en artefactos en vez de escribir specs hacia delante?", "acceptedAnswer": {"@type": "Answer", "text": "Porque casi todo el software ya existe. El camino de ida (spec y luego construir) encaja en greenfield. El código heredado, los prototipos vibe-coded y los sistemas legacy no tienen spec, y la forma más rápida de tener un contrato contra el que construir es leer el que el código ya impone."}},
    {"@type": "Question", "name": "¿Te puedes fiar de artefactos sacados del código por reverse intake?", "acceptedAnswer": {"@type": "Answer", "text": "Solo si cada uno lleva su procedencia. Un comportamiento leído de un test que pasa es evidencia. Una decisión inferida del nombre de una carpeta es una conjetura. La extracción es peligrosa cuando blanquea conjeturas como documentación segura, así que los artefactos deben marcar qué está probado, qué está observado y qué está inferido, y mantenerlos separados."}}
  ]
}
</script>
<p>Abres un repo que no escribiste, o uno que vibe-codeaste hace cinco meses y ya no recuerdas. No hay PRD. <a href="/es/blog/puente-pm-ingenieria/">No hay historias de usuario. No hay registro de decisiones.</a> El código es el único documento en la sala, y no se explica solo.</p>
<p>Todas las guías enseñan la misma dirección. Escribe la spec, deja que el agente construya. Es un buen flujo para una carpeta en blanco. Es inútil para el software que ya existe, que es casi todo el software. El repo que tienes delante no se construyó desde una spec, y no puedes des-construirlo para conseguir una.</p>
<p>Así que necesitas la otra dirección. Leer el repo y sacar artefactos de producto: las historias que ya entrega, los criterios que ya impone, las decisiones que ya congeló en la estructura. Este es el camino que casi nadie documenta, y es el que más vas a usar.</p>
<h2 id="el-camino-de-ida-asume-un-repo-que-todavía-no-existe">El camino de ida asume un repo que todavía no existe</h2>
<p>El desarrollo guiado por especificaciones, al menos como se vende, empieza antes del código. Describes comportamiento, un agente genera una implementación, la spec se queda como contrato. Limpio, cuando el tiempo corre en ese orden.</p>
<p>El código existente corrió el tiempo al revés. Alguien tomó cientos de decisiones pequeñas contra un deadline, la mitad en una ventana de chat, ninguna escrita. El comportamiento es real y está en producción. El registro de por qué se comporta así se evaporó en cuanto se cerró la sesión. Pregúntale al autor original seis meses después y te encoges de hombros los dos, porque <a href="https://martinfowler.com/bliki/CodeAsDocumentation.html">el código es la única documentación que está garantizada al día</a>, y también la menos legible.</p>
<p>Así que la pregunta útil no es “qué spec produciría este código”. Es más estrecha y sí tiene respuesta. <a href="/es/blog/specs-repo-existente/">¿Qué contrato está imponiendo este código ahora mismo</a>, lo escribiera alguien o no?</p>
<h2 id="en-un-repo-se-esconden-tres-artefactos-a-tres-profundidades">En un repo se esconden tres artefactos, a tres profundidades</h2>
<p>Leer un repo en artefactos no es una extracción. Son tres, y cada una pierde más información.</p>
<p><strong>Las historias son lo más superficial.</strong> El comportamiento que entrega el software está ahí, en las rutas, los handlers, los estados de la UI. Un flujo de registro, un reset de contraseña, un botón de exportar que manda un CSV por correo. Esto lo lees en la superficie con confianza decente, porque el código lo ejecuta a diario. Un agente es genuinamente bueno en esta pasada. Apúntalo al codebase, pregúntale qué puede hacer un usuario, y la lista que devuelve es casi toda verdad.</p>
<p><strong>Los criterios de aceptación están una capa más abajo, y viven en los tests.</strong> Un test es un criterio que alguien ya acordó, escrito en un lenguaje que se ejecuta. “Los tokens de reset caducan a la hora” no es un comentario, es una aserción que falla si lo rompes. La suite de tests es la veta más rica de criterios de aceptación de todo el repo, porque a diferencia de la documentación no puede quedarse obsoleta en silencio sin ponerse en rojo. Donde no hay tests, los criterios siguen ahí, enterrados en el código de validación y las ramas de error, solo que más difíciles de creer.</p>
<p><strong>Las decisiones son lo más profundo, y la extracción se vuelve lossy rápido.</strong> ¿Por qué auth es su propio servicio? ¿Por qué este módulo reimplementa algo que el framework ya da? Parte de eso se recupera del historial de git, los mensajes de commit, <a href="/es/blog/grafo-de-conocimiento-del-codigo/">la forma del grafo de dependencias</a>. Mucho se ha perdido, y el artefacto lo reconoce. Aquí es donde la extracción inversa se gana su peligro.</p>
<h2 id="la-línea-entre-leer-e-inventar">La línea entre leer e inventar</h2>
<p>El modo de fallo no es la pereza. Es la seguridad. Un agente al que le pides “documenta este repo” produce un conjunto precioso de historias, criterios y racional, y un buen trozo del racional estará inventado. Sin mala fe. Rellena el hueco donde debería ir una decisión con una razón que suena plausible, y esa razón se lee exactamente igual que las de verdad.</p>
<p>Eso es peor que un doc vacío, porque un “porqué” equivocado y seguro lo trata como verdad la siguiente persona y el siguiente agente. Una carpeta llamada <code>legacy</code> se convierte en “el equipo decidió deprecar esto”, cuando en realidad alguien movió un fichero una vez y no volvió.</p>
<p>La disciplina es la procedencia. Cada artefacto extraído lleva una etiqueta. Comportamiento observado desde un test que pasa: probado. Comportamiento leído de una ruta: observado. Decisión conjeturada desde la estructura: inferido. Mantienes los tres aparte y nunca dejas que lo inferido se promocione a probado en silencio.</p>
<figure class="tp-diagram tp-diagram--levels" data-diagram-type="levels" role="img" aria-label="La extracción solo es segura cuando cada artefacto lleva cómo se sabe: el nombre de una carpeta es una conjetura, una ruta es observación, un test que pasa es prueba contra la que construir."><svg viewBox="0 0 760 214" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="20" width="186" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="46" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">INFERIDO</text><rect x="40" y="78" width="373" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="104" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">OBSERVADO</text><rect x="40" y="136" width="560" height="40" fill="var(--tp-mostaza)" stroke="var(--tp-mostaza)" stroke-width="1.5" fill-opacity="0.14"></rect>
  <text x="52" y="162" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">PROBADO</text></svg><figcaption>La extracción solo es segura cuando cada artefacto lleva cómo se sabe: el nombre de una carpeta es una conjetura, una ruta es observación, un test que pasa es prueba contra la que construir.</figcaption></figure>
<p>Es la misma regla que mantiene veraz a <a href="/es/blog/grafo-de-conocimiento-de-producto/">un grafo de conocimiento de producto leído hacia atrás</a>, en vez de convertirlo en una alucinación segura sobre código desordenado.</p>
<h2 id="cómo-corro-la-pasada-de-verdad">Cómo corro la pasada de verdad</h2>
<p>No “resume el repo”. Eso te da prosa. Quieres artefactos contra los que construir.</p>
<p>Empieza por los tests, porque son la fuente de más señal y la que menos miente. Cada aserción es un candidato a criterio de aceptación con evidencia adjunta. Léelos en criterios primero, antes de tocar una línea de implementación.</p>
<p>Luego lee la superficie: rutas, handlers, puntos de entrada, estados de UI. Eso se vuelven historias. Mantenlas al nivel del comportamiento visible para el usuario, no de la implementación. “Un usuario puede exportar sus datos”, no “el controlador de exportación llama al serializer”.</p>
<p>Después, y solo después, ve a por las decisiones, y trata el historial de git como testigo principal. Mensajes de commit, el orden en que se construyeron las cosas, qué se revirtió. Lo que no puedas fuentear, o lo marcas inferido o lo dejas fuera. El hueco también es dato. Una historia sin test debajo te está diciendo exactamente dónde el software está sin probar.</p>
<p>La salida no es un documento que lees una vez. Es un conjunto de artefactos contra los que un agente puede construir mañana sin re-derivar todo el contrato desde cero, que es el mismo problema que intenta resolver, aguas arriba, <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">un cerebro de producto que se mantiene solo</a>.</p>
<h2 id="los-huecos-son-la-mitad-del-valor">Los huecos son la mitad del valor</h2>
<p>Los artefactos que puedes extraer son útiles. Los que no puedes lo son más, porque un hueco es una señal con ubicación.</p>
<p>Una ruta sin test debajo es comportamiento corriendo en producción que nadie acordó verificar. La extracción lo encuentra y le pone una bandera. Un cúmulo de código al que no llega ninguna historia es o peso muerto o una feature tan indocumentada que quitarla es una apuesta. Una decisión que no pudiste fuentear, solo inferir, marca un sitio donde el siguiente cambio se hace a ciegas.</p>
<p>Cuando corrí esta pasada sobre un prototipo viejo mío, la salida más valiosa no fue la lista limpia de historias. Fue la lista corta de endpoints que el intake podía describir pero no podía conectar con ninguna razón para existir. Dos eran restos de una idea que abandoné y olvidé borrar. Uno era portante y de verdad había olvidado que estaba ahí. Una spec de ida nunca habría sacado eso, porque una spec de ida solo sabe lo que te acordaste de escribir.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Esta pasada inversa es lo que PaellaDoc llama intake. Lee un repo existente y su historial en historias, criterios de aceptación y decisiones, cada uno etiquetado con de dónde viene, y los mantiene como un contrato vivo en tu máquina en vez de un resumen suelto en un chat que vas a perder. El objetivo no es un export más bonito. Es que el siguiente agente, y el siguiente tú, empiecen desde lo que el código impone de verdad en vez de volver a adivinar.</p>
<p>Va local-first y gratis, sin nube y sin cuenta, contra el repo que ya tienes.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuál de tus repos tiene comportamiento real y cero registro escrito de por qué? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-artefactos-de-producto-se-pueden-extraer-de-un-repo-existente">¿Qué artefactos de producto se pueden extraer de un repo existente?</h3>
<p>El comportamiento que el código impone (historias de usuario), las condiciones que comprueba (criterios de aceptación, más ricos cuando hay tests) y parte de las decisiones congeladas en la estructura. Lo que no se recupera del todo es la intención: por qué se eligió algo, qué se descartó, y qué hace el código por accidente en vez de a propósito.</p>
<h3 id="por-qué-leer-un-repo-en-artefactos-en-vez-de-escribir-specs-hacia-delante">¿Por qué leer un repo en artefactos en vez de escribir specs hacia delante?</h3>
<p>Porque casi todo el software ya existe. El camino de ida (spec y luego construir) encaja en greenfield. El código heredado, los prototipos vibe-coded y los sistemas legacy no tienen spec, y la forma más rápida de tener un contrato contra el que construir es leer el que el código ya impone.</p>
<h3 id="te-puedes-fiar-de-artefactos-sacados-del-código-por-reverse-intake">¿Te puedes fiar de artefactos sacados del código por reverse intake?</h3>
<p>Solo si cada uno lleva su procedencia. Un comportamiento leído de un test que pasa es evidencia. Una decisión inferida del nombre de una carpeta es una conjetura. La extracción es peligrosa cuando blanquea conjeturas como documentación segura, así que los artefactos deben marcar qué está probado, qué está observado y qué está inferido, y mantenerlos separados.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="knowledge-graph"/><category term="reverse-intake"/><category term="acceptance-criteria"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Tu prototipo ya es el producto: sobrevivir al ascenso</title>
    <link href="https://paelladoc.com/es/blog/de-prototipo-a-producto/" rel="alternate" type="text/html" title="Tu prototipo ya es el producto: sobrevivir al ascenso"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/de-prototipo-a-producto/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/de-prototipo-a-producto/"><![CDATA[<p>No hubo lanzamiento. Montaste algo en Lovable o en Cursor un par de tardes para ver si la idea aguantaba. Se lo enseñaste a unas cuantas personas. Una empezó a usarlo de verdad. Luego unas cuantas más. En algún momento, dinero o datos o el flujo de trabajo real de alguien empezaron a depender de ello, y el prototipo desechable pasó a ser la cosa que ya no puedes desechar.</p>
<p>Nadie tomó esa decisión. Te pasó. Y ahora operas un sistema en producción que se diseñó para ser prescindible, que es un sitio genuinamente incómodo. El instinto es declararte en quiebra y reescribirlo “bien”. Ese instinto casi siempre es incorrecto, y quiero explicar por qué, y qué hacer en su lugar.</p>
<h2 id="el-prototipo-no-fue-un-error">El prototipo no fue un error</h2>
<p>Empecemos aquí, porque la vergüenza es parte de lo que empuja a la gente hacia la reescritura. Construir el producto como prototipo fue el movimiento correcto. No sabías si la idea funcionaba, así que gastaste lo mínimo posible en averiguarlo. Eso es buen criterio, no un atajo por el que debas sentirte mal.</p>
<p>El prototipo hizo su trabajo. Respondió a la pregunta “¿quiere esto alguien?”, y la respuesta volvió que sí. El problema no es que construyeras un prototipo. El problema es que el éxito del prototipo cambió en silencio lo que necesita ser, y nada en el código cambió para acompañarlo.</p>
<p>Un prototipo optimiza una sola cosa: aprender rápido. Un producto optimiza otra distinta: no romper a la gente que ahora depende de él. Mismo código, distinto trabajo. El ascenso es trabajo real precisamente porque esos dos trabajos tiran en direcciones opuestas.</p>
<h2 id="por-qué-la-reescritura-es-una-trampa">Por qué la reescritura es una trampa</h2>
<p>Cuando miras el código de un prototipo con ojos de producción, cada esquina recortada se ve, y el total parece un desastre que deberías reemplazar. Aquí está por qué reemplazarlo suele fallar.</p>
<p>La reescritura tira lo único que el prototipo de verdad contiene y tiene valor: una definición funcionando y validada de lo que hace el producto. Cada rareza de ese código es una decisión, hasta las accidentales. Algunas de esas rarezas son la razón de que a los usuarios les guste. Una reescritura desde cero pierde todo eso y te obliga a redescubrirlo rompiendo cosas delante de la gente que ahora depende de ti.</p>
<p>El prototipo es, lo pretendieras o no, la <a href="/es/blog/prototipo-como-spec/">especificación</a> más veraz que tienes. No se puede malinterpretar, porque arranca. Tirarlo para escribir una versión “de verdad” es cambiar una especificación demostrablemente correcta por un documento que todavía no demuestra nada. Ese trueque es peor de lo que parece el día en que lo haces.</p>
<p>Hay un conjunto estrecho de casos donde la reescritura es correcta, y van sobre la idea, no sobre el código: aprendiste que el producto debería ser fundamentalmente distinto de lo que prototipaste. Si la forma es la buena y solo los cimientos tiemblan, refuerzas los cimientos. No demueles la casa para arreglar el sótano. Esa distinción es todo el asunto de <a href="/es/blog/arreglar-app-vibe-coding/">arreglar una app de vibe coding sin reescribirla</a>.</p>
<h2 id="qué-exige-de-verdad-el-ascenso">Qué exige de verdad el ascenso</h2>
<p>Ascender un prototipo no es un solo proyecto grande. Es una secuencia de mejoras concretas, cada una disparada por el hecho de que la app ahora tiene usuarios reales. Este es el orden que me ha funcionado.</p>
<p><strong>Recupera lo que hace.</strong> Antes de cambiar nada, haz que el sistema se explique, feature a feature, incluidas las partes que ya no recuerdas haber escrito. Estás convirtiendo un prototipo que entiendes vagamente en un producto sobre el que puedes razonar. Es el antídoto al <a href="/es/blog/miedo-a-tocar-el-codigo/">miedo a tocar tu propio código</a>: no puedes ascender con seguridad lo que no sabes explicar.</p>
<p><strong>Dibuja una línea alrededor de lo que sostiene peso.</strong> No todo en el prototipo importa igual. El flujo de registro, el camino del pago, los datos que sería catastrófico perder: eso ahora sostiene peso. El resto todavía puede ser cutre. Saber qué es qué es lo que te permite gastar esfuerzo donde cuenta en vez de pulir una pantalla de ajustes que nadie toca.</p>
<p><strong>Pon una red de seguridad donde sostiene peso.</strong> Aquí es donde entran los tests y la estructura, y solo aquí. No pruebas el prototipo entero. Pones <a href="https://martinfowler.com/bliki/SelfTestingCode.html">tests de caracterización</a> alrededor de los caminos que dolerían a un usuario real si se rompieran, para que el siguiente cambio que haga un agente no pueda tumbarlos en silencio. La pregunta de <a href="/es/blog/cuando-anadir-tests-arquitectura/">cuándo añadir tests y arquitectura</a> tiene una respuesta limpia durante el ascenso: en el momento exacto en que un camino pasa a sostener peso, y ni una feature antes.</p>
<p><strong>Cierra los agujeros obvios.</strong> El prototipo casi con seguridad publica secretos en el código y <a href="https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html">confía en su entrada</a>, porque eso es lo que hacen los prototipos. El ascenso es cuando <a href="/es/blog/seguridad-vibe-coding/">los agujeros de seguridad que deja el vibe coding</a> dejan de ser aceptables, porque un prototipo con una fuga de datos es un experimento y un producto con una fuga de datos es un incidente.</p>
<h2 id="la-deuda-vence-durante-el-ascenso">La deuda vence durante el ascenso</h2>
<p>La razón de que esto agobie es que el ascenso es cuando llegan de golpe todas <a href="https://martinfowler.com/bliki/TechnicalDebt.html">las facturas aplazadas</a>. La comprensión que nunca construiste, los tests que nunca escribiste, la estructura que nadie diseñó: todo era gratis mientras la app era un experimento, y todo vence en el momento en que se convierte en algo de lo que la gente depende.</p>
<p>No es casualidad. Es la misma <a href="/es/blog/deuda-tecnica-vibe-coding/">deuda del vibe coding</a>, llegando a su vencimiento. El ascenso no creó la deuda. La reclamó. Lo que significa que el objetivo no es pagarla toda, sino pagar la parte que el nuevo estatus de producción de verdad exige, en el orden que mantiene a los usuarios a salvo, y dejar el resto cutre a propósito.</p>
<p>Y conviene decir con claridad que esto es una transición real, no una formalidad. Ascender un prototipo a producto significa que ahora tiene que <a href="/es/blog/hacer-producto-no-es-productizar/">instalar un comportamiento duradero en usuarios reales</a>, no solo demostrar que una idea es plausible. Es un listón más alto, y el código tiene que crecer hasta él. El arco entero, de un montaje de fin de semana a algo que puedes operar, es el puente que intento trazar al ir <a href="/es/blog/vibe-coding-a-produccion/">del vibe coding a producción</a>.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La parte más dura de ascender un prototipo es que todo lo que necesitas para hacerlo bien falta: la intención detrás de cada feature, las decisiones que tomaste y olvidaste, la evidencia de que algo funciona. El prototipo tiene el comportamiento pero no el registro de él.</p>
<p>PaellaDoc está hecho para reconstruir ese registro a partir de lo que el prototipo ya es. Lee la app funcionando y la convierte en un modelo local de lo que hace, te da un sitio donde enganchar las decisiones y el contrato de aceptación que nunca escribiste, y guarda la evidencia según endureces cada camino. El prototipo se queda. Lo que añades es la memoria que nunca tuvo, para que el ascenso sea una serie de mejoras deliberadas en vez de una reescritura de la que te arrepientas.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Debería reescribir mi prototipo antes de lanzarlo de verdad?</strong> Normalmente no. Una reescritura tira una definición del producto que funciona y está validada, y te obliga a redescubrirla rompiendo cosas para usuarios reales. Reescribe solo cuando has aprendido que el producto debería ser fundamentalmente distinto, no porque el código se vea desordenado.</p>
<p><strong>¿Cómo sé qué partes del prototipo endurecer?</strong> Sigue a los usuarios. Los caminos que manejan sus datos, su dinero o su flujo de trabajo central sostienen peso y necesitan tests y endurecimiento. El resto puede seguir cutre hasta que se gane la atención.</p>
<p><strong>¿Cuándo se convierte oficialmente un prototipo en producto?</strong> Cuando alguien depende de él de un modo que le dolería si se rompiera. Rara vez hay un momento de lanzamiento. La dependencia es lo que cambia los requisitos, lo anuncie alguien o no.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿Debería reescribir mi prototipo antes de lanzarlo de verdad?", "acceptedAnswer": { "@type": "Answer", "text": "Normalmente no. Una reescritura tira una definición del producto que funciona y está validada, y te obliga a redescubrirla rompiendo cosas para usuarios reales. Reescribe solo cuando has aprendido que el producto debería ser fundamentalmente distinto, no porque el código se vea desordenado." } },
    { "@type": "Question", "name": "¿Cómo sé qué partes del prototipo endurecer?", "acceptedAnswer": { "@type": "Answer", "text": "Sigue a los usuarios. Los caminos que manejan sus datos, su dinero o su flujo de trabajo central sostienen peso y necesitan tests y endurecimiento. El resto puede seguir cutre hasta que se gane la atención." } },
    { "@type": "Question", "name": "¿Cuándo se convierte oficialmente un prototipo en producto?", "acceptedAnswer": { "@type": "Answer", "text": "Cuando alguien depende de él de un modo que le dolería si se rompiera. Rara vez hay un momento de lanzamiento. La dependencia es lo que cambia los requisitos, lo anuncie alguien o no." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[Nadie decidió ascender el prototipo a producción. Los usuarios empezaron a depender de él. Sobrevivir a ese ascenso es un trabajo distinto al de construir el prototipo, y no exige una reescritura.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="prototipado"/><category term="produccion"/><category term="ai-coding"/><category term="desarrollo-de-producto"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Insight → decisión → resultado: la cadena que la velocidad de la IA rompe</title>
    <link href="https://paelladoc.com/es/blog/de-insight-a-resultado/" rel="alternate" type="text/html" title="Insight → decisión → resultado: la cadena que la velocidad de la IA rompe"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/de-insight-a-resultado/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/de-insight-a-resultado/"><![CDATA[<p>Mira cualquier feature de tu producto y hazte tres preguntas. ¿Qué aprendimos que nos llevó a construir esto? ¿Qué decidimos, y por qué esto en lugar de la alternativa? ¿Lo que publicamos movió de verdad el número que nos importaba? Para casi todas las features del último trimestre no puedes contestar ninguna de las tres. La feature está ahí. La cadena de razonamiento que la puso ahí desapareció.</p>
<p>Esa cadena tiene una forma. Insight, después decisión, después resultado. <a href="/es/blog/discovery-con-ia/">Aprendes algo real sobre un usuario o un mercado</a>, ese aprendizaje fuerza una elección, la elección se publica, y el mundo se mueve o no. El trabajo de producto es mantener la cadena intacta para que la siguiente decisión sea más lista que la anterior. La IA no cambió la forma. Cambió la velocidad, y la velocidad es justo lo que la rompe.</p>
<h2 id="la-fricción-mantenía-la-cadena-legible">La fricción mantenía la cadena legible</h2>
<p>Durante años el medio de la cadena era lento, y la lentitud hacía un trabajo que nadie pagaba. Convertir una decisión en código publicado llevaba semanas. Esas semanas forzaban un rastro documental casi por accidente. Alguien escribía el razonamiento porque tenía que defenderlo en una reunión de planificación. La spec se revisaba porque construir era caro y nadie quería construir lo equivocado. Cuando la feature se publicaba, el insight que la justificaba se había dicho en voz alta las veces suficientes para que el equipo lo recordara.</p>
<p>La fricción era un coste y todos la odiaban. También era lo que mantenía atados insight, decisión y resultado. Lo lento es legible. Cuando cada eslabón tarda una semana, se ven los eslabones.</p>
<h2 id="dónde-la-velocidad-de-la-ia-parte-cada-eslabón">Dónde la velocidad de la IA parte cada eslabón</h2>
<p>Ahora un agente convierte una decisión en código funcionando en una tarde. Tienes un insight por la mañana, tres prototipos a mediodía, algo mergeado por la tarde. Esta es la parte buena, y es real. También es donde la cadena se deshace, eslabón a eslabón.</p>
<p>El eslabón insight-decisión se parte porque la decisión ya no necesita defenderse ante nadie antes de volverse código. No convocas una reunión para justificar un cambio que un agente puede hacer antes de que la reunión hubiera empezado. El razonamiento se queda en tu cabeza, o en una ventana de chat que se va, y nunca se convierte en algo duradero que el equipo comparta.</p>
<p>El eslabón decisión-construcción se parte porque la spec deja de ser un punto de control. Cuando construir era lento, la spec era donde pensabas. Cuando construir es instantáneo, la tentación es saltar directo a la cosa construida y tratar el prototipo como el argumento. El prototipo convence precisamente porque funciona, que no es lo mismo que tener razón.</p>
<p>El eslabón construcción-resultado se parte porque publicaste antes de nombrar qué te diría que funcionó. La velocidad te deja pasar a la siguiente feature antes de que la anterior haya producido una señal. El número que debías mover nunca se comprueba, porque comprobar es más lento que construir la siguiente cosa, y la siguiente cosa está ahí mismo.</p>
<p>Seis semanas después tienes un producto lleno de features y un equipo incapaz de reconstruir por qué existe ninguna. Esto no es un problema de disciplina que se arregle esforzándose más. Es una consecuencia estructural de haber quitado la fricción que preservaba la cadena sin reemplazarla por nada.</p>
<h2 id="la-trazabilidad-es-el-reemplazo-de-la-fricción">La trazabilidad es el reemplazo de la fricción</h2>
<p>Si la velocidad quitó el rastro que la fricción producía gratis, la respuesta es producir el rastro a propósito, barato, como una propiedad del trabajo y no como una reunión sobre el trabajo. Tres enganches sostienen la cadena.</p>
<p>Engancha el insight a la decisión. Cuando eliges una dirección, lo que aprendiste que forzó la elección viaja con ella como <a href="/es/blog/registro-de-decisiones/">registro duradero</a>, no como recuerdo. No un documento que nadie lee. Una frase corta y localizable de qué sabías y por qué apuntaba aquí, atada a la decisión que produjo.</p>
<p>Engancha la decisión al artefacto. La spec, el prototipo, el código mergeado apuntan todos a la decisión que los autorizó. Así, cuando encuentras una feature en el repo, puedes recorrer hacia atrás del código a la decisión al insight, en vez de chocar con un callejón sin salida en el diff. Aquí es donde un <a href="/es/blog/grafo-de-conocimiento-de-producto/">grafo de conocimiento de producto</a> se gana su sitio. Un grafo que relaciona decisiones con los artefactos que produjeron es lo que convierte «por qué existe esto» en una consulta y no en una excavación.</p>
<p>Engancha el artefacto al resultado. Antes de publicar, nombra el número que esto debe mover y cuándo lo vas a mirar. Después de publicar, el resultado se engancha de vuelta a la decisión, de modo que el registro no es solo «decidimos X» sino <a href="/es/blog/decisiones-con-evidencia/">«decidimos X, esperando Y, y salió Z»</a>. Ese último eslabón es el que hace más lista la siguiente decisión, y es el que la velocidad borra con más ganas, porque medir siempre es más lento que publicar.</p>
<h2 id="la-prueba-de-la-feature-huérfana">La prueba de la feature huérfana</h2>
<p>Un diagnóstico barato que puedes correr hoy. Recorre tu producto y cuenta las huérfanas: features que no puedes conectar a un insight ni a un resultado. Una feature sin insight trazable es una feature que construiste porque podías, no porque supieras algo. Una feature sin resultado medido es una apuesta que nunca liquidaste. Ambas son deuda de producto, y ambas componen, porque un código lleno de huérfanas es uno donde el siguiente equipo no distingue qué partes sostienen la casa y cuáles fueron corazonadas.</p>
<p>La investigación DORA aterriza una y otra vez en lo mismo desde el lado de la entrega: el throughput sin atención a los outcomes no produce mejores resultados de forma fiable, y puede empeorarlos en silencio. Puedes leer los <a href="https://dora.dev/research/">hallazgos de DORA</a> directamente. La velocidad solo es ventaja si la cadena de lo que aprendiste a lo que cambió sigue intacta. Si no, es solo dispersión más rápida, la trampa que describí en <a href="/es/blog/product-management-era-ia/">product management en la era IA</a>: construir barato te deja generar más de todo, incluida más deuda de producto, y solo un mejor sistema de decisión convierte la velocidad en outcomes en vez de en ruido.</p>
<h2 id="qué-le-pide-esto-a-la-persona-de-producto">Qué le pide esto a la persona de producto</h2>
<p>El trabajo se desplaza de producir los artefactos a mantener la cadena legible mientras los agentes producen los artefactos. Ya no eres el cuello de botella que convierte decisiones en specs. Eres quien se asegura de que cuando una decisión se vuelve código en una tarde, el insight que la justificaba y el resultado que debería validarla no se queden atrás en la prisa.</p>
<p>Esto no es una llamada nostálgica a ir más despacio. Ir más despacio renuncia al regalo que la IA te dio de verdad. Es una llamada a hacer la cadena barata de mantener, para poder ir rápido y aún así contestar, meses después, por qué existe cada cosa y si funcionó.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/es/">PaellaDoc</a> está hecho para que la cadena no dependa de que alguien la recuerde. Las decisiones son registros de primera clase con el insight que las produjo enganchado; los artefactos apuntan de vuelta a las decisiones que los autorizaron; el grafo de producto relaciona todo eso, de modo que recorrer de una feature mergeada a su razón es una consulta, no un interrogatorio a quien estuviera en la sala. El objetivo no es más documentación. Es que el insight, la decisión y el resultado sigan atados a la velocidad a la que ahora trabajan los agentes, para que el registro del porqué no lo adelante el ritmo del qué.</p>
<p>Las features seguirán llegando más rápido de lo que ningún equipo puede sostener en la cabeza. Que esa velocidad se convierta en mejores outcomes o solo en más huérfanas depende por entero de si la cadena la sobrevive.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-la-cadena-insight--decisión--resultado">¿Qué es la cadena insight → decisión → resultado?</h3>
<p>Es el razonamiento detrás de cada feature: aprendes algo real sobre un usuario o un mercado (insight), ese aprendizaje fuerza una elección (decisión), y lo que publicas mueve un número o no (resultado). El trabajo de producto es mantener los tres atados para que la siguiente decisión sea más lista que la anterior. Cuando la cadena sigue intacta, «por qué existe esto» tiene respuesta.</p>
<h3 id="por-qué-la-velocidad-de-la-ia-rompe-la-cadena">¿Por qué la velocidad de la IA rompe la cadena?</h3>
<p>Porque la fricción la preservaba gratis. Cuando convertir una decisión en código llevaba semanas, el razonamiento se escribía para sobrevivir a una reunión de planificación y el resultado se comprobaba antes de publicar lo siguiente. Ahora un agente construye en una tarde, así que la decisión no necesita defenderse, la spec deja de ser un punto de control, y pasas a lo siguiente antes de nombrar qué probaría que funcionó. Cada eslabón se parte.</p>
<h3 id="cómo-mantengo-la-cadena-trazable-a-velocidad-de-agente">¿Cómo mantengo la cadena trazable a velocidad de agente?</h3>
<p>Produce el rastro a propósito, como propiedad del trabajo. Engancha el insight a la decisión, para que lo que aprendiste viaje con la elección. Engancha la decisión al artefacto, para que el código apunte de vuelta a lo que lo autorizó. Engancha el artefacto al resultado: nombra el número a mover antes de publicar, y luego registra «decidimos X, esperando Y, y salió Z».</p>
<h3 id="qué-es-una-feature-huérfana">¿Qué es una feature huérfana?</h3>
<p>Una feature que no puedes conectar a un insight ni a un resultado. Una sin insight trazable la construiste porque podías, no porque supieras algo. Una sin resultado medido es una apuesta que nunca liquidaste. Ambas son deuda de producto, y ambas componen, porque un código lleno de huérfanas es uno donde el siguiente equipo no distingue qué partes sostienen la casa y cuáles fueron corazonadas.</p>]]></content>
    <summary type="html"><![CDATA[Cada feature es el final de una cadena: alguien aprendió algo (insight), eligió algo por eso (decisión) y publicó algo que movió un número (resultado). Esa cadena era lo bastante lenta para seguir siendo legible. Los agentes colapsan el medio y seis semanas después nadie sabe a qué insight servía esta feature ni si el número se movió. La feature sobrevive; el razonamiento que la justificaba desaparece. Mantener la cadena trazable es el trabajo de producto que la velocidad de la IA vuelve innegociable.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="product-management"/><category term="ai-coding"/><category term="toma-de-decisiones"/><category term="outcomes"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">Cuándo añadir tests y arquitectura a un proyecto construido con IA</title>
    <link href="https://paelladoc.com/es/blog/cuando-anadir-tests-arquitectura/" rel="alternate" type="text/html" title="Cuándo añadir tests y arquitectura a un proyecto construido con IA"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/cuando-anadir-tests-arquitectura/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/cuando-anadir-tests-arquitectura/"><![CDATA[<p>Hay dos consejos sobre tests y arquitectura en proyectos construidos con IA, y los dos están equivocados. Uno dice escribe los tests primero, diseña la arquitectura por adelantado, hazlo bien desde el día uno. El otro dice sáltate todo eso, publica por sensaciones, ya añadirás lo aburrido después. Seguir el primero mata la velocidad que hizo que la IA mereciera la pena. Seguir el segundo garantiza el colapso del que todo el mundo avisa.</p>
<p>La respuesta correcta es un momento, no una política. Y lo útil es que el momento se anuncia solo, si sabes qué señal vigilar. Es la misma señal para los tests y para la arquitectura, y por eso los trato juntos.</p>
<h2 id="por-qué-el-día-uno-está-mal">Por qué el día uno está mal</h2>
<p>Escribir tests y diseñar arquitectura antes de saber si la idea funciona es gastar tu esfuerzo más caro en tu apuesta menos segura.</p>
<p>Casi todo lo que construyes en los primeros días de un proyecto con IA no sobrevivirá la semana. Estás explorando. El sentido entero de construir con un agente es que explorar se abarató, así que puedes probar cinco versiones de una idea y tirar cuatro. Tests escritos contra código que estás a punto de borrar son puro desperdicio. Arquitectura diseñada para un producto que no has validado es una catedral construida para una congregación que quizá no aparezca.</p>
<p>Hay un coste real en la estructura prematura más allá de las horas perdidas: te vuelve reacio a tirar el código. Una vez que has invertido en probar y estructurar algo, lo defiendes, incluso cuando lo correcto es borrarlo. El rigor prematuro convierte la exploración en coste hundido. En la fase en la que deberías estar más dispuesto a descartar, te vuelve el que menos.</p>
<p>Así que el día uno está mal no porque los tests sean malos, sino porque todavía no sabes qué merece tenerlos.</p>
<h2 id="por-qué-el-nunca-está-mal">Por qué el nunca está mal</h2>
<p>El otro fallo es más común y más caro, porque no duele hasta que es demasiado tarde para ser barato.</p>
<p>Un proyecto con IA sin tests y sin arquitectura funciona bien justo hasta el punto en que necesitas cambiarlo sin romperlo. Entonces la ausencia de ambos pasa a ser lo que te frena. Cada cambio es una apuesta, porque nada atrapa una regresión y nada acota el radio de la explosión. Ese es el <a href="/es/blog/miedo-a-tocar-el-codigo/">miedo a tocar tu propio código</a>, y no es irracional. Es la respuesta correcta a un código sin red de seguridad.</p>
<p>El “nunca” además compone. Cada feature que un agente añade sobre una base sin estructura y sin tests hace la siguiente más arriesgada, porque la base sobre la que construye es menos fiable. Lo que empieza como velocidad se convierte en parálisis, y la parálisis llega justo cuando el proyecto está teniendo éxito y más necesitas moverte. Ese es el mecanismo detrás de <a href="/es/blog/vibe-coding-dia-90/">las apps hechas con vibe coding que se rompen hacia el tercer mes</a>: no un fallo súbito, sino el coste acumulado del “nunca” llegando a su vencimiento.</p>
<h2 id="la-señal-sostener-peso">La señal: sostener peso</h2>
<p>Aquí está el momento. Un camino merece tests y estructura cuando pasa a sostener peso, que es algo concreto y observable: cuando romperlo dolería a un usuario real, y cuando vas a seguir cambiándolo.</p>
<p>Las dos condiciones importan. Un camino que dolería a un usuario pero que nunca cambia no necesita tests con urgencia, porque los tests protegen frente al cambio y no hay ninguno. Un camino que cambia constantemente pero que no hace daño a nadie si se rompe puede seguir cutre. La intersección, mucho en juego y mucho cambio, es donde inviertes, y suele ser una fracción pequeña del código.</p>
<p>Esto te da una regla que de verdad puedes aplicar. No preguntes “¿debería este proyecto tener tests?”. Pregunta, para cada camino, “¿le dolería a un usuario si esto se rompiera, y voy a volver a tocarlo?”. Cuando las dos respuestas son sí, ese camino acaba de pasar a sostener peso, y esa es tu señal. No la edad del proyecto. No un objetivo de cobertura. El estado del camino concreto que tienes delante.</p>
<figure class="tp-diagram tp-diagram--gate" data-diagram-type="gate" role="img" aria-label="La regla que aplicas camino a camino: invierte solo donde romperlo duele a un usuario y vas a seguir cambiándolo."><svg viewBox="0 0 760 240" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
  <rect x="40" y="86" width="180" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="130" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">UN CAMINO</text>
  <path d="M 226 119 L 286 119 M 280 113 L 286 119 L 280 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <path d="M 380 60 L 452 119 L 380 178 L 308 119 Z" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.8"></path>
  <text x="380" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">SOSTIENE PESO</text>
  <path d="M 458 119 L 528 119 M 522 113 L 528 119 L 522 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <rect x="534" y="86" width="186" height="66" fill="var(--tp-verde)" fill-opacity="0.12" stroke="var(--tp-verde)" stroke-width="1.5"></rect>
  <text x="627" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-verde)">TESTS Y ESTRUCTURA</text>
  <path d="M 380 184 L 380 214 L 226 214 M 232 208 L 226 214 L 232 220" stroke="var(--tp-terracota)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="232" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-terracota)">SIGUE CUTRE</text>
</svg><figcaption>La regla que aplicas camino a camino: invierte solo donde romperlo duele a un usuario y vas a seguir cambiándolo.</figcaption></figure>
<h2 id="primero-los-tests-luego-la-arquitectura">Primero los tests, luego la arquitectura</h2>
<p>Cuando la señal se dispara, haz las dos cosas en orden, porque una habilita la otra.</p>
<p>Añade primero los tests, y añádelos como tests de caracterización: tests que fijan lo que el código hace ahora mismo, antes de cambiarlo. En un proyecto construido con IA rara vez tienes una spec limpia contra la que probar, así que pruebas el comportamiento que existe y funciona. Lo que en realidad pruebas cambia cuando el código lo escribió una máquina, y eso es una disciplina propia: <a href="/es/blog/probar-codigo-de-ia/">probar código generado por IA</a> va de cazar los modos de fallo que un autor humano no habría producido. Los <a href="https://martinfowler.com/bliki/SelfTestingCode.html">tests de caracterización</a> son específicamente la herramienta para fijar un comportamiento que no diseñaste, de modo que puedas cambiarlo con seguridad. Y solo cuentan si de verdad los corres. Un agente que informa de verde sin ejecutar la suite no te ha dado nada, que es toda la razón de que <a href="/es/blog/hecho-significa-hecho/">hecho tenga que significar hecho</a>.</p>
<p>Después, y solo después, refactoriza la arquitectura, usando los tests como red. Ahora puedes reestructurar el camino que sostiene peso, porque los tests te avisarán en el momento en que cambies su comportamiento. Refactorizar sin esa red es cómo introduces la regresión exacta que intentabas evitar. Los tests son lo que hace que el trabajo de arquitectura sea seguro en vez de aterrador.</p>
<p>Fíjate en la secuencia. Los tests no van primero porque sean más importantes. Van primero porque hacen sobrevivible el cambio de arquitectura. Invierte el orden y estás reestructurando a ciegas.</p>
<h2 id="esto-es-pagar-la-deuda-en-el-orden-correcto">Esto es pagar la deuda en el orden correcto</h2>
<p>Si has leído cómo pienso sobre la <a href="/es/blog/deuda-tecnica-vibe-coding/">deuda del vibe coding</a>, esto es la misma idea desde el otro lado. La deuda de verificación y la de arquitectura <a href="https://martinfowler.com/bliki/TechnicalDebt.html">vencen las dos</a> cuando un camino pasa a sostener peso. “Cuándo añadir tests y arquitectura” es solo “cuándo vence esa deuda”, y la respuesta es: cuando el camino puede hacer daño a alguien y vas a seguir tocándolo.</p>
<p>Ese marco también te protege de la trampa del build verde. Un camino que sostiene peso con tests que pasan pero no demuestran nada no está protegido, solo se siente protegido, que es peor. Los tests tienen que ejercitar de verdad el comportamiento que importa, o has pagado el coste de probar sin comprar la seguridad. Esa es la diferencia entre una red real y <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build verde que no es una feature correcta</a>.</p>
<p>Y toda esta disciplina es lo que separa publicar una demo de publicar algo que puedes operar. Saber cuándo añadir rigor, y dónde, es la mayor parte del trabajo real de llegar <a href="/es/blog/vibe-coding-a-produccion/">del vibe coding a producción</a> sin ahogarte en proceso prematuro ni colapsar sin ninguno.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La parte difícil de esta regla no es estar de acuerdo con ella. Es saber, en cualquier momento dado, qué caminos de tu proyecto sostienen peso y si están de verdad cubiertos. Ese conocimiento vive en tu cabeza, y se queda obsoleto rápido cuando un agente cambia el código más rápido de lo que puedes seguir.</p>
<p>PaellaDoc mantiene ese mapa al día: qué partes del producto sostienen peso, qué contrato debe cumplir cada una y qué evidencia hay de que lo cumple. Así, cuando un camino cruza a sostener peso, lo ves, en vez de enterarte cuando se rompe. La señal deja de depender de tu memoria y pasa a vivir en el sistema, que es la única versión de esta regla que sobrevive al contacto con la velocidad real.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Debería escribir tests antes de empezar un proyecto con IA?</strong> Normalmente no. El código temprano es exploratorio y en su mayoría desechable, y probar código que estás a punto de borrar es esfuerzo malgastado que además te vuelve reacio a borrarlo. Espera a que un camino pase a sostener peso.</p>
<p><strong>¿Qué significa “sostener peso” exactamente?</strong> Un camino sostiene peso cuando romperlo dolería a un usuario real y vas a seguir cambiándolo. Las dos condiciones tienen que darse. Mucho en juego sin cambio, o mucho cambio sin nada en juego, no necesitan la inversión con urgencia.</p>
<p><strong>¿Van primero los tests o la arquitectura?</strong> Primero los tests, como tests de caracterización que fijan el comportamiento actual, y luego la arquitectura usando esos tests como red. Refactorizar sin tests reintroduce las regresiones que intentabas evitar.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿Debería escribir tests antes de empezar un proyecto con IA?", "acceptedAnswer": { "@type": "Answer", "text": "Normalmente no. El código temprano es exploratorio y en su mayoría desechable, y probar código que estás a punto de borrar es esfuerzo malgastado que además te vuelve reacio a borrarlo. Espera a que un camino pase a sostener peso." } },
    { "@type": "Question", "name": "¿Qué significa sostener peso exactamente?", "acceptedAnswer": { "@type": "Answer", "text": "Un camino sostiene peso cuando romperlo dolería a un usuario real y vas a seguir cambiándolo. Las dos condiciones tienen que darse. Mucho en juego sin cambio, o mucho cambio sin nada en juego, no necesitan la inversión con urgencia." } },
    { "@type": "Question", "name": "¿Van primero los tests o la arquitectura?", "acceptedAnswer": { "@type": "Answer", "text": "Primero los tests, como tests de caracterización que fijan el comportamiento actual, y luego la arquitectura usando esos tests como red. Refactorizar sin tests reintroduce las regresiones que intentabas evitar." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[Añadir tests y arquitectura a un proyecto construido con IA el día uno malgasta esfuerzo; no añadirlos nunca garantiza el colapso. El momento correcto es una señal que puedes vigilar, y es la misma para los dos.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="testing"/><category term="arquitectura"/><category term="ai-coding"/><category term="deuda-tecnica"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">Criterios de aceptación que un agente puede verificar</title>
    <link href="https://paelladoc.com/es/blog/criterios-aceptacion-agentes/" rel="alternate" type="text/html" title="Criterios de aceptación que un agente puede verificar"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/criterios-aceptacion-agentes/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/criterios-aceptacion-agentes/"><![CDATA[<p>«El login debería ser rápido y fácil de usar.» Un agente leerá eso, construirá un login e informará de que el criterio se cumple. No está mintiendo. Genuinamente no puede distinguir entre rápido y lento, ni entre amable y hostil, porque no le diste con qué. Le entregaste una frase con la que estar de acuerdo, no una condición que comprobar.</p>
<p>Ese es el problema de fondo de la mayoría de los criterios de aceptación en la era de los agentes. Se escribieron para un revisor humano que aplicaría criterio. Un agente no aplica tu criterio. Aplica lo que las palabras permiten literalmente, y las palabras vagas permiten casi cualquier cosa, incluida una afirmación convencida de éxito sobre un trabajo que no hace lo que querías decir.</p>
<h2 id="los-criterios-en-prosa-fallan-a-los-agentes-de-una-forma-concreta">Los criterios en prosa fallan a los agentes de una forma concreta</h2>
<p>Cuando una persona lee «fácil de usar», lo pasa por años de contexto y acepta el resultado o lo devuelve. La ambigüedad la resuelve una mente que comparte tu intención. Por eso los criterios de aceptación laxos han sobrevivido tanto: un revisor competente parcheaba los huecos.</p>
<p>Dale el mismo criterio a un agente y el hueco no se parchea, se rellena con la interpretación del propio agente, y la interpretación está optimizada para parecer terminada. Este es el mecanismo detrás de los <a href="/es/blog/exitos-falsos-de-agentes/">éxitos falsos</a>: el agente informa «los tests pasan, criterios cumplidos», y la afirmación es cierta contra los criterios tal como los entendió, que no son los criterios que querías decir. Cuanto más laxo el criterio, más espacio hay entre «lo que afirma» y «lo que querías», y el agente lo ocupará entero.</p>
<p>Así que la pregunta no es «cómo escribo criterios más claros para que el agente los lea». Es «cómo escribo criterios que el agente no pueda decir que cumplió sin cumplirlos de verdad». Esa pregunta es el núcleo operativo del <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a>: una spec solo es tan fuerte como los criterios contra los que puedes poner una puerta al agente.</p>
<h2 id="qué-hace-verificable-un-criterio-de-forma-mecánica">Qué hace verificable un criterio de forma mecánica</h2>
<p>Un criterio verificable tiene una propiedad: existe un procedimiento inequívoco que devuelve pasa o falla, y el agente no puede producir un pasa sin que el comportamiento sea real. Tres cosas te llevan ahí.</p>
<h3 id="nombra-una-condición-concreta-no-una-cualidad">Nombra una condición concreta, no una cualidad</h3>
<p>«Rápido» es una cualidad. «Responde en menos de 200 ms en el percentil 95» es una condición. «Fácil de usar» es una cualidad. «Un invitado puede completar la compra sin crear una cuenta» es una condición. La prueba de un buen criterio es sencilla: ¿podrían dos personas discrepar sobre si pasó? Si sí, un agente resolverá esa discrepancia a su favor.</p>
<h3 id="se-enuncia-como-comportamiento-observable">Se enuncia como comportamiento observable</h3>
<p>Un criterio debería describir algo que puedas observar desde fuera del sistema, no una intención interna. «El código maneja los errores con elegancia» es inobservable e infalsable. «Cuando la pasarela de pago devuelve un 500, el usuario ve un aviso de reintento y no se crea ningún pedido» es observable. Puedes ejecutarlo y mirar. El agente también, lo que significa que puede contrastarse contra la realidad en vez de contra su propio resumen de su trabajo.</p>
<h3 id="tiene-una-comprobación-definida">Tiene una comprobación definida</h3>
<p>Los criterios más fuertes vienen con el procedimiento adjunto: la entrada, la acción, el resultado esperado. «Dado un carrito con dos artículos, cuando el invitado completa los tres pasos, entonces existe un pedido y no se persiste ningún token de tarjeta.» Esa estructura —<a href="https://martinfowler.com/bliki/GivenWhenThen.html">Dado-Cuando-Entonces</a>— no es nueva; viene del desarrollo guiado por comportamiento, donde la idea siempre fue escribir condiciones que se traduzcan directamente en comprobaciones ejecutables. Lo que cambió es lo que está en juego. Cuando un humano construía la feature, un Dado-Cuando-Entonces laxo era un boceto útil. Cuando lo construye un agente y se autoinforma, la comprobación tiene que ser lo bastante apretada como para que pasarla exija que el comportamiento exista.</p>
<h2 id="malo-y-bueno-lado-a-lado">Malo y bueno, lado a lado</h2>
<p>El hueco se ve más fácil directamente:</p>
<ul>
<li>«La búsqueda debería funcionar bien» → «Una búsqueda por el título exacto de un producto devuelve ese producto como primer resultado.»</li>
<li>«El formulario debería validar la entrada» → «Enviar el formulario con el campo de email vacío muestra un error en línea y no lanza ninguna petición.»</li>
<li>«El rendimiento debería ser aceptable» → «La lista de productos se renderiza en menos de un segundo con 500 elementos en el conjunto de datos.»</li>
<li>«Manejar los casos límite» → «Un pedido con cero artículos no se puede enviar; el botón de envío está deshabilitado y la API rechaza un payload de cero artículos con un 400.»</li>
</ul>
<p>Fíjate en que las versiones buenas no son más largas por ser prosa más detallada. Son más precisas porque cada una nombra una entrada, una acción y un resultado observable. Ese es todo el movimiento: sustituir cualidades que el agente puede afirmar por condiciones que el agente tiene que producir.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Cambia cualidades que un agente puede afirmar por condiciones que tiene que producir y puedes observar."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">Afirmable</p>
    <ul><li>Rápido</li><li>Fácil de usar</li><li>Gestiona errores</li><li>Funciona bien</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">Comprobable</p>
    <ul><li>Menos de 200 ms</li><li>Compra sin cuenta</li><li>Reintento en el 500</li><li>Título exacto primero</li></ul>
  </div>
</div><figcaption>Cambia cualidades que un agente puede afirmar por condiciones que tiene que producir y puedes observar.</figcaption></figure>
<h2 id="los-criterios-como-definición-de-hecho-del-agente">Los criterios como definición de hecho del agente</h2>
<p>Los criterios de aceptación verificables son cómo consigues que un agente demuestre la finalización en vez de afirmarla. Es el mismo principio de <a href="/es/blog/hecho-significa-hecho/">hecho significa hecho</a>: una tarea no está terminada porque el agente lo diga, está terminada porque una comprobación definida pasó contra el resultado real. Los criterios escritos como condiciones comprobables son justo lo que esa puerta necesita. Escritos como prosa, no hay puerta, solo la palabra del agente.</p>
<p>Por eso también los criterios de aceptación pertenecen a la spec, no a la cabeza de un revisor. Una <a href="/es/blog/spec-como-contrato/">spec es el contrato</a>, y los criterios de aceptación son la parte del contrato que decide si se cumplió. Si viven solo en prosa que un humano interpreta, no pueden viajar con el trabajo, no se pueden reejecutar cuando el código cambia y no pueden evitar que la <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">spec derive</a> a medida que el comportamiento se mueve. Los criterios verificables son lo que permite que una <a href="/es/blog/especificaciones-vivas/">spec viva</a> te diga cuándo la realidad ha divergido del contrato, porque puedes ejecutarlos otra vez y verlos fallar.</p>
<p>Hay un límite que conviene decir claro. No todo criterio se puede reducir hoy a una comprobación automática, y algunos necesitan de verdad criterio humano, como si un flujo se siente bien. La meta no es fingir que el juicio no existe. Es hacer que todo criterio que <em>puede</em> ser mecánico lo sea de verdad, para que el juicio humano se gaste en las pocas cosas que realmente lo necesitan en vez de reevaluar «fácil de usar» en cada ejecución.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Los criterios de aceptación solo funcionan como puerta si están anclados al trabajo y se pueden ejecutar contra el resultado, no enterrados en un documento que un humano tiene que comprobar a ojo. PaellaDoc mantiene los criterios conectados con la spec, el código y la evidencia de cada ejecución, de modo que «hecho» significa que una comprobación definida pasó y la prueba está adjunta, no que un agente resumió su propio trabajo como completo. El criterio deja de ser una frase con la que estar de acuerdo y pasa a ser una condición que el trabajo tiene que satisfacer.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Los criterios de aceptación para agentes son distintos de los criterios para personas?</strong> Los buenos son iguales: concretos, observables, comprobables. La diferencia es que las personas toleran criterios vagos rellenando huecos con criterio, y los agentes no. Escribir para agentes solo obliga a la disciplina que siempre fue la idea correcta.</p>
<p><strong>¿Tengo que escribir cada criterio como Dado-Cuando-Entonces?</strong> No. Dado-Cuando-Entonces es una forma útil porque obliga a una entrada, una acción y un resultado, pero cualquier criterio que nombre una condición concreta y observable con una comprobación definida funciona. El formato importa menos que la propiedad: ¿podría el agente afirmarlo sin hacerlo?</p>
<p><strong>¿Y los criterios que necesitan juicio humano, como si algo se siente bien?</strong> Mantenlos explícitos y aparte. Algunos criterios necesitan de verdad a una persona. El error es dejar que los subjetivos se escondan entre los mecánicos, de modo que el agente autoinforme pasa en todo. Haz mecánicos los mecánicos y marca los humanos como pendientes de revisión.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="sdd"/><category term="criterios-de-aceptacion"/><category term="desarrollo-guiado-por-especificaciones"/><category term="verificacion"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/sdd-hero.png" />
  </entry>

  <entry>
    <title type="html">Controlar el coste de la IA cuando cada tarea quema tokens</title>
    <link href="https://paelladoc.com/es/blog/controlar-costes-de-ia/" rel="alternate" type="text/html" title="Controlar el coste de la IA cuando cada tarea quema tokens"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/controlar-costes-de-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/controlar-costes-de-ia/"><![CDATA[<p>La primera vez que un agente de IA me sorprendió en coste no fue una tarea grande. Fue una pequeña que se atascó, se reintentó en bucle y corrió un modelo pesado en círculos hasta que me dio por mirar. El trabajo que produjo valía unos dos minutos de un motor barato. Los tokens que quemó, no.</p>
<p>Esa es la forma del problema. El gasto en tokens es invisible mientras ocurre y evidente un mes después, cuando llega la factura y la decisión que lo causó ya es historia. No puedes gestionar un coste que solo ves después de gastarlo.</p>
<p>Controlar el coste de la IA no va de buscar una suscripción más barata. Va de mover la decisión a donde le toca: la tarea concreta, con un número delante, antes de que los tokens se hayan ido.</p>
<h2 id="el-coste-es-un-hecho-por-tarea-no-del-mes">El coste es un hecho por tarea, no del mes</h2>
<p>Tu factura es un número. Tu trabajo son mil tareas, y son tremendamente desiguales. Un arreglo de copy de una línea y una migración de base de datos aparecen los dos como “uso de IA” en el extracto, pero uno debería costar un redondeo y el otro se gana su precio.</p>
<p>Cuando solo ves el total del mes, no puedes distinguirlos. No puedes encontrar la tarea que estuvo una hora en bucle. No puedes ver que la mitad de tu gasto se fue en ediciones triviales enrutadas, por defecto, a tu motor más caro. El agregado esconde justo la información que necesitarías para actuar.</p>
<p>Así que el primer movimiento no es un límite. Es visibilidad a nivel de tarea. Qué costó este run en tokens. Qué motor usó. Cuánto de eso fue el trabajo real y cuánto fueron reintentos. Hasta que no puedas responder eso por tarea, cada conversación sobre coste es una adivinanza.</p>
<h2 id="un-presupuesto-que-la-tarea-no-pueda-superar-a-escondidas">Un presupuesto que la tarea no pueda superar a escondidas</h2>
<p>Una vez ves el coste por tarea, puedes ponerle un tope.</p>
<p>Un presupuesto por tarea es una idea simple que casi ningún setup tiene. Antes de que arranque un run, decides el techo: este tipo de trabajo lleva un perfil ligero y un tope bajo, ese otro lleva un perfil fuerte porque se lo gana. La tarea corre dentro de ese sobre. Si lo revienta, se para y te avisa, en vez de gastarte el mes en silencio con un agente que se lió.</p>
<p>Esto importa por el modo de fallo con el que abrí. Los agentes no se pasan de gasto en las tareas que estabas mirando. Se pasan en la que se torció a las 2 de la mañana, se reintentó sola y no tenía techo contra el que chocar. Un presupuesto no está para exprimir los runs buenos. Está para cazar el run que perdió el hilo antes de que te cueste una cena fuera.</p>
<p>Los perfiles hacen esto vivible en vez de tedioso. No pones precio a cada tarea a mano. Defines unos pocos tramos, cheap, balanced, strong, y la tarea hereda un techo razonable de su tramo. La decisión manual ocurre una vez, en el tramo, no una vez por tarea.</p>
<figure class="tp-diagram tp-diagram--levels" data-diagram-type="levels" role="img" aria-label="Perfiles, no precio por tarea: cada tarea hereda un techo y un motor de su tramo, y solo el trabajo que se lo gana llega al frontier."><svg viewBox="0 0 760 272" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="20" width="140" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="46" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">CHEAP</text><rect x="40" y="78" width="280" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="104" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">BALANCED</text><rect x="40" y="136" width="420" height="40" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="52" y="162" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">STRONG</text><rect x="40" y="194" width="560" height="40" fill="var(--tp-mostaza)" stroke="var(--tp-mostaza)" stroke-width="1.5" fill-opacity="0.14"></rect>
  <text x="52" y="220" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">FRONTIER</text></svg><figcaption>Perfiles, no precio por tarea: cada tarea hereda un techo y un motor de su tramo, y solo el trabajo que se lo gana llega al frontier.</figcaption></figure>
<p>El tope también cambia cómo se comporta un agente cuando se atasca, que es de lo que va todo esto. Sin techo, un run confundido sigue intentándolo, porque nada le dice que pare. Con techo, llegar al límite es una señal. Saca a la superficie la tarea que necesita un humano en vez de moler tu presupuesto a oscuras. Un presupuesto es tanto una alarma como una cartera.</p>
<h2 id="enruta-el-trabajo-barato-a-motores-baratos">Enruta el trabajo barato a motores baratos</h2>
<p>La fuente de desperdicio más grande y más aburrida es mandar trabajo trivial a un modelo frontier porque es a lo que la herramienta apuntó por defecto.</p>
<p>Un retoque de copy no necesita tu motor más fuerte. Tampoco un rename, un comentario, un refactor pequeño que los tests ya cubren. Si todo eso va al mismo modelo caro que tus migraciones arriesgadas, estás pagando precio frontier por trabajo que un modelo ligero termina igual de bien. El routing por coste es el arreglo: el perfil de la tarea decide qué motor la recoge, y el trabajo barato aterriza en motores baratos por defecto.</p>
<p>Este es el mismo argumento que <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">enrutar cada tarea al motor adecuado</a>, leído con la lente del coste. Allí el punto era encaje y disponibilidad. Aquí es la factura. Es el mismo mecanismo. Una vez la unidad que enrutas es la tarea y no el modelo, el control de coste deja de ser una feature aparte y pasa a ser una propiedad de cómo se despacha el trabajo — que es lo que más importa cuando corres <a href="/es/blog/sesiones-paralelas-agentes/">varias sesiones de agentes en paralelo</a> y cada una gasta en silencio.</p>
<p>El motor que no pagas en absoluto es el local. El trabajo que puede correr en un modelo open source a través de Ollama te cuesta electricidad y nada más. Para una buena parte de las tareas rutinarias esa es la respuesta correcta, y una fábrica que trata <a href="/es/blog/tu-propio-modelo/">los motores locales como de primera</a> te deja tomarla.</p>
<h2 id="el-coste-que-olvidas-contar">El coste que olvidas contar</h2>
<p>El coste obvio es el precio en tokens de un run que sale bien. El que se come los presupuestos es todo lo que hay alrededor.</p>
<p>Reintentos. Un agente que falla, reintenta, vuelve a fallar y lo hace tres veces antes de que nadie se dé cuenta ha pagado cuatro veces por una tarea. Deriva. El trabajo que se salió de la spec sin avisar y hay que rehacer no es un descuento, es un segundo run completo. Bucles de verificación que re-ejecutan todo para comprobarlo. Contexto que reenvías en cada turno porque la herramienta no tiene memoria y recarga el mundo cada vez.</p>
<p>Nada de eso aparece como una línea llamada “desperdicio”. Aparece como uso normal, que es justo por lo que sobrevive. La forma de encontrarlo es la misma visibilidad de antes: si puedes ver que una tarea se corrió cuatro veces, o que un run costó el triple que sus vecinos, puedes ir a arreglar la causa. Si solo tienes el total del mes, el desperdicio es estructural, invisible, y se queda.</p>
<p>Aquí también se cruzan el control de coste y la verificación. Un agente que demuestra de forma creíble que terminó es un agente que no vuelves a correr para asegurarte. Barato y correcto no están en tensión aquí. El sistema que obliga a un modelo a demostrar que terminó es el mismo que te evita pagar dos veces por el mismo trabajo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc trata el coste como una propiedad de la tarea, no como una sorpresa a final de mes. Cada tarea lleva un perfil, cheap, balanced, strong, frontier, y ese perfil decide el motor y el techo. El trabajo barato se enruta a motores baratos, o a un modelo local a través de Ollama por el precio de la electricidad, y el motor caro queda reservado para la tarea que se lo gana.</p>
<p>Como la <a href="/es/blog/fabrica-local-de-software/">fábrica local de software</a> es local y el trabajo está acotado, puedes ver qué costó de verdad un run y cuánto de eso fueron reintentos o recuperación en vez de trabajo a la primera. Y como una tarea se cierra solo cuando la evidencia lo dice, no estás pagando otra vez solo para convencerte de que funcionó. La ventaja no es un modelo más barato. Es un sistema que gasta a propósito y te deja verlo hacerlo.</p>
<p>¿Sabes cuánto costaron tus últimas diez tareas, una a una? Si la respuesta de verdad es “el total del mes, más o menos”, esa es la brecha que conviene cerrar primero.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cómo-controlo-el-coste-de-la-ia-en-programación">¿Cómo controlo el coste de la IA en programación?</h3>
<p>Mueve la decisión de la factura del mes a la tarea concreta. Primero consigue visibilidad a nivel de tarea: qué costó un run en tokens, qué motor usó, cuánto fueron reintentos. Después ponle un tope con un presupuesto por tarea y enruta el trabajo barato a motores baratos por defecto. El coste deja de ser una sorpresa a final de mes y pasa a ser una propiedad de cómo se despacha cada tarea, con el número delante mientras todavía puedes actuar.</p>
<h3 id="por-qué-mi-agente-de-ia-quemó-tantos-tokens">¿Por qué mi agente de IA quemó tantos tokens?</h3>
<p>Normalmente no es la tarea que estabas mirando. Los agentes se pasan en la que se torció: se atascó, se reintentó en bucle y corrió un modelo frontier en círculos sin un techo contra el que chocar. El resto se esconde en costes que olvidas contar: reintentos, deriva que hay que rehacer, bucles de verificación y contexto reenviado en cada turno porque la herramienta no tiene memoria. Nada aparece como “desperdicio”; parece uso normal.</p>
<h3 id="cómo-pongo-un-presupuesto-de-tokens-por-tarea">¿Cómo pongo un presupuesto de tokens por tarea?</h3>
<p>Define unos pocos tramos —cheap, balanced, strong, frontier— en vez de poner precio a cada tarea a mano. Cada tarea hereda un techo y un motor razonables de su tramo, así que la decisión manual ocurre una vez, en el tramo. Cuando un run revienta su tope, se para y te avisa, en vez de gastarte el mes en silencio. El presupuesto es tanto una alarma que saca a la superficie un run confundido como una cartera.</p>
<h3 id="debería-enrutar-las-tareas-baratas-a-modelos-más-baratos">¿Debería enrutar las tareas baratas a modelos más baratos?</h3>
<p>Sí; es la fuente de desperdicio más grande y más aburrida. Un retoque de copy, un rename, un comentario o un refactor pequeño que los tests ya cubren no necesitan tu motor más fuerte. Deja que el perfil de la tarea decida qué motor la recoge, para que el trabajo barato aterrice en motores baratos por defecto. El trabajo rutinario que puede correr en un modelo local open source a través de Ollama cuesta solo electricidad, que suele ser la respuesta correcta.</p>]]></content>
    <summary type="html"><![CDATA[La primera vez que un agente me sorprendió en coste no fue una tarea grande. Fue una pequeña que se atascó, se reintentó en bucle y corrió un modelo frontier en círculos hasta que me di cuenta. El problema del gasto en tokens es que es invisible hasta la factura, y para entonces la decisión que lo causó tiene un mes. Controlar el coste de la IA no va de elegir un plan más barato. Va de convertir el coste en una decisión por tarea, con un presupuesto pegado, un motor más barato para el trabajo barato y el número visible mientras todavía puedes actuar.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="factory"/><category term="paelladoc"/><category term="control-costes-ia"/><category term="presupuesto-tokens"/><category term="model-routing"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/factory-hero.png" />
  </entry>

  <entry>
    <title type="html">Construir software con agentes de IA: la guía operativa</title>
    <link href="https://paelladoc.com/es/blog/construir-software-con-agentes-de-ia/" rel="alternate" type="text/html" title="Construir software con agentes de IA: la guía operativa"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/construir-software-con-agentes-de-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/construir-software-con-agentes-de-ia/"><![CDATA[<p>Construir software con agentes de IA es fácil de empezar y difícil de sostener. La primera tarde parece magia. Tres meses después tienes una app que no terminas de leer, una carpeta de decisiones que ya no cuadra con el código y la sensación incómoda de que los agentes avanzan rápido en direcciones que nunca aprobaste.</p>
<p>Los agentes no son el problema. Escriben buen código. El problema es que generar código nunca fue la parte difícil de entregar software, y ahora que es barato, todo lo que siempre fue difícil pasa a ser el trabajo entero. Ese trabajo tiene una forma. Este es el mapa.</p>
<p>Yo opero agentes a diario construyendo PaellaDoc. No en una demo, en un producto real con usuarios, invariantes y un backlog que tiene que sobrevivir a que yo olvide cosas. Lo que sigue es el bucle que de verdad corro, partido en cinco partes: definir, especificar, ejecutar, verificar, aprender. Cada parte es un sitio donde el trabajo se pierde si no lo sostienes. Cada una es una parada de este mapa, y cada una enlaza al cluster donde lo he escrito en detalle.</p>
<h2 id="la-única-idea-debajo-de-las-cinco-partes">La única idea debajo de las cinco partes</h2>
<p>Esta es la frase a la que se reduce la guía entera, la misma que atraviesa todo lo que construyo:</p>
<blockquote>
<p>El agente puede escribir el código. No puede ser lo que decide si el código cuenta, porque es la misma cosa a la que se está juzgando.</p>
</blockquote>
<p>Algo fuera del agente tiene que sostener el contrato: qué estás construyendo, qué tiene que seguir siendo cierto, qué evidencia demuestra que está hecho. Cuando construyes con un solo agente en un solo chat, ese algo eres tú, sosteniéndolo todo en la cabeza. Funciona hasta que el trabajo se te sale de una cabeza. <a href="https://www.anthropic.com/engineering/building-effective-agents">Construir con agentes a cualquier escala seria</a> es la disciplina de sacar ese contrato de tu cabeza y meterlo en un sistema que sobreviva a las sesiones, a los modelos y a tu propia mala memoria. El manifiesto detrás de este sitio a eso lo llama ser <a href="/es/blog/eres-el-runtime/">el runtime</a>. Las cinco partes de abajo son cómo dejas de serlo a mano.</p>
<h2 id="parte-1-definir-decidir-se-encareció">Parte 1. Definir: decidir se encareció</h2>
<p>Construir se abarató. Decidir qué construir se encareció, y casi nadie ha vuelto a poner precio a su atención en consecuencia. Cuando un agente produce una feature que funciona en una tarde, el coste de construir lo equivocado se desploma a casi nada por intento y estalla en el agregado. Acabas con una feature factory corriendo a velocidad de máquina, entregando superficie que nadie pidió.</p>
<p>La primera parte del bucle es negarte a que los agentes arranquen hasta saber qué comportamiento intentas instalar y por qué. Esto es trabajo de producto, y la IA cambió su economía sin cambiar su naturaleza. El discovery sigue siendo hablar con la realidad. Un modelo es buena socia para pensar y pésima para decidir, porque sintetiza con aplomo una respuesta a partir de lo que le diste, haya evidencia o no. Toda la disciplina vive en <a href="/es/blog/product-management-era-ia/">product management en la era IA</a>: las decisiones, las asunciones arriesgadas, la evidencia de que un cambio merece la pena antes de que los agentes lo construyan entero.</p>
<p>Hay una trampa concreta que conviene nombrar. Cuando construir es caro, una mala idea muere en el backlog porque nadie quiere pagar por construirla. Cuando construir es barato, esa misma mala idea se construye, se lanza y se defiende, porque ya existe y alguien le ha cogido cariño. La producción barata no solo te deja construir más cosas buenas. Quita la fricción que antes mataba a las flojas, y esa fricción hacía un trabajo real. La Parte 1 va de volver a poner fricción deliberada justo donde el mercado la quitó: en la decisión, no en el teclado.</p>
<p>Definir es también donde muchos proyectos reales arrancan hoy, de lado: alguien vibe-codea un prototipo un fin de semana, funciona, y sin ruido se convierte en el producto. Es una rampa de entrada legítima, no un pecado. Solo significa que el paso de definir ocurre después de la primera build en vez de antes, y el ascenso de prototipo a producción tiene su propio puente difícil, que es todo el cluster de <a href="/es/blog/vibe-coding-a-produccion/">vibe coding a producción</a>. En cualquier caso, sales de la Parte 1 con intención que puedes defender, no con una intuición.</p>
<h2 id="parte-2-especificar-convertir-la-intención-en-contrato">Parte 2. Especificar: convertir la intención en contrato</h2>
<p>La intención en tu cabeza no se puede delegar a un agente, y la intención en un prompt se evapora cuando termina la sesión. El puente entre decidir y construir es la especificación: el contrato que dice qué tiene que cambiar, qué no, y cómo reconocer un resultado correcto.</p>
<p>Es la parte que casi todo el mundo se salta, y es la palanca más barata de todo el bucle. Una spec no es ceremonia. Es lo que te deja apuntar un agente a una tarea y demostrar después si la hizo, sin volver a litigar el diseño entero de memoria. El argumento completo es el <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a>: <a href="https://github.com/github/spec-kit">el contrato de aceptación existe antes de escribir una línea</a>, y un build verde no es lo mismo que una feature correcta.</p>
<p>Dos propiedades hacen que una spec valga la pena cuando quien la consume son agentes. Primero, tiene que ser portable, capaz de entrar por una herramienta y salir por otra sin degradarse en prosa, que es el argumento de <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">las especificaciones de software deberían ser portables</a>. Segundo, sus criterios de aceptación tienen que ser cosas que una máquina pueda comprobar de verdad, no sensaciones que un humano tenga que mirar a ojo. Sales de la Parte 2 con un contrato que puede viajar con la tarea a la ejecución y volver con la evidencia pegada.</p>
<h2 id="parte-3-ejecutar-operar-los-agentes-sin-ser-su-runtime">Parte 3. Ejecutar: operar los agentes sin ser su runtime</h2>
<p>Ahora los agentes escriben. Esta es la parte que todo el mundo cree que es el trabajo entero, y es la que más parece magia y menos se comporta como tal a escala.</p>
<p>En el momento en que pasas de un agente a varios, el trabajo deja de ser “promptear bien” y se convierte en operaciones. Partes el producto en tareas, abres <a href="/es/blog/sesiones-paralelas-agentes/">sesiones paralelas</a> en worktrees, enrutas cada tarea al motor adecuado y pagas el coste real de ser el scheduler. Peleas con la <a href="/es/blog/perdida-de-contexto-entre-sesiones/">pérdida de contexto entre sesiones</a>, el asesino de productividad que aparece cada vez que una ventana se compacta o una sesión nueva arranca en frío y olvida la decisión que tomaste ayer. Decides qué <a href="/es/blog/memoria-agentes-de-codigo/">memoria para agentes de código</a> tiene que persistir fuera del chat, porque el chat es el único sitio donde tus decisiones duraderas jamás deberían vivir. Y aceptas que <a href="/es/blog/los-agentes-derivan/">los agentes van a derivar</a>, así que diseñas para la divergencia en vez de rezar contra ella, y aprendes a correr <a href="/es/blog/orquestacion-multiagente/">varios agentes sin que se contaminen entre sí</a>.</p>
<p>Toda esta parte es un cluster, el que contiene esta guía: <a href="/es/blog/eres-el-runtime/">operar agentes de código</a>. Su verdad incómoda es que un buen desarrollador puede hacer todo esto a mano y no darse cuenta, porque se le da bien. Justo por eso queda invisible y sin precio. El trabajo de la Parte 3 es real lo hayas nombrado o no, y nombrarlo es el primer paso para sacarlo de tu propia atención.</p>
<p>Esto es lo que se siente en un día normal. Tengo varias sesiones abiertas, cada una en su worktree, cada una en una tarea distinta. Una refactoriza un módulo, una añade una feature, una persigue un bug. Sobre la hora dos noto que la sesión de la feature y la del refactor han editado la misma interfaz, de formas incompatibles, y ninguna sabe que la otra existe. Nadie se lo ha dicho, porque “el otro agente cambió el contrato” no es algo que un agente pueda observar desde dentro de su propia ventana. Así que paro, leo los dos diffs, decido qué forma gana y le paso a la sesión perdedora una corrección. Esa interrupción es el trabajo. No es un fallo de las herramientas. Es la coordinación que antes se repartía entre un equipo de humanos que hablaban entre ellos, ahora colapsada en una persona que tiene que ser el único canal entre agentes que no se ven. Multiplícalo por ocho sesiones y entiendes por qué throughput y sistema de entrega no son lo mismo.</p>
<figure class="tp-diagram tp-diagram--lanes" data-diagram-type="lanes" role="img" aria-label="Las sesiones en paralelo no se ven entre sí, así que la colisión solo aparece al reconciliar, y hoy alguien tiene que ser ese canal entre ellas."><svg viewBox="0 0 760 222" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="40" y1="58" x2="720" y2="58" stroke="var(--tp-rule)" stroke-width="1"></line>
  <text x="40" y="40" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">REFACTOR</text>
  <circle cx="180" cy="58" r="5" fill="var(--tp-mostaza)"></circle><line x1="40" y1="112" x2="720" y2="112" stroke="var(--tp-rule)" stroke-width="1"></line>
  <text x="40" y="94" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">FEATURE</text>
  <circle cx="310" cy="112" r="5" fill="var(--tp-mostaza)"></circle><line x1="40" y1="166" x2="720" y2="166" stroke="var(--tp-rule)" stroke-width="1"></line>
  <text x="40" y="148" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">BUG</text>
  <circle cx="440" cy="166" r="5" fill="var(--tp-mostaza)"></circle><line x1="600" y1="26" x2="600" y2="184" stroke="var(--tp-terracota)" stroke-width="1.5" stroke-dasharray="4 6"></line>
  <text x="600" y="206" text-anchor="middle" font-family="var(--tp-mono)" font-size="11" letter-spacing="2" fill="var(--tp-terracota)">RECONCILIAR</text></svg><figcaption>Las sesiones en paralelo no se ven entre sí, así que la colisión solo aparece al reconciliar, y hoy alguien tiene que ser ese canal entre ellas.</figcaption></figure>
<p>La ejecución también tiene un sitio físico. Todo esto puede correr en la nube de otro, medido y con límites, o puede correr en tu máquina, donde tu código y tu contexto siguen siendo tuyos. Es el argumento de <a href="/es/manifiesto/">el manifiesto</a> detrás de este sitio, y la definición operativa de <a href="/es/blog/fabrica-local-de-software/">la fábrica local de software</a>: producto, código y evidencia en hardware que posees, con agentes enrutados entre motores en vez de atados a un proveedor. Sales de la Parte 3 con código que funciona y, si lo hiciste bien, un rastro de lo que pasó.</p>
<h2 id="parte-4-verificar-que-hecho-signifique-algo">Parte 4. Verificar: que «hecho» signifique algo</h2>
<p>El agente dice que está hecho. El build está verde. Ninguna de las dos cosas es evidencia. Esta es la parte de construir con agentes que la velocidad de las Partes 1 a 3 vuelve innegociable, porque el output dejó de ser el cuello de botella el día en que los agentes empezaron a producir más de lo que puedes leer.</p>
<p>Verificar es donde rechazas el éxito auto-declarado. Hecho significa que el comportamiento pasa los criterios de aceptación que existían antes de escribir una línea, con la evidencia pegada. La disciplina entera es <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado por IA</a>: evidencia, no sensaciones. Es también donde vive el modo de fallo del código de IA, el que me sigo encontrando: código <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto y globalmente incoherente</a>, cada diff sensato por su cuenta mientras el sistema pierde el hilo en silencio. Un agente que arregla el requisito nuevo y rompe callado un invariante viejo pasará su propia revisión siempre, porque nada le dijo que el invariante existía.</p>
<p>La versión más afilada que me sigo encontrando es un agente que reporta «tests pasan» de tests que nunca corrió, o que pasan porque no comprueban nada relevante. Un éxito auto-reportado es una afirmación, no un resultado, y a velocidad de agente recibes demasiadas afirmaciones para revisarlas leyendo una a una. Así que la verificación tiene que volverse algo que hace el sistema, no algo que haces tú mirando un resumen. Puertas que corren los criterios reales contra el comportamiento real, y un run que no tiene permiso para llamarse hecho hasta que están verdes.</p>
<p>Por eso los criterios de la Parte 2 importan tanto aquí. Verificar no es una actividad aparte atornillada al final. Es el contrato de la Parte 2, ejecutado contra el resultado real. Sales de la Parte 4 con trabajo que está demostrado o marcado con claridad como todavía-no, y sin checks verdes mintiéndote.</p>
<h2 id="parte-5-aprender-quedarte-con-lo-que-el-sistema-acaba-de-descubrir">Parte 5. Aprender: quedarte con lo que el sistema acaba de descubrir</h2>
<p>Cada run produce algo que vale la pena guardar y que no es código: una decisión, un invariante descubierto a las malas, la razón por la que se descartó un enfoque. Si ese conocimiento solo vive en el transcript, muere cuando el transcript se va scroll arriba, y el siguiente agente, o el siguiente tú, lo redescubre rompiendo lo mismo otra vez.</p>
<p>La Parte 5 es hacer que el sistema recuerde. No un wiki que nadie actualiza, sino una estructura a la que el trabajo escribe como efecto secundario de hacer el trabajo. La forma de eso es un <a href="/es/blog/grafo-de-conocimiento-de-producto/">grafo de conocimiento de producto</a>, respaldado en el lado de ingeniería por un <a href="/es/blog/grafo-de-conocimiento-del-codigo/">grafo de conocimiento del código</a>: la topología real del producto, las relaciones que los agentes necesitan para razonar un cambio en vez de hacer grep a ciegas y rezar. La memoria que persiste aquí es lo que impide que la pérdida de contexto de la Parte 3 sea permanente, y lo que deja a un agente hacer onboarding contra el grafo en vez de contra un conocimiento tribal que nadie escribió.</p>
<p>Y debajo de las cinco partes hay una forma de trabajar, no una herramienta. El hilo más viejo de este sitio, <a href="/es/blog/guia-del-framework-de-desarrollo-ai-first/">el framework de desarrollo AI-first</a>, es el argumento de que este bucle es una disciplina que adoptas a propósito, no un set de features que compras. El framework es el método. Las cinco partes son el método en movimiento.</p>
<h2 id="las-cinco-partes-son-un-sistema-no-cinco-herramientas">Las cinco partes son un sistema, no cinco herramientas</h2>
<p>Esta es la parte que más importa, y la razón de que el interlinking de este sitio sea el argumento y no un adorno. Si te compras una herramienta de discovery, una de specs, un ejecutor de agentes, un dashboard de tests y un wiki, no has construido este bucle. Has construido cinco silos, con las costuras entre ellos como el sitio exacto donde el trabajo se va a morir: la decisión que nunca llegó a la spec, la spec que el agente nunca vio, la evidencia que vive en un log de CI que nadie lee, el invariante que solo estuvo en la cabeza de alguien.</p>
<p>El bucle solo funciona cuando el mismo contrato fluye por las cinco partes. La intención de la Parte 1 se convierte en los criterios de aceptación de la Parte 2, viaja con la tarea por la ejecución de la Parte 3, se comprueba contra el resultado real en la Parte 4 y deja atrás conocimiento que el sistema guarda en la Parte 5. Un contrato, cinco paradas, ningún traspaso donde se aplane de vuelta a prosa.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="El mismo contrato cambia de forma en cada parada pero nunca se vuelve cinco cosas distintas; las costuras entre herramientas son donde el trabajo se va a morir."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="94" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">INTENCIÓN</text><path d="M 154 95 L 176 95 M 170 89 L 176 95 L 170 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="182" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="236" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CRITERIOS</text><path d="M 296 95 L 318 95 M 312 89 L 318 95 L 312 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="324" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="378" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">TAREA</text><path d="M 438 95 L 460 95 M 454 89 L 460 95 L 454 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="466" y="62" width="108" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="520" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EVIDENCIA</text><path d="M 580 95 L 602 95 M 596 89 L 602 95 L 596 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="608" y="62" width="108" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="662" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">CONOCIMIENTO</text></svg><figcaption>El mismo contrato cambia de forma en cada parada pero nunca se vuelve cinco cosas distintas; las costuras entre herramientas son donde el trabajo se va a morir.</figcaption></figure>
<p>Eso es lo que construyo, y la razón de construirlo local-first y portable en vez de como otro silo en la nube. No un agente mejor. Los agentes son buenos. La capa donde el contrato sigue vivo por las cinco partes, en tu máquina, por encima de cualquier modelo o proveedor. El agente escribe el código. Tú te quedas la intención de producto y las decisiones que importan. El sistema carga con el resto.</p>
<p>Construir software con agentes de IA, bien hecho, no es teclear más rápido. Es correr este bucle a propósito, y negarte a ser el único sitio donde se sostiene.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuál de las cinco partes corre ahora mismo en tu cabeza sin que la hayas nombrado? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cómo-empiezo-a-construir-software-con-agentes-de-ia">¿Cómo empiezo a construir software con agentes de IA?</h3>
<p>Empieza negándote a que los agentes construyan hasta saber qué comportamiento instalas y por qué. El código es la parte barata ahora; decidir qué construir es donde se movió el coste. Define intención que puedas defender, conviértela en una spec con criterios de aceptación que una máquina pueda comprobar, y solo entonces apunta agentes a la tarea.</p>
<h3 id="qué-hace-falta-además-del-modelo-para-construir-con-agentes">¿Qué hace falta además del modelo para construir con agentes?</h3>
<p>Algo fuera del agente que sostenga el contrato, porque el agente no puede juzgar si su propio código cuenta. Eso significa una spec que diga qué tiene que cambiar y seguir siendo cierto, memoria que persista decisiones e invariantes fuera del chat, y puertas que demuestren que el trabajo está hecho. Con un agente en un chat, ese algo eres tú.</p>
<h3 id="cómo-se-verifica-lo-que-construyen-los-agentes">¿Cómo se verifica lo que construyen los agentes?</h3>
<p>No fiándote del «hecho» ni de un build verde. Hecho significa que el comportamiento pasa los criterios de aceptación que existían antes de escribir una línea, con la evidencia pegada. A velocidad de agente recibes demasiadas afirmaciones para revisarlas leyendo, así que la verificación tiene que volverse puertas que el sistema corre contra el comportamiento real, no mirar un resumen.</p>
<h3 id="cómo-se-escala-de-un-agente-a-varios">¿Cómo se escala de un agente a varios?</h3>
<p>En el momento en que pasas de uno a varios, el trabajo se vuelve operaciones: partir el producto en tareas, correr sesiones en paralelo, pelear con la pérdida de contexto, persistir memoria compartida y reconciliar agentes que no se ven. Solo escala cuando el mismo contrato fluye por definir, especificar, ejecutar, verificar y aprender, en vez de vivir en tu cabeza.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="construir-con-agentes"/><category term="ai-coding"/><category term="agents"/><category term="paelladoc"/><category term="runtime"/><category term="spec-driven-development"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">El conocimiento tribal es un punto único de fallo</title>
    <link href="https://paelladoc.com/es/blog/conocimiento-tribal/" rel="alternate" type="text/html" title="El conocimiento tribal es un punto único de fallo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/conocimiento-tribal/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/conocimiento-tribal/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿Qué es el conocimiento tribal en un equipo de software?", "acceptedAnswer": {"@type": "Answer", "text": "El porqué sin documentar que vive en las cabezas: la razón de que un módulo esté estructurado raro, la mina que nadie toca, la restricción que es obvia para quien la construyó e invisible para el resto. Es conocimiento real sin representación externa, así que desaparece cuando desaparece la persona."}},
    {"@type": "Question", "name": "¿Por qué el conocimiento tribal es un punto único de fallo?", "acceptedAnswer": {"@type": "Answer", "text": "Porque todo el sistema depende de que una cabeza esté disponible. Cuando esa persona está de vacaciones, se va o simplemente lo olvida, el conocimiento desaparece y el código se queda diciendo qué hace pero no por qué. No hay redundancia ni backup, que es la definición exacta de un punto único de fallo."}},
    {"@type": "Question", "name": "¿Por qué los agentes de IA empeoran el conocimiento tribal?", "acceptedAnswer": {"@type": "Answer", "text": "Porque hacen onboarding desde cero cada sesión y no pueden absorber contexto de pasillo. Un junior humano va pillando las reglas no escritas a lo largo de meses. Un agente nunca. Ve el código, no el porqué detrás, así que cualquier conocimiento que solo vive en cabezas es permanentemente invisible para la parte del equipo que más crece."}}
  ]
}
</script>
<p>Todo equipo tiene una. La persona a la que le escribes por Slack cuando algo en el módulo de pagos pinta mal, porque es la única que recuerda por qué se construyó así y qué parte no debes tocar jamás. Funciona. Funciona hasta el día en que está de vacaciones durante un incidente, o acepta otro trabajo, y descubres que el módulo era portante y que su documentación era un ser humano.</p>
<p>A esto lo llamamos conocimiento tribal y lo tratamos como un activo blando, la señal de un equipo con oficio. También es un riesgo que valoramos en cero exacto hasta el día en que detona. El conocimiento tribal es un punto único de fallo con un nombre simpático.</p>
<h2 id="el-conocimiento-tribal-es-el-porqué-sin-copia-externa">El conocimiento tribal es el “porqué” sin copia externa</h2>
<p>El código ya te dice qué hace. Lo puedes leer. Lo que el código no te puede decir es por qué hace eso en vez de la alternativa obvia, por qué existe esta rama fea, por qué se separó este servicio, por qué nadie ha borrado eso que parece muerto.</p>
<p>Ese “porqué” es el conocimiento tribal. Es real, es portante, y existe en exactamente un sitio: una cabeza. No en el repo, no en un doc, no en un ticket. Quien lo tiene normalmente ni lo vive como conocimiento. Para esa persona es obvio, así que nunca lo escribió, porque lo obvio no se documenta. Y por eso mismo es peligroso. El contexto más crítico de tu sistema es <a href="/es/blog/memoria-de-producto/">el que nadie pensó que valía la pena registrar</a>.</p>
<h2 id="el-fallo-no-es-que-la-persona-se-vaya-es-que-falta-la-redundancia">El fallo no es que la persona se vaya. Es que falta la redundancia.</h2>
<p>La ingeniería de fiabilidad tiene una regla que ya aplicas a la infraestructura. Si al caer un nodo se cae el sistema entero, ese nodo es un punto único de fallo y le añades redundancia. Nadie corre producción sobre una sola base de datos sin réplica y se queda tan tranquilo.</p>
<p>Con el conocimiento lo hacemos constantemente. Una persona entiende el flujo de auth. Una persona sabe por qué la migración no se puede correr un lunes. Una persona recuerda al cliente que causó esa restricción rara. Cero réplicas. En cuanto ese nodo no está disponible, de vacaciones, distraído, ido, el conocimiento no está y el código se queda diciendo el qué sin el porqué.</p>
<p>El arreglo no es “contrata gente que no se vaya nunca”. Es el mismo arreglo que para la base de datos. Redundancia. El conocimiento tiene que existir en más de un sitio, y al menos uno de esos sitios tiene que ser un sistema, no un segundo humano frágil. Es lo que <a href="https://dora.dev/capabilities/documentation-quality/">la investigación sobre rendimiento de equipos no para de mostrar</a>: la documentación interna de calidad es una de las prácticas que mejor predice si un equipo aguanta el cambio, y es justo la práctica que el conocimiento tribal sustituye en silencio.</p>
<h2 id="ahora-los-nuevos-fichajes-son-agentes-y-nunca-aprenden-las-reglas-de-la-tribu">Ahora los nuevos fichajes son agentes, y nunca aprenden las reglas de la tribu</h2>
<p>Esto es lo que cambió, y por qué dejó de ser un problema lento de RRHH para volverse uno operativo este año.</p>
<p>Un junior humano absorbe el conocimiento tribal por ósmosis. Se sienta cerca del senior, escucha el incidente, le dicen “ah, eso no lo despliegues nunca un viernes”, y a los seis meses las reglas no escritas han calado. Es lento, pierde cosas, pero funciona porque la tribu se transmite sola.</p>
<p>Los agentes no se sientan en ningún sitio. Un agente de código hace onboarding desde cero cada sesión. Lee el código, no el pasillo. Nunca estuvo en la sala cuando alguien explicó por qué la lógica de reintentos no es idempotente a propósito. Así que hace lo razonable que el código parece invitar, y pisa de lleno la mina que la tribu entera aprendió a esquivar hace años.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="La tribu se transmite sola a un humano que se sienta al lado durante meses; un agente no se sienta en ningún sitio y empieza cada sesión ciego a cada regla no escrita."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">junior humano</p>
    <ul><li>absorbe por ósmosis</li><li>aprende en meses</li><li>escucha el porqué</li><li>la tribu se transmite</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">agente nuevo</p>
    <ul><li>onboarding desde cero</li><li>cada sesión</li><li>lee código no sala</li><li>pisa la mina</li></ul>
  </div>
</div><figcaption>La tribu se transmite sola a un humano que se sienta al lado durante meses; un agente no se sienta en ningún sitio y empieza cada sesión ciego a cada regla no escrita.</figcaption></figure>
<p>Esto no lo arreglas escribiendo un prompt mejor. El conocimiento no está en el modelo y no está en el repo, así que ninguna cantidad de ventana de contexto ayuda. Un agente reconstruirá con total seguridad el mismo bug que la tribu ya sufrió, porque la cicatriz que enseñó a los humanos nunca se escribió en ningún sitio que el agente pueda leer. La parte del equipo que más rápido crece es estructuralmente ciega a tu contexto más importante.</p>
<h2 id="externaliza-la-tribu-no-solo-la-documentes">Externaliza la tribu, no solo la documentes</h2>
<p>La respuesta refleja es “escribe más docs”, y falla por la razón de siempre. Docs en prosa escritos una vez, apartados a un lado, <a href="/es/blog/documentacion-viva/">se pudren más rápido de lo que se mueve el código</a> y nadie se fía de ellos en un trimestre. Acabas con conocimiento tribal más un cementerio de wikis obsoletas, que es peor.</p>
<p>Lo que sí ayuda es convertir el “porqué” en <a href="/es/blog/grafo-de-conocimiento-del-codigo/">algo estructurado y pegado a lo que explica</a>. No una página de wiki sobre el módulo de pagos, sino una decisión registrada contra el módulo de pagos: esto es idempotente a propósito, aquí está el incidente que lo forzó, no lo cambies sin leer eso. Con procedencia incluida, para que el siguiente lector sepa si es una restricción probada o la memoria de una persona.</p>
<p>Hecho así, el conocimiento deja de ser tribal. Se vuelve consultable, por un humano en su primer día y por un agente a las 2 de la mañana, desde la misma fuente. Ese es todo el sentido de <a href="/es/blog/onboarding-contra-el-grafo/">hacer onboarding contra un grafo de conocimiento en vez de contra el conocimiento tribal</a>: el recién llegado, de carbono o de silicio, aprende del sistema, no de quien esté despierto. Y es la misma apuesta que <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">un cerebro de producto que se mantiene solo</a>, donde el contexto se actualiza según se mueve el código en vez de decaer en un doc que nadie abre.</p>
<h2 id="la-factura-llega-toda-de-golpe">La factura llega toda de golpe</h2>
<p>La razón de que el conocimiento tribal siga sin valorarse es que no cuesta nada casi cualquier día normal. El senior está disponible, la pregunta se contesta en un hilo, el sistema pinta sano. El riesgo es invisible porque está dormido.</p>
<p>Luego vence todo en un momento, normalmente el peor. El incidente entra mientras la única persona que entiende el subsistema que falla está en un avión. La reescritura se atasca porque nadie de los que quedan sabe decir por qué existía la restricción vieja, así que el equipo o mantiene una regla que no entiende o la quita y reintroduce el bug original. La estimación que asumía un cambio de dos días se dispara, porque los dos días solo eran dos días para quien llevaba el mapa en la cabeza.</p>
<p>Nada de esto aparece en una reunión de planificación. Aparece como un pico en un canal de incidentes, y para entonces el momento más barato para haber externalizado el conocimiento, que era cualquier tarde tranquila del año anterior, ya pasó.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>PaellaDoc existe en parte porque me cansé de ser el punto único de fallo de mis propios proyectos. Lee un repo y su historial en decisiones y restricciones atadas al código que explican, cada una etiquetada con de dónde viene, y lo mantiene en tu máquina como un registro vivo. El “porqué” del senior deja de ser algo que tienes que pillarle con el humor adecuado para que te lo cuente. Se vuelve algo que tanto tus compañeros como tus agentes pueden consultar directamente, para que la tribu sobreviva a la tribu.</p>
<p>Local-first y gratis, sin nube y sin cuenta, contra el repo que ya tienes.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Qué parte de tu sistema depende de que una sola persona esté disponible? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-el-conocimiento-tribal-en-un-equipo-de-software">¿Qué es el conocimiento tribal en un equipo de software?</h3>
<p>El porqué sin documentar que vive en las cabezas: la razón de que un módulo esté estructurado raro, la mina que nadie toca, la restricción que es obvia para quien la construyó e invisible para el resto. Es conocimiento real sin representación externa, así que desaparece cuando desaparece la persona.</p>
<h3 id="por-qué-el-conocimiento-tribal-es-un-punto-único-de-fallo">¿Por qué el conocimiento tribal es un punto único de fallo?</h3>
<p>Porque todo el sistema depende de que una cabeza esté disponible. Cuando esa persona está de vacaciones, se va o simplemente lo olvida, el conocimiento desaparece y el código se queda diciendo qué hace pero no por qué. No hay redundancia ni backup, que es la definición exacta de un punto único de fallo.</p>
<h3 id="por-qué-los-agentes-de-ia-empeoran-el-conocimiento-tribal">¿Por qué los agentes de IA empeoran el conocimiento tribal?</h3>
<p>Porque hacen onboarding desde cero cada sesión y no pueden absorber contexto de pasillo. Un junior humano va pillando las reglas no escritas a lo largo de meses. Un agente nunca. Ve el código, no el porqué detrás, así que cualquier conocimiento que solo vive en cabezas es permanentemente invisible para la parte del equipo que más crece.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="knowledge"/><category term="paelladoc"/><category term="knowledge-graph"/><category term="tribal-knowledge"/><category term="onboarding"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/knowledge-hero.png" />
  </entry>

  <entry>
    <title type="html">Bucles de verificación: hooks, puertas y el fin del éxito auto-declarado</title>
    <link href="https://paelladoc.com/es/blog/bucles-de-verificacion/" rel="alternate" type="text/html" title="Bucles de verificación: hooks, puertas y el fin del éxito auto-declarado"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/bucles-de-verificacion/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/bucles-de-verificacion/"><![CDATA[<p>Un agente termina una tarea y escribe: «Hecho. Todos los tests pasan». Quizá los ejecutó. Quizá miró el código, decidió que los tests pasarían e informó de la conclusión que esperaba. El mensaje se lee idéntico en ambos casos. Ese es el problema entero en una frase. El <a href="/es/blog/exitos-falsos-de-agentes/">éxito auto-declarado</a> es una afirmación con la forma exacta de una prueba, sin nada de su sustancia, y por defecto lo aceptas porque comprobarlo cada vez agota.</p>
<p>Un bucle de verificación elimina la elección. El agente deja de ser lo que decide si tuvo éxito. Lo decide una puerta, y la puerta corre sobre evidencia.</p>
<h2 id="por-qué-el-éxito-auto-declarado-no-vale-nada">Por qué el éxito auto-declarado no vale nada</h2>
<p>El fallo es estructural, no cuestión de un modelo mentiroso. Un agente optimiza por producir la salida que parece completar la tarea. Un «los tests pasan» seguro es texto de alta probabilidad tras una tarea que se parece a terminar. Si un proceso de test salió con código cero es un hecho sobre el mundo; la frase es un hecho sobre las expectativas del modelo. La mayoría de las veces coinciden. Las veces que no, son justo los fallos que necesitabas cazar, y llegan vestidos con el mismo mensaje verde que los éxitos.</p>
<p>No cierras esta brecha pidiéndole al agente que tenga más cuidado, ni añadiendo «y asegúrate de que los tests pasan de verdad» al prompt. Eso produce lenguaje más seguro, no más verificación. La brecha solo cierra cuando la afirmación y la prueba las producen procesos distintos, y el que te crees no es el que está siendo corregido.</p>
<h2 id="el-bucle-en-concreto">El bucle, en concreto</h2>
<p>Un bucle de verificación tiene cuatro partes, y cada una tiene que ser mecánica.</p>
<p>Un disparador. Algo lanza la comprobación automáticamente en un momento fijo, no <a href="/es/blog/hecho-significa-hecho/">cuando el agente se siente listo</a>. El momento suele ser el fin de un turno, una escritura de fichero o un intento de commit.</p>
<p>Una comprobación que produce un veredicto. Un comando que el agente no escribió y no puede editar corre y sale con un estado. Tests, un chequeo de tipos, un linter, un build, un script que busca en el diff un patrón prohibido. El veredicto es el código de salida, no el resumen que el agente hace de él.</p>
<p>Una puerta que actúa sobre el veredicto. Si pasa, el trabajo avanza o se integra. Si falla, el trabajo se bloquea y el fallo se devuelve. La puerta no es un consejo. Una puerta que el agente puede sortear hablando es una sugerencia.</p>
<p>Un camino de vuelta. Al fallar, el error real, el stderr de verdad, vuelve al contexto del agente con la instrucción de arreglar y reejecutar. Y el bucle se repite. El agente arregla, la comprobación se dispara de nuevo, la puerta reevalúa. Cierra cuando la comprobación pasa o cuando se alcanza un límite y se llama a un humano.</p>
<p>Esa última parte es lo que lo hace un bucle y no solo un muro. El agente puede seguir intentándolo, pero cada intento tiene que sobrevivir a la misma puerta, y la puerta lee la realidad. «Los tests pasan» deja de ser algo que el agente dice y se vuelve algo que el agente tiene que hacer verdad, una y otra vez, hasta que la máquina esté de acuerdo.</p>
<h2 id="hooks-donde-el-bucle-se-engancha-al-mundo">Hooks: donde el bucle se engancha al mundo</h2>
<p>Un bucle vale lo que su disparador, y el disparador tiene que ser algo que el agente no pueda saltarse. Para eso están los hooks. Un hook es un punto donde tu tooling ejecuta tu comando automáticamente ante un evento, sin cooperación del modelo.</p>
<p>Hay capas, y quieres varias.</p>
<p>En la capa del harness del agente, las herramientas de código modernas te dejan correr un comando en eventos del ciclo de vida, cuando el agente termina de responder, antes o después de una llamada a herramienta, antes de escribir un fichero. Es el bucle más ceñido, porque el fallo vuelve al contexto de inmediato y el agente lo arregla en la misma sesión, mientras aún recuerda qué estaba haciendo.</p>
<p>En la capa de control de versiones, un hook de pre-commit o pre-push corre las comprobaciones antes de dejar entrar el cambio en la historia. Reacciona más lento que un hook del harness, pero caza lo que se coló, y le da igual qué agente o humano produjo el cambio.</p>
<p>En la capa de integración, las comprobaciones vuelven a correr en cada push, independientes del setup local de nadie. Esto es terreno viejo para equipos humanos. La <a href="https://martinfowler.com/articles/continuousIntegration.html">integración continua</a> ya significa que cada cambio se verifica automáticamente contra el sistema entero, y la investigación DORA lleva años mostrando que la <a href="https://dora.dev/capabilities/continuous-integration/">integración continua</a> y la <a href="https://dora.dev/capabilities/test-automation/">automatización de tests</a> son lo que deja a los equipos ir rápido sin romper cosas. Los agentes no inventaron la necesidad. La volvieron innegociable, porque el volumen de cambio sin revisar subió un orden de magnitud.</p>
<figure class="tp-diagram tp-diagram--stack" data-diagram-type="stack" role="img" aria-label="Los mismos checks a tres distancias del teclado. El hook del harness es el más cercano: el agente se autocorrige en el bucle."><svg viewBox="0 0 760 208" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="120" y="20" width="520" height="42" fill="var(--tp-mostaza)" fill-opacity="0.14" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="380" y="47" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">HOOK DEL HARNESS</text><rect x="120" y="76" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="103" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">HOOK PRE-COMMIT</text><rect x="120" y="132" width="520" height="42" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="159" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">CI DE INTEGRACIÓN</text></svg><figcaption>Los mismos checks a tres distancias del teclado. El hook del harness es el más cercano: el agente se autocorrige en el bucle.</figcaption></figure>
<p>Quieres el hook rápido del harness para que el agente se autocorrija en el bucle, y los hooks más lentos de control de versiones e integración para que nada llegue a la rama compartida por la fuerza de una frase. Las mismas comprobaciones, a distintas distancias del teclado. La necesidad se multiplica cuando <a href="/es/blog/orquestacion-multiagente/">corres varios agentes en paralelo</a>: nadie vigila ningún turno concreto, así que la puerta es lo único que sostiene la línea.</p>
<h2 id="qué-debería-comprobar-la-puerta">Qué debería comprobar la puerta</h2>
<p>Una puerta no vale nada si comprueba lo que no toca, y hay un fuerte tirón hacia puertas fáciles de pasar que no demuestran nada. «Compila» es una puerta que un agente supera enviando el comportamiento equivocado. «Los tests pasan» solo es tan fuerte como los tests, y si el agente escribió los tests en el mismo aliento que el código, la puerta comprueba si el código está de acuerdo consigo mismo.</p>
<p>La puerta debería comprobar contra algo que el agente no redactó. Criterios de aceptación escritos antes de generar. Una <a href="/es/blog/probar-codigo-de-ia/">suite de tests que la implementación nunca vio</a>. Un escaneo de seguridad con reglas que pusiste tú. Un build que tiene que producir un artefacto que corre, no solo un chequeo de tipos limpio. El principio general, el que separa una puerta real del teatro: la comprobación tiene que poder fallar. Si no sabes describir la entrada que la pone en rojo, no está verificando nada.</p>
<h2 id="el-fallo-que-todo-el-mundo-construye-primero">El fallo que todo el mundo construye primero</h2>
<p>La primera versión común de un bucle de verificación es un hook que corre los tests e imprime el resultado, y luego el agente lee el resultado y te lo informa. Eso no es un bucle. Es el mismo éxito auto-declarado con un paso de más, porque el agente sigue siendo lo último entre la comprobación y tu decisión, y aún puede resumir un fallo como «casi todo pasa, un problema menor, hecho».</p>
<p>El bucle solo funciona cuando la puerta actúa sobre el veredicto crudo directamente. El código de salida bloquea la integración. La salida del test que falla, sin editar, es lo que reentra al contexto. En cuanto un humano o un agente puede parafrasear el veredicto antes de que surta efecto, has reabierto la brecha exacta que el bucle iba a cerrar.</p>
<p>Este es el mecanismo bajo la idea entera de <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado por IA con evidencia en vez de sensaciones</a>. No prompts más cuidadosos. No un modelo mejor. Un bucle donde el éxito lo define una comprobación que el agente no puede editar, disparada por un hook que no puede saltarse, aplicada por una puerta que no puede sortear hablando, repetida hasta que la realidad esté de acuerdo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Cablear esto a mano es la parte que nadie presupuesta. Acabas siendo tú el disparador, corriendo los tests tras cada sesión; la puerta, decidiendo si los fallos importan; y el camino de vuelta, pegando los errores y pidiendo un arreglo. Eso es hacer el trabajo del bucle a mano, sesión a sesión. PaellaDoc corre el bucle por ti: las comprobaciones se disparan con los eventos, la puerta lee códigos de salida y no resúmenes, los fallos vuelven al agente con la salida real, y la ejecución no cierra como hecha hasta que existe la evidencia. Defines una vez qué significa «verificado» y dejas de ser lo que se interpone entre una frase segura y el botón de integrar.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-un-bucle-de-verificación-para-agentes-de-código">¿Qué es un bucle de verificación para agentes de código?</h3>
<p>Es un mecanismo de cuatro partes que le quita al agente la decisión de «tuvo éxito»: un disparador lanza una comprobación automáticamente, una comprobación que el agente no puede editar produce un veredicto desde su código de salida, una puerta actúa sobre ese veredicto bloqueando o dejando pasar el trabajo, y un camino de vuelta devuelve los fallos reales para arreglarlos. Se repite hasta que la comprobación pasa o un límite llama a un humano. «Los tests pasan» pasa a ser algo que el agente tiene que hacer verdad, no algo que dice.</p>
<h3 id="por-qué-no-basta-con-un-hook-que-corre-los-tests-e-informa-del-resultado">¿Por qué no basta con un hook que corre los tests e informa del resultado?</h3>
<p>Porque deja al agente como lo último entre la comprobación y tu decisión, así que aún puede resumir un fallo como «casi todo pasa, un problema menor, hecho». Eso es éxito auto-declarado con un paso de más, no un bucle. El bucle solo funciona cuando la puerta actúa sobre el veredicto crudo directamente: el código de salida bloquea la integración y la salida del fallo, sin editar, reentra al contexto. En cuanto alguien parafrasea el veredicto antes de que surta efecto, la brecha se reabre.</p>
<h3 id="cómo-impiden-los-hooks-que-un-agente-se-salte-la-verificación">¿Cómo impiden los hooks que un agente se salte la verificación?</h3>
<p>Un hook ejecuta tu comando automáticamente ante un evento, sin cooperación del modelo. Usa varias capas: un hook del harness que se dispara cuando el agente termina un turno o escribe un fichero (el más ceñido, se autocorrige en la sesión), un hook de pre-commit o pre-push antes de que el cambio entre en la historia, y CI de integración que reejecuta en cada push independiente del setup local de nadie. Las mismas comprobaciones a tres distancias del teclado.</p>
<h3 id="qué-debería-comprobar-de-verdad-una-puerta-de-verificación">¿Qué debería comprobar de verdad una puerta de verificación?</h3>
<p>Algo que el agente no redactó. «Compila» se supera enviando el comportamiento equivocado, y «los tests pasan» solo es tan fuerte como los tests, que no valen si el agente los escribió junto al código. Comprueba contra criterios de aceptación escritos antes de generar, una suite que la implementación nunca vio, un escaneo de seguridad con tus reglas, o un build que tenga que producir un artefacto que corre. La regla que separa una puerta real del teatro: tiene que poder fallar. Si no sabes describir la entrada que la pone en rojo, no verifica nada.</p>]]></content>
    <summary type="html"><![CDATA[Todo agente de código termina su turno igual: declara éxito. A veces ejecutó los tests. A veces decidió, por la forma del código, que probablemente pasarían. No puedes distinguirlo desde el mensaje. Un bucle de verificación hace la distinción estructural en vez de confiada: el agente no cierra su propio turno, lo hace una puerta, y la puerta solo abre con evidencia que el agente no puede fabricar. Este es el mecanismo, los hooks que lo disparan y dónde cierra el bucle.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="verification-loops"/><category term="ai-coding"/><category term="verification"/><category term="continuous-integration"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">La brecha de confianza: por qué el output dejó de ser el cuello de botella</title>
    <link href="https://paelladoc.com/es/blog/brecha-de-confianza/" rel="alternate" type="text/html" title="La brecha de confianza: por qué el output dejó de ser el cuello de botella"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/brecha-de-confianza/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/brecha-de-confianza/"><![CDATA[<p>El código aparece casi al instante ahora. Describes una feature, un agente la escribe, y treinta segundos después hay un diff en tu pantalla con aspecto plausible. Luego pasas los siguientes cuarenta minutos decidiendo si te lo crees. Leyéndolo, hurgándolo, confiando a medias, publicándolo con un nudo en el estómago. Escribirlo salió gratis. Confiar en él te costó la tarde.</p>
<p>Esa brecha, entre que el código exista y que estés dispuesto a poner tu nombre en él, es el verdadero cuello de botella ahora. Siempre estuvo ahí. Antes se escondía dentro del tiempo que costaba escribir el código, porque si lo escribías despacio a mano, confiabas en él como subproducto de construirlo. Quita la escritura lenta y la confianza deja de venir gratis. Se queda ahí de pie, sola, sin pagar, y resulta ser la parte cara.</p>
<h2 id="el-output-nunca-fue-de-verdad-la-restricción">El output nunca fue de verdad la restricción</h2>
<p>Pasamos décadas optimizando la producción. Lenguajes más rápidos, mejores editores, autocompletado, frameworks, snippets, todo dirigido a sacar el código de tu cabeza y meterlo en el fichero más rápido. Funcionó, y todo ese tiempo resolvía el problema equivocado, o mejor dicho un problema a punto de desaparecer.</p>
<p>Porque la producción ya está resuelta. No perfectamente, pero muy por encima del punto en que restringe algo. Los modelos escriben código. El cuello de botella no se desvaneció cuando producir se abarató, se movió, como se mueve siempre un cuello de botella, a la siguiente cosa más escasa. Y la siguiente cosa más escasa es la confianza. Puedes generar diez implementaciones de una feature antes de comer. No puedes confiar en diez implementaciones antes de comer. La lectura, la comprobación, el «¿rompe esto lo de al lado?», eso no se aceleró nada. Si acaso se volvió más lento, porque ahora respondes por código que no escribiste y no entiendes del todo.</p>
<p>Por eso «la IA me hizo más rápido» tantas veces sabe a mentira para la hora de cenar. La generación se aceleró. La tarde no se acortó. El tiempo solo se mudó, de escribir a verificar, y nadie te avisó de que lo segundo es más duro que lo primero.</p>
<h2 id="la-confianza-no-es-una-sensación-y-esa-es-la-buena-noticia">La confianza no es una sensación, y esa es la buena noticia</h2>
<p>Aquí está la trampa. Como la confianza se siente como un estado subjetivo, intentamos ganárnosla subjetivamente. Leemos el diff con más ahínco. Miramos el código hasta que se disipa la incomodidad y a eso lo llamamos seguridad. Pero una sensación de seguridad no es lo mismo que un código correcto, y la sensación es justo lo que un agente fluido y de tono seguro fabrica mejor. Un agente que escribe código de aspecto limpio e <a href="/es/blog/exitos-falsos-de-agentes/">informa «hecho, los tests pasan»</a> produce la sensación de fiabilidad merézcala el código o no.</p>
<p>Así que la confianza subjetiva no escala y ni siquiera sigue bien a la realidad. La salida es dejar de confiar en el código y empezar a confiar en el proceso que produjo la evidencia. Es un objeto distinto por completo. No tienes que creerte la frase del agente. Tienes que poder comprobar la afirmación que hay detrás, mecánicamente, igual cada vez.</p>
<p>La confianza mecánica tiene este aspecto. Hay una especificación de qué significa correcto, escrita antes del código, para que «correcto» no lo decida mirar lo que sea que el agente produjo. Hay una comprobación que el agente no escribió y no puede editar, y pasa o falla por su cuenta. Hay un registro de la comprobación corriendo, salida real, no un resumen. Cuando esas tres cosas existen, tu confianza no está en la palabra del modelo. Está en una cadena de evidencia que puedes inspeccionar. Ese tipo de confianza escala, porque verificar una afirmación contra evidencia fija es rápido, y aguanta, porque la evidencia no cambia su versión para agradarte.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="La confianza mecánica es una cadena que puedes inspeccionar, no una sensación que te autoconvences."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">SPEC PRIMERO</text><path d="M 250 95 L 272 95 M 266 89 L 272 95 L 266 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">CHECK INDEPENDIENTE</text><path d="M 488 95 L 510 95 M 504 89 L 510 95 L 504 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="62" width="204" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="618" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">EJECUCIÓN REGISTRADA</text></svg><figcaption>La confianza mecánica es una cadena que puedes inspeccionar, no una sensación que te autoconvences.</figcaption></figure>
<h2 id="cómo-cierra-la-brecha-de-verdad">Cómo cierra la brecha de verdad</h2>
<p>Cierras la brecha de confianza encogiendo la parte que depende de que tú leas todo personalmente, y agrandando la parte por la que una máquina puede responder.</p>
<p>Mueve la definición de correcto antes de generar. Si decides qué significa «funciona» solo después de ver el código, el código ya enmarcó tu juicio, y tu confianza es en realidad familiaridad. Los criterios de aceptación puestos de antemano te dan algo contra lo que comprobar que la implementación no llegó a moldear.</p>
<p>Haz que la evidencia sea un artefacto real, no una afirmación. «Los tests pasan» es una frase. Un proceso de test que salió con código cero, con su salida capturada, es evidencia. La diferencia es el juego entero. Una la tienes que creer, la otra la puedes mirar. <a href="/es/blog/desarrollo-basado-en-evidencia/">Cerrar el trabajo con la prueba adjunta</a> es lo que convierte una promesa en un hecho sobre el que actuar sin releer el mundo.</p>
<p>Verifica las fronteras a las que el agente es ciego. Un modelo escribe cada pieza para que sea localmente correcta, y la corrección local es justo lo que se le da bien. La brecha de confianza vive en las costuras, donde el código nuevo se encuentra con el viejo, donde una asunción aquí contradice un invariante allá. Es el problema de lo <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto y globalmente incoherente</a>, y es precisamente la región donde leer el diff te dice menos, porque el diff te muestra el cambio y esconde todo lo que el cambio debía respetar. Aquí la confianza viene de comprobaciones que cruzan las costuras, <a href="https://martinfowler.com/articles/practical-test-pyramid.html">tests de integración</a> y contratos, no de mirar un fichero con más intensidad.</p>
<p>Reserva tu atención para lo que solo tú puedes juzgar. La confianza mecánica no quita al humano, lo recoloca. La máquina responde por «los tests pasan y no hubo regresión». Tú respondes por «este es el comportamiento correcto que construir». Son trabajos distintos, y colapsarlos es lo que te quema la tarde. Cuando la capa mecánica es sólida, tu tiempo de lectura va a las decisiones que de verdad piden una persona, no a hacer de niñera de un tic verde.</p>
<h2 id="la-brecha-es-donde-vive-ahora-la-disciplina">La brecha es donde vive ahora la disciplina</h2>
<p>Hay un desplazamiento entero escondido en esto, de producir software a <a href="/es/blog/aseguramiento-de-software/">asegurarlo</a>, y reordena el trabajo. Cuando el output era escaso, el buen ingeniero era el que sabía producir. Cuando la confianza es escasa, el buen ingeniero es el que sabe establecerla, rápido y de forma repetible, sobre un volumen de código que ningún humano leería línea a línea. No es un descenso del oficio. Es el oficio moviéndose adonde se movió la restricción.</p>
<p>Nada de esto significa leer con menos cuidado cuando la lectura importa. Significa no gastar tu único recurso escaso, la atención cuidadosa, en cosas por las que una máquina debería haber respondido antes de que el código llegara a ti. La brecha de confianza es el verdadero tema de <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado por IA</a>: no cómo hacer que el agente produzca más, sino cómo hacer creíble su output a la velocidad a la que llega.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>La brecha de confianza es justo la costura que PaellaDoc está hecho para sostener. Los criterios que pones antes de generar viven junto al código, para que «correcto» no sea algo que reconstruyes desde el diff. Las comprobaciones corren y dejan un registro, para que la evidencia sea un artefacto que inspeccionas en vez de una frase que crees. Y el trabajo no llega a «hecho» hasta que esa evidencia existe. Dejas de ser el mecanismo de confianza entero, leyendo cada línea para sentirte bien al publicar, y vuelves a gastar tu juicio donde cuenta: decidir qué debería ser verdad, y dejar que el sistema demuestre que lo es.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-la-brecha-de-confianza-en-el-código-generado-por-ia">¿Qué es la brecha de confianza en el código generado por IA?</h3>
<p>Es la distancia entre que el código exista y que estés dispuesto a poner tu nombre en él. Cuando escribías el código despacio a mano, confiabas en él como subproducto de construirlo. Los agentes quitaron la escritura lenta, y la confianza deja de venir gratis. Se queda ahí sin pagar, y resulta ser la parte cara: el código llega en segundos, creértelo te lleva el resto de la tarde.</p>
<h3 id="por-qué-la-ia-no-me-hace-más-rápido-en-realidad">¿Por qué la IA no me hace más rápido en realidad?</h3>
<p>Porque la generación se aceleró mientras la verificación no. Puedes producir diez implementaciones de una feature antes de comer, pero no puedes confiar en diez antes de comer. El cuello de botella no se desvaneció cuando producir se abarató, se movió a la siguiente cosa más escasa, que es la confianza. El tiempo se mudó de escribir a verificar, y verificar es más duro, porque ahora respondes por código que no escribiste y no entiendes del todo.</p>
<h3 id="cómo-confío-en-código-que-no-escribí-y-no-entiendo-del-todo">¿Cómo confío en código que no escribí y no entiendo del todo?</h3>
<p>Deja de intentar ganarte la confianza subjetivamente leyendo el diff con más ahínco, porque eso solo fabrica una sensación que un agente fluido produce bien. Confía en el proceso: una especificación de correcto escrita antes del código, una comprobación que el agente no puede editar y pasa o falla por su cuenta, y una ejecución registrada con salida real. Esa cadena de evidencia es inspeccionable y escala, porque verificar una afirmación contra evidencia fija es rápido.</p>
<h3 id="dónde-falla-más-a-menudo-el-código-generado-por-ia">¿Dónde falla más a menudo el código generado por IA?</h3>
<p>En las costuras, donde el código nuevo se encuentra con el viejo, donde una asunción aquí contradice un invariante allá. Un modelo escribe cada pieza para que sea localmente correcta, que es justo lo que se le da bien, así que el diff parece limpio mientras la incoherencia se esconde en lo que el cambio debía respetar. Leer el fichero cambiado es lo que menos te dice aquí. La confianza en las fronteras viene de tests de integración y contratos que cruzan las costuras, no de mirar un fichero con más intensidad.</p>]]></content>
    <summary type="html"><![CDATA[Desde que existe el software, producirlo era la parte difícil. Teclear era lento, así que optimizamos teclear. Esa restricción desapareció. Un agente produce en un minuto más código con aspecto de funcionar del que puedes leer en una hora, y el nuevo recurso escaso es la confianza: la seguridad de que el código hace lo que debe y no rompe nada más. La brecha de confianza es la distancia entre que el código exista y que estés dispuesto a publicarlo. No se cierra generando más rápido. Se cierra construyendo confianza mecánicamente, para que creerte el código escale con el output en vez de ahogarse en él.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="trust-gap"/><category term="ai-coding"/><category term="verification"/><category term="software-assurance"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Prueba la asunción más arriesgada antes de que los agentes lo construyan todo</title>
    <link href="https://paelladoc.com/es/blog/asuncion-mas-arriesgada/" rel="alternate" type="text/html" title="Prueba la asunción más arriesgada antes de que los agentes lo construyan todo"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/asuncion-mas-arriesgada/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/asuncion-mas-arriesgada/"><![CDATA[<p>La disciplina clásica es simple. Antes de construir una feature, encuentra la asunción de la que depende que sea a la vez más probable que esté equivocada y más cara de que lo esté, y prueba esa, barata, primero. Si toda la idea descansa sobre «los usuarios nos confiarán su login del banco» y eso resulta falso, todo lo de abajo fue desperdicio. Así que sondeas la creencia de carga antes de verter los cimientos.</p>
<p>Esto existía porque construir era caro. La prueba de la asunción más arriesgada era una forma de no gastar tres meses de ingeniería para descubrir, al final, que la cosa que nadie podía construir era la cosa que todos daban por hecha. Era un seguro contra la construcción lenta y costosa.</p>
<p>Construir ya no es lento ni costoso. Lo que cambia la disciplina en dos direcciones a la vez, una que la hace más fácil y otra que la hace más peligrosa.</p>
<h2 id="la-trampa-que-tiende-construir-barato">La trampa que tiende construir barato</h2>
<p>Este es el modo de fallo del que nadie te avisa. Cuando construir era lento, el coste de la construcción era en sí mismo una función forzosa. <em>Tenías</em> que pensar antes de construir, porque construir era la parte cara y no podías permitirte hacerlo a ciegas. La fricción te hacía identificar la asunción arriesgada, porque saltarte ese paso dolía demasiado.</p>
<p>Ahora un agente construye la feature entera en una tarde. La fricción desapareció, y con ella lo que antes forzaba el pensamiento. Así que el nuevo default es construirla sin más. ¿Para qué identificar la asunción más arriesgada y diseñar una prueba cuidadosa cuando podrías tener la feature entera funcionando para la cena? Saltas directo a la construcción, porque la construcción dejó de ser el paso caro.</p>
<p>Y entonces publicas una feature completamente construida que descansa sobre una creencia que nunca comprobaste. La asunción seguía ahí. Seguía siendo la parte más arriesgada. Solo que nunca te paraste a nombrarla, porque construir se abarató lo suficiente como para que pararse pareciera la opción lenta. Así es exactamente como <a href="/es/blog/product-management-era-ia/">construir barato hace que decidir se encarezca</a>: la baratura elimina la fricción que antes pensaba por ti, y ahora tienes que aportar ese pensamiento a propósito.</p>
<h2 id="la-economía-de-los-experimentos-en-realidad-mejoró">La economía de los experimentos en realidad mejoró</h2>
<p>Lo frustrante es que construir barato debería hacer <em>mejor</em> la prueba de la asunción más arriesgada, no obsoleta. Toda la razón por la que probabas una asunción en vez de diez era que cada prueba costaba ingeniería de verdad. Racionabas experimentos porque los experimentos eran caros.</p>
<p>Esa restricción se levantó en gran parte. Cuando construir un sondeo es casi gratis, puedes correr el experimento que antes nunca habrías justificado. La puerta falsa, el <a href="/es/blog/prototipo-como-spec/">prototipo desechable</a>, las dos variantes enseñadas a diez usuarios, la versión que solo funciona para un camino para que puedas mirar si alguien lo recorre. Cosas que eran demasiado caras de construir solo para aprender de ellas ahora son lo bastante baratas como para construirlas justo para aprender y luego tirarlas.</p>
<p>Así que la economía mejoró a tu favor. Puedes permitirte más experimentos, más rápido, sobre las asunciones que de verdad importan. La pega es que esto solo ayuda si aún haces la parte de pensar, que es nombrar qué asunción merece un experimento. Construir barato te da la capacidad de probar más. No te dice qué probar. Eso sigue siendo tu trabajo, y es el trabajo que la baratura te tienta calladamente a saltarte.</p>
<h2 id="nombrar-la-asunción-más-arriesgada-sigue-yendo-primero">Nombrar la asunción más arriesgada sigue yendo primero</h2>
<p>La habilidad que no se automatizó es identificar, de todo lo que una feature da por hecho, la creencia que es más probable que esté equivocada y más costosa si lo está. Eso es un juicio sobre tus usuarios, tu mercado y tu producto, y ninguna cantidad de velocidad de construcción lo produce.</p>
<p>Una forma útil de encontrarla: por cada cosa que la feature da calladamente por hecha, hazte dos preguntas. ¿Cuánta confianza tengo en que esto es cierto? ¿Y cuánto de la idea entera se derrumba si es falso? La asunción que es a la vez tambaleante y de carga es la que hay que probar primero. Normalmente no es una asunción técnica, porque los agentes hacen la parte técnica fácil. Es una <a href="/es/blog/discovery-con-ia/">creencia sobre si los usuarios quieren esto</a>, confiarán en esto, cambiarán su comportamiento por esto, pagarán por esto. Esas son las creencias que una feature en marcha no puede confirmar solo por existir, y son justo las que construir barato te tienta a asumir en vez de probar.</p>
<p>Hay un orden en esto que la velocidad no para de descolocar. Identifica la asunción, decide qué evidencia te movería de verdad, y luego construye el sondeo más pequeño que produzca esa evidencia. Construir barato te tienta a invertir el orden: construir primero, mirar lo que vuelva y aplicar ingeniería inversa a una lección a partir de ello. Esa inversión <a href="/es/blog/de-insight-a-resultado/">blanquea una construcción como hallazgo</a>. Acabas tratando «lo publicamos y nadie se quejó en voz alta» como validación de una creencia que nunca dijiste en voz alta, lo cual no es evidencia de nada salvo de que construir es rápido ahora. El orden importa más que nunca justo porque ya nada externo lo obliga.</p>
<h2 id="prueba-la-asunción-no-la-feature">Prueba la asunción, no la feature</h2>
<p>El movimiento es apuntar el construir barato a la asunción en vez de a la feature entera. No son lo mismo, y la diferencia es toda la disciplina.</p>
<figure class="tp-diagram tp-diagram--compare" data-diagram-type="compare" aria-label="Apunta el construir barato a la creencia arriesgada, no a la feature entera: un sondeo interroga una asunción y está hecho para tirarse."><div class="tp-diagram-compare">
  <div class="tp-diagram-compare-panel">
    <p class="tp-diagram-compare-title">construye la feature</p>
    <ul><li>Cola entera de decisiones</li><li>Funde muchas creencias</li><li>Difícil de tirar</li></ul>
  </div>
  <div class="tp-diagram-compare-panel tp-diagram-compare-panel--accent">
    <p class="tp-diagram-compare-title">construye el sondeo</p>
    <ul><li>Aísla una creencia</li><li>Barato de construir</li><li>Hecho para borrarse</li></ul>
  </div>
</div><figcaption>Apunta el construir barato a la creencia arriesgada, no a la feature entera: un sondeo interroga una asunción y está hecho para tirarse.</figcaption></figure>
<p>Construir la feature entera para ver si a los usuarios les gusta se siente como una prueba, y es una mala. Es cara incluso a velocidad de agente, porque una feature entera arrastra una cola entera de decisiones, estados y pulido que ahora tienes que mantener. Y funde una docena de asunciones en una sola señal turbia, así que cuando no cuaja no puedes saber qué creencia estaba equivocada.</p>
<p>Probar la asunción significa construir la cosa más pequeña posible que interrogue la única creencia arriesgada y nada más. Si el riesgo es «¿nos confiarán los usuarios su login del banco?», no construyes la integración bancaria entera. Construyes el punto donde la conectarían y miras si lo hacen. Construir barato hace trivial ese sondeo aislado. La habilidad es apuntarlo a la creencia, no al producto. Confunde las dos y estás de vuelta en <a href="/es/blog/que-es-una-feature-factory/">correr una feature factory</a>, publicando features completamente construidas y llamando a su existencia un proceso de aprendizaje.</p>
<p>La otra ventaja de un sondeo frente a una construcción completa es que un sondeo es barato de tirar, y tirarlo es el objetivo. Una feature completamente construida acumula una gravedad que nadie planeó. La hiciste, funciona, borrarla ahora se siente como desperdicio, así que se queda incluso cuando la asunción de debajo resultó tambaleante. Un sondeo no carga con ese peso. Existe para responder una pregunta y luego morir, salga como salga la respuesta, que es justo lo que mantiene el experimento veraz en vez de que se vuelva calladamente un compromiso.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Por eso en <a href="/es/">PaellaDoc</a> una asunción es algo que puedes nombrar y seguir, no una creencia que se queda implícita hasta que falla. Antes de que los agentes lo construyan todo, las asunciones arriesgadas son explícitas, conectadas a la decisión que depende de ellas y a la evidencia que las confirmaría o las mataría. Construir barato se vuelve lo que debería ser, una forma de correr el experimento que responde la pregunta arriesgada, en vez de una forma de saltarte la pregunta y construir encima de una apuesta sin examinar.</p>
<p>Los agentes construirán con gusto la cosa entera antes de que hayas pensado en qué parte de ella podría estar equivocada. Ese es el nuevo peligro, y es la imagen espejo del viejo. Antes protegías contra la construcción desperdiciada. Ahora proteges contra las asunciones sin examinar, porque la construcción que antes forzaba el examen es gratis. Nombra la creencia más arriesgada. Apunta el construir barato a eso, y solo a eso. Luego decide.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-la-prueba-de-la-asunción-más-arriesgada">¿Qué es la prueba de la asunción más arriesgada?</h3>
<p>Antes de construir una feature, encuentras la asunción de la que depende que sea a la vez más probable que esté equivocada y más cara de que lo esté, y pruebas esa, barata, primero. Si toda la idea descansa sobre una creencia que resulta falsa, todo lo construido encima fue desperdicio. Así que sondeas la creencia de carga antes de verter los cimientos.</p>
<h3 id="cómo-encuentro-la-asunción-más-arriesgada">¿Cómo encuentro la asunción más arriesgada?</h3>
<p>Por cada cosa que la feature da calladamente por hecha, hazte dos preguntas: cuánta confianza tengo en que es cierto, y cuánto de la idea se derrumba si es falso. La asunción que es a la vez tambaleante y de carga es la que hay que probar primero. Normalmente no es técnica, porque los agentes hacen eso fácil. Es una creencia sobre si los usuarios lo quieren, confían en ello o pagarán por ello.</p>
<h3 id="construyo-la-feature-entera-para-probarla-ahora-que-construir-es-barato">¿Construyo la feature entera para probarla ahora que construir es barato?</h3>
<p>No. Una feature entera arrastra una cola de decisiones, estados y pulido que tienes que mantener, y funde una docena de asunciones en una señal turbia, así que cuando falla no sabes qué creencia estaba mal. Apunta el construir barato a la única creencia arriesgada: construye el sondeo más pequeño que la interrogue y nada más, y que sea barato de tirar.</p>
<h3 id="por-qué-construir-barato-hace-esta-disciplina-más-importante-no-menos">¿Por qué construir barato hace esta disciplina más importante, no menos?</h3>
<p>Porque el coste de construir antes forzaba el pensamiento. Cuando construir era caro, tenías que nombrar la asunción arriesgada antes de poder permitirte construir. Ahora un agente construye la feature entera en una tarde, así que la fricción desapareció y el default es saltar directo a la construcción, publicando algo que descansa sobre una creencia que nunca comprobaste. Los experimentos se abarataron; nombrar qué probar sigue siendo tu trabajo.</p>]]></content>
    <summary type="html"><![CDATA[La prueba de la asunción más arriesgada solía protegerte de malgastar meses de ingeniería. Ahora los agentes construyen la feature entera antes de que hayas nombrado siquiera la asunción, así que la disciplina se desplaza: construir barato hace trivialmente asequible correr diez experimentos pequeños, pero solo si aún te paras a preguntar sobre qué creencia descansa todo antes de apuntar a ella con los agentes.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="pm"/><category term="riskiest-assumptions"/><category term="product-management"/><category term="ai-coding"/><category term="experiments"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/pm-hero.png" />
  </entry>

  <entry>
    <title type="html">De producir a asegurar: el nuevo cuello de botella del software</title>
    <link href="https://paelladoc.com/es/blog/aseguramiento-de-software/" rel="alternate" type="text/html" title="De producir a asegurar: el nuevo cuello de botella del software"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/aseguramiento-de-software/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/aseguramiento-de-software/"><![CDATA[<p>Piensa en dónde iba el esfuerzo. Durante casi toda la historia del software, la parte cara era hacer que la cosa existiera: escribir el código, conseguir que compilara, pelearlo hasta que funcionara siquiera. Todo en cómo organizábamos equipos asumía que la producción era el recurso escaso. Las estimaciones eran sobre cuánto se tardaría en construir. La contratación, sobre cuánto se podía construir. El cuello de botella era el teclado.</p>
<p>Los agentes movieron el cuello de botella, y muchos procesos siguen optimizando la estación que ya no es la restricción.</p>
<h2 id="qué-se-abarató-y-qué-no">Qué se abarató y qué no</h2>
<p>Sé preciso con lo que cambió. Producir código se abarató de forma drástica. Un agente convierte una descripción en una implementación funcionando en minutos, y lo hace otra vez, y otra, a través de sesiones en paralelo, más rápido de lo que podría cualquier equipo de humanos. La estación de producción, aquella en la que todo solía atascarse, ahora corre casi gratis.</p>
<p>Lo que no se abarató es saber que el código producido es correcto, que es seguro y que es coherente con todo lo que lo rodea. Ese trabajo, llámalo aseguramiento, cuesta exactamente lo que costó siempre, y podría decirse que más, porque ahora tiene que seguir el ritmo de una tasa de producción que ya no lo espera. El modelo escribe la feature en cinco minutos. Decidir si fiarse de la feature le sigue costando a un humano la misma hora cuidadosa de siempre.</p>
<p>Cuando una estación de una línea se acelera enormemente y la siguiente no, la restricción se mueve a la estación lenta. No es una metáfora, es como se comporta cualquier pipeline. El cuello de botella de construir software se ha movido de producir a asegurar. El recurso escaso y caro ya no es generar código. Es establecer que el código generado se puede creer.</p>
<figure class="tp-diagram tp-diagram--bars" data-diagram-type="bars" role="img" aria-label="Conceptual, no medido: producir código se abarató; asegurarlo no. Esa brecha es la nueva restricción."><svg viewBox="0 0 760 260" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="60" y1="200" x2="700" y2="200" stroke="var(--tp-rule)" stroke-width="1.2"></line><rect x="110" y="155" width="240" height="45" fill="var(--tp-ink)" fill-opacity="0.28"></rect>
  <text x="230" y="226" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">PRODUCIR</text><rect x="390" y="50" width="240" height="150" fill="var(--tp-mostaza)" fill-opacity="0.85"></rect>
  <text x="510" y="226" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">ASEGURAR</text></svg><figcaption>Conceptual, no medido: producir código se abarató; asegurarlo no. Esa brecha es la nueva restricción.</figcaption></figure>
<h2 id="el-síntoma-crecimiento-rápido-podredumbre-más-rápida">El síntoma: crecimiento rápido, podredumbre más rápida</h2>
<p>Puedes detectar un equipo que no ha notado el cambio por sus síntomas. La base de código crece rápido, lo que se siente como progreso. Luego empieza a pudrirse más rápido de lo que crece, lo que se siente como mala suerte y en realidad es estructura. Features que individualmente pasaron la revisión se combinan en un comportamiento que nadie diseñó. Cada cambio era <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto</a> y el conjunto deriva hacia la incoherencia, porque la estación de producción corría a tope mientras el aseguramiento seguía siendo un sello de goma al final.</p>
<p>La pista es dónde aparece el dolor. Si tus días difíciles son sobre generar código, vives en el mundo antiguo. Si tus días difíciles son sobre fiarte del código, revisarlo, reconstruir por qué existe, decidir si el último verde fue real, entonces el cuello de botella ya se movió y tu proceso puede no haberse movido con él.</p>
<p>La trampa es que los instintos del mundo antiguo aún se sienten productivos. Generar más parece impulso, y el impulso es satisfactorio, así que la respuesta natural a ir por detrás es apuntar los agentes a más trabajo. Pero si la restricción es el aseguramiento, esa respuesta empeora el problema en vez de arreglarlo: ensancha el hueco entre lo que se ha producido y lo que se ha verificado, y ese hueco creciente es justo la podredumbre. Sentirse ocupado y estar bloqueado se ven idénticos desde dentro cuando optimizas la estación equivocada.</p>
<h2 id="asegurar-no-es-hacer-más-tests">Asegurar no es hacer más tests</h2>
<p>Sería fácil oír «aseguramiento» y echar mano de «escribe más tests». Los tests son parte, pero el aseguramiento es la pregunta mayor a la que sirven: ¿se puede creer este output, y cómo lo sé? Eso incluye si los tests llegaron a ejecutarse, que no es algo que la palabra del agente pueda zanjar. Es todo el problema detrás de un <a href="/es/blog/exitos-falsos-de-agentes/">éxito falso</a>, donde «los tests pasan» es una frase generada en vez de un evento observado.</p>
<p>El aseguramiento es la disciplina de convertir afirmaciones en evidencia al ritmo al que llegan las afirmaciones. Cubre qué prueba de verdad <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde</a> y qué no, si la compleción costó <a href="/es/blog/hecho-significa-hecho/">una demostración real</a>, y si la evidencia sobrevive más allá de la terminal en la que se imprimió. Testear es una herramienta dentro del aseguramiento. El aseguramiento es la estación.</p>
<h2 id="qué-cambia-cuando-la-restricción-es-el-aseguramiento">Qué cambia cuando la restricción es el aseguramiento</h2>
<p>Nombrar el cuello de botella solo sirve si cambia lo que haces. Unas cuantas cosas se mueven en cuanto aceptas que el aseguramiento, y no la producción, es el recurso escaso.</p>
<p>Las estimaciones dejan de ser sobre tiempo de construcción. La vieja pregunta, «cuánto se tarda en escribir esto», es casi gratis de responder ahora y casi inútil, porque escribirlo es la parte barata. La pregunta que predice tu caudal real es «cuánto se tarda en fiarse de esto», y ese es el número por el que merece la pena planificar. Un cambio que un agente escribe en cinco minutos pero que toca una ruta de pagos no es un cambio de cinco minutos. Es lo que tarde el aseguramiento, y fingir lo contrario es como los equipos se comprometen a una velocidad que en realidad no pueden sostener.</p>
<p>La planificación de capacidad también se invierte. Añadir más generación, más agentes, más sesiones en paralelo, no sube el output más allá del punto en que el aseguramiento se satura. Solo ahonda la cola de trabajo sin verificar esperando al único humano que puede decidir si fiarse de él. Pasado ese punto, más producción no es más entrega, es más inventario. La palanca que mueve software terminado y fiable es la capacidad de aseguramiento, y ahí es donde va la inversión una vez que la restricción se ha movido.</p>
<p>Y la definición de progreso cambia. En una línea limitada por la producción, un diff grande se siente como un buen día. En una línea limitada por el aseguramiento, un diff grande que llega sin evidencia es un pasivo que ahora tienes que saldar, y un cambio pequeño que cierra con su prueba adjunta es lo que de verdad hizo avanzar el sistema. El equipo que interioriza esto deja de celebrar el volumen y empieza a celebrar el cambio verificado y coherente, que es el único que compone en vez de pudrirse.</p>
<h2 id="optimizar-la-estación-correcta">Optimizar la estación correcta</h2>
<p>En cuanto aceptas que la restricción se movió, el trabajo se vuelve obvio aunque no sea fácil. Dejas de verter esfuerzo en producir más, más rápido, porque la producción no es el cuello de botella y acelerar un no-cuello-de-botella solo amontona inventario delante del de verdad. Más código generado delante de un paso de aseguramiento que no puede seguir el ritmo no es progreso, es una cola creciente de cambios sin verificar.</p>
<p>En su lugar inviertes en el caudal del aseguramiento. Haz que la evidencia sea un subproducto del trabajo para que no cueste una pasada manual aparte. Revisa en los momentos que llevan más información en vez de intentar leerlo todo, que es la salida de la <a href="/es/blog/fatiga-de-revision/">fatiga de review</a>. Cierra cada tarea con la prueba adjunta para que la confianza no haya que reconstruirla a mano después, el argumento del <a href="/es/blog/desarrollo-basado-en-evidencia/">desarrollo basado en evidencia</a>. Cada uno de esos movimientos apunta al mismo blanco: subir cuánto output puedes asegurar por hora, porque ese número, no cuánto puedes producir, es ahora lo que topa el sistema entero. Es la forma concreta de la afirmación de que <a href="/es/blog/verificar-codigo-generado-por-ia/">el cuello de botella es la confianza, no el output</a>.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p><a href="/">PaellaDoc</a> es, en estos términos, una apuesta por que el aseguramiento es la restricción. Se niega al éxito auto-declarado, ejecuta el contrato de aceptación contra el resultado real y captura la evidencia junto al cambio, para que la estación de aseguramiento pueda seguir el ritmo de una estación de producción que se volvió muy rápida. La idea no es frenar la generación. Es hacer que fiarse de la generación sea lo bastante barato como para que las dos estaciones corran a la misma velocidad en vez de que una inunde a la otra.</p>
<p>Producir software dejó de ser la parte difícil. Asegurarlo se convirtió en todo el juego. Construye para la estación que es de verdad el cuello de botella.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-el-aseguramiento-de-software-en-la-era-de-la-ia">¿Qué es el aseguramiento de software en la era de la IA?</h3>
<p>El aseguramiento es el trabajo de saber que el código producido es correcto, seguro y coherente con todo lo que lo rodea, y poder mostrar cómo lo sabes. Es la pregunta mayor a la que sirven los tests: ¿se puede creer este output, incluido si los tests llegaron a ejecutarse? Los agentes abarataron producir código. El aseguramiento cuesta lo que costó siempre, así que se convirtió en la restricción de cuánto software terminado se entrega.</p>
<h3 id="por-qué-se-movió-el-cuello-de-botella-de-escribir-código-a-verificarlo">¿Por qué se movió el cuello de botella de escribir código a verificarlo?</h3>
<p>Cuando una estación de la línea se acelera enormemente y la siguiente no, la restricción se mueve a la estación lenta. Los agentes convierten una descripción en una implementación funcionando en minutos, a través de sesiones en paralelo. Decidir si fiarse de esa implementación le sigue costando a un humano la misma hora cuidadosa. Producir se abarató, asegurar no, así que el recurso escaso ya no es generar código sino establecer que el código generado se puede creer.</p>
<h3 id="asegurar-es-simplemente-hacer-más-tests">¿Asegurar es simplemente hacer más tests?</h3>
<p>No. Los tests son una herramienta dentro del aseguramiento, no su totalidad. El aseguramiento es la disciplina de convertir afirmaciones en evidencia al ritmo al que llegan: si un build en verde prueba que la feature es correcta, si la compleción costó una demostración real, si los tests llegaron a ejecutarse, y si la prueba sobrevive más allá de la terminal en la que se imprimió. Testear es un instrumento; el aseguramiento es la estación.</p>
<h3 id="cómo-deberían-cambiar-las-estimaciones-cuando-el-aseguramiento-es-el-cuello-de-botella">¿Cómo deberían cambiar las estimaciones cuando el aseguramiento es el cuello de botella?</h3>
<p>Deja de estimar tiempo de construcción y empieza a estimar tiempo de confianza. «Cuánto se tarda en escribir esto» es casi gratis de responder ahora y casi inútil. Un cambio que un agente escribe en cinco minutos pero que toca una ruta de pagos no es un cambio de cinco minutos, es lo que tarde el aseguramiento. Planificar por tiempo de construcción te compromete a una velocidad insostenible, porque el trabajo sin verificar se amontona ante el único humano que puede fiarse de él.</p>]]></content>
    <summary type="html"><![CDATA[Durante décadas la parte escasa y cara del software fue producirlo. Los agentes hundieron ese coste. Lo que no se abarató es saber que el output es correcto, seguro y coherente. El cuello de botella se movió de producir a asegurar, y un proceso que sigue tratando la producción como la parte difícil está optimizando la estación equivocada.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="verify"/><category term="software-assurance"/><category term="ai-coding"/><category term="verificacion"/><category term="proceso-de-ingenieria"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/verify-hero.png" />
  </entry>

  <entry>
    <title type="html">Cimientos bajo el castillo de naipes: arreglar una app vibe-coded sin reescribirla</title>
    <link href="https://paelladoc.com/es/blog/arreglar-app-vibe-coding/" rel="alternate" type="text/html" title="Cimientos bajo el castillo de naipes: arreglar una app vibe-coded sin reescribirla"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/arreglar-app-vibe-coding/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/arreglar-app-vibe-coding/"><![CDATA[<p>La app funciona, pero parece un castillo de naipes. Sabes que si sacas una carta, algo al otro lado de la sala se cae, así que has dejado de sacar cartas. Cada cambio lo haces conteniendo la respiración. El consejo de todos es el mismo: reescríbela bien, hazla como se debe esta vez.</p>
<p>No hace falta, y casi siempre no deberías. Una reescritura apaga la única cosa que tienes que funciona para perseguir estructura que puedes añadir sin apagar nada. La alternativa es más silenciosa y muchísimo más eficaz: poner cimientos bajo la casa mientras está en pie, pieza de carga a pieza de carga, de modo que con cada pieza el conjunto se vuelve más firme en vez de más frágil.</p>
<h2 id="por-qué-la-app-parece-de-naipes">Por qué la app parece de naipes</h2>
<p>La fragilidad no es aleatoria y no es porque el código sea “malo”. Le faltan tres cosas concretas, y cada pieza que falta es una fuente del pavor:</p>
<ul>
<li><strong>Sin contrato escrito.</strong> Nadie escribió qué se supone que hace la app, así que nada puede decirte cuándo un cambio lo violó. “Correcto” vive solo en tu memoria de haber clicado por ahí.</li>
<li><strong>Sin red de seguridad.</strong> Nada atrapa una rotura automáticamente. Te enteras de que las cosas están rotas como se enteran tus usuarios, usando la app.</li>
<li><strong>Sin límites.</strong> Las features se meten directamente en las tripas unas de otras, así que un cambio en un sitio aflora en otro no relacionado. Por eso sacar una carta tira otra.</li>
</ul>
<p>No puedes arreglar las tres a la vez, y el orden en que las arreglas es todo el juego. Hazlo mal y dejas la casa más temblorosa mientras intentas apuntalarla.</p>
<h2 id="por-qué-reescribir-es-el-error-caro">Por qué reescribir es el error caro</h2>
<p>Reescribir tienta porque un archivo en blanco parece más seguro que una maraña que no entiendes. Es una trampa por tres razones.</p>
<p>Tiras comportamiento que funciona. El código enredado codifica meses de correcciones pequeñas, casos límite que pisaste y arreglaste, cosas que funcionan por razones que has olvidado. Una reescritura descarta todo eso y redescubres esos casos límite de incidente en producción en incidente en producción.</p>
<p>Reconstruyes los mismos huecos. Si reescribes igual que construiste, por vibes, obtienes un nuevo castillo de naipes. Si reescribes con cuidado, estás haciendo meses de trabajo para llegar a un sitio al que podrías haber llegado en semanas reforzando lo que tienes.</p>
<p>Y la app está apagada todo ese tiempo, o mantienes dos versiones a la vez, que es peor. Mientras tanto, el enfoque de refuerzo no deja la app fuera de servicio ni un segundo.</p>
<h2 id="el-orden-que-de-verdad-funciona">El orden que de verdad funciona</h2>
<p>El refuerzo solo es seguro en una secuencia. Cada paso es lo que hace seguro el siguiente.</p>
<figure class="tp-diagram tp-diagram--flow" data-diagram-type="flow" role="img" aria-label="El único orden seguro. Cada paso hace seguro el siguiente; sáltate uno y el refuerzo se vuelve demolición a ciegas."><svg viewBox="0 0 760 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="142" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">ESCRIBE LA SPEC</text><path d="M 250 95 L 272 95 M 266 89 L 272 95 L 266 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="278" y="62" width="204" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="380" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">FIJA CON TESTS</text><path d="M 488 95 L 510 95 M 504 89 L 510 95 L 504 101" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="516" y="62" width="204" height="66" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.5"></rect>
  <text x="618" y="101" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-mostaza)">REFUERZA</text></svg><figcaption>El único orden seguro. Cada paso hace seguro el siguiente; sáltate uno y el refuerzo se vuelve demolición a ciegas.</figcaption></figure>
<h3 id="1-escribe-la-spec-que-nunca-se-escribió">1. Escribe la spec que nunca se escribió</h3>
<p>Antes de tocar nada, escribe qué hace ya la app, desde fuera, en presente. No cómo funciona el código, cuál es el comportamiento: este rol puede hacer esto, no puede hacer aquello, este total siempre cuadra con la suma de esas partes. Son especificaciones retroactivas, y son lo más barato y de mayor palanca de esta lista, porque definen qué significa “sigue funcionando”. Sin ellas, cada cambio posterior se juzga a ojo.</p>
<p>Hacer esto sobre una app que ya existe, en vez de antes de construir, tiene su propia técnica, y vale la pena hacerlo a propósito: el método completo está en <a href="/es/blog/specs-repo-existente/">añadir specs a un repo existente</a> sin parar el mundo.</p>
<h3 id="2-fija-el-comportamiento-actual-con-tests-de-caracterización">2. Fija el comportamiento actual con tests de caracterización</h3>
<p>Ahora captura lo que la app hace ahora mismo en tests. No tests que afirmen lo ideal, tests que congelen lo actual, para que el siguiente cambio hable en el instante en que mueve algo. Son tests de caracterización, y son <a href="https://martinfowler.com/bliki/SelfTestingCode.html">tu red de seguridad</a>. El punto todavía no es la corrección, es la detección: quieres que la casa te avise en el momento en que una carta se mueve, antes que tus usuarios.</p>
<p>Prueba primero los caminos que dolerían si se rompieran: la aritmética del dinero, la frontera de permisos, el flujo que todos usan. No buscas cobertura, buscas un cable trampa en los muros de carga.</p>
<h3 id="3-ahora-y-solo-ahora-refuerza-la-estructura">3. Ahora, y solo ahora, refuerza la estructura</h3>
<p>Con un contrato y una red en su sitio, cada cambio está comprobado, así que ahora es seguro hacer el trabajo estructural que temías: poner un límite donde dos features se meten una en otra, extraer la lógica copiada y pegada que multiplica cada bug, añadir el contrato que impide que una feature rompa otra en silencio. Hazlo en piezas pequeñas. Después de cada pieza, los tests confirman que no moviste nada que no pretendías, y la casa está, de forma medible, más firme que antes.</p>
<p>Este es el paso por el que todos quieren empezar, y es el que es letal sin los dos primeros. Reforzar la estructura sin red es exactamente cómo “una refactorización pequeña” se lleva por delante cuatro cosas a la vez.</p>
<h2 id="por-qué-el-orden-no-es-opcional">Por qué el orden no es opcional</h2>
<p>Sáltate el paso 1 y tus tests fijan comportamiento que no puedes juzgar, congelando bugs en su sitio como si fueran features. Sáltate el paso 2 y el paso 3 es demolición a ciegas. La secuencia, contrato, luego red, luego estructura, no es una preferencia de estilo. Es la diferencia entre que la casa se vuelva más firme con cada cambio o más cerca de caer.</p>
<p>Por eso también “verde” no es la meta en ningún paso. Un <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">build que pasa no es una feature correcta</a>, es un build que compiló. Tu evidencia de que la casa está más firme es el comportamiento verificado contra la spec, no la ausencia de rojo.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Cada paso de aquí es algo que puedes hacer a mano, y en una app pequeña deberías, al menos una vez, para sentir lo que compra. Deja de escalar en cuanto la app es lo bastante grande como para que sostener la spec, la red y la estructura en la cabeza a la vez sea el cuello de botella de verdad, que es justo cuando la app se volvió digna de reforzar.</p>
<p>PaellaDoc está construido para cargar con eso. Lee la app en marcha y la convierte en un modelo que puedes navegar, mantiene las specs retroactivas pegadas al código que describen, y vuelve a ejecutar la app para producir evidencia de que un comportamiento sigue en pie tras un cambio en vez de fiarse de una barra verde. La casa no deja de ser tuya. Deja de ser un castillo de naipes, porque ahora algo distinto de tu memoria sostiene la estructura. Esto es una instancia del cruce mayor que despliego en <a href="/es/blog/vibe-coding-a-produccion/">de vibe coding a producción</a>.</p>
<p>Construiste algo que la gente usa. Te lo puedes quedar, y puedes dejar de contener la respiración cada vez que lo cambias.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿De verdad puedo arreglar una app vibe-coded sin reescribirla?</strong> Sí, y normalmente deberías. Una reescritura descarta comportamiento que funciona y reconstruye los mismos huecos. Reforzar en su sitio, spec, luego tests, luego estructura, hace la app más firme con cada cambio y nunca la deja fuera de servicio.</p>
<p><strong>¿Qué son los tests de caracterización?</strong> Tests que congelan el comportamiento actual de la app en vez de afirmar el ideal. Su trabajo es la detección: te avisan en el instante en que un cambio mueve algo que funcionaba, para que encuentres las roturas antes que tus usuarios.</p>
<p><strong>¿Por qué no puedo empezar a refactorizar las partes enredadas?</strong> Porque sin spec y sin tests, refactorizar es demolición a ciegas. Escribe qué hace la app, fíjalo con tests, y solo entonces reestructura, para que cada cambio esté comprobado sobre la marcha.</p>]]></content>
    <summary type="html"><![CDATA[Tu app vibe-coded parece un castillo de naipes: tocas una cosa y te preparas para el derrumbe. No tienes que reescribirla. Puedes poner cimientos por debajo con la app en marcha, pieza de carga a pieza de carga.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="vibe"/><category term="vibe-coding"/><category term="deuda-tecnica"/><category term="tests-de-caracterizacion"/><category term="spec-driven-development"/><category term="mantenibilidad"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/vibe-hero.png" />
  </entry>

  <entry>
    <title type="html">AGENTS.md, CLAUDE.md, reglas de Cursor: dónde deberían vivir tus decisiones</title>
    <link href="https://paelladoc.com/es/blog/agents-md-claude-md-reglas/" rel="alternate" type="text/html" title="AGENTS.md, CLAUDE.md, reglas de Cursor: dónde deberían vivir tus decisiones"/>
    <published>2026-07-20T00:00:00+02:00</published>
    <updated>2026-07-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/agents-md-claude-md-reglas/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/agents-md-claude-md-reglas/"><![CDATA[<p>Añades una regla a <code>CLAUDE.md</code>. La semana siguiente pasas una tarea a Codex, y nunca lee la regla. Pegas la misma instrucción en <code>.cursor/rules</code>. Ahora la misma convención vive en tres ficheros, alejándose entre sí a tres velocidades, y ninguno es el sitio donde alguien nuevo miraría para entender por qué el producto funciona como funciona.</p>
<p>Todas las comparativas serias de estos ficheros que he leído discuten lo mismo: cómo hacer que el agente escriba código en tu estilo. Tabs o espacios, qué runner de tests, en qué carpeta va el componente nuevo. Importa, pero es la mitad barata del problema. La mitad cara es dónde viven las decisiones de producto: por qué la auth es stateless, por qué nunca hacemos soft-delete, por qué este endpoint se mantiene idempotente aunque complique el handler. Esas son las instrucciones que, cuando desaparecen, te cuestan una reescritura. Y un fichero de reglas es un mal sitio para ellas.</p>
<h2 id="para-qué-sirve-de-verdad-cada-fichero">Para qué sirve de verdad cada fichero</h2>
<p>Separemos los tres, porque no son la misma clase de cosa.</p>
<p><strong>AGENTS.md</strong> es lo más parecido a un estándar neutral que tiene este espacio. Es un Markdown plano en la raíz del repo que cualquier agente puede leer, definido en abierto en <a href="https://agents.md/">agents.md</a>, y adoptado por varias herramientas en vez de por un solo proveedor. Su trabajo es el contrato operativo del repo: cómo se compila, cómo se corren los tests, qué comandos son seguros, cuál es la estructura. Es agnóstico al agente a propósito, y por eso es el sitio correcto para hechos que son verdad da igual quién ejecute.</p>
<p><strong>CLAUDE.md</strong> es la convención de Anthropic para Claude Code, y es útil de verdad cuando Claude Code es tu executor. Anthropic lo documenta en sus <a href="https://www.anthropic.com/engineering/claude-code-best-practices">buenas prácticas de Claude Code</a>, y puede cargar contexto por directorio, permisos de herramientas, los pequeños rituales que una sesión necesita. La trampa está en el nombre. Es el fichero de Claude. En cuanto enrutas una tarea a otro motor, se queda sin leer.</p>
<p><strong>Las reglas de Cursor</strong> (el directorio <code>.cursor/rules</code>) son la misma idea atada a Cursor, con más estructura sobre cuándo aplica cada regla. GitHub Copilot tiene su propia versión también, las <a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/add-custom-instructions/add-repository-instructions">instrucciones personalizadas del repositorio</a>. Bien dentro de esa herramienta. Invisible fuera.</p>
<p>Así que el mapa real es: un estándar abierto para los hechos operativos, y un conjunto de ficheros de proveedor para el comportamiento específico de cada herramienta. Ninguno se diseñó para ser la memoria de tu producto.</p>
<h2 id="la-línea-que-decide-dónde-va-una-regla">La línea que decide dónde va una regla</h2>
<p>Este es el test que uso. Para cualquier instrucción que vayas a escribir, pregunta: ¿esto es <strong>cómo funciona el repo</strong>, o <strong>por qué el producto decidió algo</strong>?</p>
<ul>
<li><em>Cómo funciona el repo</em> es estable, verificable y verdad para todo agente. “Corre <code>make test</code> antes de decir que está hecho.” “Las migraciones viven en <code>db/migrate</code>.” “Nunca edites ficheros generados.” Esto va en AGENTS.md, porque es el contrato operativo y debe viajar al motor que uses.</li>
<li><em>Por qué el producto decidió algo</em> es una decisión con un motivo y un radio de daño. “Mantenemos el webhook de pago idempotente porque el proveedor reintenta.” “No cacheamos el saldo porque un saldo obsoleto es un ticket de soporte y una devolución.” Eso no es una convención de código. Es el contrato de producto, y no pinta nada en un fichero que un agente concreto resulta que lee.</li>
</ul>
<p>Cuando metes decisiones en un fichero de reglas, se estropean tres cosas. El fichero crece hasta que los agentes lo leen en diagonal. Los motivos se comprimen en órdenes, así que el <em>por qué</em> desaparece y solo sobrevive el <em>qué</em>, con lo que el siguiente no distingue una regla que sostiene el edificio de un resto olvidado. Y la decisión pasa a vivir en el formato de una sola herramienta, así que no sobrevive a un cambio de motor. La versión general de esto la argumenté en <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">las especificaciones de software deberían ser portables</a>: el artefacto que carga una decisión tiene que durar más que la herramienta que lo leyó.</p>
<h2 id="los-ficheros-de-reglas-son-convenciones-las-decisiones-son-contratos">Los ficheros de reglas son convenciones. Las decisiones son contratos.</h2>
<p>Una convención le dice a un agente cómo encajar. Un contrato le dice qué no puede romper. Los ficheros de reglas están hechos para lo primero y fallan en silencio en lo segundo.</p>
<p>El fallo es silencioso porque nada peta. El agente lee la regla que sigue ahí, la obedece, y produce un build verde contra una instrucción que dejó de ser verdad hace dos sprints. De eso va entero <a href="/es/blog/reglas-de-agentes-vivas/">tu fichero de reglas miente a tus agentes</a>: una regla obsoleta no lanza un error, solo despista, con seguridad. Una decisión que solo vive como una línea en <code>CLAUDE.md</code> no lleva motivo pegado ni dueño, así que nadie nota cuando la realidad la deja atrás.</p>
<p>Un contrato se comporta distinto. Carga el motivo, viaja con la tarea en vez de sentarse en un fichero global que todo agente lee a medias, y es comprobable. El criterio de aceptación “el saldo nunca se sirve desde caché” se puede testear. La línea de <code>CLAUDE.md</code> “prefiere lecturas frescas” no. Uno es un gate. El otro es una intuición con buenas intenciones.</p>
<h2 id="qué-guardo-en-cada-sitio">Qué guardo en cada sitio</h2>
<p>Este es el reparto que corro a diario, operando agentes en más de un motor:</p>








































<table><thead><tr><th>Instrucción</th><th>Dónde vive</th><th>Por qué ahí</th></tr></thead><tbody><tr><td>Comandos de build y test</td><td>AGENTS.md</td><td>operativo, agnóstico al motor</td></tr><tr><td>Estructura del repo, comandos seguros</td><td>AGENTS.md</td><td>verdad para todo agente</td></tr><tr><td>Permisos de herramientas de Claude</td><td>CLAUDE.md</td><td>solo lo lee Claude Code</td></tr><tr><td>Alcance de reglas de Cursor</td><td><code>.cursor/rules</code></td><td>solo lo aplica Cursor</td></tr><tr><td>”Por qué nunca hacemos soft-delete”</td><td>la spec / registro de decisión</td><td>es una decisión, con motivo</td></tr><tr><td>Criterios de aceptación de un cambio</td><td>el contrato de la tarea</td><td>tiene que ser verificable y viajar</td></tr></tbody></table>
<p>Los ficheros de reglas se quedan pequeños y operativos. Las decisiones viven en <a href="/es/blog/memoria-agentes-de-codigo/">artefactos que persisten fuera de cualquier sesión</a>, cargan su motivo y se pueden comprobar, cerca de la tarea que las necesita. Cuando enruto el mismo trabajo a otro modelo, como en <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">enrutar cada tarea al motor correcto</a>, el fichero operativo puede releerlo el motor nuevo y la decisión viaja con el trabajo igualmente. Nada importante queda atrapado en el Markdown de un proveedor.</p>
<h2 id="dónde-encaja-paelladoc">Dónde encaja PaellaDoc</h2>
<p>Es el mismo argumento que el resto de lo que construyo. Un fichero de reglas vale como nota operativa y es peligroso como memoria de producto, porque el contrato de producto tiene que estar por encima de cualquier agente o no es un contrato, solo un ajuste que alquilas hasta que la herramienta cambia. PaellaDoc guarda las decisiones, los criterios de aceptación y los motivos como artefactos de primera clase que viajan con la tarea y se comprueban en el gate, escriba el código el motor que escriba. El <code>AGENTS.md</code> sigue diciéndole al agente cómo compilar. El contrato decide si lo que construyó cuenta. Ese reparto de trabajo es la tesis entera del runtime: <a href="/es/blog/eres-el-runtime/">tú eres el runtime</a> sosteniéndolo a mano, hasta que lo hace otra cosa.</p>
<h2 id="faq">FAQ</h2>
<h3 id="uso-agentsmd-o-claudemd">¿Uso AGENTS.md o CLAUDE.md?</h3>
<p>Los dos, para trabajos distintos. Guarda los hechos operativos (build, test, estructura, comandos seguros) en AGENTS.md para que todo motor los lea. Guarda el comportamiento específico de Claude en CLAUDE.md si Claude Code es uno de tus executors. No dupliques el mismo contenido en ambos, o heredas el problema de deriva en cuanto una copia cambie.</p>
<h3 id="dónde-deberían-vivir-las-decisiones-de-producto-si-no-en-el-fichero-de-reglas">¿Dónde deberían vivir las decisiones de producto si no en el fichero de reglas?</h3>
<p>En un artefacto que cargue el motivo y se pueda verificar, cerca del trabajo que gobierna: una spec, un registro de decisión, o los criterios de aceptación de la tarea. Los ficheros de reglas comprimen las decisiones en órdenes y pierden el <em>por qué</em>, y están atados a una herramienta. Una decisión necesita durar más que la sesión y que el motor.</p>
<h3 id="sigo-necesitando-las-reglas-de-cursor-si-tengo-agentsmd">¿Sigo necesitando las reglas de Cursor si tengo AGENTS.md?</h3>
<p>Si usas Cursor y quieres su alcance y su aplicación por glob, sí, para comportamiento específico de la herramienta. Solo que no dejes que se convierta en el único sitio donde se escribe una decisión de verdad, porque es invisible para cualquier otro agente al que puedas enrutar trabajo.</p>]]></content>
    <summary type="html"><![CDATA[]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="runtime"/><category term="agents-md"/><category term="claude-md"/><category term="reglas-cursor"/><category term="agentes"/><category term="runtime"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/clusters/runtime-hero.png" />
  </entry>

  <entry>
    <title type="html">PAELLADOC ya tiene benchmarks de inferencia</title>
    <link href="https://paelladoc.com/es/blog/que-modelo-de-ia-es-mejor-segun-para-que/" rel="alternate" type="text/html" title="PAELLADOC ya tiene benchmarks de inferencia"/>
    <published>2026-07-17T00:00:00+02:00</published>
    <updated>2026-07-17T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/que-modelo-de-ia-es-mejor-segun-para-que/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/que-modelo-de-ia-es-mejor-segun-para-que/"><![CDATA[<p>La mayoría de benchmarks de modelos sirven de poco en el momento en que tienes que tomar una decisión de producto.</p>
<p>Se ejecutaron desde la cuenta de otro, por otro proveedor, en otro sitio del mundo y con un prompt que tú no vas a mandar nunca. Luego una gráfica de colores te dice qué modelo «ganó».</p>
<p>Está bien si te gustan las gráficas. No basta si tienes que decidir qué mueve un chat, un agente, un flujo de código o un producto que tiene que portarse bien un lunes por la mañana.</p>
<p>Por eso PAELLADOC ya tiene su propio <strong>módulo de benchmarks de inferencia</strong>.</p>
<p>Lanza campañas controladas contra las rutas que tienes configuradas en tu Mac y guarda el resultado en local: workload, endpoint, parámetros, entorno, qué volvió, cuánto tardó y si falló.</p>
<p>No es un leaderboard de modelos. Es una forma de ver qué está haciendo tu stack.</p>
<h2 id="por-qué-hacía-falta">Por qué hacía falta</h2>
<p>«Rápido» es una palabra bastante inútil cuando hablas de la respuesta de una IA.</p>
<p>Un modelo puede empezar a contestar en un segundo y tardar dos minutos en acabar. Otro puede dejar al usuario mirando un mensaje vacío medio minuto y después escribir a buen ritmo. Un tercero puede ir bien hasta que le metes 100K tokens o lanzas diez peticiones a la vez.</p>
<p>Son problemas distintos. Hasta ahora era demasiado fácil aplastarlos en una sensación: esta ruta parece lenta; esta se siente bien; este proveedor fue inestable la semana pasada.</p>
<p>El módulo nuevo convierte esa sensación en una campaña que puedes mirar después.</p>
<h2 id="qué-guarda-una-campaña">Qué guarda una campaña</h2>
<p>Eliges un workload controlado y una ruta. PAELLADOC crea las muestras, las ejecuta y conserva el contexto de la medición.</p>
<p>Los workloads controlados cubren 1K, 10K y 100K de contexto de texto, además de visión. Puedes lanzar una sola petición o un escenario en paralelo. Importa porque un modelo que parece correcto con una petición corta y tranquila se puede comportar de otra forma con contexto grande o concurrencia.</p>
<p>En cada ejecución se guardan las cosas que de verdad notas:</p>
<ul>
<li>cuándo llegó el primer token;</li>
<li>cuándo llegó la primera respuesta utilizable;</li>
<li>a qué velocidad generó salida una vez arrancó el streaming;</li>
<li>cuándo llegó la respuesta completa;</li>
<li>los tokens que reportó el proveedor;</li>
<li>reintentos, fallos y muestras incompletas.</li>
</ul>
<p>También se conserva la ruta detrás del número: proveedor, endpoint, tipo de cuenta, identidad de modelo, parámetros, entorno del cliente y protocolo de benchmark. Si faltan esos detalles o la identidad del modelo no es fiable, PAELLADOC puede ocultar el rendimiento en vez de enseñar un número limpio que no se debería comparar.</p>
<p>Esa última parte no es decoración. Es la diferencia entre medir una ruta e inventarte una liga.</p>
<h2 id="las-primeras-campañas-ya-han-demostrado-el-porqué">Las primeras campañas ya han demostrado el porqué</h2>
<p>He empezado a usar el módulo con las primeras campañas de 10K y 100K. Los datos todavía son pequeños y no están para convertirlos en claims grandilocuentes. Precisamente por eso el módulo sirve.</p>
<p>Una ruta de 10K empezó a mostrar texto aproximadamente al segundo. Otra tardó más de treinta segundos en soltar el primer token visible. La segunda puede ser útil para el trabajo adecuado; simplemente no es la que pondría detrás de un chat donde hay una persona esperando.</p>
<p>Las ejecuciones de 100K en paralelo son todavía más reveladoras. Algunas muestras han terminado, otras han fallado y otras aún no están en estado terminal. La salida correcta no es una gráfica de velocidad escogida a mano. Es una campaña incompleta con los fallos pegados.</p>
<p>Eso es lo que quería que hiciera el módulo: avisarme de cuándo todavía <strong>no</strong> tengo evidencia suficiente.</p>
<h2 id="para-qué-sirve">Para qué sirve</h2>
<p>Esto no pretende decirte qué modelo es «el mejor». Una prueba de latencia no sabe si el código es correcto, si un plan es bueno, si el modelo ha usado una herramienta con seguridad o si su política de datos encaja contigo.</p>
<p>Sí hace que la siguiente decisión deje de ser tan a ojo.</p>
<p>Si estás haciendo un flujo interactivo, mira la espera hasta el primer token. Si generas un documento largo en segundo plano, mira el tiempo hasta terminar. Si enrutas un agente por un repo grande, corre el workload que se parezca a ese trabajo. Si una ruta no es fiable, no escondas los fallos porque las muestras que salieron bien se vean rápidas.</p>
<p>Después llevas el resultado a la decisión grande: siguen importando calidad, coste, privacidad, disponibilidad y validación. Ese es el trabajo del <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">routing de modelos</a>. El módulo de benchmark le da a esa capa algo mejor que intuición.</p>
<h2 id="local-por-defecto-exportable-cuando-hace-falta">Local por defecto, exportable cuando hace falta</h2>
<p>Las campañas viven con el resto de los datos del proyecto en tu máquina. No son datos de entrenamiento para un ranking público compartido. Puedes inspeccionar una campaña en la app, exportar el informe en Markdown o usar el resultado estructurado en otro sitio.</p>
<p>Eso hace útil el módulo de dos maneras. Primero, contesta una pregunta práctica hoy: ¿qué ruta configurada debo usar para este tipo de trabajo? Segundo, deja registro de por qué esa elección tenía sentido entonces, para repetir la prueba cuando cambie un proveedor, modelo, cuenta o camino de red.</p>
<h2 id="qué-viene-ahora">Qué viene ahora</h2>
<p>El módulo acaba de empezar a recoger campañas reales. Lo siguiente no es sacar deprisa un leaderboard público a partir de unas pocas ejecuciones. Es construir historial suficiente para ver variación, fallos y cambios con el tiempo; y después conectar esos datos con calidad de tarea real.</p>
<p>Ahí es donde un benchmark se vuelve infraestructura de producto útil, en vez de otra página de opiniones sobre modelos.</p>
<p>PAELLADOC ya tiene el sitio para hacerlo.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿Qué mide el módulo de benchmarks de inferencia de PAELLADOC?", "acceptedAnswer": { "@type": "Answer", "text": "Ejecuta campañas locales controladas y guarda latencia hasta el primer token, tiempo hasta la primera respuesta utilizable, velocidad de salida, tiempo de respuesta completo, tokens del proveedor, fallos, configuración de ruta, parámetros y entorno." } },
    { "@type": "Question", "name": "¿Un benchmark de inferencia dice qué modelo de IA es mejor?", "acceptedAnswer": { "@type": "Answer", "text": "No. Mide cómo se comporta una ruta configurada ante un workload controlado. Calidad, corrección, privacidad, coste y uso de herramientas necesitan una evaluación separada." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[PAELLADOC ya tiene un módulo local de benchmarks de inferencia. Ejecuta campañas controladas contra las rutas que usas de verdad y conserva juntos latencia, fallos, parámetros, entorno e identidad del modelo.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="product"/><category term="benchmarks-de-inferencia"/><category term="modelos-de-ia"/><category term="elegir-modelo-ia"/><category term="agentes-de-ia"/><category term="herramientas-para-desarrolladores"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/inference-timing-routes-hero.png" />
  </entry>

  <entry>
    <title type="html">Las especificaciones de software deberían ser portables</title>
    <link href="https://paelladoc.com/es/blog/las-especificaciones-de-software-deberian-ser-portables/" rel="alternate" type="text/html" title="Las especificaciones de software deberían ser portables"/>
    <published>2026-07-16T00:00:00+02:00</published>
    <updated>2026-07-16T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/las-especificaciones-de-software-deberian-ser-portables/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/las-especificaciones-de-software-deberian-ser-portables/"><![CDATA[<p><strong>Las especificaciones de software deberían ser portables.</strong> La descripción de un cambio debería poder entrar por el flujo de un agente, convertirse en trabajo estructurado, código, tests y evidencia de ejecución, y salir después de forma que otra persona u otra herramienta puedan entenderla.</p>
<p>Parece obvio. No es como funciona la mayor parte del desarrollo asistido por IA.</p>
<p>Hoy las partes importantes de un cambio suelen estar partidas entre un chat, una carpeta de Markdown, un gestor de tareas, una pull request y la memoria de quien lo hizo. Cambias de agente, de editor o vuelves tres semanas después, y la intención ya <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">empieza a separarse del código</a>. El código puede seguir ahí. La razón por la que existe, el comportamiento que prometía y la prueba de que funcionó son mucho más fáciles de perder.</p>
<p>No es un argumento contra las especificaciones. Es un argumento contra tratarlas como archivos que pertenecen a una herramienta concreta.</p>
<h2 id="una-especificación-es-un-contrato-no-un-destino">Una especificación es un contrato, no un destino</h2>
<p>Una buena especificación de software explica qué tiene que cambiar, qué no puede cambiar y cómo reconocer un resultado correcto. Es el <a href="/es/blog/spec-como-contrato/">contrato entre la intención de producto y la implementación</a>.</p>
<p>Ese contrato no debería quedarse encerrado en la herramienta que lo escribió primero.</p>
<p>Debería poder importarse una propuesta, unos requisitos, decisiones de diseño y tareas desde un flujo de trabajo orientado a agentes. Debería poder conectarse ese material con un modelo de producto, un repositorio, el trabajo que sigue y la evidencia que vuelve. Y debería poder exportarse de nuevo sin obligar a la siguiente herramienta a reconstruir su significado desde un montón de prosa.</p>
<p>La distinción importante es esta:</p>
<blockquote>
<p>Una especificación portable conserva la intención. Una especificación verificada demuestra el comportamiento.</p>
</blockquote>
<p>Hacen falta las dos. La portabilidad mantiene vivo el contrato entre herramientas. La verificación decide si el contrato se ha cumplido de verdad. Como explicamos en <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">qué es el desarrollo guiado por especificaciones</a>, un build verde no basta: los <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación</a> deben ejecutarse contra el resultado real.</p>
<h2 id="el-fallo-contexto-bloqueado-dentro-de-un-workflow">El fallo: contexto bloqueado dentro de un workflow</h2>
<p>Las herramientas de código con IA son muy buenas creando un bucle local:</p>
<ol>
<li>Describes un cambio.</li>
<li>Un agente prepara un plan.</li>
<li>El agente aplica el plan.</li>
<li>Sigues adelante.</li>
</ol>
<p>El bucle se rompe cuando el contexto tiene que salir de su casa original. Un nuevo agente no ve las decisiones que había detrás del plan. Un compañero ve tareas terminadas, pero no el contrato de aceptación. Un mantenedor futuro ve un diff, pero no por qué se descartó otra alternativa. El repositorio puede seguir correcto por piezas mientras el producto se vuelve cada vez más difícil de razonar como un todo.</p>
<p>Es el mismo problema del software <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto, globalmente incoherente</a>: cada cambio aislado puede tener sentido y, aun así, el sistema perder dirección compartida.</p>
<p>Markdown no es el problema. Markdown es un buen formato de intercambio. El problema empieza cuando una carpeta de Markdown es la única representación del cambio.</p>
<h2 id="mover-el-cambio-sin-aplanarlo">Mover el cambio sin aplanarlo</h2>
<p>PAELLADOC trata ahora un workflow externo de especificaciones como un sobre interoperable, no como un destino rival.</p>
<p>OpenSpec es un formato práctico que ya puede entrar y salir de PAELLADOC. Sus archivos conocidos de propuesta, specs, diseño y tareas sirven porque hacen legible un cambio fuera de un único chat. La idea no es sustituir ese formato por otro silo. La idea es llevarlo a través de la implementación y devolverlo con el contexto que ha adquirido.</p>
<p>Puedes traer un paquete de cambio: propuesta, requisitos, diseño y tareas. PAELLADOC convierte ese material en un modelo local vivo del trabajo: artefactos de producto, relaciones, contexto de ejecución y expectativas de validación. El cambio puede recorrer después la fábrica, desde discovery y planificación hasta agentes, código, revisión y evidencia.</p>
<p>Cuando toca salir, ese mismo cambio se puede exportar otra vez. El siguiente agente o herramienta recibe un contrato legible, no solo un diff final.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/portable-software-specification-flow_480.avif 480w, /assets/images/portable-software-specification-flow_768.avif 768w, /assets/images/portable-software-specification-flow_1024.avif 1024w, /assets/images/portable-software-specification-flow_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/portable-software-specification-flow_480.webp 480w, /assets/images/portable-software-specification-flow_768.webp 768w, /assets/images/portable-software-specification-flow_1024.webp 1024w, /assets/images/portable-software-specification-flow_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/portable-software-specification-flow_480.png" srcset="/assets/images/portable-software-specification-flow_480.png 480w, /assets/images/portable-software-specification-flow_768.png 768w, /assets/images/portable-software-specification-flow_1024.png 1024w, /assets/images/portable-software-specification-flow_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Una especificación de software continua sobre papel cruza varias superficies de trabajo y termina en una carpeta sellada de verificación; representa un contrato portable entre herramientas." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>No es una importación de una sola dirección a propósito. Una importación de una sola dirección convierte las otras herramientas en una ruta de migración. Un formato bidireccional las convierte en participantes de un workflow más amplio.</p>
<h2 id="qué-debe-sobrevivir-al-viaje">Qué debe sobrevivir al viaje</h2>
<p>Una especificación portable es más que un título y una checklist. Como mínimo necesita llevar cinco cosas.</p>
<figure class="tp-diagram tp-diagram--graph" data-diagram-type="graph" role="img" aria-label="Las cinco cosas que una spec tiene que llevar para seguir teniendo sentido al moverse entre herramientas."><svg viewBox="0 0 760 320" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><line x1="380" y1="160" x2="140" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="140" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="140" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">INTENCIÓN</text><line x1="380" y1="160" x2="620" y2="62" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="620" cy="62" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="620" y="88" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">LÍMITES</text><line x1="380" y1="160" x2="96" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="96" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="96" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">DECISIONES</text><line x1="380" y1="160" x2="664" y2="232" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="664" cy="232" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="664" y="258" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">PROCEDENCIA</text><line x1="380" y1="160" x2="380" y2="40" stroke="var(--tp-rule)" stroke-width="1.2"></line>
  <circle cx="380" cy="40" r="7" fill="none" stroke="var(--tp-ink)" stroke-width="1.5"></circle>
  <text x="380" y="66" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="1.5" fill="var(--tp-mute)">EVIDENCIA</text><circle cx="380" cy="160" r="14" fill="var(--tp-mostaza)" fill-opacity="0.16" stroke="var(--tp-mostaza)" stroke-width="1.8"></circle>
  <text x="380" y="194" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">SPEC PORTABLE</text></svg><figcaption>Las cinco cosas que una spec tiene que llevar para seguir teniendo sentido al moverse entre herramientas.</figcaption></figure>
<h3 id="1-intención">1. Intención</h3>
<p>¿Qué comportamiento de usuario o de negocio debe cambiar? Sin eso, una lista de tareas se puede ejecutar perfectamente y seguir creando una feature factory: un registro de output sin una explicación del comportamiento que buscaba instalar. <a href="/es/blog/hacer-producto-no-es-productizar/">Hacer producto es instalar un comportamiento</a>, no acumular superficie.</p>
<h3 id="2-límites">2. Límites</h3>
<p>¿Qué queda explícitamente fuera? ¿Qué tiene que seguir siendo cierto después del cambio? Las restricciones suelen valer más que el camino feliz, sobre todo cuando un agente es capaz de generar mucho código plausible a gran velocidad.</p>
<h3 id="3-decisiones">3. Decisiones</h3>
<p>¿Por qué este diseño y no otro? Las decisiones de arquitectura, los trade-offs y los riesgos conocidos deben seguir unidos al cambio. No son ceremonia; son el camino más corto para entender un diff futuro.</p>
<h3 id="4-trabajo-y-procedencia">4. Trabajo y procedencia</h3>
<p>¿Qué tareas, archivos, componentes, servicios y tests pertenecen al contrato? Una especificación portable debe poder adquirir referencias al código que la implementa, no limitarse a señalar un repositorio vago.</p>
<h3 id="5-evidencia">5. Evidencia</h3>
<p>¿Qué se ejecutó? ¿Qué pasó? ¿Contra qué versión del contrato? Una casilla marcada es estado útil. No es evidencia. La diferencia importa más cuando la implementación la ha producido un agente de IA y nadie ha revisado cada línea.</p>
<p>Por eso importa un <a href="/es/blog/grafo-de-conocimiento-de-producto/">grafo de conocimiento de producto</a>: da a la especificación un lugar donde enganchar intención, código, decisiones y prueba sin reducirlos todos a un documento indiferenciado.</p>
<h2 id="interoperabilidad-no-es-vendor-lock-in-con-un-botón-de-importación-más-bonito">Interoperabilidad no es vendor lock-in con un botón de importación más bonito</h2>
<p>Hay una trampa habitual en las herramientas para developers: llamar interoperable a algo porque acepta una importación y, después, hacer que toda acción valiosa dependa de una representación interna propietaria.</p>
<p>La prueba es más sencilla: ¿puede salir el trabajo con su significado intacto?</p>
<p>Si cambias de agente mañana, ¿puede el siguiente entender la propuesta, los límites, las decisiones, las tareas y el resultado? Si el equipo decide trabajar con otro editor, ¿puede conservar sus contratos aceptados? Si el producto cambia, ¿puedes encontrar la evidencia que ya está obsoleta en vez de confiar en un verde antiguo?</p>
<p>Las especificaciones portables responden a esa prueba. Permiten que cambie el workflow sin obligar a que se reinicie la memoria del producto.</p>
<h2 id="por-qué-importa-más-con-agentes-de-ia">Por qué importa más con agentes de IA</h2>
<p>Cuanto más rápido escribe código un agente, más caro resulta perder el rastro de decisiones que rodea a ese código.</p>
<p>La IA ha abaratado producir un diff. No ha abaratado decidir qué construir, proteger las restricciones ni demostrar el comportamiento. De hecho, eleva el listón: cuando la implementación abunda, la intención duradera y la verificación se convierten en las partes escasas.</p>
<p>Por eso la unidad útil no es el prompt, el chat ni siquiera la tarea. Es el contrato portable que puede sobrevivir a los tres.</p>
<h2 id="la-visión-de-la-fábrica-local-de-software">La visión de la fábrica local de software</h2>
<p>PAELLADOC no intenta poseer el lugar donde se escribe cada especificación. Está construyendo la fábrica local donde una especificación puede convertirse en software mantenible.</p>
<p>Entra el contrato. Se conecta con el producto y el código. Se ejecuta el trabajo. Se captura la evidencia. Vuelve a salir.</p>
<p>Los agentes cambiarán. Los editores cambiarán. Los frameworks cambiarán.</p>
<p><strong>La intención, las decisiones y la prueba deberían sobrevivirles.</strong></p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Las especificaciones de software portables son lo mismo que el desarrollo guiado por especificaciones?</strong> No exactamente. El desarrollo guiado por especificaciones define el contrato de aceptación antes de implementar. La portabilidad hace que ese contrato pueda moverse entre herramientas y conserve su vínculo con el código y la verificación posteriores.</p>
<p><strong>¿Una especificación portable garantiza que la implementación sea correcta?</strong> No. Conserva el contrato; la validación en runtime y la evidencia de aceptación siguen siendo las que demuestran que es correcto.</p>
<p><strong>¿Para qué exportar una especificación después de implementar?</strong> Para que otro agente, compañero o mantenedor futuro reciba la intención, decisiones, tareas y contexto de verificación que hay detrás del código, en lugar de tener que deducirlo de un diff.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿Las especificaciones de software portables son lo mismo que el desarrollo guiado por especificaciones?", "acceptedAnswer": { "@type": "Answer", "text": "No exactamente. El desarrollo guiado por especificaciones define el contrato de aceptación antes de implementar. La portabilidad hace que ese contrato pueda moverse entre herramientas y conserve su vínculo con el código y la verificación posteriores." } },
    { "@type": "Question", "name": "¿Una especificación portable garantiza que la implementación sea correcta?", "acceptedAnswer": { "@type": "Answer", "text": "No. Conserva el contrato; la validación en runtime y la evidencia de aceptación siguen siendo las que demuestran que es correcto." } },
    { "@type": "Question", "name": "¿Para qué exportar una especificación después de implementar?", "acceptedAnswer": { "@type": "Answer", "text": "Para que otro agente, compañero o mantenedor futuro reciba la intención, decisiones, tareas y contexto de verificación que hay detrás del código, en lugar de tener que deducirlo de un diff." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[Las especificaciones de software no deberían quedar atrapadas en un agente de IA, editor o chat. Deben viajar como contrato, conectarse con el código y la evidencia que las implementan, y poder salir sin perder contexto.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="especificaciones-de-software"/><category term="spec-driven-development"/><category term="ai-coding"/><category term="desarrollo-con-agentes"/><category term="verificacion"/><category term="interoperabilidad"/><category term="paelladoc"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/software-specifications-protocol-hero.png" />
  </entry>

  <entry>
    <title type="html">Le pedí la misma app a la Codex app dos veces. Ninguna llegó al día siguiente.</title>
    <link href="https://paelladoc.com/es/blog/codex-app-dia-siguiente/" rel="alternate" type="text/html" title="Le pedí la misma app a la Codex app dos veces. Ninguna llegó al día siguiente."/>
    <published>2026-07-11T00:00:00+02:00</published>
    <updated>2026-07-11T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/codex-app-dia-siguiente/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/codex-app-dia-siguiente/"><![CDATA[<p>Cada vez que enseño PaellaDoc alguien me suelta la misma: “esto Codex te lo hace en diez minutos”.</p>
<p>Vale. Se lo he pedido a la Codex app (la de escritorio, no el CLI). Dos veces: la segunda, pidiéndole además que lo comprobara todo antes de entregar. Y he subido los tres repos a GitHub — <a href="https://github.com/jlcases/gestor-familiar-codex">el primer intento</a>, <a href="https://github.com/jlcases/gestor-familiar-codex-verificado">el segundo</a> y <a href="https://github.com/jlcases/gestor-familiar-paelladoc">el de PaellaDoc</a> — para que no tengas que fiarte de mí.</p>
<h2 id="el-primer-prompt">El primer prompt</h2>
<p>Esto le he escrito a la Codex app un sábado por la tarde, iba con prisa:</p>
<pre><code>/goal hazme una app de gestión familiar con svelte y fastapi
y sqlite que sea SOTA no me preguntes nada
</code></pre>
<p>Modelo <code>gpt-5.6-sol</code>. Después, dos mensajes más: “como la abro?” y “hazlo tu”. Diez minutos en total.</p>
<p>A PaellaDoc le he dado todavía menos:</p>
<pre><code>Gestor familiar
</code></pre>
<p>Sin spec en ningún caso. La gente pide las apps así.</p>
<h2 id="diez-minutos-después">Diez minutos después</h2>
<p>La Codex app ha entregado “Nido”. La portada es mejor que la de PaellaDoc, se lo concedo sin pelearme: paleta cálida, tipografía cuidada, saludo con tu nombre. En un vídeo de demo gana ella.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/codex-nido-home_480.avif 480w, /assets/images/codex-nido-home_768.avif 768w, /assets/images/codex-nido-home_1024.avif 1024w, /assets/images/codex-nido-home_1200.avif 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/codex-nido-home_480.webp 480w, /assets/images/codex-nido-home_768.webp 768w, /assets/images/codex-nido-home_1024.webp 1024w, /assets/images/codex-nido-home_1200.webp 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/codex-nido-home_480.png" srcset="/assets/images/codex-nido-home_480.png 480w, /assets/images/codex-nido-home_768.png 768w, /assets/images/codex-nido-home_1024.png 1024w, /assets/images/codex-nido-home_1200.png 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Portada de Nido: dashboard con saludo, métricas de tareas, compra y gastos, y agenda familiar" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><em>La portada de Nido tal cual la ha entregado la Codex app. Captura de mi sesión del 11 de julio.</em></p>
<p>Luego he hecho clic.</p>
<p>Clic en “Añadir tarea”, el botón principal de la app. No pasa nada. El modal no se abre.</p>
<p>Clic en “Tareas”. El menú la marca activa y el contenido se queda clavado en la portada.</p>
<p>Marco una tarea como hecha. El dato llega a la base de datos, el contador baja… y la pantalla se muere en esqueletos de carga.</p>
<p>Vuelvo a “Inicio”. Nada. La app entera está muerta hasta que le das a F5. Recargo y pruebo Calendario: mismo crash.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/codex-nido-frozen-nav_480.avif 480w, /assets/images/codex-nido-frozen-nav_768.avif 768w, /assets/images/codex-nido-frozen-nav_1024.avif 1024w, /assets/images/codex-nido-frozen-nav_1200.avif 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/codex-nido-frozen-nav_480.webp 480w, /assets/images/codex-nido-frozen-nav_768.webp 768w, /assets/images/codex-nido-frozen-nav_1024.webp 1024w, /assets/images/codex-nido-frozen-nav_1200.webp 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/codex-nido-frozen-nav_480.png" srcset="/assets/images/codex-nido-frozen-nav_480.png 480w, /assets/images/codex-nido-frozen-nav_768.png 768w, /assets/images/codex-nido-frozen-nav_1024.png 1024w, /assets/images/codex-nido-frozen-nav_1200.png 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Nido con la sección Calendario activa en el menú pero la miga de pan y el contenido clavados en Inicio" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><em>El menú dice Calendario. La miga de pan y el contenido, Inicio. La vista ha crasheado antes de pintarse.</em></p>
<p>La consola repite lo mismo todo el rato:</p>
<pre><code>Uncaught Svelte error: invalid_snippet_arguments
A snippet function was passed invalid arguments.
Snippets should only be instantiated via `{@render ...}`
    in Modal.svelte / in App.svelte
</code></pre>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/codex-nido-dead-after-one-click_480.avif 480w, /assets/images/codex-nido-dead-after-one-click_768.avif 768w, /assets/images/codex-nido-dead-after-one-click_1024.avif 1024w, /assets/images/codex-nido-dead-after-one-click_1200.avif 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/codex-nido-dead-after-one-click_480.webp 480w, /assets/images/codex-nido-dead-after-one-click_768.webp 768w, /assets/images/codex-nido-dead-after-one-click_1024.webp 1024w, /assets/images/codex-nido-dead-after-one-click_1200.webp 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/codex-nido-dead-after-one-click_480.png" srcset="/assets/images/codex-nido-dead-after-one-click_480.png 480w, /assets/images/codex-nido-dead-after-one-click_768.png 768w, /assets/images/codex-nido-dead-after-one-click_1024.png 1024w, /assets/images/codex-nido-dead-after-one-click_1200.png 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Nido tras interactuar: la sección Calendario muestra solo bloques de esqueleto de carga, sin contenido" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><em>Y así se queda. Solo revive con F5.</em></p>
<p>Cuatro de las cinco secciones. Ningún formulario de alta. El bug es lo de menos: el proyecto traía un chequeo, <code>svelte-check</code>, y pasa con 0 errores sobre esta app. Puedes tener el <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">build en verde</a> y una app que nadie ha visto arrancar.</p>
<h2 id="lo-que-ha-salido-del-otro-lado">Lo que ha salido del otro lado</h2>
<p>PaellaDoc ha tardado tres días y medio con la misma petición. Más feo, sí. Pero los 59 casos e2e que deja en el repo recorren la app en un navegador real: familia desde cero, adultos y niños con roles, presupuesto mensual por categoría, gastos con pagador y responsable que pasan de pendiente a pagado, el niño marca su tarea y el adulto la revisa. Hay un test cuyo único trabajo es comprobar que el niño no puede tocar tareas de otros.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/paelladoc-empty-start_480.avif 480w, /assets/images/paelladoc-empty-start_768.avif 768w, /assets/images/paelladoc-empty-start_1024.avif 1024w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/paelladoc-empty-start_480.webp 480w, /assets/images/paelladoc-empty-start_768.webp 768w, /assets/images/paelladoc-empty-start_1024.webp 1024w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/paelladoc-empty-start_480.png" srcset="/assets/images/paelladoc-empty-start_480.png 480w, /assets/images/paelladoc-empty-start_768.png 768w, /assets/images/paelladoc-empty-start_1024.png 1024w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Gestor familiar recién arrancado: panel vacío con presupuestos, gastos y tareas a cero, listo para crear la familia" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><em>El primer arranque: vacío, listo para tu familia. Sin datos ficticios sembrados. Esta captura la ha dejado el gate al validar el criterio “panel inicial vacío”; no la he hecho yo.</em></p>
<p>Cada criterio de aceptación deja su evidencia en el repo: captura más un JSON con lo comprobado. Este es de hoy:</p>
<pre><code class="language-json">{
  "acceptance_criteria": "AC-US-01-4-3-02",
  "verified": {
    "finance": { "budget": "1000.00", "spent": "200.00",
                 "pending": "125.40", "paid": "74.60" },
    "tasks_after_review": { "pending_adult_review": 0 },
    "persisted_after_reload": true
  }
}
</code></pre>
<p>1.000 menos 200, 800. 125,40 más 74,60, 200. Al céntimo. Y la captura que va al lado:</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/paelladoc-adult-summary-evidence_480.avif 480w, /assets/images/paelladoc-adult-summary-evidence_768.avif 768w, /assets/images/paelladoc-adult-summary-evidence_1024.avif 1024w, /assets/images/paelladoc-adult-summary-evidence_1200.avif 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/paelladoc-adult-summary-evidence_480.webp 480w, /assets/images/paelladoc-adult-summary-evidence_768.webp 768w, /assets/images/paelladoc-adult-summary-evidence_1024.webp 1024w, /assets/images/paelladoc-adult-summary-evidence_1200.webp 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/paelladoc-adult-summary-evidence_480.png" srcset="/assets/images/paelladoc-adult-summary-evidence_480.png 480w, /assets/images/paelladoc-adult-summary-evidence_768.png 768w, /assets/images/paelladoc-adult-summary-evidence_1024.png 1024w, /assets/images/paelladoc-adult-summary-evidence_1200.png 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Página completa del Gestor familiar con resumen financiero adulto, familia con roles, presupuesto, gastos y tareas por miembro" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><em>Página completa, dejada por el gate al validar AC-US-01-4-3-02. Los números coinciden con el JSON.</em></p>
<h2 id="y-si-le-pides-que-lo-verifique-lo-he-hecho">”¿Y si le pides que lo verifique?” Lo he hecho.</h2>
<p>Es la objeción que me iba a poner todo el mundo, así que la he probado antes de escribir esto. Segunda sesión, mismo sábado, prompt ampliado:</p>
<pre><code>/goal hazme una app de gestión familiar con svelte y fastapi
y sqlite que sea SOTA no me preguntes nada y comprueba que
todo va perfecto antes de entregármelo
</code></pre>
<p>Y esta vez la Codex app verificó de verdad. Su log de sesión lo cuenta: arrancó los servidores, vio el puerto 8000 ocupado y movió la API al 8010, recorrió la página con Playwright, sacó capturas, comprobó botones, probó la vista móvil y arregló un bug de calendario que encontró por el camino. Quince minutos. Cerró con “implementación y verificación completadas sin errores ni avisos”.</p>
<p>Se nota muchísimo. Esta vez los clics funcionan: he creado una tarea, la he completado, la he borrado; los formularios validan; hay estados de carga, de error y de vacío. Hasta trae 3 tests de backend, en verde.</p>
<p>Y aun así, mira la captura con calma:</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/codex-verificado-home_480.avif 480w, /assets/images/codex-verificado-home_768.avif 768w, /assets/images/codex-verificado-home_1024.avif 1024w, /assets/images/codex-verificado-home_1200.avif 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/codex-verificado-home_480.webp 480w, /assets/images/codex-verificado-home_768.webp 768w, /assets/images/codex-verificado-home_1024.webp 1024w, /assets/images/codex-verificado-home_1200.webp 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/codex-verificado-home_480.png" srcset="/assets/images/codex-verificado-home_480.png 480w, /assets/images/codex-verificado-home_768.png 768w, /assets/images/codex-verificado-home_1024.png 1024w, /assets/images/codex-verificado-home_1200.png 1200w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Segunda app de la Codex app: saludo Buenos días por la tarde y tira semanal que pone el día 11 bajo viernes siendo sábado" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><em>Captura de las 18:45 de la tarde: el saludo dice “Buenos días”. La cabecera dice sábado; la tira de días pone el 11 en viernes. El mini-calendario de abajo, que sí acierta, contradice a los dos.</em></p>
<p>La app está congelada en el día en que se generó:</p>
<ul>
<li>“Sábado, 11 de julio” y “Buenos días, familia.” están escritos a fuego en la plantilla.</li>
<li>El panel de “hoy” filtra los eventos con un <code>startsWith('2026-07-11')</code> literal. Desde el día 12, vacío para siempre.</li>
<li>El formulario de gasto no tiene campo de fecha: el código manda <code>spent_on: '2026-07-11'</code> fijo. Cada gasto que registres después del 11 de julio queda contabilizado el 11 de julio. Nadie lo notará hasta que el total del mes no cuadre.</li>
<li>La tira semanal es un <code>[7..13]</code> clavado que además pone el día 11 bajo el viernes, siendo sábado. Dos widgets de la misma pantalla se contradicen, y la verificación visual que miró esa pantalla no lo vio.</li>
</ul>
<p>La verificación pasó porque se hizo el mismo día que la app. Compró “funciona hoy”, en sentido literal. Y fue una pasada manual: no dejó ni un script para repetirla.</p>



























































<table><thead><tr><th></th><th>Codex app, intento 1</th><th>Codex app, intento 2</th><th>PaellaDoc</th></tr></thead><tbody><tr><td>Tiempo</td><td>~10 min</td><td>~15 min</td><td>3,5 días</td></tr><tr><td>Tokens procesados</td><td>1.896.844</td><td>2.582.741</td><td>582.670.973</td></tr><tr><td>Tokens escritos</td><td>17.959</td><td>22.893</td><td>2.394.349</td></tr><tr><td>Tests que quedan en el repo</td><td>0</td><td>3</td><td>59 + 59 e2e</td></tr><tr><td>Verificación repetible</td><td>no</td><td>no</td><td>sí, con evidencia</td></tr><tr><td>Commits</td><td>0</td><td>0</td><td>218</td></tr><tr><td>Sobrevive al primer clic</td><td>no</td><td>sí</td><td>sí</td></tr><tr><td>Funciona al día siguiente</td><td>no</td><td>no</td><td>sí</td></tr></tbody></table>
<h2 id="las-cosas-extra-que-nadie-ha-pedido">Las cosas extra que nadie ha pedido</h2>
<p>Hay un gradiente claro: cuanto más dialogas con la Codex app, mejor sale. Sin verificación, la app murió al primer clic; con una frase más, sobrevive a los clics. Con más conversación, iría a más.</p>
<p>Pero hay un techo, y no es de esfuerzo: es que la generación no es determinista. Cada pasada añade superficie que nadie ha pedido, y esa superficie parece funcional sin estarlo. En estos dos intentos, verificados uno a uno:</p>
<ul>
<li>Flechas de “mes anterior / siguiente” que no hacen nada.</li>
<li>Un enlace “Ver agenda completa →” que abre el formulario de crear plan, porque no existe ninguna agenda.</li>
<li>Un evento decorativo, “Noche tranquila en casa · 20:30”, pintado todos los días entre los eventos reales.</li>
<li>Una nota lateral fija, “Todo en calma. La semana está bien repartida.”, diga lo que diga la semana.</li>
<li>Un presupuesto de “1.800 € previstos” (1.200 € en el primer intento) que nadie ha pedido y no se puede configurar.</li>
<li>Una campana de notificaciones con su puntito rojo, sin notificaciones detrás.</li>
</ul>
<p>En el gestor de PaellaDoc pasa lo contrario, y es la diferencia de fondo: las features son las que se han decidido, cada una lleva su criterio de aceptación validado, y no hay nada más. Ni un botón sin cablear. Hasta el estado vacío del primer arranque es una feature declarada, con su criterio y su captura de evidencia.</p>
<h2 id="qué-compran-los-tokens">Qué compran los tokens</h2>
<p>Yo sabía pedir verificación, y no ha bastado. La gente que escribe “hazme una app de gestión familiar” ni siquiera sabe que hay que pedirla. Si la verificación depende de que el usuario sepa pedirla, y de que una pasada de quince minutos vea todo lo que puede fallar mañana, no hay verificación.</p>
<p>Ahí se van los 582 millones de tokens de PaellaDoc. De escribir código, solo 2,39 millones; el resto es el loop ejecutando la app, mirándola y repitiendo, 541 veces. En el historial hay commits que se llaman literalmente “Reparar validación e2e: el resumen adulto refleja el estado final del flujo completo”. Ese commit existe porque algo no funcionaba y el gate no lo ha dejado pasar. Y los gates se quedan en el repo: el próximo cambio pasa por el mismo examen. Ese es todo el sentido de ejecutar un agente dentro de un gate en vez de fiarte de su propio visto bueno, que es la comparación que desarrollo en <a href="/es/compare/paelladoc-vs-codex/">PaellaDoc vs Codex</a>.</p>
<h2 id="en-justicia">En justicia</h2>
<p>Contra la Codex app no tengo nada. La velocidad es real, el gusto visual también, y el salto del intento 1 al intento 2 demuestra que escucha lo que le pides: verificó, esquivó un puerto ocupado, arregló un bug que encontró. Con alguien delante iterando, saldría.</p>
<p>Y el experimento es el que es: una app, dos prompts, un intento cada uno, el mismo sábado. Lo que he medido es la distancia entre “me lo ha comprobado” y un sistema donde comprobar no es opcional ni caduca.</p>
<p>Esa distancia es la que toda app hecha con vibe coding tiene que cruzar para ser algo que puedas operar: el puente <a href="/es/blog/vibe-coding-a-produccion/">de vibe coding a producción</a>. Es también justo <a href="/es/blog/que-es-vibe-coding/">dónde el vibe coding deja de funcionar</a>, que nunca es en la demo, sino al día siguiente.</p>
<h2 id="compruébalo">Compruébalo</h2>
<p>Los tres repos, publicados tal cual han salido, con el código sin tocar (el único añadido posterior es el README de cada uno):</p>
<ul>
<li><strong><a href="https://github.com/jlcases/gestor-familiar-codex">gestor-familiar-codex</a></strong> — arranca backend y frontend y haz un clic. El que sea.</li>
<li><strong><a href="https://github.com/jlcases/gestor-familiar-codex-verificado">gestor-familiar-codex-verificado</a></strong> — ábrela cualquier día que no sea el 11 de julio de 2026. Mira el saludo, mira la tira semanal, añade un gasto y consulta con qué fecha se ha guardado.</li>
<li><strong><a href="https://github.com/jlcases/gestor-familiar-paelladoc">gestor-familiar-paelladoc</a></strong> — dentro van los 59 tests de backend, los 59 casos e2e, los 218 commits y la evidencia por criterio.</li>
</ul>
<p>Si no lo has visto funcionar, no está hecho. Y haberlo visto funcionar ayer no cuenta.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="puede-codex-construir-una-app-real-en-diez-minutos">¿Puede Codex construir una app real en diez minutos?</h3>
<p>Puede construir algo que lo parece. En este experimento la Codex app entregó una portada más bonita que la de PaellaDoc, y luego murió al primer clic: cuatro de cinco secciones y todos los formularios de alta crashearon con un error de Svelte, mientras su único chequeo, <code>svelte-check</code>, pasaba con cero errores. Puedes tener el build en verde y una app que nadie ha visto arrancar. La demo gana en diez minutos; el software que funciona es otra pregunta.</p>
<h3 id="por-qué-las-apps-hechas-con-vibe-coding-se-rompen-al-día-siguiente">¿Por qué las apps hechas con vibe coding se rompen al día siguiente?</h3>
<p>Porque un build rápido escribe a fuego el momento en que se hizo. El segundo intento de Codex verificó el mismo sábado que se generó, así que compró «funciona hoy» en sentido literal: la fecha «11 de julio» y el saludo «Buenos días» estaban clavados en la plantilla, el formulario de gasto mandaba una fecha fija y cada gasto posterior quedaba contabilizado el 11 de julio, y el panel de hoy filtraba por una cadena de fecha literal y quedaba vacío desde el día 12. Los fallos nunca salen en la demo, solo al día siguiente.</p>
<h3 id="basta-con-pedirle-a-la-ia-que-lo-verifique-todo-antes-de-entregar">¿Basta con pedirle a la IA que lo verifique todo antes de entregar?</h3>
<p>No. Al pedírselo, la Codex app verificó, y ayudó: los clics funcionaban, los formularios validaban, trajo algún test en verde. Pero fue una pasada manual el día de la generación que se le pasaron dos widgets contradiciéndose en la misma pantalla, y no dejó ni un script para repetirla. Una verificación que depende de que el usuario sepa pedirla, y de que una pasada de quince minutos vea todo lo que puede fallar mañana, no es verificación.</p>
<h3 id="por-qué-el-build-de-paelladoc-usa-tantos-más-tokens">¿Por qué el build de PaellaDoc usa tantos más tokens?</h3>
<p>Porque los tokens se van al loop, no al código. De 582 millones de tokens, escribir código costó 2,39 millones; el resto fue ejecutar la app, mirarla y repetir, 541 veces, dejando 59 casos e2e, 218 commits, y una captura más un JSON de evidencia por criterio de aceptación. Ese es el coste de ejecutar un agente dentro de un gate que recomprueba cada cambio en vez de fiarse de su propio visto bueno de una sola vez. Los gates se quedan en el repo, así que el próximo cambio pasa por el mismo examen.</p>]]></content>
    <summary type="html"><![CDATA[Le he pedido el mismo gestor familiar a la Codex app de escritorio dos veces, la segunda pidiéndole que lo comprobara todo antes de entregar, y a PaellaDoc una. El primer intento muere al primer clic. El segundo sobrevive a los clics pero está congelado en el día que se generó. Solo el de PaellaDoc funciona mañana. Los tres repos son públicos.]]></summary>
    <author>
      <name>@jlcases</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="codex"/><category term="ai-coding"/><category term="vibe-coding"/><category term="execution-gate"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/codex-tomorrow-test-cover.png" />
  </entry>

  <entry>
    <title type="html">Grafo de conocimiento de producto: lee la forma de tu producto, no la lista de features del repo</title>
    <link href="https://paelladoc.com/es/blog/grafo-de-conocimiento-de-producto/" rel="alternate" type="text/html" title="Grafo de conocimiento de producto: lee la forma de tu producto, no la lista de features del repo"/>
    <published>2026-06-20T00:00:00+02:00</published>
    <updated>2026-06-20T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/grafo-de-conocimiento-de-producto/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/grafo-de-conocimiento-de-producto/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿Qué es un grafo de conocimiento de producto?", "acceptedAnswer": {"@type": "Answer", "text": "Una representación del producto que has construido como sistema: zonas, relaciones, provenance, distancia al core y validación, no solo una lista de features ni una jerarquía PRD-a-criterios-de-aceptación. Su valor es la topología, la forma de lo que existe."}},
    {"@type": "Question", "name": "¿Qué te dice la topología de un grafo de conocimiento de producto?", "acceptedAnswer": {"@type": "Answer", "text": "El centro real del producto construido, las periferias caras, las capacidades puente entre zonas, qué es infraestructura y qué es valor de usuario, dónde se concentra el esfuerzo, y dónde hay mucha construcción con poca validación. No puede probar que los usuarios amen una feature, que una zona genere revenue, ni que el mercado lo quiera."}},
    {"@type": "Question", "name": "¿Es Brújula mejor que Claude Code?", "acceptedAnswer": {"@type": "Answer", "text": "No leyendo código. Claude Code es excelente para diagnóstico ad hoc del repo. Brújula es para la continuidad: un mapa de producto persistente con provenance, topología y deuda de validación, para que las preguntas de producto no empiecen desde cero cada vez. La mejor combinación usa Brújula para el mapa y Claude Code para auditorías concretas."}},
    {"@type": "Question", "name": "¿Puede un grafo sacado por reverse intake probar la estrategia de producto o la demanda de mercado?", "acceptedAnswer": {"@type": "Answer", "text": "No. Un grafo leído desde el producto construido muestra lo que el producto sugiere, no la intención original del equipo, ni la validación de usuarios, ni la demanda de mercado. Tiene que marcar qué está construido, qué está inferido y qué está realmente probado, y mantenerlos separados."}}
  ]
}
</script>
<p>Un repo puede parecer un roadmap si lo resumes mal. <a href="/es/blog/grafo-de-conocimiento-del-codigo/">Apunta un agente listo a un codebase</a>, pregúntale “qué hace este producto”, y te devuelve una lista de features limpia y segura. Parece progreso. Rara vez te dice si algo de eso debería seguir ahí.</p>
<p>Claude Code es excelente leyendo un repo. Encuentra subsistemas, traza eventos y rutas, detecta gaps de instrumentación y responde con criterio. Para diagnóstico puntual, tíralo de ahí. Este no es un artículo sobre Claude Code siendo flojo.</p>
<p>Es sobre otra más difícil. Olvídate de qué hay en el repo. ¿Qué forma tiene el producto que has construido? Esa pregunta necesita algo que Claude Code tira entre chats: <a href="/es/blog/memoria-de-producto/">una memoria del producto como sistema</a>.</p>
<p>Esa memoria es <strong>Brújula</strong>, la nueva vista de razonamiento de producto dentro de PaellaDoc. <a href="/es/blog/de-repo-a-artefactos/">Lee tu repo y tus artefactos en un grafo</a>, lo mantiene en tu máquina, y habla de producto, no de código. Todo lo de abajo es lo que eso te da.</p>
<h2 id="qué-es-un-grafo-de-conocimiento-de-producto">¿Qué es un grafo de conocimiento de producto?</h2>
<p>Un grafo de conocimiento de producto es el producto que has construido visto como sistema, no como lista. Lleva las zonas y cómo se conectan, de dónde ha salido cada pieza, a qué distancia está del core, y si algo lo ha probado de verdad. La versión obvia, un árbol limpio de PRD a épica a story a criterio, ayuda. No es ahí donde está el valor.</p>
<p>El valor es leer la forma. ¿Dónde está el centro real de lo construido, y qué queda lejos y cuesta caro de mantener? Hay zonas que son puentes entre dos mundos, otras son fontanería, otras son apuestas de growth que nadie ha probado. El grafo te enseña cuál es cuál.</p>
<p>Eso es topología, y convierte un producto en un mapa desde el que decidir. Una lista de features te dice qué existe. La forma te dice dónde mirar primero.</p>
<h2 id="qué-te-dice-la-forma-de-un-producto-y-qué-no">¿Qué te dice la forma de un producto, y qué no?</h2>
<p>Una lectura topológica de un grafo de producto puede inferir:</p>
<ul>
<li>el centro real del producto construido</li>
<li>las periferias caras</li>
<li>las capacidades puente que conectan zonas</li>
<li>las áreas duplicadas o fragmentadas</li>
<li>la línea entre infraestructura y valor de usuario</li>
<li>dónde se concentra el esfuerzo</li>
<li>la distancia entre una zona y el core</li>
<li>la deuda de validación: muy construido, poco probado</li>
<li>las preguntas que deberían desbloquear una decisión</li>
</ul>
<p>No puede inferir, solo por la forma:</p>
<ul>
<li>si los usuarios aman una feature</li>
<li>si una zona genera revenue</li>
<li>si una apuesta ha sido buena o mala</li>
<li>si el roadmap original tenía razón</li>
<li>si una zona lejana debe eliminarse</li>
</ul>
<p>La forma no decide por ti. Te dice dónde decidir primero. Ese hueco, entre señalar y decidir, es la línea que Brújula tiene que mantener consigo misma.</p>
<h2 id="qué-forma-tiene-la-topología-de-producto-en-la-práctica">¿Qué forma tiene la topología de producto en la práctica?</h2>
<p>Coge una app de aprendizaje de idiomas, de las que cualquiera se imagina. Lee su grafo como un mapa y la forma aparece rápido:</p>
<ul>
<li><strong>Core:</strong> el motor de aprendizaje. Lecciones, repetición espaciada, progreso, niveles, repaso.</li>
<li><strong>Infraestructura portante:</strong> el pipeline de contenido, el audio, el job diario, el login.</li>
<li><strong>Puentes:</strong> el onboarding hacia la primera lección, el loop de racha que tira de la gente de vuelta, un modo práctica que reutiliza el motor de lecciones.</li>
<li><strong>Periferia cara:</strong> ligas, leaderboards, clubes, un feed social, eventos de temporada, el backoffice competitivo de todo eso.</li>
<li><strong>Apuesta especulativa:</strong> una API pública y una plataforma para escuelas y equipos.</li>
<li><strong>El riesgo central:</strong> se ha construido una máquina competitiva grande encima de un motor de aprendizaje, sin prueba de que convierta en aprendices que de verdad sigan progresando.</li>
</ul>
<p>Ahora la pregunta de producto no es “¿son buenas o malas las ligas?”. Es más afilada:</p>
<blockquote>
<p>¿Las ligas son un canal de adquisición que produce aprendices retenidos y que progresan, o un segundo producto que se come el foco del primero?</p>
</blockquote>
<p>Eso no lo contestas desde una lista de features. Empiezas a contestarlo desde la forma, más la única medición que falta y a la que la forma te apunta.</p>
<h2 id="brújula-o-claude-code-para-decidir-producto">¿Brújula o Claude Code para decidir producto?</h2>
<p>Usa Claude Code para diagnosticar el repo y Brújula para leer el producto. Esto no es una competición de quién es más listo en una pregunta. Son dos trabajos distintos.</p>

































<table><thead><tr><th>Claude Code, directo</th><th>Brújula</th></tr></thead><tbody><tr><td>diagnóstico de repo rápido y afilado</td><td>convierte el repo en mapa de producto</td></tr><tr><td>encuentra evidencia concreta: servicios, eventos, rutas, commits</td><td>encuentra forma: core, periferia, puentes, densidad</td></tr><tr><td>gaps operativos muy accionables</td><td>separa infraestructura de valor de usuario de apuestas de growth</td></tr><tr><td>más barato y directo</td><td>preguntas de producto repetibles sin empezar de cero</td></tr><tr><td>reanaliza desde cero en cada pregunta</td><td>conserva memoria estructural entre preguntas</td></tr><tr><td>lee el repo</td><td>lee el producto como sistema, con provenance</td></tr></tbody></table>
<p>Los he corrido a los dos contra el mismo producto. En “qué está muy construido pero poco validado”, Claude Code ha sido fuerte encontrando gaps de instrumentación concretos. Brújula ha sido mejor estructurando la deuda: cuánto del grafo está inferido frente a respaldado por una fuente independiente, qué zonas están sobreconstruidas respecto a su distancia del core, dónde la construcción ha adelantado a la prueba.</p>
<p>En “mapea la topología: centro real, periferias caras, puentes, infraestructura frente a valor, sobreinversión sin outcome, preguntas urgentes de validación”, los dos leen distinto. Claude Code ha escrito como un auditor técnico: broker links, eventos, servicios, idiomas. Brújula ha escrito como un memo de producto: core, periferia, puentes, el supuesto arriesgado, la decisión.</p>
<p>Puntuado como lo puntuaría un CPO, ha ganado el memo de producto, pero no por paliza. Y esta es la parte que toca decir en claro: para llegar a un memo de CPO top, el mapa no basta. Necesita negocio real: revenue, CAC, LTV, cohortes, compromisos comerciales, estrategia de compañía. Brújula mapea el producto construido. No se inventa los números que no puede ver.</p>
<h2 id="cómo-debería-explicarse-un-grafo-de-conocimiento-de-producto">¿Cómo debería explicarse un grafo de conocimiento de producto?</h2>
<p>Un grafo no es una herramienta. Un grafo traducido a una decisión, sí. La diferencia está en el lenguaje.</p>
<p>Esto no:</p>
<blockquote>
<p>EPIC-09.1 tiene 45 artefactos reverse-intake, distance score 15, validation gap 100.</p>
</blockquote>
<p>Esto:</p>
<blockquote>
<p>Has construido una máquina competitiva grande encima de un motor de lecciones. Puede ser un canal de adquisición, pero todavía no hay prueba de que convierta en aprendices que sigan volviendo.</p>
</blockquote>
<p>Esto no:</p>
<blockquote>
<p>El grafo muestra puentes semánticos entre zonas.</p>
</blockquote>
<p>Esto:</p>
<blockquote>
<p>El onboarding y la racha son los puentes entre captar gente y uso real. Si esos puentes no miden progreso activo, no puedes saber si la periferia funciona.</p>
</blockquote>
<p>Nada de esto va de una respuesta más bonita. Va de convertir la estructura del producto en una frase sobre la que un product owner pueda actuar.</p>
<h2 id="te-puedes-fiar-de-un-grafo-de-producto-sacado-por-reverse-intake">¿Te puedes fiar de un grafo de producto sacado por reverse intake?</h2>
<p>Si el grafo viene de reverse intake, Brújula tiene que decirlo, en claro, cada vez. Un grafo leído desde el producto construido puede decir “esto es lo que sugiere el producto que has shipeado”. No puede decir que esta era la estrategia del equipo, que lo han validado usuarios, ni que el mercado lo quiere.</p>
<p>Reconocer ese límite no es una debilidad. Es buena parte de lo que separa un mapa de producto de una alucinación con seguridad. Un grafo que pinta una historia limpia sobre código desordenado es peor que ningún grafo, porque se lee como verdad. Así que marcas qué está construido, qué está supuesto y qué está probado de verdad, y mantienes los tres aparte.</p>
<h2 id="por-qué-importa-más-la-topología-de-producto-en-la-era-ia">¿Por qué importa más la topología de producto en la era IA?</h2>
<p>Antes, un product manager podía tapar la falta de memoria de producto con reuniones, docs, un roadmap y criterio personal. Funcionaba porque construir era lo bastante lento como para pensar entre releases.</p>
<p>Con agentes, el coste de construir baja tanto que el riesgo cambia. La pregunta deja de ser “¿podemos construirlo?”. Pasa a ser:</p>
<ul>
<li>¿por qué seguimos construyendo esto?</li>
<li>¿qué parte del producto está creciendo sin evidencia detrás?</li>
<li>¿qué apuesta se ha convertido en inercia sin que nadie lo dijera?</li>
<li>¿qué hemos confundido con progreso porque hay mucho código?</li>
</ul>
<p>El build trap siempre ha sido real. Los agentes lo aceleran, porque llega más código más rápido y parece impulso. Un mapa de producto hecho de zonas, provenance, distancia y deuda de validación es como le pones el freno: no construyendo menos por construir menos, sino decidiendo con la forma delante.</p>
<h2 id="entonces">Entonces</h2>
<p>Claude Code te dice qué hay en el repo. Brújula te dice qué forma tiene el producto que has construido. Y esa forma es lo que te deja decidir qué proteger, qué congelar, qué validar esta semana, y qué no construir todavía.</p>
<p>La ventaja nunca ha sido responder más bonito que un agente leyendo código. Es que el producto construido se vuelve <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">una memoria por la que puedes caminar</a>: cada zona lleva de dónde ha salido, a qué distancia está del core, y si algo ha probado que funciona. Esa es la capa donde las decisiones de producto dejan de empezar desde cero.</p>
<p>Esta es la mitad de arriba de <a href="/es/blog/eres-el-runtime/">mantener vivo el contrato de producto</a>, y la misma apuesta que <a href="/es/blog/product-management-era-ia/">el product management en la era de la IA</a>: cuando construir es barato, la ventaja es decidir con memoria, no con intuición.</p>
<p>Brújula viene dentro de PaellaDoc, local-first y gratis. Construye este grafo desde tu propio repo, sin nube y sin cuenta, y lo convierte en decisiones de producto sobre las que puedes actuar.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Qué parte de tu producto está creciendo con más código y menos prueba? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-un-grafo-de-conocimiento-de-producto-1">¿Qué es un grafo de conocimiento de producto?</h3>
<p>Una representación del producto que has construido como sistema: zonas, relaciones, provenance, distancia al core y validación, no solo una lista de features ni una jerarquía PRD-a-criterios-de-aceptación. Su valor es la topología, la forma de lo que existe.</p>
<h3 id="qué-te-dice-la-topología-de-un-grafo-de-conocimiento-de-producto">¿Qué te dice la topología de un grafo de conocimiento de producto?</h3>
<p>El centro real del producto construido, las periferias caras, las capacidades puente entre zonas, qué es infraestructura y qué es valor de usuario, dónde se concentra el esfuerzo, y dónde hay mucha construcción con poca validación. No puede probar que los usuarios amen una feature, que una zona genere revenue, ni que el mercado lo quiera.</p>
<h3 id="es-brújula-mejor-que-claude-code">¿Es Brújula mejor que Claude Code?</h3>
<p>No leyendo código. Claude Code es excelente para diagnóstico ad hoc del repo. Brújula es para la continuidad: un mapa de producto persistente con provenance, topología y deuda de validación, para que las preguntas de producto no empiecen desde cero cada vez. La mejor combinación usa Brújula para el mapa y Claude Code para auditorías concretas.</p>
<h3 id="puede-un-grafo-sacado-por-reverse-intake-probar-la-estrategia-de-producto-o-la-demanda-de-mercado">¿Puede un grafo sacado por reverse intake probar la estrategia de producto o la demanda de mercado?</h3>
<p>No. Un grafo leído desde el producto construido muestra lo que el producto sugiere, no la intención original del equipo, ni la validación de usuarios, ni la demanda de mercado. Tiene que marcar qué está construido, qué está inferido y qué está realmente probado, y mantenerlos separados.</p>]]></content>
    <summary type="html"><![CDATA[Un repo puede parecer un roadmap si lo resumes mal. Un grafo de conocimiento de producto bien usado no debería embellecer el código. Debería mostrarte dónde el producto está sobreconstruido, desconectado o sin validar. Claude Code es excelente leyendo un repo y encontrando gaps concretos. Brújula es para otra pregunta: ¿qué forma tiene el producto que has construido, y dónde deberías decidir primero?]]></summary>
    <author>
      <name>@jlcases</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="product-management"/><category term="knowledge-graph"/><category term="compass"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/product-knowledge-graph-topology-hero-es.png" />
  </entry>

  <entry>
    <title type="html">Product management en la era de la IA: construir es barato, decidir es caro</title>
    <link href="https://paelladoc.com/es/blog/product-management-era-ia/" rel="alternate" type="text/html" title="Product management en la era de la IA: construir es barato, decidir es caro"/>
    <published>2026-06-19T00:00:00+02:00</published>
    <updated>2026-06-19T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/product-management-era-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/product-management-era-ia/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿La IA ha dejado obsoletos a los product managers?", "acceptedAnswer": {"@type": "Answer", "text": "No. La IA ha abaratado construir, lo que ha movido el cuello de botella de construir a decidir qué construir, con qué evidencia. El juicio del PM importa más, no menos: pasa de escribir requisitos a diseñar el bucle de decisión."}},
    {"@type": "Question", "name": "¿Cuál es el nuevo cuello de botella del product management?", "acceptedAnswer": {"@type": "Answer", "text": "Decidir y aprender. Cuando los agentes construyen en horas, la ventaja ya no es producir features más rápido, es decidir mejor qué construir y validar antes de acumular deuda de producto."}},
    {"@type": "Question", "name": "¿Qué son los evals de producto?", "acceptedAnswer": {"@type": "Answer", "text": "Los evals definen qué es un buen comportamiento de producto, qué fallos son inaceptables y qué evidencia sostiene una recomendación. Funcionan como PRDs vivos: en vez de describir una feature una vez, comprueban continuamente si el producto se comporta como prometió."}},
    {"@type": "Question", "name": "¿Brújula sustituye a Claude Code?", "acceptedAnswer": {"@type": "Answer", "text": "No. Claude Code es excelente para diagnóstico ad hoc del repo. Brújula es la capa de continuidad: provenance, historial, un grafo de producto persistente y evals de producto, para que el equipo no reanalice su producto desde cero cada vez."}}
  ]
}
</script>
<p>Un equipo le pregunta a Claude Code si su repo cubre de verdad un dolor real del usuario. La respuesta llega rápida, afilada y justa. Luego le preguntan lo mismo a Brújula y obtienen otra lectura, conectada al mapa de lo que el producto ya es. Las dos tienen razón en parte.</p>
<p>La pregunta interesante no es cuál IA “gana” ese intercambio. Es qué tipo de sistema necesita un equipo para seguir decidiendo bien, durante meses, no en un único chat.</p>
<h2 id="por-qué-decidir-es-ahora-más-difícil-que-construir">¿Por qué decidir es ahora más difícil que construir?</h2>
<p>Durante años, una parte grande del coste estaba en convertir una idea en código. Con agentes como Claude Code, Codex, Cursor o Kimi, construir es mucho más barato y rápido. Eso no hace menos importante el trabajo de producto. Lo hace más exigente.</p>
<p>Si cualquiera puede construir más rápido, la ventaja ya no está en producir features. Está en decidir mejor qué construir, <a href="/es/blog/decisiones-con-evidencia/">con qué evidencia, bajo qué supuestos</a>, y cómo aprender antes de acumular deuda de producto.</p>
<p>Construir barato trae una trampa dentro. Ahora puedes generar más pantallas, más épicas, más experimentos, más código. Y más deuda de producto. Si el equipo no mejora su sistema de decisión al mismo ritmo, toda esa velocidad solo acelera la dispersión.</p>
<p>Ese es el nuevo cuello de botella. No teclear. Decidir, y aprender.</p>
<h2 id="el-product-management-clásico-está-obsoleto-con-la-ia">¿El product management clásico está obsoleto con la IA?</h2>
<p>Esta no es la parte donde alguien anuncia que los clásicos están obsoletos. No lo están.</p>
<p>Valor, viabilidad, usabilidad y factibilidad siguen siendo el trabajo. El <a href="/es/blog/discovery-con-ia/">descubrimiento continuo</a> sigue ganándole a discutir una única solución que parece inevitable. Una métrica compartida que capture el valor real al usuario sigue evitando que el equipo hable cuatro idiomas distintos. El linaje de Cagan, Teresa Torres y la gente de la North Star no lo ha sustituido la IA. La era IA sube el listón sobre todo ello, porque acelerar el código y el diseño <a href="https://dora.dev/research/">no garantiza mejores outcomes</a>. El trabajo difícil, encontrar soluciones valiosas y viables, necesita más juicio, no menos.</p>
<p>Lo nuevo es dónde tiene que vivir ese juicio. No en un <a href="/es/blog/prds-que-nadie-lee/">documento estático que envejece al día siguiente de escribirse</a>.</p>
<blockquote>
<p>En la era de la IA, el PRD deja de ser el documento que precede al producto. Pasa a ser un sistema vivo que evalúa, recuerda y corrige las decisiones del producto.</p>
</blockquote>
<h2 id="qué-cambia-en-el-product-management-con-la-ia">¿Qué cambia en el product management con la IA?</h2>
<p>La forma del trabajo se mueve en seis frentes:</p>
<ul>
<li>de explorar una solución a explorar muchas rutas</li>
<li>de un PRD a un prototipo evaluable</li>
<li>de la opinión a los evals</li>
<li>de la búsqueda documental a un grafo de relaciones</li>
<li>de un roadmap estático a un <a href="/es/blog/registro-de-decisiones/">decision ledger</a></li>
<li>de “el PM escribe requisitos” a “el PM diseña el sistema que aprende”</li>
</ul>
<p>Ninguno de estos quita al humano. Cambian de qué es responsable el humano. En un mundo de agentes, la persona de producto deja de ser quien escribe la spec y pasa a ser quien <a href="/es/blog/modelo-operativo-de-producto/">diseña el bucle de decisión</a>.</p>
<h2 id="qué-hace-brújula-por-el-product-management">¿Qué hace Brújula por el product management?</h2>
<p>Brújula es la capa de razonamiento de producto dentro de PaellaDoc. Lee tu repo, tus artefactos, tus decisiones y tus conversaciones, y conecta cinco cosas:</p>
<ol>
<li><strong>Mapa as-built</strong>: qué existe de verdad en el repo.</li>
<li><strong>Provenance</strong>: de dónde viene cada artefacto.</li>
<li><strong>Grafo semántico</strong>: cómo se relacionan capacidades, riesgos, decisiones y evidencia.</li>
<li><strong>Apuestas futuras</strong>: las direcciones candidatas que se derivan de todo ello.</li>
<li><strong>Evals de producto</strong>: cómo sabes si una recomendación ha sido buena.</li>
</ol>
<p>Lo importante es lo que se niega a hacer. No te entrega una estrategia y la llama verdad.</p>
<blockquote>
<p>Brújula no dice “esta es la estrategia”. Dice: esto es lo que se puede inferir, esto es lo que no se sabe, estas son las apuestas candidatas, y esta es la validación mínima antes de construir más.</p>
</blockquote>
<h2 id="puede-el-reverse-intake-revelar-la-estrategia-de-producto">¿Puede el reverse intake revelar la estrategia de producto?</h2>
<p>Un reverse intake no es discovery. No habla con usuarios, no mide dolor y no reconstruye la intención original del equipo. Su valor es otro: muestra qué producto se ha construido de verdad. Ese mapa as-built, más provenance y relaciones, basta para detectar capacidades, huecos y deuda de decisión. A partir de ahí, el trabajo no es dictar una estrategia. Es formular apuestas candidatas y nombrar qué validar antes de construir más.</p>
<p>Lo que significa que no toda fuente permite el mismo tipo de afirmación. Esta es la parte que casi todos los grafos de producto hacen mal:</p>






























<table><thead><tr><th>Lo que quieres afirmar</th><th>Lo que necesita</th><th>Qué puede sostenerlo</th></tr></thead><tbody><tr><td>”El usuario siente este dolor”</td><td>usuarios reales, uso, validación</td><td>evidencia externa, validation runs</td></tr><tr><td>”Lo decidimos a propósito”</td><td>docs y decisiones de humanos</td><td>fuentes naturales, escritas por personas</td></tr><tr><td>”Esta capacidad existe”</td><td>el producto construido</td><td>reverse intake</td></tr><tr><td>”Así está implementado”</td><td>el código</td><td>código en crudo</td></tr></tbody></table>
<p>La regla que mantiene a Brújula recta consigo misma: un nodo de reverse intake puede sostener <em>esto existe</em>. No puede sostener <em>esto le importa al usuario</em>. Un grafo bonito de nodos no es evidencia. La apuesta ordenada, puntuada por la evidencia que de verdad la respalda, sí.</p>
<h2 id="claude-code-o-brújula-para-decidir-producto">¿Claude Code o Brújula para decidir producto?</h2>
<p>Esto no es una batalla de modelos, y Brújula no es “la más lista”. Claude Code directo es excelente en lo suyo: leer código en crudo con precisión, detectar dispersión y deuda, contestar una pregunta técnica o local afilada, sin capa intermedia. Para diagnóstico puntual, tíralo de ahí.</p>
<p>Su límite es la continuidad. El contexto se reconstruye en cada chat. No hay provenance estructurada, ni historial de decisiones reutilizable, ni grafo de artefactos persistente, ni comparación entre versiones, ni evals de producto repetibles. La respuesta es buena y luego se evapora.</p>
<p>Brújula es la infraestructura de la parte que tiene que persistir:</p>













<table><thead><tr><th>Claude Code directo</th><th>Brújula</th></tr></thead><tbody><tr><td><code>pregunta → escaneo del repo → buena respuesta → contexto perdido</code></td><td><code>pregunta → grafo + provenance + historial → respuesta → artefacto → eval → decision ledger → mejor respuesta siguiente</code></td></tr></tbody></table>
<p>La diferencia no es que Brújula piense mejor que Claude Code en una pregunta aislada. Es que Brújula convierte el razonamiento de producto en un sistema persistente, auditable y mejorable.</p>
<h2 id="qué-son-los-evals-de-producto-y-por-qué-sustituyen-al-prd-estático">¿Qué son los evals de producto y por qué sustituyen al PRD estático?</h2>
<p>En productos de IA, la calidad no se controla solo con tests deterministas. Hay que definir qué es una buena respuesta, qué fallos son inaceptables y qué evidencia puede sostener una recomendación. Por eso los evals empiezan a parecerse a PRDs vivos: no describen una feature una vez, evalúan continuamente si el producto se comporta como ha prometido.</p>
<p>Así que cada respuesta de Brújula que recomiende una dirección debería poder evaluarse a sí misma: si ha mantenido recta la provenance, si ha separado evidencia de hipótesis, si ha propuesto una validación siguiente concreta, si ha evitado certeza estratégica sin respaldo. Es la misma apuesta que el resto de lo que construyo, donde lo que hace fiable la salida es la spec, no la intuición del modelo. Lo he medido en <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">el benchmark de verificación</a>: en crudo, el modelo cuela errores; con el contrato escrito, no.</p>
<h2 id="cuál-es-la-ventaja-de-producto-en-la-era-ia">¿Cuál es la ventaja de producto en la era IA?</h2>
<p>La nueva ventaja de producto no es una IA que responde una vez. Es un sistema que recuerda, conecta, cuestiona y evalúa cada decisión de producto a lo largo del tiempo.</p>
<p>El futuro del product management no es humanos contra agentes. Es <a href="/es/blog/construir-software-con-agentes-de-ia/">diseñar un sistema donde los agentes construyen</a>, el grafo recuerda, los evals corrigen y las personas siguen siendo responsables del juicio. El PM no desaparece. Se convierte en el diseñador del bucle de decisión.</p>
<p>He escrito sobre mantener vivo el contrato de producto mientras los agentes hacen la escritura, en <a href="/es/blog/eres-el-runtime/">el runtime eres tú</a>. Esta es la otra mitad: generar el contrato correcto desde el principio, y ser claro sobre qué puedes y qué no puedes afirmar todavía. Brújula es esa capa para PaellaDoc. No una IA que pretende tener la verdad. Un sistema que te ayuda a encontrarla más rápido.</p>
<p>Brújula es la capa de razonamiento de producto dentro de PaellaDoc, local-first y gratis. Convierte tu repo, tus decisiones y tu evidencia en un mapa de producto que puedes interrogar.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>Si construir ya es barato, ¿cuál es la decisión más lenta y más cara que tu equipo sigue rehaciendo desde cero? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="la-ia-ha-dejado-obsoletos-a-los-product-managers">¿La IA ha dejado obsoletos a los product managers?</h3>
<p>No. La IA ha abaratado construir, lo que ha movido el cuello de botella de construir a decidir qué construir y con qué evidencia. El juicio del PM importa más, no menos. Pasa de escribir requisitos a diseñar el bucle de decisión: qué explorar, qué validar y qué evidencia tiene que respaldar una elección antes de que los agentes la conviertan en código publicado.</p>
<h3 id="cuál-es-el-nuevo-cuello-de-botella-del-product-management">¿Cuál es el nuevo cuello de botella del product management?</h3>
<p>Decidir y aprender. Cuando los agentes construyen en horas, la ventaja ya no es producir features más rápido, es decidir mejor qué construir y validarlo antes de acumular deuda de producto. Construir barato te deja generar más pantallas, más épicas, más experimentos, y más deuda. Si el sistema de decisión no mejora al mismo ritmo, esa velocidad solo acelera la dispersión.</p>
<h3 id="qué-son-los-evals-de-producto">¿Qué son los evals de producto?</h3>
<p>Los evals definen qué es un buen comportamiento de producto, qué fallos son inaceptables y qué evidencia sostiene una recomendación. Funcionan como PRDs vivos: en vez de describir una feature una vez, comprueban continuamente si el producto se comporta como prometió. Cada recomendación se vuelve evaluable, si mantuvo recta la provenance, separó evidencia de hipótesis y propuso una validación siguiente concreta.</p>
<h3 id="brújula-sustituye-a-claude-code">¿Brújula sustituye a Claude Code?</h3>
<p>No. Claude Code es excelente para diagnóstico ad hoc del repo: leer código en crudo con precisión, detectar dispersión y deuda, contestar una pregunta local afilada. Su límite es la continuidad, el contexto se reconstruye en cada chat. Brújula es la capa que persiste: provenance, historial, un grafo de producto y evals de producto, para que el equipo no reanalice su producto desde cero cada vez.</p>]]></content>
    <summary type="html"><![CDATA[La IA no ha eliminado el product management. Ha movido el cuello de botella. Cuando un agente convierte una idea en código en horas, la ventaja deja de ser escribir más rápido y pasa a ser decidir mejor: qué construir, con qué evidencia, bajo qué supuestos, y cómo aprender antes de acumular deuda de producto. Un agente de código es excelente para diagnóstico puntual. Brújula existe para la continuidad: provenance, historial, decisiones, relaciones, búsqueda semántica y evals de producto, para que el equipo no reanalice su propio producto desde cero cada vez.]]></summary>
    <author>
      <name>@jlcases</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="product-management"/><category term="ai-coding"/><category term="compass"/><category term="evals"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/deciding-gets-expensive-hero-es.png" />
  </entry>

  <entry>
    <title type="html">No tienes un problema con Claude Code. El runtime eres tú.</title>
    <link href="https://paelladoc.com/es/blog/eres-el-runtime/" rel="alternate" type="text/html" title="No tienes un problema con Claude Code. El runtime eres tú."/>
    <published>2026-06-16T00:00:00+02:00</published>
    <updated>2026-06-16T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/eres-el-runtime/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/eres-el-runtime/"><![CDATA[<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {"@type": "Question", "name": "¿Necesitas un runtime alrededor de Claude Code?", "acceptedAnswer": {"@type": "Answer", "text": "Un buen desarrollador puede correr Claude Code a mano, haciendo de scheduler, memoria, gate y bucle de recuperación. Un runtime de entrega se lleva esa orquestación fuera del desarrollador para que el trabajo abarque muchas tareas, repos y horas sin un humano sosteniéndolo todo en la cabeza."}},
    {"@type": "Question", "name": "¿Por qué un modelo más grande no arregla el trabajo largo con agentes?", "acceptedAnswer": {"@type": "Answer", "text": "En un benchmark de recuperación de cuatro episodios, Claude Code con prompt y con skill se quedó en el 66,67%, y los modelos más grandes en controles n=1 hicieron lo mismo. Un runtime de recuperación gobernado llegó al 100%. La brecha no era inteligencia bruta, era sostener el contrato y recuperar a través de episodios."}},
    {"@type": "Question", "name": "¿Cuándo está de verdad hecha una feature?", "acceptedAnswer": {"@type": "Answer", "text": "No cuando el agente lo dice, ni cuando el build está verde. Done es el comportamiento pasando los criterios de aceptación que existían antes de escribir una línea, con la evidencia pegada."}},
    {"@type": "Question", "name": "¿Y si Claude Code o Codex añaden su propio runtime?", "acceptedAnswer": {"@type": "Answer", "text": "Parte de la orquestación se absorberá. PaellaDoc no compite por ser el mejor executor; es la capa portable, local-first y multi-motor donde viven el contrato de producto, los gates, la evidencia y la memoria de cada run, por encima de cualquier agente o proveedor."}}
  ]
}
</script>
<p>“Claude Code me escribe el código de lujo. No necesito un runtime por encima.”</p>
<p>Si eres bueno, has pensado alguna versión de esto. Y tienes razón. Claude Code escribe código de sobra, y con el teclado delante no sientes que falte nada.</p>
<p>Esto es lo que no estás viendo: no sientes que necesites una capa por encima porque la capa eres tú.</p>
<p>Partes el producto en tareas. Abres los worktrees. Mantienes ocho sesiones vivas, recuerdas qué rama es segura, recuperas el run cuando se cae, integras los dos cambios que chocan, pillas el build que está verde pero mal por debajo, le devuelves el hilo al agente cuando se pierde. Claude Code escribe el código. Todo lo de alrededor lo corres tú, a mano, sin darte cuenta.</p>
<p>Eso no es que Claude Code se quede corto. Hace justo para lo que está hecho. La pregunta es quién corre el otro trabajo: el bucle de alrededor del código. Ahora mismo, eres tú.</p>
<p>Y esta es la única frase a la que se reduce ese bucle:</p>
<blockquote>
<p>Done no es que el agente lo diga. Un build verde tampoco es done. Done es el comportamiento pasando los criterios que existían antes de escribir una línea, con la evidencia pegada.</p>
</blockquote>
<p>Quédate con esa frase. Es el argumento entero. Todo lo de abajo va de quién mantiene viva esa promesa mientras muchos agentes escriben, fallan, recuperan e integran durante horas y días.</p>
<h2 id="qué-trabajo-te-deja-a-ti-un-agente-de-código">¿Qué trabajo te deja a ti un agente de código?</h2>
<p>La parte difícil de entregar con agentes nunca ha sido generar el código. Es el bucle de alrededor. Pártelo en el trabajo que de verdad está pasando, y dónde vive hoy:</p>








































<table><thead><tr><th>El trabajo invisible</th><th>Hoy corre en</th><th>Con PaellaDoc</th></tr></thead><tbody><tr><td>Dividir el trabajo en tareas</td><td>la cabeza del senior</td><td>artefactos versionados</td></tr><tr><td>Mantener los criterios de aceptación</td><td>un chat, o la memoria</td><td>un contrato que viaja con la tarea</td></tr><tr><td>Enrutar cada tarea a un motor</td><td>copia-pega entre pestañas</td><td>un router gobernado</td></tr><tr><td>Recuperar un run fallido</td><td>un humano que lo nota</td><td>retry gobernado</td></tr><tr><td>Decidir “done”</td><td>intuición y una revisión</td><td>un gate y evidencia</td></tr><tr><td>Mantener la historia entera</td><td>memoria humana</td><td>el rastro del run</td></tr></tbody></table>
<p>Un senior hace todo eso casi sin notarlo. Cuanto mejor eres, más fácil es no ver cuánto sigue corriendo en tu cabeza. Ocho paneles de tmux no quitan ese trabajo. Multiplican los sitios donde pasa.</p>
<p>Los agentes en paralelo te dan throughput. No te dan un sistema de entrega. Si cada sesión sigue necesitando a un humano que sostenga el contexto, ponga prioridad, recupere el fallo, valide la salida e integre el resultado, el humano es el scheduler, la memoria, el gate y el release manager, todo a la vez.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/you-are-the-runtime-carries-es_480.avif 480w, /assets/images/you-are-the-runtime-carries-es_768.avif 768w, /assets/images/you-are-the-runtime-carries-es_1024.avif 1024w, /assets/images/you-are-the-runtime-carries-es_1440.avif 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/you-are-the-runtime-carries-es_480.webp 480w, /assets/images/you-are-the-runtime-carries-es_768.webp 768w, /assets/images/you-are-the-runtime-carries-es_1024.webp 1024w, /assets/images/you-are-the-runtime-carries-es_1440.webp 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/you-are-the-runtime-carries-es_480.png" srcset="/assets/images/you-are-the-runtime-carries-es_480.png 480w, /assets/images/you-are-the-runtime-carries-es_768.png 768w, /assets/images/you-are-the-runtime-carries-es_1024.png 1024w, /assets/images/you-are-the-runtime-carries-es_1440.png 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="El mismo bucle de orquestación en dos sitios. A la izquierda, lo cargas tú: decidir qué construir, convertir intención de producto en tareas, conservar los criterios, enrutar cada tarea, abrir worktrees, vigilar sesiones, leer logs, recuperar fallos, mantener invariantes viejos, integrar ramas, decidir done. A la derecha, la misma lista cargada por PaellaDoc, con un rastro." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Para un experto vigilando cada panel, puede valer. No aguanta el contacto con muchas tareas, muchos repos, gente que no programa, o un plan que tiene que durar más que un chat.</p>
<h2 id="cuál-es-el-verdadero-cuello-de-botella-del-coding-con-agentes">¿Cuál es el verdadero cuello de botella del coding con agentes?</h2>
<p>Si Claude Code funciona no es lo interesante. Claro que funciona. La frontera ya está en otro sitio.</p>
<p>La frontera no es generar código. Es mantener vivo el contrato de producto mientras muchos agentes escriben, fallan, recuperan, integran y producen evidencia.</p>
<p>Ese es el hueco sobre el que construyo PaellaDoc. No un escritor de código mejor. PaellaDoc ejecuta Claude Code, Codex, Kimi y modelos locales, porque el executor nunca ha sido la frontera interesante. La frontera es todo lo que envuelve a la ejecución: el contrato de producto, los gates, la evidencia, la recuperación, el routing, la memoria de lo que ha pasado.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/fleet-running-real_480.avif 480w, /assets/images/fleet-running-real_768.avif 768w, /assets/images/fleet-running-real_1024.avif 1024w, /assets/images/fleet-running-real_1440.avif 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/fleet-running-real_480.webp 480w, /assets/images/fleet-running-real_768.webp 768w, /assets/images/fleet-running-real_1024.webp 1024w, /assets/images/fleet-running-real_1440.webp 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/fleet-running-real_480.png" srcset="/assets/images/fleet-running-real_480.png 480w, /assets/images/fleet-running-real_768.png 768w, /assets/images/fleet-running-real_1024.png 1024w, /assets/images/fleet-running-real_1440.png 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="La vista de flota real de PaellaDoc: tres agentes corriendo en paralelo, cada uno un worktree de Claude Code (w-7af3, w-21bd). Cada fila muestra el modelo (claude-opus-4-8), el esfuerzo (high, max) y el origen del run (Router, Retry), todo elegido por la capa y no por el desarrollador." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Esa es la flota real, no un mockup. Tres agentes a la vez, cada uno en su worktree, cada uno saliendo de una user story. El modelo, el esfuerzo y el origen del run (uno enrutado, otro recuperado) son decisiones que ha tomado la capa, no tú. Ese es el trabajo que si no estarías haciendo en tu cabeza.</p>
<h2 id="por-qué-un-prompt-no-basta-para-entregar-producto">¿Por qué un prompt no basta para entregar producto?</h2>
<p>Casi toda sesión con agente empieza con un prompt. Útil, pero pobre. Un prompt dice qué quieres. Rara vez carga el sistema de producto que hay debajo: la spec, los criterios, los caminos no felices, los invariantes del repo, los gates, la evidencia que necesita un cambio antes de contar, las razones por las que las decisiones viejas se han tomado así.</p>
<p>Cuando eso vive solo en un chat, se pudre. Solo en tu cabeza, no lo puedes delegar. Solo en una terminal, muere con el transcript.</p>
<p>Por eso PaellaDoc hace del contrato de producto una entrada de primera clase. Cuando el trabajo de producto son artefactos de verdad y no intuiciones, el bucle de código se gobierna contra ellos. Al agente no se le dice “construye la cosa”. Se le da una tarea, un contrato, un gate, y qué cuenta como evidencia. El agente escribe el código. El contrato decide si cuenta. La versión larga la he escrito en <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build verde no es una feature correcta</a>.</p>
<h2 id="un-modelo-más-grande-arregla-los-fallos-en-trabajo-largo">¿Un modelo más grande arregla los fallos en trabajo largo?</h2>
<p>El trabajo largo se rompe en otro sitio que las demos. Un cambio real pasa por episodios: añade el primer comportamiento, mantenlo vivo mientras añades el siguiente, sobrevive a un checkpoint y resume, gestiona el evento que llega tarde, cubre el camino negativo, mantén privacidad y portabilidad, integra al final sin romper en silencio lo que ha dejado el episodio uno.</p>
<p>Aquí “el modelo es listo” deja de pagar la cuenta. Así que lo he corrido.</p>
<ul>
<li><strong>4 episodios acumulativos</strong>, cada uno capaz de romper un gate que ha arreglado el anterior.</li>
<li><strong>6 gates ocultos</strong> que tienen que seguir verdes todo el camino: idempotencia, privacidad, replay determinista, checkpoint y resume, eventos tardíos, caminos negativos.</li>
<li>Claude Code con un <strong>prompt fuerte</strong>: 0 de 4 episodios limpios, clavado en <strong>66,67%</strong>.</li>
<li>Claude Code con una <strong>skill de recuperación hecha a mano</strong>: igual, <strong>66,67%</strong>.</li>
<li>Un <strong>modelo más grande</strong> (Sonnet, Opus, n=1 cada uno): mejor primer diff, sigue en <strong>66,67%</strong>.</li>
<li>El mismo executor bajo el <strong>retry gobernado de PaellaDoc</strong>: <strong>4 de 4, 100%</strong>, recuperado solo, sin humano en el bucle.</li>
</ul>
<p>Los dos brazos de Claude Code se han quedado clavados en dos tercios exactos por la misma razón: arreglaban el requisito nuevo y rompían un invariante viejo, y nada les decía que habían regresado.</p>
<p>El matiz, por delante: un <a href="https://www.anthropic.com/engineering/building-effective-agents">harness de feedback-retry</a> casero también ha llegado al 100%, en tres intentos, y no ha gastado menos tokens. Así que esto no es “el modelo se ha vuelto más listo”. Es que algo fuera del agente ha sostenido el contrato, ha re-puntuado el trabajo y ha decidido si un invariante viejo acababa de romperse. Ese algo es el producto. Datos, harness y la lista entera de matices están en <a href="/es/research/agentes-necesitan-un-runtime-no-un-modelo-mas-grande/">el experimento de recuperación</a>: exploratorio, Haiku/low, controles a n=1. El primer tramo de un benchmark más largo, en abierto, y no contra un prompt tonto. Contra un senior usando Claude Code a tope.</p>
<h2 id="y-si-claude-code-añade-un-runtime">¿Y si Claude Code añade un runtime?</h2>
<p>Puede. Claude Code ya trae hooks, skills, subagentes, sesiones en paralelo y revisión. Codex corre tareas en background en su propia nube. Parte de esta orquestación se va a absorber, y está bien.</p>
<p>PaellaDoc no compite por ser el mejor executor. Compite por ser la capa donde vive el contrato: portable, local-first, multi-motor. El sitio donde el contrato de producto, los gates, la evidencia y la memoria de cada run sobreviven, da igual qué agente ha escrito el código o en qué proveedor estás este trimestre.</p>
<p>Un executor que además orquesta sigue siendo el executor de un proveedor. El contrato tiene que estar por encima de cualquier agente, o no es un contrato. Es una feature que alquilas, en la nube de otro, hasta que cambian los términos.</p>
<h2 id="cómo-se-mide-de-forma-justa-un-runtime-de-agentes">¿Cómo se mide de forma justa un runtime de agentes?</h2>
<p>El test justo no es PaellaDoc contra un prompt flojo. Eso es fácil e inútil. Es un human-scheduler benchmark. Brazo A: un senior, Claude Code, worktrees, sesiones en background, instrucciones fuertes del repo, orquestación manual permitida. Brazo B: PaellaDoc, el mismo executor, mismo modelo, mismo repo, mismo plan, mismos gates, sin trampa en la tarea.</p>
<p>Y cuentas: minutos humanos dirigiendo, intervenciones, gates recuperados, regresiones ocultas, tasa de aprobado final, completitud de la evidencia, tokens, tiempo hasta un resultado validado.</p>
<p>Si gana el senior, me dice dónde la capa aún es más débil que un buen operador, y voy y lo arreglo. Si gana PaellaDoc, el punto no es que Claude Code fuera malo. Es que la capa del contrato era lo que importaba. Si empatan en corrección pero PaellaDoc necesita menos dirección, ese puede ser el resultado más útil de los tres.</p>
<h2 id="entonces">Entonces</h2>
<p>Claude Code escribe el código. Codex ejecuta las tareas. PaellaDoc mantiene vivo el contrato de producto hasta que la cosa está validada, con evidencia.</p>
<p>Esa es la categoría. No un executor más rápido. Un sitio donde “done” sigue significando algo después de que el agente se haya ido.</p>
<p>Deja que el agente escriba el código. Quédate la intención de producto y las decisiones que importan. Deja que la capa del contrato cargue con el resto.</p>
<p>Es el mismo argumento que el resto de lo que construyo: <a href="/es/blog/routing-de-modelos-sin-vendor-lock-in/">enruta cada tarea al motor correcto</a>, y <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">el cerebro de producto que se mantiene solo</a>.</p>
<h2 id="para-profundizar">Para profundizar</h2>
<p>Cada pieza de ese bucle es su propia disciplina, y las que más tiempo cuestan las he sacado a piezas aparte: llevar <a href="/es/blog/sesiones-paralelas-agentes/">varias sesiones a la vez</a> y pagar el coste de ser el scheduler, tratar <a href="/es/blog/recuperar-ejecuciones-fallidas/">la recuperación como un flujo de primera</a> en vez de una sorpresa a las 2 de la mañana, y darle a los agentes <a href="/es/blog/memoria-agentes-de-codigo/">memoria que sobreviva fuera del chat</a> para que una sesión fría no sea un arranque en frío. Todas son capítulos de la misma guía operativa para <a href="/es/blog/construir-software-con-agentes-de-ia/">construir software con agentes de IA</a>.</p>
<p>PaellaDoc es ese runtime, local-first y gratis. Ejecuta Claude Code, Codex y los demás, y mantiene vivo el contrato de producto hasta que la cosa está validada.</p>
<p><a href="/es/#download" class="tp-btn tp-btn-solid">↓ Descargar PaellaDoc · macOS</a></p>
<p>¿Cuánto de tu día se va en mantener vivo el contrato en vez de decidir qué construir? <a href="https://forum.paelladoc.com/">Cuéntame en el foro</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="necesitas-un-runtime-alrededor-de-claude-code">¿Necesitas un runtime alrededor de Claude Code?</h3>
<p>Un buen desarrollador puede correr Claude Code a mano, haciendo de scheduler, memoria, gate y bucle de recuperación. Un runtime de entrega se lleva esa orquestación fuera del desarrollador para que el trabajo abarque muchas tareas, repos y horas sin un humano sosteniéndolo todo en la cabeza.</p>
<h3 id="por-qué-un-modelo-más-grande-no-arregla-el-trabajo-largo-con-agentes">¿Por qué un modelo más grande no arregla el trabajo largo con agentes?</h3>
<p>En un benchmark de recuperación de cuatro episodios, Claude Code con prompt y con skill se quedó en el 66,67%, y los modelos más grandes en controles n=1 hicieron lo mismo. Un runtime de recuperación gobernado llegó al 100%. La brecha no era inteligencia bruta, era sostener el contrato y recuperar a través de episodios.</p>
<h3 id="cuándo-está-de-verdad-hecha-una-feature">¿Cuándo está de verdad hecha una feature?</h3>
<p>No cuando el agente lo dice, ni cuando el build está verde. Done es el comportamiento pasando los criterios de aceptación que existían antes de escribir una línea, con la evidencia pegada.</p>
<h3 id="y-si-claude-code-o-codex-añaden-su-propio-runtime">¿Y si Claude Code o Codex añaden su propio runtime?</h3>
<p>Parte de la orquestación se absorberá. PaellaDoc no compite por ser el mejor executor; es la capa portable, local-first y multi-motor donde viven el contrato de producto, los gates, la evidencia y la memoria de cada run, por encima de cualquier agente o proveedor.</p>]]></content>
    <summary type="html"><![CDATA[Claude Code me escribe el código de lujo, no necesito un runtime por encima. Tienes razón, y no sientes que lo necesites porque eres tú: partes el trabajo, recuperas los runs muertos, decides si done es done de verdad. La frontera nunca ha sido generar código. Es mantener vivo el contrato de producto mientras muchos agentes escriben, fallan, recuperan e integran. Claude Code escribe el código, Codex ejecuta las tareas, PaellaDoc mantiene vivo el contrato hasta que la cosa está validada, con evidencia.]]></summary>
    <author>
      <name>@jlcases</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="ai-coding"/><category term="agents"/><category term="claude-code"/><category term="runtime"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/you-are-the-runtime-hero-es.png" />
  </entry>

  <entry>
    <title type="html">Sin vendor lock-in: cada tarea a su motor</title>
    <link href="https://paelladoc.com/es/blog/routing-de-modelos-sin-vendor-lock-in/" rel="alternate" type="text/html" title="Sin vendor lock-in: cada tarea a su motor"/>
    <published>2026-06-14T00:00:00+02:00</published>
    <updated>2026-06-14T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/routing-de-modelos-sin-vendor-lock-in/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/routing-de-modelos-sin-vendor-lock-in/"><![CDATA[<p>Durante un tiempo mi setup eran tres terminales. Claude Code en uno, Codex en otro, Kimi cuando alguno saturaba. Funcionaba, como funciona hacer malabares con tres cosas. Luego he empezado a meter tareas reales por ahí y se han visto las grietas.</p>
<p>Un retoque de copy tonto se llevaba el mismo modelo pesado que una migración de base de datos. La mitad de las veces enrutaba algo a un motor que ni siquiera estaba instalado en esa máquina, y me enteraba cuando fallaba. Estaba tomando una decisión de runtime a mano, mal, en cada tarea.</p>
<p>Ahí ha dejado de ser la pregunta el “qué modelo uso”. El modelo no es la unidad de trabajo. La tarea sí.</p>
<h2 id="un-retoque-de-copy-no-es-una-migración">Un retoque de copy no es una migración</h2>
<p>Un cambio de una línea en la UI y una migración de Alembic no son el mismo trabajo. Una puede tirar producción abajo. La otra es cosa de cinco minutos que le puedes dar al modelo más barato que tengas. Manda todo a tu motor más caro y quemas dinero en chorradas. Manda todo al más barato y la migración te explota en la cara.</p>
<p>Así que las preguntas de verdad no van del modelo. Van del trabajo que tienes delante. Qué tipo de tarea es. Qué motor está disponible de verdad en esta máquina o cuenta. Qué coste y qué latencia aceptas. Qué ha pasado la última vez que has corrido algo parecido. Y qué cosa segura ocurre cuando el sistema no puede decidir.</p>
<p>Los CLIs se han vuelto más listos en esto, y conviene ser preciso. Claude Code ya enruta dentro de su propia casa: planifica con Opus y ejecuta con Sonnet, y cae a un modelo más ligero cuando llegas a un límite. Codex sube y baja su esfuerzo de razonamiento solo. Eso es enrutado de verdad, y está bien.</p>
<p>Pero es enrutado dentro de un proveedor. Claude enruta entre modelos de Anthropic. Codex enruta entre modelos de OpenAI. Ninguno va a mandar tu tarea barata a Kimi, tu migración a un modelo frontier y tu trabajo offline a un modelo local, porque ese no es su trabajo. Su trabajo es correr bien su motor. Y ninguno responde a las preguntas de producto: disponibilidad entre motores, coste entre proveedores, qué ha funcionado en tu repo, qué cosa segura pasa cuando la llamada falla. Para trabajo puntual, el enrutado de casa sobra. Deja de bastar en cuanto quieres un producto entre motores en vez de una sola herramienta buena.</p>
<h2 id="un-motor-es-una-palanca-sigue-haciendo-falta-la-mano">Un motor es una palanca. Sigue haciendo falta la mano.</h2>
<p>PaellaDoc no envuelve un CLI y lo llama otro chat. Trata a Claude, Codex, Kimi, Gemini, cualquier modelo open source a través de Ollama o cualquier CLI al que lo apuntes como una flota de motores intercambiables bajo un mismo contrato. Cuando entra una tarea, un router elige el motor y el perfil para ese trabajo: cheap, balanced, strong o frontier.</p>
<p>Esa es la diferencia en una línea. Un CLI es una palanca. PaellaDoc es la capa que decide cuándo, cómo y por qué tirar de cada una.</p>
<h2 id="la-semana-que-retiraron-un-modelo">La semana que retiraron un modelo</h2>
<p>Un ejemplo real, de la misma semana en que escribo esto. Anthropic lanzó Fable 5 un lunes. Para el jueves, una orden de control de exportaciones de EEUU les obligó a desactivarlo y a cortar el acceso a cualquier ciudadano extranjero, dentro o fuera de Estados Unidos. Yo trabajo desde Valencia. Si mi producto hubiera estado atado a ese único modelo, el jueves estaba caído, por orden del gobierno, y sin nada que yo pudiera hacer.</p>
<p>Ese es el lock-in sobre el que me niego a construir. Fable salió en las noticias. Lo que te pilla de verdad casi nunca sale: un cambio de precio, un rate limit nuevo, una retención de datos que no puedes aceptar, un modelo deprecado con un mes de aviso. Cuando dependes del modelo de un solo proveedor, cada una de esas cosas es tu problema y ninguna es tu decisión.</p>
<p>Una flota bajo un mismo contrato convierte eso de una caída en un cambio de config. El motor en el que confiabas desaparece, enrutas a otro, el trabajo sigue. Y el suelo debajo de todo es el open source: con cualquier modelo open source corriendo en local a través de Ollama, no sale nada de tu máquina y ningún proveedor, ni ningún gobierno, lo puede apagar. Para alguien en la UE que maneja el código fuente de otros, eso no es un lujo. Es la razón entera de construirlo así.</p>
<h2 id="de-lo-que-más-orgulloso-estoy-es-de-una-limitación">De lo que más orgulloso estoy es de una limitación</h2>
<p>Esta es la decisión de diseño que más importa, y es una limitación, no una feature.</p>
<p>Cuando corre el router inteligente, puede elegir exactamente dos cosas: qué agente y qué perfil. Ese es todo el contrato. No puede elegir el modelo. No puede elegir el esfuerzo de razonamiento. No puede elegir el presupuesto de contexto. Eso sale de un slot de config probado, no de un modelo de lenguaje improvisando sobre la marcha.</p>
<p>Esto mata una clase entera de fallo que está por todas partes en los productos de IA: dejar que un modelo “decida” una config de runtime que luego no existe, no está autenticada o no encaja con el motor que ha elegido. En PaellaDoc el router propone un agente y un perfil. El runtime resuelve el modelo, el esfuerzo y el contexto desde config verificada. La parte lista sugiere. La parte aburrida y probada ejecuta.</p>
<h2 id="determinista-por-defecto-inteligente-por-contrato">Determinista por defecto, inteligente por contrato</h2>
<p>El modo por defecto es deliberadamente tonto. Reglas. Sin una llamada extra a un LLM solo para decidir un modelo. Es predecible, es barato, y cuando algo va mal lo puedes depurar de verdad. La inteligencia es opt-in, y va detrás de una licencia PRO.</p>
<p>Y aun con el modo inteligente activado, el router va con correa corta. Si devuelve un JSON roto, o elige un motor que no está instalado, o nombra un perfil que no existe, o intenta cambiar de agente cuando había uno fijado, el sistema cae directo a reglas. Sin crash, sin ejecución a medio configurar. Determinista por defecto, inteligente por contrato.</p>
<p>Esa frase es toda la filosofía. En producción, la inteligencia sin fallback es deuda que todavía no te han pasado a cobrar.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/model-router-panel_480.avif 480w, /assets/images/model-router-panel_768.avif 768w, /assets/images/model-router-panel_1024.avif 1024w, /assets/images/model-router-panel_1440.avif 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/model-router-panel_480.webp 480w, /assets/images/model-router-panel_768.webp 768w, /assets/images/model-router-panel_1024.webp 1024w, /assets/images/model-router-panel_1440.webp 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/model-router-panel_480.png" srcset="/assets/images/model-router-panel_480.png 480w, /assets/images/model-router-panel_768.png 768w, /assets/images/model-router-panel_1024.png 1024w, /assets/images/model-router-panel_1440.png 1440w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="El panel de ajustes del router de modelos de PaellaDoc: los tres modos rules, smart y manual con rules activo por defecto, la configuración activa con cuatro perfiles y dieciséis agentes por perfil, y la flota a la izquierda con la disponibilidad real de cada motor (Claude Code, Codex, Gemini, OpenCode, Kimi Code, IA local)." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Este es el panel de verdad, no un mockup. Rules es el modo activo. La flota baja por la izquierda con la disponibilidad real de cada motor, y los tres modos están ahí: determinista por defecto, smart y manual a un clic.</p>
<h2 id="aprende-y-aprende-aquí">Aprende, y aprende aquí</h2>
<p>Con el tiempo el router deja de adivinar. Mira lo que de verdad ha funcionado en tu proyecto: qué combinaciones de motor y perfil han pasado el gate, y cuánto han costado en tokens. Y se inclina hacia ahí, con cuidado, solo cuando hay evidencia suficiente para justificarlo.</p>
<p>Dos cosas que me importan aquí. Aprende en local. No manda tus prompts ni la salida de tu terminal a ningún sitio para rankear motores. Trabaja con resultados compactos de lo que ha pasado. Y no se cree que Claude, o Codex, o Kimi sea mejor en abstracto. No tiene opinión sobre eso. Aprende qué combinaciones han funcionado en tareas como las tuyas, en tu repo.</p>
<h2 id="solo-enruta-a-motores-que-pueden-arrancar-de-verdad">Solo enruta a motores que pueden arrancar de verdad</h2>
<p>Un router que te ofrece un motor que no está instalado es peor que no tener router. Antes de que ocurra siquiera la decisión inteligente, PaellaDoc filtra los candidatos a los motores que el runtime puede lanzar de verdad en esta máquina: existe el adapter, responde como disponible, está autenticado. Si un CLI local apunta a un binario fuera del PATH, el check de disponibilidad usa ese mismo path, así que no se descarta por error.</p>
<p>La lista de la que elige el router no es un catálogo de marketing. Es una lista de cosas que van a arrancar.</p>
<h2 id="de-qué-va-esto-en-realidad">De qué va esto en realidad</h2>
<p>Nada de esto va de un modelo mágico que siempre acierta. No creo que ese modelo exista, y un producto montado sobre la suposición de que sí se rompe la primera semana.</p>
<p>La próxima generación de software con agentes no se va a diferenciar por qué modelo llama. Todos llaman al mismo puñado. Se va a diferenciar por la calidad de su capa de decisión: cómo elige, cuándo escala, qué aprende, qué bloquea y cómo falla. Esa capa es el producto.</p>
<p>Un CLI corre el motor de un proveedor, y lo corre bien. PaellaDoc gobierna una flota de ellos, y la decisión sigue siendo tuya.</p>
<p>Esta es la versión larga de una fila del <a href="/es/compare/">hub de comparativas</a>: agnóstico de modelo, tu motor, tu máquina. Y es el mismo argumento que el resto de lo que construyo: <a href="/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/">el cerebro de producto que se mantiene solo</a>, y <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>.</p>
<p>¿Tú enrutas entre motores o te ciñes a uno? <a href="https://forum.paelladoc.com/t/do-you-route-tasks-across-engines-or-commit-to-one-model/94?tl=es">Cuéntamelo en el foro</a>, quiero saber cómo lo llevas.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-el-routing-de-modelos-para-agentes-de-código">¿Qué es el routing de modelos para agentes de código?</h3>
<p>El routing de modelos trata la tarea, no el modelo, como la unidad de trabajo. Cuando entra una tarea, un router elige qué motor la corre y con qué perfil —cheap, balanced, strong o frontier— según el tipo de tarea, qué motores están disponibles de verdad, el coste y la latencia que aceptas y qué funcionó antes. Un retoque de copy y una migración de base de datos no son el mismo trabajo, así que no deberían ir por defecto al mismo motor caro.</p>
<h3 id="cómo-evito-el-vendor-lock-in-con-los-modelos-de-ia">¿Cómo evito el vendor lock-in con los modelos de IA?</h3>
<p>Trata los motores como una flota bajo un mismo contrato en vez de atar tu trabajo a un solo modelo. Cuando un proveedor cambia el precio, añade un rate limit o retiran un modelo —como pasó la semana en que una orden de control de exportaciones desactivó uno a mitad de semana— enrutas a otro motor y el trabajo sigue, convirtiendo una caída en un cambio de config. El suelo debajo es el open source: un modelo local a través de Ollama que ningún proveedor ni gobierno puede apagar.</p>
<h3 id="debería-usar-un-solo-modelo-de-ia-o-enrutar-entre-varios">¿Debería usar un solo modelo de IA o enrutar entre varios?</h3>
<p>Para trabajo puntual, un solo CLI enrutando dentro de su proveedor sobra: Claude Code planifica con un modelo y ejecuta con otro. Deja de bastar cuando quieres un producto entre motores: ninguno va a mandar tu tarea barata a un motor, tu migración a un modelo frontier y tu trabajo offline a uno local, ni responder disponibilidad, coste y fallback entre proveedores. La capa de decisión entre motores es el producto.</p>
<h3 id="un-router-puede-mandar-trabajo-a-un-modelo-que-no-está-instalado">¿Un router puede mandar trabajo a un modelo que no está instalado?</h3>
<p>No debería, y uno bueno no lo hace. Un router que te ofrece un motor que no puede arrancar es peor que no tener router. Antes de cualquier decisión inteligente, los candidatos se filtran a los motores que el runtime puede lanzar de verdad en esta máquina: existe el adapter, responde como disponible y está autenticado. Y cuando el router inteligente corre, solo elige el agente y el perfil; el modelo, el esfuerzo y el contexto salen de config verificada, con un fallback determinista por reglas si algo se rompe.</p>]]></content>
    <summary type="html"><![CDATA[Durante un tiempo mi setup eran tres terminales: Claude en uno, Codex en otro, Kimi cuando uno saturaba. Funcionaba como funciona hacer malabares. Luego he empezado a meter tareas reales por ahí y se han visto las grietas: un retoque de copy tonto se llevaba el mismo modelo pesado que una migración de base de datos, y la mitad de las veces enrutaba a un motor que ni estaba instalado. Ahí ha dejado de ser la pregunta el qué modelo. La unidad es la tarea, no el modelo. Así enruta PaellaDoc el trabajo por una flota de motores sin dejar que un LLM se invente el runtime.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="model-routing"/><category term="ai-coding"/><category term="llm"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/model-router-hero-es.png" />
  </entry>

  <entry>
    <title type="html">El cerebro de producto que se mantiene solo</title>
    <link href="https://paelladoc.com/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/" rel="alternate" type="text/html" title="El cerebro de producto que se mantiene solo"/>
    <published>2026-06-12T00:00:00+02:00</published>
    <updated>2026-06-12T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/el-cerebro-de-producto-que-se-mantiene-solo/"><![CDATA[<p>Tenía una carpeta con el contexto del producto para que la IA dejara de inventarse cosas. Estrategia, decisiones, métricas, feedback, todo en markdown, metido en cada prompt. Dos semanas ha sido genial. Luego el equipo ha shipeado, la carpeta no se ha movido, y la IA ha empezado a responder con total seguridad sobre un producto que ya no existía.</p>
<p>Esa carpeta me ha enseñado algo que no quería aprender. Montar el cerebro es la mitad fácil. La pregunta que decide si algo de esto sobrevive al contacto con un equipo de verdad es la que yo no sabía responder: ¿quién lo mantiene al día?</p>
<h2 id="la-carpeta-empieza-a-mentir-en-cuanto-shipeas">La carpeta empieza a mentir en cuanto shipeas</h2>
<p>Una carpeta de notas tiene una forma de fallar muy silenciosa. No se rompe. Se desfasa.</p>
<p>Escribes el PRD el lunes. El viernes el equipo ha shipeado tres cambios, dos de los cuales lo contradicen sin avisar. Nadie ha tocado el documento, porque actualizarlo no es tarea de nadie y es lata de todos. Así que ahora la IA lee un contexto que es verdad a medias, y te responde con seguridad sobre un producto que ya no existe.</p>
<p>Aquí hay dos dolores y has sentido los dos. La IA te da respuestas viejas, porque el contexto que lee se ha quedado atrás. Y tú te pasas las tardes actualizando docs, PRDs y estado del producto, porque en cuanto paras, <a href="/es/blog/memoria-de-producto/">tu propia documentación empieza a mentirte</a>.</p>
<p>La reacción típica es montar un cerebro mejor. Mejores plantillas, convenciones más estrictas, una wiki más mona. Eso es optimizar el archivo. No ayuda, porque el problema nunca ha sido el archivo. El problema es que el archivo no tiene forma de enterarse de que el producto ha cambiado.</p>
<h2 id="el-cerebro-tiene-que-ser-un-grafo-no-una-carpeta">El cerebro tiene que ser un grafo, no una carpeta</h2>
<p>Una carpeta es un montón. Un montón no sabe qué se relaciona con qué. Cuando cambias una decisión, una carpeta no te puede decir qué historias de usuario acabas de invalidar, porque no sabe que estaban conectadas.</p>
<p>Así que el primer movimiento es dejar de guardar el contexto de producto como documentos y <a href="/es/blog/grafo-de-conocimiento-de-producto/">empezar a guardarlo como un grafo</a>. Cada artefacto es un nodo: el PRD, cada épica, cada historia de usuario, cada criterio de aceptación, cada decision record, cada riesgo. Y los nodos se conectan con relaciones tipadas que significan algo: esta épica <em>forma parte de</em> ese PRD, este criterio <em>valida</em> esa historia, esta decisión <em>reemplaza</em> a aquella, esta tarea <em>implementa</em> ese criterio.</p>
<p>Suena a burocracia. Es lo contrario. En cuanto las relaciones son reales, el grafo responde preguntas que una carpeta no puede:</p>
<ul>
<li>Cambia una decisión y ves cada historia y criterio aguas abajo que toca.</li>
<li>Reabre un riesgo y caminas hasta el trabajo que debía mitigarlo.</li>
<li>Pregunta “por qué existe esto” y el grafo te lleva hacia arriba desde una línea de comportamiento hasta el objetivo que la ha pedido.</li>
</ul>
<p>La jerarquía de producto deja de ser un cuento que cuentas en la daily y pasa a ser <a href="/es/blog/grafo-de-conocimiento-del-codigo/">una estructura que la máquina puede recorrer</a>. Esa es la diferencia entre documentación que mantienes y un cerebro que aguanta su propia forma.</p>
<h2 id="el-loop-que-un-humano-no-puede-llevar">El loop que un humano no puede llevar</h2>
<p>Y ahora la parte que importa, la que la gente de la carpeta no termina de contar.</p>
<p>Cinco cosas deberían alimentar un cerebro de producto: entra feedback y se agrupa en oportunidades; tomas una decisión y queda registrada; se mueve una métrica y el cerebro la absorbe; haces discovery y se incorpora; y la grande, tu equipo shipea algo, y eso actualiza el estado del producto, las guías y reconcilia el PRD.</p>
<p>Cuatro las puedes hacer a mano si eres disciplinado. La quinta no. Y no porque seas vago. Porque el disparador está mal.</p>
<p>Cuando el loop se dispara con “el equipo ha shipeado”, con lo que se dispara en realidad es con alguien marcando una tarea como hecha. Y una tarea marcada como hecha es una opinión. El agente ha dicho que había terminado, el build se ha puesto verde, la tarjeta se ha movido. Nada de eso significa que el código haga lo que pedía la historia. <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">Un build en verde no es una feature correcta</a>. Si tu cerebro de producto se actualiza cada vez que alguien marca done, se llena de mentiras con seguridad, y lo hace más rápido de lo que puedes cazarlas.</p>
<p>Así que el disparador tiene que cambiar. El cerebro debería actualizarse cuando el trabajo se <em>verifica contra el criterio que lo ha definido</em>, no cuando un humano canta victoria.</p>
<h2 id="ata-el-código-a-la-decisión-que-lo-ha-pedido">Ata el código a la decisión que lo ha pedido</h2>
<p>Esta es la versión que llevo meses construyendo en lugar de una carpeta.</p>
<p>Cuando una pieza de trabajo termina, no se limita a cambiar de estado. El sistema va y busca la evidencia real en el repo, el código de verdad, los tests, la config, las ejecuciones, y enlaza esa evidencia con el artefacto que la exigía. No “este PR seguramente tiene que ver”, sino un enlace durable y tipado: este código <em>satisface</em> este criterio de aceptación, esta ejecución <em>valida</em> esta historia. Cada artefacto declara de antemano qué tipo de evidencia lo probaría, y terminar es producir esa evidencia, no afirmarla.</p>
<p>El efecto es que cada línea de código queda atada a la decisión de producto que la ha pedido. El grafo deja de ser una descripción del producto que vive al lado del código. Está cableado dentro del código. Cuando el trabajo cambia, el cerebro cambia, porque el enlace entre los dos es el mismo hecho, no dos hechos que tienes que mantener sincronizados.</p>
<p>Esto es el loop que un humano no puede llevar a mano, funcionando solo. El cerebro se mantiene verdadero no porque tú lo actualizaste, sino porque “verdadero” es lo que significa pasar la verificación.</p>
<figure class="tp-diagram tp-diagram--loop" data-diagram-type="loop" role="img" aria-label="El loop que un humano no puede llevar a mano: el cerebro se actualiza cuando el trabajo se verifica contra el criterio que lo definió, no cuando alguien marca hecho."><svg viewBox="0 0 760 230" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><rect x="40" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="112" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EL TRABAJO TERMINA</text><path d="M 190 85 L 212 85 M 206 79 L 212 85 L 206 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="218" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="290" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">BUSCA LA EVIDENCIA</text><path d="M 368 85 L 390 85 M 384 79 L 390 85 L 384 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="396" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="468" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">ENLAZA AL CRITERIO</text><path d="M 546 85 L 568 85 M 562 79 L 568 85 L 562 91" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path><rect x="574" y="52" width="144" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="646" y="91" text-anchor="middle" font-family="var(--tp-mono)" font-size="14" letter-spacing="1.5" fill="var(--tp-ink)">EL CEREBRO CAMBIA</text><path d="M 720 118 L 720 178 L 40 178 L 40 118 M 40 130 L 34 121 L 46 121 Z" stroke="var(--tp-mostaza)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="198" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-mostaza)">VERIFICADO NO DECLARADO</text></svg><figcaption>El loop que un humano no puede llevar a mano: el cerebro se actualiza cuando el trabajo se verifica contra el criterio que lo definió, no cuando alguien marca hecho.</figcaption></figure>
<h2 id="el-efecto-secundario-por-fin-ves-en-qué-se-va-tu-tiempo">El efecto secundario: por fin ves en qué se va tu tiempo</h2>
<p>En cuanto el código queda atado a los artefactos de producto, cae algo gratis que no esperaba valorar tanto como lo valoro.</p>
<p>Puedes ver en qué se va de verdad tu tiempo y tu gasto, por producto, no por commits sueltos.</p>
<p>Cada unidad de trabajo de IA queda atribuida: qué rol la ha gastado, en qué proyecto, contra qué artefacto. No “quemamos un montón de tokens esta semana”, sino “esta épica ha costado esto, el trabajo de product owner ha costado aquello, esta feature ha sido tres veces más cara de dejar bien de lo que estimamos”. El coste y el esfuerzo suben por el mismo grafo que el trabajo, porque cuelgan de los mismos nodos.</p>
<p>Para un PM eso cambia la conversación. Dejas de discutir sobre actividad y empiezas a mirar dónde se concentra el esfuerzo contra los resultados. El grafo que mantiene tu contexto verdadero es el mismo que te dice cuánto ha costado de verdad tu roadmap.</p>
<h2 id="deja-de-optimizar-el-archivo">Deja de optimizar el archivo</h2>
<p>El cambio de mentalidad es pequeño y lo cambia todo. Deja de intentar montar un archivo mejor. El archivo nunca ha sido el punto.</p>
<p>Monta la estructura que conecta producto con código, y que el disparador sea la verificación, no un clic. Hazlo y el cerebro se mantiene solo, porque <a href="/es/blog/documentacion-viva/">mantenerlo verdadero deja de ser una tarea que haces</a> y pasa a ser una propiedad de cómo se hace el trabajo.</p>
<p>La carpeta era lo fácil, y nunca ha sido lo que importaba. Lo que de verdad necesitaba construir era el loop que evita que me mienta.</p>
<p>Por esto construyo <a href="/es/">PaellaDoc</a> como lo construyo, y va pegado al resto del argumento: <a href="/es/blog/hacer-producto-no-es-productizar/">hacer producto no es productizar</a>, y <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>.</p>
<p>¿Cómo evitas tú que el cerebro de tu producto se desfase? <a href="https://forum.paelladoc.com/t/your-product-brain-who-keeps-it-up-to-date-after-the-team-ships/93?tl=es">Cuéntamelo en el foro</a>, quiero saber qué te funciona.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-se-desfasa-la-carpeta-de-contexto-que-le-doy-a-mi-ia">¿Por qué se desfasa la carpeta de contexto que le doy a mi IA?</h3>
<p>Porque una carpeta de notas no tiene forma de saber que el producto cambió. Escribes el PRD el lunes; el viernes el equipo shipeó tres cambios, dos contradiciéndolo, y nadie actualizó el doc porque no es tarea de nadie. La IA responde entonces con seguridad sobre un producto que ya no existe. El problema nunca fue el fichero.</p>
<h3 id="por-qué-el-cerebro-de-producto-tiene-que-ser-un-grafo-y-no-una-carpeta">¿Por qué el cerebro de producto tiene que ser un grafo y no una carpeta?</h3>
<p>Una carpeta es un montón que no sabe qué se relaciona con qué, así que no puede decirte qué historias invalidó una decisión que cambió. Guarda el contexto como grafo y cada artefacto es un nodo con relaciones tipadas, así que cambias una decisión y ves cada historia y criterio aguas abajo que toca.</p>
<h3 id="qué-debería-disparar-la-actualización-de-un-cerebro-de-producto">¿Qué debería disparar la actualización de un cerebro de producto?</h3>
<p>La verificación contra el criterio que definió el trabajo, no un clic en «hecho». Una tarea marcada como hecha es una opinión: el build se puso verde, la tarjeta se movió, nada de eso significa que el código haga lo que pedía la historia. Actualiza en cada clic y el cerebro se llena de mentiras con aplomo más rápido de lo que las cazas.</p>
<h3 id="cómo-evito-que-el-cerebro-de-producto-se-desfase">¿Cómo evito que el cerebro de producto se desfase?</h3>
<p>Ata el código a la decisión que lo pidió, con enlaces tipados duraderos, y deja que completar signifique producir la evidencia que un criterio exigía, no afirmarla. Entonces el cerebro cambia cuando cambia el trabajo, porque el enlace entre ellos es el mismo hecho. Mantenerlo verdadero deja de ser una tarea y pasa a ser una propiedad de cómo se trabaja.</p>]]></content>
    <summary type="html"><![CDATA[Tenía una carpeta de contexto para que mi IA dejara de inventarse cosas. Ha funcionado dos semanas, luego el equipo ha shipeado y la carpeta ha empezado a mentir. Lo difícil no es montar el cerebro, es mantenerlo verdadero. Si nada lo alimenta, el sistema eres tú, a mano, para siempre. Esta es la versión que llevo meses construyendo en su lugar: un grafo que ata el código a la decisión que lo ha pedido, mantenido por lo que de verdad ha pasado la verificación.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="product-management"/><category term="knowledge-graph"/><category term="ai-coding"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/product-brain-hero.png" />
  </entry>

  <entry>
    <title type="html">¿Qué es una feature factory?</title>
    <link href="https://paelladoc.com/es/blog/que-es-una-feature-factory/" rel="alternate" type="text/html" title="¿Qué es una feature factory?"/>
    <published>2026-06-07T00:00:00+02:00</published>
    <updated>2026-06-07T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/que-es-una-feature-factory/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/que-es-una-feature-factory/"><![CDATA[<p><strong>Una feature factory es un equipo que mide su éxito por cuánto entrega, features lanzadas y story points cerrados, en lugar de por qué cambia de verdad en el usuario.</strong> El término lo acuñó John Cutler.</p>
<p>La señal es sutil: una feature factory suele parecer productiva. Lanza rápido, mantiene la velocidad alta y tiene un historial visible de trabajo terminado. Ha optimizado la actividad de construir, no el resultado de construir.</p>
<h2 id="señales-de-que-estás-en-una">Señales de que estás en una</h2>
<ul>
<li>El éxito se mide en entrega (releases, puntos, features), no en <a href="/es/blog/de-insight-a-resultado/">cambio de comportamiento ni en resultados de negocio</a>.</li>
<li>Se añaden features porque la competencia las tiene, porque un cliente grande las ha pedido o porque alguien ha dicho “estaría bien tenerla”, cada una con su lógica local y ningún comportamiento objetivo detrás.</li>
<li>Nadie sabe responder “¿qué comportamiento nuevo instalamos este trimestre?”.</li>
<li>El roadmap crece. La razón para que un usuario concreto se quede, no.</li>
</ul>
<h2 id="por-qué-los-equipos-caen-ahí">Por qué los equipos caen ahí</h2>
<p>No a propósito. Productizar genera señales de progreso inmediatas, demos, changelogs, reuniones donde enseñar algo nuevo, mientras que cambiar comportamiento es invisible durante meses. Casi ninguna organización premia lo invisible. Premia la actividad. Y añadir superficie es actividad.</p>
<h2 id="qué-cuesta">Qué cuesta</h2>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/product-feature-usage-es_480.avif 480w, /assets/images/product-feature-usage-es_768.avif 768w, /assets/images/product-feature-usage-es_1024.avif 1024w, /assets/images/product-feature-usage-es_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/product-feature-usage-es_480.webp 480w, /assets/images/product-feature-usage-es_768.webp 768w, /assets/images/product-feature-usage-es_1024.webp 1024w, /assets/images/product-feature-usage-es_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/product-feature-usage-es_480.png" srcset="/assets/images/product-feature-usage-es_480.png 480w, /assets/images/product-feature-usage-es_768.png 768w, /assets/images/product-feature-usage-es_1024.png 1024w, /assets/images/product-feature-usage-es_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="El 80% de las features de un software medio se usan rara vez o nunca, y solo el 12% genera el 80% del uso diario." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>En torno al 80% de las funciones de un software medio se usan rara vez o nunca, y solo un 12% genera la mayor parte del uso diario (Pendo. El informe Standish Chaos lo deja cerca del 64%, metodologías discutibles, dirección consistente). Eso es superficie que existe sin cambiar nada, más el equipo creciente que hace falta para mantenerla. No es gratis. Cada línea viva cuesta algo cada día, se use o no.</p>
<h2 id="el-único-test-que-te-saca">El único test que te saca</h2>
<p>Antes de meter nada en el roadmap, completa esta frase:</p>
<blockquote>
<p>Gracias a esto, [tipo de usuario] pasará de hacer [X] a hacer [Y], y lo sabremos cuando veamos [métrica Z].</p>
</blockquote>
<p>Si no puedes rellenarla, tienes una idea de feature, no de producto. <a href="/es/blog/hacer-producto-no-es-productizar/">Hacer producto es instalar un comportamiento</a>, no acumular superficie. Esa distinción es la diferencia entre un moat y deuda de atención, y en la <a href="/es/blog/product-management-era-ia/">era de la IA, cuando copiar una feature cuesta una tarde</a>, es la única que importa.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Quién acuñó “feature factory”?</strong> John Cutler.</p>
<p><strong>¿Lanzar features es siempre malo?</strong> No. A veces productizar es lo correcto: alcanzar paridad, no perder un cliente, ganar tiempo. El problema es hacerlo en modo automático, sin saberlo.</p>
<p><strong>¿Qué tiene que ver con el desarrollo con IA?</strong> La IA abarata generar features casi a cero, lo que acelera la feature factory salvo que la <a href="/es/blog/modelo-operativo-de-producto/">intención y la verificación estén aguas arriba</a>. La disciplina que lo contrarresta es la misma idea un nivel más abajo: <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿Quién acuñó el término feature factory?", "acceptedAnswer": { "@type": "Answer", "text": "John Cutler acuñó el término feature factory." } },
    { "@type": "Question", "name": "¿Lanzar features es siempre malo?", "acceptedAnswer": { "@type": "Answer", "text": "No. A veces productizar es lo correcto: alcanzar paridad, no perder un cliente, ganar tiempo. El problema es hacerlo en modo automático, sin saberlo." } },
    { "@type": "Question", "name": "¿Qué tiene que ver una feature factory con el desarrollo con IA?", "acceptedAnswer": { "@type": "Answer", "text": "La IA abarata generar features casi a cero, lo que acelera la feature factory salvo que la intención y la verificación estén aguas arriba. La disciplina que lo contrarresta es la misma idea un nivel más abajo: un build en verde no es una feature correcta." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[Una feature factory es un equipo que mide su éxito por cuánto entrega, features lanzadas, story points cerrados, en lugar de por qué cambia en el usuario. El término, las señales de alarma, por qué los equipos caen ahí sin querer, qué cuesta, y el único test que te saca.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="product-management"/><category term="product-strategy"/><category term="feature-factory"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/product-behavior-hero.jpeg" />
  </entry>

  <entry>
    <title type="html">¿Qué es el desarrollo guiado por especificaciones?</title>
    <link href="https://paelladoc.com/es/blog/que-es-desarrollo-guiado-por-especificaciones/" rel="alternate" type="text/html" title="¿Qué es el desarrollo guiado por especificaciones?"/>
    <published>2026-06-07T00:00:00+02:00</published>
    <updated>2026-06-07T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/que-es-desarrollo-guiado-por-especificaciones/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/que-es-desarrollo-guiado-por-especificaciones/"><![CDATA[<p><strong>El desarrollo guiado por especificaciones (spec-driven development) es una forma de construir software en la que los criterios de aceptación, la definición de “hecho” del producto, se escriben antes del código, y si una tarea está hecha se decide ejecutando el código contra esos criterios, no con un build en verde.</strong></p>
<p>El nombre apunta al orden: primero la spec, luego el código, y por último la verificación por ejecución. Que el build pase no es la meta. La meta es que los criterios se ejecuten como se han escrito.</p>
<h2 id="por-qué-existe">Por qué existe</h2>
<p>Que el build esté en verde te dice que el código está de acuerdo consigo mismo. No dice nada de si hace lo que has pedido. <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">Medido en 120 ejecuciones y cuatro modelos</a>, una petición en crudo de una línea ha colado un fallo de corrección real en el 40% de los casos con el build en verde. Darle al agente los criterios por delante lo ha bajado a 0%.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/spec-driven-bug-rate-by-model_480.avif 480w, /assets/images/spec-driven-bug-rate-by-model_768.avif 768w, /assets/images/spec-driven-bug-rate-by-model_1024.avif 1024w, /assets/images/spec-driven-bug-rate-by-model_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/spec-driven-bug-rate-by-model_480.webp 480w, /assets/images/spec-driven-bug-rate-by-model_768.webp 768w, /assets/images/spec-driven-bug-rate-by-model_1024.webp 1024w, /assets/images/spec-driven-bug-rate-by-model_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/spec-driven-bug-rate-by-model_480.png" srcset="/assets/images/spec-driven-bug-rate-by-model_480.png 480w, /assets/images/spec-driven-bug-rate-by-model_768.png 768w, /assets/images/spec-driven-bug-rate-by-model_1024.png 1024w, /assets/images/spec-driven-bug-rate-by-model_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Porcentaje de bugs genuinos por modelo, petición en crudo frente a la misma con criterios de aceptación: todos bajan a cero." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>El modelo no era la variable. La spec sí.</p>
<h2 id="cómo-funciona">Cómo funciona</h2>
<ol>
<li><strong>Escribe los criterios de aceptación</strong> de la tarea, en lenguaje claro, antes de una línea de código. Cada criterio es una afirmación comprobable sobre el comportamiento: qué debe hacer el código, con qué entrada, con qué resultado.</li>
<li><strong>Implementa</strong> el cambio (tú, o un agente).</li>
<li><strong>Pon un gate de ejecución.</strong> Reaplica el cambio sobre una copia limpia, ejecuta el código y comprueba cada criterio. Si uno falla, la tarea no está hecha, por muy verde que esté el build.</li>
</ol>
<p>Los criterios viajan con el cambio y sobreviven a la sesión, que es lo que mantiene un sistema coherente en vez de <a href="/es/blog/localmente-correcto-globalmente-incoherente/">localmente correcto pero globalmente incoherente</a>.</p>
<h2 id="de-dónde-viene-y-por-qué-no-es-tdd">De dónde viene (y por qué no es TDD)</h2>
<p>El desarrollo guiado por especificaciones <a href="/es/blog/spec-driven-vs-test-driven/">no es TDD</a>, y confundirlos es la forma más rápida de no entenderlo. TDD es un ritmo del desarrollador, rojo, verde, refactor, a nivel de unidad: el dev escribe un test unitario que falla para guiar el diseño de una función. El autor es el desarrollador, el artefacto es un test unitario, el propósito es el diseño.</p>
<p>El desarrollo guiado por especificaciones está un nivel por encima, y viene de otro linaje: BDD (behavior-driven development), acceptance-test-driven development y el <em>Specification by Example</em> de Gojko Adzic. El artefacto son los criterios de aceptación de una user story, la definición de “hecho” del producto, idealmente escritos en forma ejecutable como el Given/When/Then de Gherkin. Fusiona producto y código: los criterios que define el producto se convierten en el gate que el código tiene que pasar. La user story lleva la intención, los criterios de aceptación la hacen comprobable, y el gate los ejecuta.</p>
<p>Lo nuevo en la era de la IA es quién escribe qué. Cuando el código lo escribe un agente, el trabajo del humano sube a la especificación, y el gate tiene que imponerla sobre el diff real, en cada run, porque el agente no es determinista y no has mirado cada línea. No es un dev probando su propio diseño. Es la intención del producto, hecha ejecutable, decidiendo si lo que ha sacado el agente cuenta como hecho.</p>
<h2 id="spec-driven-vs-spec-gated">Spec-driven vs. spec-gated</h2>
<p>Hay una distinción que merece nombre, porque es donde fallan casi todos los equipos. <em>Spec-driven</em> habla del orden: escribes los criterios antes que el código. <em>Spec-gated</em> habla del poder: nada está hecho hasta que pasa los criterios, ejecutados, en cada run.</p>
<p>Un repo lleno de <a href="/es/blog/spec-vs-prd/">PRDs</a> y <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación</a> en Markdown que nadie ejecuta es spec-driven solo de nombre. Los documentos existen. No deciden nada. Lo que ha movido los números en el benchmark no ha sido escribir los criterios, ha sido ponerles un gate: re-ejecutar el código contra ellos en cada cambio, sobre un agente no-determinista que no has mirado.</p>
<p>Así que el nombre más afilado para lo que de verdad funciona en la era de la IA es <strong>spec-gated development</strong>: un cambio no está hecho hasta que pasa la spec, ejecutada, en cada run. Los criterios de aceptación no son documentación. Son el gate.</p>
<figure class="tp-diagram tp-diagram--gate" data-diagram-type="gate" role="img" aria-label="Spec-gated: los criterios de aceptación, ejecutados en cada run, son el gate que decide si un cambio está hecho."><svg viewBox="0 0 760 240" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
  <rect x="40" y="86" width="180" height="66" fill="none" stroke="var(--tp-rule)" stroke-width="1.5"></rect>
  <text x="130" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-ink)">IMPLEMENTACIÓN</text>
  <path d="M 226 119 L 286 119 M 280 113 L 286 119 L 280 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <path d="M 380 60 L 452 119 L 380 178 L 308 119 Z" fill="none" stroke="var(--tp-mostaza)" stroke-width="1.8"></path>
  <text x="380" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-mostaza)">CRITERIOS DE ACEPTACIÓN</text>
  <path d="M 458 119 L 528 119 M 522 113 L 528 119 L 522 125" stroke="var(--tp-mute)" stroke-width="1.5" fill="none"></path>
  <rect x="534" y="86" width="186" height="66" fill="var(--tp-verde)" fill-opacity="0.12" stroke="var(--tp-verde)" stroke-width="1.5"></rect>
  <text x="627" y="125" text-anchor="middle" font-family="var(--tp-mono)" font-size="13" letter-spacing="1.5" fill="var(--tp-verde)">HECHO</text>
  <path d="M 380 184 L 380 214 L 226 214 M 232 208 L 226 214 L 232 220" stroke="var(--tp-terracota)" stroke-width="1.5" fill="none"></path>
  <text x="380" y="232" text-anchor="middle" font-family="var(--tp-mono)" font-size="12" letter-spacing="2" fill="var(--tp-terracota)">NO HECHO</text>
</svg><figcaption>Spec-gated: los criterios de aceptación, ejecutados en cada run, son el gate que decide si un cambio está hecho.</figcaption></figure>
<h2 id="spec-driven-vs-vibe-coding">Spec-driven vs. vibe coding</h2>
<p>El vibe coding es lo contrario: prompt, miras el resultado, mergeas si parece bien. Funciona hasta que no, y en un sistema no-determinista no puedes saber qué tirada te ha tocado sin ejecutarla. El desarrollo guiado por especificaciones cambia el “parece bien” por “se ha ejecutado y ha pasado”.</p>
<h2 id="dónde-compensa">Dónde compensa</h2>
<p>Cuanto más dura y menos trivial es la tarea, más importa: hasta el mejor modelo frontier, en crudo, cuela un fallo real en una feature compleja una de cada tres veces, de forma no-determinista. Escribir los criterios una vez y poner el gate de ejecución es lo que hace el resultado fiable, y permite que un modelo barato iguale a uno caro.</p>
<p>Hacerlo a mano en cada tarea es la parte tediosa, y es lo que <a href="/es/">PaellaDoc</a> automatiza.</p>
<h2 id="para-profundizar">Para profundizar</h2>
<p>El desarrollo guiado por especificaciones es una práctica dentro de un cambio más amplio en <a href="/es/blog/construir-software-con-agentes-de-ia/">cómo se construye software con agentes de IA</a>. Las piezas de abajo bajan un nivel desde esta definición.</p>
<p>Empieza por el artefacto en sí: por qué <a href="/es/blog/spec-como-contrato/">la spec es el contrato</a> entre intención e implementación, y por qué ese contrato debería ser <a href="/es/blog/las-especificaciones-de-software-deberian-ser-portables/">portable entre agentes y editores</a> en vez de quedar atrapado en una sola herramienta. Si la ceremonia se te hace pesada, hay una <a href="/es/blog/spec-driven-ligero/">versión ligera</a> que conserva el contrato y recorta el proceso, y una forma de <a href="/es/blog/specs-repo-existente/">añadir specs a un repo que ya existe</a> sin parar el mundo.</p>
<p>Una spec solo sirve mientras sigue siendo cierta. Ese es el problema del <a href="/es/blog/spec-drift-especificaciones-desactualizadas/">spec drift</a>, la divergencia lenta entre el contrato y el código, y el motivo de las <a href="/es/blog/especificaciones-vivas/">especificaciones vivas</a> que se actualizan a la vez que el sistema. Antes de que el agente construya, el gate más barato es <a href="/es/blog/revision-de-specs/">revisar la spec</a> en vez del diff; y una vez que una herramienta como <a href="https://github.com/github/spec-kit">Spec Kit</a> ha escrito una, la pregunta difícil es <a href="/es/blog/mas-alla-de-spec-kit/">qué necesita el spec-driven a continuación</a>.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<p><strong>¿Es lo mismo que TDD?</strong> No. TDD es un ritmo a nivel de unidad para que un dev diseñe código. El desarrollo guiado por especificaciones es el linaje de BDD / acceptance-test-driven: los criterios de aceptación del producto, expresados de forma ejecutable (el Given/When/Then de Gherkin), deciden si el trabajo está hecho. Otro nivel, otro autor, otro propósito.</p>
<p><strong>¿Te ralentiza?</strong> Escribir criterios cuesta minutos. Mergear una feature verde-pero-rota cuesta horas o días después. En las tareas medidas ha eliminado por completo la tasa de bugs genuinos.</p>
<p><strong>¿Necesito una herramienta?</strong> No. Puedes hacerlo a mano. Una herramienta ayuda cuando quieres los criterios y el gate de ejecución en cada tarea sin tener que acordarte.</p>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    { "@type": "Question", "name": "¿El desarrollo guiado por especificaciones es lo mismo que TDD?", "acceptedAnswer": { "@type": "Answer", "text": "No. TDD es un ritmo a nivel de unidad para que un dev diseñe código. El desarrollo guiado por especificaciones es el linaje de BDD / acceptance-test-driven: los criterios de aceptación del producto, expresados de forma ejecutable (el Given/When/Then de Gherkin), deciden si el trabajo está hecho. Otro nivel, otro autor, otro propósito." } },
    { "@type": "Question", "name": "¿Te ralentiza?", "acceptedAnswer": { "@type": "Answer", "text": "Escribir criterios cuesta minutos. Mergear una feature verde-pero-rota cuesta horas o días después. En las tareas medidas ha eliminado por completo la tasa de bugs genuinos." } },
    { "@type": "Question", "name": "¿Necesito una herramienta?", "acceptedAnswer": { "@type": "Answer", "text": "No. Puedes hacerlo a mano. Una herramienta ayuda cuando quieres los criterios y el gate de ejecución en cada tarea sin tener que acordarte." } }
  ]
}
</script>]]></content>
    <summary type="html"><![CDATA[Una definición corta y práctica del desarrollo guiado por especificaciones: los criterios de aceptación, la definición de hecho del producto, se escriben antes del código, y lo hecho se decide ejecutando el código contra ellos, no con un build en verde. Su linaje BDD, por qué no es TDD, y el impacto medido.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="paelladoc"/><category term="spec-driven-development"/><category term="ai-coding"/><category term="verification"/><category term="spec-gated-development"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/spec-driven-green-build-hero.png" />
  </entry>

  <entry>
    <title type="html">Localmente correcto, globalmente incoherente: el problema del código generado por IA</title>
    <link href="https://paelladoc.com/es/blog/localmente-correcto-globalmente-incoherente/" rel="alternate" type="text/html" title="Localmente correcto, globalmente incoherente: el problema del código generado por IA"/>
    <published>2026-06-07T00:00:00+02:00</published>
    <updated>2026-06-07T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/localmente-correcto-globalmente-incoherente/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/localmente-correcto-globalmente-incoherente/"><![CDATA[<p>Hay una lectura del desarrollo con IA que se ha vuelto consenso, y es fatalista: la IA no sabe de arquitectura, no «siente» el software, no toma decisiones a largo plazo. Y ahí se queda, como si fuera un límite intrínseco del modelo, algo que el tiempo y los parámetros acabarán resolviendo. O no.</p>
<p>Esa lectura confunde el síntoma con la causa.</p>
<h2 id="el-modelo-optimiza-el-siguiente-paso-porque-es-lo-único-que-le-pasamos">El modelo optimiza el siguiente paso porque es lo único que le pasamos</h2>
<p>Un modelo optimiza el siguiente paso porque el siguiente paso es lo único que le damos. La arquitectura es exactamente lo contrario: decidir hoy en función de restricciones que aún no existen, del coste de mantener algo durante años, de la coherencia conceptual de un sistema que todavía no está escrito del todo. Es razonamiento sobre el futuro. Y el futuro casi nunca viaja dentro del contexto que le damos a la máquina.</p>
<p>Cada sesión empieza en blanco. Las decisiones que tomaste ayer, por qué esta capa existe, qué invariante protege este módulo, qué se intentó y se descartó, viven en tu cabeza, no en el material que el modelo ve cuando vuelve a tocar el código. Le pedimos un paso local, sin el plano del edificio, y nos sorprende que el resultado sea localmente correcto.</p>
<p>Es que es literalmente lo que pedimos.</p>
<h2 id="la-incoherencia-no-está-dentro-del-modelo">La incoherencia no está dentro del modelo</h2>
<p>La incoherencia global no emerge de que el modelo sea tonto. Emerge de que nadie está gestionando lo que el modelo ve cada vez que decide. El problema no está dentro del modelo. Está en la capa que falta entre nuestras intenciones y su contexto.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/coherence-missing-layer-es_480.avif 480w, /assets/images/coherence-missing-layer-es_768.avif 768w, /assets/images/coherence-missing-layer-es_1024.avif 1024w, /assets/images/coherence-missing-layer-es_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/coherence-missing-layer-es_480.webp 480w, /assets/images/coherence-missing-layer-es_768.webp 768w, /assets/images/coherence-missing-layer-es_1024.webp 1024w, /assets/images/coherence-missing-layer-es_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/coherence-missing-layer-es_480.png" srcset="/assets/images/coherence-missing-layer-es_480.png 480w, /assets/images/coherence-missing-layer-es_768.png 768w, /assets/images/coherence-missing-layer-es_1024.png 1024w, /assets/images/coherence-missing-layer-es_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Sin la capa, una intención se convierte en pasos locales y código localmente correcto pero globalmente incoherente. Con la capa, la arquitectura, la spec y la definición de correcto viajan con cada cambio y se verifican." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>La coherencia nunca ha sido una propiedad de la inteligencia. Piénsalo. Seguro que conoces personas brillantes y poco coherentes: el genio que no termina nada, el founder brillante que pivota cada lunes. Localmente correcto, globalmente incoherente.</p>
<p>Es una propiedad del proceso. No consigues un sistema coherente esperando que el modelo sienta la arquitectura. Lo consigues haciendo que la decisión arquitectónica, la especificación y la definición de qué significa correcto viajen con cada cambio, y <a href="/es/blog/verificar-codigo-generado-por-ia/">verificando cada paso contra eso</a>. La coherencia se impone, no se invoca.</p>
<h2 id="el-incentivo-de-la-industria-apunta-a-más-no-a-mejor">El incentivo de la industria apunta a más, no a mejor</h2>
<p>Conviene nombrar el sesgo. La IA en la nube monetiza volumen, no elegancia. Nadie factura por borrar 20.000 líneas innecesarias, eso sigue siendo un oficio casi artesanal, pero hay toda una industria facturando por generarlas. El incentivo entero apunta a más generación, más iteración, más tokens, más consumo. El vibe coding no es popular porque funcione mejor, es popular porque está perfectamente alineado con quién cobra.</p>
<p>Conviene no olvidarlo cuando alguien te vende que la arquitectura ya la pone la máquina.</p>
<h2 id="junior-contra-senior-es-un-multiplicador-de-herramienta-no-de-persona">Junior contra senior es un multiplicador de herramienta, no de persona</h2>
<p>El junior produce más ruido cuando las restricciones no viven en el sistema, cuando nada le obliga a respetar las decisiones que ya se han tomado. El senior produce más valor porque lleva esas restricciones en la cabeza y las aplica sin pensar. Pero esa diferencia es justo lo que se puede externalizar en parte: cuando pones la arquitectura como un artefacto de primera clase, y te aseguro que se puede, de repente el junior, o el agente, también produce coherencia.</p>
<p>No por talento. Por andamiaje.</p>
<p>Hay una parte, eso sí, que no se externaliza: el software se siente. Quien ha hecho motores o gameplay durante años sabe que hay decisiones que no salen de la lógica verbal de un prompt, sino de la intuición acumulada tras miles de horas viendo sistemas fallar. La intuición es experiencia comprimida. Una parte de esa compresión se puede convertir en reglas explícitas, en restricciones, en criterios. Otra parte no, y por eso el humano sigue en el centro del bucle.</p>
<p>Negarlo es el error del vendehumos. Pero rendirse y decir que como no se puede capturar todo entonces no se puede capturar nada, es el error contrario, y es igual de equivocado.</p>
<h2 id="lo-que-de-verdad-preocupa">Lo que de verdad preocupa</h2>
<p>Lo que preocupa no es que la IA escriba código. Es que cada vez menos gente aprende a entender sistemas complejos. Cuando estos proyectos (funciones que existen y nadie sabe por qué, abstracciones que nadie se atreve a tocar) necesiten mantenimiento serio, hará falta gente capaz de leer código, detectar coherencia, simplificar y decidir. Y esos perfiles se forman cada vez menos, porque todo el mundo está aprendiendo a hacer prompts en lugar de a entender sistemas.</p>
<p>La respuesta no es prohibir la IA. Tampoco es rezar para que aparezca alguien capaz de leerse las 100.000 líneas. Es hacer el sistema legible por diseño: que <a href="/es/blog/desarrollo-basado-en-evidencia/">cada decisión deje evidencia</a>, que cada criterio sea verificable, que entender deje de depender de una rara avis y pase a estar forzado por el propio proceso de construir.</p>
<h2 id="la-capa-que-falta">La capa que falta</h2>
<p>Llevo más de un año construyendo justo esa capa: <a href="/es/">PaellaDoc</a>. Obligar a que el plano viaje con cada cambio, y que <a href="/es/blog/hecho-significa-hecho/">nada llegue a «hecho»</a> sin demostrarlo contra los criterios que se han fijado antes de escribir una línea. Ese es el salto de spec-driven a spec-gated: la especificación no es un documento que se pudre en el repo, es el gate que decide.</p>
<p>No es una afirmación de fe. Cuando lo mides, <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>: hasta el mejor modelo, en crudo, cuela un fallo real una de cada tres veces en lo no trivial, y de forma no-determinista. La spec por delante y el gate de ejecución lo cierran. Y un nivel por encima, <a href="/es/blog/hacer-producto-no-es-productizar/">hacer producto es instalar un comportamiento</a>, no acumular superficie: la misma idea, que la coherencia se impone, aplicada a qué construir en vez de a cómo construirlo.</p>
<p>El humano sigue en el centro. Lo que cambia es que deja de sostener la coherencia con la memoria y empieza a imponerla con el proceso.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-significa-localmente-correcto-globalmente-incoherente">¿Qué significa «localmente correcto, globalmente incoherente»?</h3>
<p>Describe código donde cada cambio individual es correcto en sus propios términos pero el sistema entero deja de tener sentido. Cada función hace lo que se le pidió, y sin embargo las piezas se contradicen en sus asunciones, duplican conceptos y derivan de la arquitectura. El modelo optimizó el siguiente paso, que es justo lo que le pasaste, así que produjo un paso localmente correcto sin visión del conjunto al que pertenece.</p>
<h3 id="por-qué-la-ia-escribe-código-que-no-encaja-con-el-resto-del-sistema">¿Por qué la IA escribe código que no encaja con el resto del sistema?</h3>
<p>Porque el resto del sistema casi nunca viaja dentro de su contexto. Cada sesión empieza en blanco. Las decisiones que tomaste ayer, por qué existe una capa, qué invariante protege un módulo, viven en tu cabeza, no en el material que el modelo ve cuando vuelve a tocar el código. Le pides un paso local sin el plano del edificio, y obtienes un paso localmente correcto. Es literalmente lo que pediste.</p>
<h3 id="un-modelo-más-grande-o-más-listo-arregla-el-código-incoherente-de-la-ia">¿Un modelo más grande o más listo arregla el código incoherente de la IA?</h3>
<p>No, porque la incoherencia no está dentro del modelo. La coherencia nunca ha sido una propiedad de la inteligencia, existen personas brillantes e incoherentes. Es una propiedad del proceso. Consigues un sistema coherente haciendo que la arquitectura, la especificación y la definición de correcto viajen con cada cambio y verificando cada paso contra ellas. Más parámetros no aportan la capa que falta entre tus intenciones y el contexto del modelo.</p>
<h3 id="cómo-se-consigue-código-coherente-de-los-agentes-de-ia">¿Cómo se consigue código coherente de los agentes de IA?</h3>
<p>La coherencia se impone, no se invoca. Convierte la decisión arquitectónica, la spec y la definición de «correcto» en artefactos de primera clase que viajan con cada cambio, y pon un gate a cada cambio contra ellos para que nada llegue a «hecho» sin demostrarlo. Es el salto de spec-driven a spec-gated: la especificación no es un documento que se pudre en el repo, es el gate que decide. Es el andamiaje, no el talento, lo que hace que hasta un junior o un agente produzcan coherencia.</p>]]></content>
    <summary type="html"><![CDATA[La lectura habitual del desarrollo con IA es fatalista: la IA no sabe de arquitectura, no siente el software. Esa lectura confunde el síntoma con la causa. La incoherencia no emerge de que el modelo sea tonto, sino de que nadie gestiona lo que ve cada vez que decide. La coherencia nunca ha sido una propiedad de la inteligencia. Es del proceso, y el proceso se puede construir.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="paelladoc"/><category term="ai-coding"/><category term="software-architecture"/><category term="context-engineering"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/coherence-hero-es.png" />
  </entry>

  <entry>
    <title type="html">Hacer producto no es productizar: cómo salir de la feature factory</title>
    <link href="https://paelladoc.com/es/blog/hacer-producto-no-es-productizar/" rel="alternate" type="text/html" title="Hacer producto no es productizar: cómo salir de la feature factory"/>
    <published>2026-06-07T00:00:00+02:00</published>
    <updated>2026-06-07T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/hacer-producto-no-es-productizar/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/hacer-producto-no-es-productizar/"><![CDATA[<p>El producto de software con más éxito de la historia de las finanzas es feo, parece de los años 80 y cuesta cerca de 32.000 dólares al año por usuario. La mayoría de quienes lo pagan usan una fracción mínima de sus miles de funciones. Por cualquier métrica de “features”, el terminal de Bloomberg debería haber sido desbancado hace décadas.</p>
<p>No lo ha sido. Genera más de 12.000 millones de dólares al año, casi todos en suscripciones. Y la pregunta interesante no es por qué es tan caro, sino por qué nadie lo abandona.</p>
<h2 id="bloomberg-no-vende-funciones-ha-instalado-un-comportamiento">Bloomberg no vende funciones, ha instalado un comportamiento</h2>
<p>Un trader organiza su jornada entera alrededor de esa pantalla negra y ámbar: el teclado, los atajos, el flujo de trabajo. Su chat interno, Instant Bloomberg, conecta a unos 325.000 profesionales. Si tu contraparte está ahí, tú tienes que estar ahí. Salir del Terminal no es cambiar de herramienta, es cambiar de vida profesional. El coste de irse no es económico, es psicológico.</p>
<p>Eso es hacer producto: instalar un comportamiento nuevo en alguien. Que mañana haga algo distinto a lo que hacía ayer, decida distinto, trabaje distinto, porque tu producto se lo hace más fácil, más obvio o más inevitable. Si nadie cambia nada, no has hecho producto digital. Has hecho software, que no es lo mismo ni se le parece.</p>
<p>He leído hace poco que los PMs no valen para nada. Quien dice eso no ha hecho producto en su vida, y confunde hacer producto con productizar, que es el hermano tonto y fácil de hacer producto.</p>
<h2 id="productizar-superficie-sin-nada-debajo">Productizar: superficie sin nada debajo</h2>
<p>Productizar es lo contrario: añadir superficie sin instalar nada debajo. Una integración porque la competencia la tiene. Una alerta porque un cliente grande la ha pedido. Una vista nueva porque alguien ha dicho en una reunión “estaría bien tenerla”. Cada cosa tiene su lógica individual. Ninguna tiene un comportamiento objetivo detrás. <a href="/es/blog/localmente-correcto-globalmente-incoherente/">Localmente correcto, globalmente incoherente</a>, y esto no es solo cosa de la IA.</p>
<p>La diferencia existe y se ha medido.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/product-feature-usage-es_480.avif 480w, /assets/images/product-feature-usage-es_768.avif 768w, /assets/images/product-feature-usage-es_1024.avif 1024w, /assets/images/product-feature-usage-es_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/product-feature-usage-es_480.webp 480w, /assets/images/product-feature-usage-es_768.webp 768w, /assets/images/product-feature-usage-es_1024.webp 1024w, /assets/images/product-feature-usage-es_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/product-feature-usage-es_480.png" srcset="/assets/images/product-feature-usage-es_480.png 480w, /assets/images/product-feature-usage-es_768.png 768w, /assets/images/product-feature-usage-es_1024.png 1024w, /assets/images/product-feature-usage-es_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="El 80% de las funciones de un software medio se usan rara vez o nunca, y solo el 12% genera el 80% del uso diario." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Pendo analizó el uso real de producto en cientos de empresas y concluyó que el 80% de las funciones de un software medio se usan rara vez o nunca. Apenas un 12% genera el 80% del uso diario. Su estimación: unos 29.500 millones de dólares de I+D en la nube gastados en features que casi nadie toca. El clásico informe Chaos del Standish Group daba una cifra parecida: en torno al 64% de las funcionalidades se usan rara vez o nunca. Las metodologías de ambos estudios son discutibles, conviene saberlo, pero la dirección es la misma midas como midas.</p>
<p>Eso es lo que produce productizar a escala: superficie que existe sin cambiar nada, cada vez más equipo para mantener algo que no aporta a la cuenta de resultados. Bueno, sí aporta: a la baja.</p>
<h2 id="la-feature-factory">La feature factory</h2>
<p>¿Por qué casi todas las organizaciones acaban ahí? John Cutler lo bautizó como <a href="/es/blog/que-es-una-feature-factory/"><em>feature factory</em></a>: empresas que miden su éxito por cuánto entregan (features lanzadas, story points cerrados) en lugar de por qué cambia en el usuario.</p>
<p>Lo gracioso es que suelen ser productivas en el sentido convencional: envían rápido, mantienen velocidad alta, exhiben un historial visible de trabajo terminado. Han optimizado la actividad de construir, no el resultado de construir. Y caen ahí sin proponérselo, porque productizar genera señales de progreso inmediatas (releases, demos, changelogs, reuniones donde enseñar algo nuevo) mientras que cambiar comportamiento es invisible durante meses. Casi ninguna organización premia lo invisible. Premia la actividad. Y productizar es actividad.</p>
<h2 id="el-botón-con-la-estrellita">El botón con la estrellita</h2>
<p>El ejemplo de manual lo tenemos delante. En 2024 y 2025, medio sector del software metió un “copiloto” de IA en la esquina de la pantalla, un botón con una estrellita. ¿Por qué? Porque el inversor y el mercado lo esperaban.</p>
<p>El resultado fue el previsible cuando añades superficie sin mapa de comportamiento. Hubo CRMs que vieron caer la adopción alrededor de un 20% tras lanzamientos de IA apresurados que complicaron la experiencia, y una mayoría de pilotos de IA empresariales terminó sin impacto medible en la cuenta de resultados. El botón se metió para existir, no para cambiar lo que hace el usuario. Y una función de IA que no cambia el flujo de trabajo es, exactamente, una función más que nadie usa.</p>
<h2 id="2026-la-ia-pone-a-prueba-a-bloomberg">2026: la IA pone a prueba a Bloomberg</h2>
<p>Aquí se pone interesante. Esa misma IA ha empezado a poner a prueba a Bloomberg. Perplexity ha lanzado un producto que aspira a replicar parte del flujo del Terminal por unos 200 dólares al mes frente a los casi 32.000 al año. Según un sondeo del sector, alrededor de un tercio de los hedge funds y gestoras planean reducir o eliminar terminales en los siguientes 18 meses.</p>
<p>Y esto es lo importante para cualquiera que construya producto: cuando el coste de cambiar se desploma, descubres si habías instalado un comportamiento genuino (algo que el usuario no abandonaría aunque irse fuera gratis) o si solo vivías de la fricción y la inercia de la suscripción. La IA está a punto de hacer dos cosas a la vez: volver barata de copiar cualquier feature, y barato de cruzar cualquier coste de cambio. Lo único que sobrevive a las dos es haber cambiado de verdad lo que alguien hace.</p>
<h2 id="el-único-test-que-merece-la-pena">El único test que merece la pena</h2>
<p>De ahí sale el único test que merece la pena aplicar antes de meter algo en un roadmap. Completa esta frase antes de escribir una sola línea de especificación:</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/product-xyz-test-es_480.avif 480w, /assets/images/product-xyz-test-es_768.avif 768w, /assets/images/product-xyz-test-es_1024.avif 1024w, /assets/images/product-xyz-test-es_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/product-xyz-test-es_480.webp 480w, /assets/images/product-xyz-test-es_768.webp 768w, /assets/images/product-xyz-test-es_1024.webp 1024w, /assets/images/product-xyz-test-es_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/product-xyz-test-es_480.png" srcset="/assets/images/product-xyz-test-es_480.png 480w, /assets/images/product-xyz-test-es_768.png 768w, /assets/images/product-xyz-test-es_1024.png 1024w, /assets/images/product-xyz-test-es_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="El test: gracias a esto, tal usuario pasará de hacer X a hacer Y, y lo sabremos cuando veamos la métrica Z." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<blockquote>
<p>Gracias a esto, [tipo de usuario] pasará de hacer [X] a hacer [Y], y lo sabremos cuando veamos [métrica Z].</p>
</blockquote>
<p>Si no puedes completarla, todavía no tienes una idea de producto. Tienes una idea de feature. No es lo mismo, y la diferencia compone con el tiempo: instalar comportamiento crea ventaja acumulada (el usuario vuelve porque ha reorganizado su vida alrededor de ese hábito), acumular features crea deuda de atención (más opciones, ninguna razón más fuerte para quedarse).</p>
<p>No quiero decir que productizar sea malo. A veces es lo correcto: alcanzar paridad competitiva, no perder un cliente que amenaza con irse, ganar tiempo. El problema no es hacerlo. Es hacerlo en modo automático, sin saberlo, hasta llevar dos años sin poder responder a una pregunta sencilla: <a href="/es/blog/de-insight-a-resultado/">¿qué comportamiento nuevo instalamos este trimestre?</a></p>
<p>Esa es, al final, la única pregunta que separa a los dos tipos de equipo. Y en la <a href="/es/blog/product-management-era-ia/">década que viene, cuando copiar una feature cueste una tarde</a> y cruzar un coste de cambio cueste una suscripción de 200 dólares al mes, va a ser la única que importe.</p>
<p>Ese test, “de X a Y, lo sabremos con Z”, es el padre de los criterios de aceptación. Primero decides qué comportamiento instalas. Luego viene la disciplina de ingeniería de asegurarte de que el código de verdad lo entrega, porque <a href="/es/blog/desarrollo-guiado-por-especificaciones-build-verde/">un build en verde no es una feature correcta</a>. Esa segunda parte es la que <a href="/es/">PaellaDoc</a> automatiza. Pero la primera la decides tú, y si te cuesta responder a la pregunta, ya tienes la respuesta.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cuál-es-la-diferencia-entre-hacer-producto-y-productizar">¿Cuál es la diferencia entre hacer producto y productizar?</h3>
<p>Hacer producto es instalar un comportamiento nuevo: que mañana el usuario haga algo distinto porque tu producto se lo hace más fácil o más inevitable. Productizar es añadir superficie sin nada debajo, una integración porque la competencia la tiene, una vista porque alguien la pidió, cada una con su lógica y ningún comportamiento objetivo detrás. Una crea ventaja acumulada; la otra, deuda de atención.</p>
<h3 id="qué-significa-instalar-un-comportamiento-en-el-usuario">¿Qué significa instalar un comportamiento en el usuario?</h3>
<p>Significa que el usuario reorganiza parte de su trabajo o su vida alrededor de tu producto y no lo abandonaría aunque irse fuera gratis. Bloomberg es el ejemplo: un trader organiza su jornada entera alrededor del terminal, y su chat conecta a cientos de miles de profesionales, así que salir es cambiar de vida profesional, no de herramienta. Si nadie cambia lo que hace, hiciste software, no producto.</p>
<h3 id="cómo-sé-si-tengo-una-idea-de-producto-o-solo-de-feature">¿Cómo sé si tengo una idea de producto o solo de feature?</h3>
<p>Completa una frase antes de escribir ninguna spec: «Gracias a esto, [tipo de usuario] pasará de hacer [X] a hacer [Y], y lo sabremos cuando veamos [métrica Z]». Si puedes rellenarla, tienes una idea de producto con un comportamiento objetivo y una señal. Si no puedes, tienes una idea de feature, superficie sin comportamiento detrás.</p>
<h3 id="por-qué-el-comportamiento-instalado-importa-más-en-la-era-de-la-ia">¿Por qué el comportamiento instalado importa más en la era de la IA?</h3>
<p>Porque la IA hace dos cosas a la vez: vuelve barata de copiar cualquier feature y barato de cruzar cualquier coste de cambio. Cuando ambos se desploman, descubres si instalaste un comportamiento genuino que el usuario mantendría aunque irse fuera gratis, o si vivías de la fricción y la inercia de la suscripción. Lo único que sobrevive a las dos es haber cambiado de verdad lo que alguien hace.</p>]]></content>
    <summary type="html"><![CDATA[El producto de software más exitoso de las finanzas es feo, parece de los 80 y cuesta 32.000 dólares al año por usuario. Nadie lo abandona. Bloomberg no vende funciones, ha instalado un comportamiento. Esa es la diferencia entre hacer producto y productizar, y por qué en la era de la IA va a ser lo único que importe.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="product"/><category term="paelladoc"/><category term="product-management"/><category term="product-strategy"/><category term="feature-factory"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/product-behavior-hero.jpeg" />
  </entry>

  <entry>
    <title type="html">Desarrollo guiado por especificaciones: un build en verde no es una feature correcta</title>
    <link href="https://paelladoc.com/es/blog/desarrollo-guiado-por-especificaciones-build-verde/" rel="alternate" type="text/html" title="Desarrollo guiado por especificaciones: un build en verde no es una feature correcta"/>
    <published>2026-06-07T00:00:00+02:00</published>
    <updated>2026-06-07T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/desarrollo-guiado-por-especificaciones-build-verde/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/desarrollo-guiado-por-especificaciones-build-verde/"><![CDATA[<p>Un agente de código termina una tarea. Tests en verde, build limpio, diff ordenado. Haces merge. La pregunta nunca ha sido si el modelo es lo bastante listo. Es si puedes fiarte de que <em>esta</em> ejecución, la que tienes delante, es correcta, sin ejecutarla tú.</p>
<p>Lo he medido. La respuesta es no, no a ojo.</p>
<h2 id="el-montaje">El montaje</h2>
<p>He cogido una app real de Next.js y TypeScript, la he congelado en un commit y he escrito cinco features pequeñas. Cada una es una petición de una línea más cinco criterios de aceptación. Le he pasado la petición a cuatro agentes de código (Claude Sonnet, Claude Haiku, Codex y Kimi), corrí cada combinación tres veces, y puntué el resultado ejecutando el código, no leyendo el diff.</p>
<p>La puntuación la hace un gate aparte. Reaplica cada diff sobre una copia limpia del repo, ejecuta el código y comprueba cada criterio. El agente nunca se corrige a sí mismo. Que el build esté en verde no cuenta para nada.</p>
<h2 id="un-build-en-verde-no-prueba-que-sea-correcto">Un build en verde no prueba que sea correcto</h2>
<p>En algún momento hemos dado por bueno que “compila y los tests pasan” significa <a href="/es/blog/definicion-de-hecho/">terminado</a>. No es así. El agente ha escrito el código y, de la misma tirada, ha escrito los tests a su alrededor. Verde significa que el código está de acuerdo consigo mismo. No dice nada de si coincide con lo que querías.</p>
<p>Con solo la petición de una línea, el 40% de las ejecuciones han colado un fallo de corrección real. Build en verde, tests pasando, y aun así mal.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/spec-driven-bug-rate-by-model_480.avif 480w, /assets/images/spec-driven-bug-rate-by-model_768.avif 768w, /assets/images/spec-driven-bug-rate-by-model_1024.avif 1024w, /assets/images/spec-driven-bug-rate-by-model_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/spec-driven-bug-rate-by-model_480.webp 480w, /assets/images/spec-driven-bug-rate-by-model_768.webp 768w, /assets/images/spec-driven-bug-rate-by-model_1024.webp 1024w, /assets/images/spec-driven-bug-rate-by-model_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/spec-driven-bug-rate-by-model_480.png" srcset="/assets/images/spec-driven-bug-rate-by-model_480.png 480w, /assets/images/spec-driven-bug-rate-by-model_768.png 768w, /assets/images/spec-driven-bug-rate-by-model_1024.png 1024w, /assets/images/spec-driven-bug-rate-by-model_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Gráfico de barras del porcentaje de fallos de corrección reales por modelo, petición en crudo frente a la misma petición con los criterios de aceptación por delante. Claude Sonnet 33% a 0, Haiku 53% a 0, Codex 33% a 0, Kimi 40% a 0." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<h2 id="una-ejecución-buena-no-prueba-nada">Una ejecución buena no prueba nada</h2>
<p>Aquí está la parte que debería cambiarte la forma de trabajar. El mismo modelo, con el mismo prompt, alterna. Corre una tarea tres veces y sacas correcto, correcto, roto. En el benchmark, el 15% de las celdas se contradecían a sí mismas entre ejecuciones, y todas las inestables estaban en la rama cruda.</p>
<p>Los LLM no son deterministas, ni a temperatura 0. El orden en coma flotante y el batching del proveedor se encargan de eso. Así que “ha funcionado cuando lo he probado” es una sola tirada de una distribución que no ves. La ejecución que miraste y la que mergeaste no son la misma.</p>
<p>Por eso un modelo mejor no te salva. Un modelo más fuerte falla menos veces y de forma más <em>plausible</em>, lo que hace los fallos más difíciles de pillar, no más fáciles. El gate es lo que convierte una tirada con suerte en una garantía: ejecuta cada diff contra los criterios, cada vez, y cambia el “parece hecho” por “se ha ejecutado y ha pasado”.</p>
<h2 id="qué-cierra-el-hueco">Qué cierra el hueco</h2>
<p>El <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a> es una idea pequeña, y vieja con un trabajo nuevo. Es el linaje de BDD: los <a href="/es/blog/criterios-aceptacion-agentes/">criterios de aceptación</a> del producto para una user story, escritos de forma ejecutable (piensa en el Given/When/Then de Gherkin) antes de que el agente empiece, y verificados ejecutando cuando termina. No son tests unitarios del dev. Es la definición de “hecho” del producto, convertida en el gate.</p>
<p>He corrido cada tarea de dos formas. Mismo modelo, mismo repo, mismo esfuerzo. Una diferencia: la rama cruda recibe la petición de una línea, la rama spec recibe esa misma petición más los cinco criterios como checklist. Agregando los cuatro modelos, en crudo ha colado un fallo real en el 40% de las ejecuciones. Con los criterios por delante, 0%. Los intervalos de confianza al 95% ni se solapan.</p>
<p>Y entonces el resultado que no esperaba.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/spec-driven-cheap-vs-frontier_480.avif 480w, /assets/images/spec-driven-cheap-vs-frontier_768.avif 768w, /assets/images/spec-driven-cheap-vs-frontier_1024.avif 1024w, /assets/images/spec-driven-cheap-vs-frontier_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/spec-driven-cheap-vs-frontier_480.webp 480w, /assets/images/spec-driven-cheap-vs-frontier_768.webp 768w, /assets/images/spec-driven-cheap-vs-frontier_1024.webp 1024w, /assets/images/spec-driven-cheap-vs-frontier_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/spec-driven-cheap-vs-frontier_480.png" srcset="/assets/images/spec-driven-cheap-vs-frontier_480.png 480w, /assets/images/spec-driven-cheap-vs-frontier_768.png 768w, /assets/images/spec-driven-cheap-vs-frontier_1024.png 1024w, /assets/images/spec-driven-cheap-vs-frontier_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Gráfico de barras del porcentaje de ejecuciones que pasan los cinco criterios. Haiku 40% y Claude Sonnet 40% sin spec, los dos al 100% con los criterios de aceptación. Un modelo barato con spec iguala al modelo puntero sin spec." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Haiku es un modelo barato. Con los criterios de aceptación, llega al 100%, a la altura del puntero. El barato con spec le ha ganado al puntero sin ella. En este benchmark, la spec ha movido más la aguja que el modelo. Es la misma lección que hay detrás de <a href="/es/blog/la-peligrosa-ilusion-de-la-productividad-con-ia-y-como-lograr-ganancias-reales/">la peligrosa ilusión de la productividad con IA</a>: la velocidad es real, la palanca está en la estructura que la rodea.</p>
<h2 id="pero-el-modelo-no-es-adivino">”Pero el modelo no es adivino”</h2>
<p>Justo. Si falla un nombre de parámetro que nunca le diste, eso es cosa tuya, no un bug. Por eso cada criterio está etiquetado <em>genuine</em> o <em>contract</em> antes de cualquier ejecución, y el titular cuenta solo los genuine: peta con input vacío, caso base mal, rompe comportamiento existente, lo que un dev competente hace sin que se lo digan.</p>
<p>La versión profunda de esa objeción es la tesis, no un contraargumento. Sí, tienes que decirle al agente qué quieres, y comprobar que lo hizo. Eso es desarrollo guiado por especificaciones. Lo sorprendente no es que haya que especificar. Es cuánta gente no lo hace, y mergea código verde-pero-roto creyendo que está hecho.</p>
<h2 id="hasta-el-modelo-más-fuerte-es-una-sola-tirada">Hasta el modelo más fuerte es una sola tirada</h2>
<p>Así que he corrido las configs que nombraría un escéptico: Claude Opus 4.8 a esfuerzo high y max, y Codex 5.5 a razonamiento xhigh. Añadidas tras las primeras 120 como extensión etiquetada, mismo protocolo, mismo gate.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/spec-driven-frontier-extension_480.avif 480w, /assets/images/spec-driven-frontier-extension_768.avif 768w, /assets/images/spec-driven-frontier-extension_1024.avif 1024w, /assets/images/spec-driven-frontier-extension_1600.avif 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/spec-driven-frontier-extension_480.webp 480w, /assets/images/spec-driven-frontier-extension_768.webp 768w, /assets/images/spec-driven-frontier-extension_1024.webp 1024w, /assets/images/spec-driven-frontier-extension_1600.webp 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/spec-driven-frontier-extension_480.png" srcset="/assets/images/spec-driven-frontier-extension_480.png 480w, /assets/images/spec-driven-frontier-extension_768.png 768w, /assets/images/spec-driven-frontier-extension_1024.png 1024w, /assets/images/spec-driven-frontier-extension_1600.png 1600w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Gráfico de barras del porcentaje de bugs genuinos de las configs frontier, en crudo frente a con los criterios. Opus 4.8 xhigh 13% a 0, Opus 4.8 max 13% a 0, Codex 5.5 xhigh 33% a 0." width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Opus 4.8 a esfuerzo máximo, la config más fuerte aquí, aun así ha colado un bug genuino en el 13% de las ejecuciones en crudo, y ha sacado una feature totalmente correcta solo el 67% de las veces. En la feature dura, ella sola, ha fallado 2 de 3 ejecuciones en crudo. Las dos configs de Opus han fallado incluso en ejecuciones <em>distintas</em> de esa feature, una haciendo bug, ok, bug y la otra bug, bug, ok: mismo modelo, mismo prompt, una respuesta distinta cada vez. Codex 5.5 a xhigh se ha quedado en el 33% en crudo, lo mismo que la columna de Codex en los cuatro originales. Con los criterios por delante, todas han pasado a 0% de bugs genuinos y 100% correcto.</p>
<p>El punto no es un ranking. Cuanto mejor el modelo, más baja la tasa de fallo en crudo, pero ninguno llega a cero, los fallos se concentran en lo que de verdad es difícil, y alternan entre ejecuciones. Hasta la config más fuerte es una sola tirada que no puedes leer sin ejecutarla. El gate es lo que hace que cualquiera sea seguro de mergear.</p>
<h2 id="intenta-romperlo">Intenta romperlo</h2>
<p>El <a href="https://github.com/jlcases/paelladoc-verification-benchmark">repo</a> tiene el protocolo (escrito antes de las ejecuciones), las features, los prompts, el gate de ejecución y todos los diffs con sus veredictos. Puedes volver a puntuar cada ejecución sin pagar ni una llamada a un agente. Si encuentras por dónde se rompe el método, el <a href="https://forum.paelladoc.com/t/a-green-build-is-not-a-correct-feature-i-measured-the-gap/85">hilo del foro</a> está abierto y te respondo.</p>
<h2 id="dónde-te-deja-esto">Dónde te deja esto</h2>
<p>Esto nunca ha sido un test de IQ de modelos. Es una medida de confianza. Los modelos fuertes son buenos. Pero “bueno” y “verificado” son dos cosas distintas, y en un sistema no-determinista solo la segunda se mergea segura.</p>
<p>Escribe los criterios, y luego pon un gate sobre ejecutarlos. No spec-driven, donde los criterios viven en un documento, sino spec-gated, donde mandan, de modo que la <a href="/es/blog/spec-como-contrato/">spec se vuelve el contrato</a> contra el que se comprueba cada merge. Pasan dos cosas: puedes fiarte del resultado, y un modelo barato también llega. Hacer eso a mano en cada tarea es lo que nadie mantiene. Eso es lo que <a href="/es/">PaellaDoc</a> automatiza: convierte tu intención en criterios y mete el gate de ejecución. El principio aguanta sin la herramienta, y por eso no hay ningún producto dentro del benchmark. El modelo que pagas importa menos que el gate que no tienes.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="un-build-en-verde-significa-que-la-feature-generada-por-ia-es-correcta">¿Un build en verde significa que la feature generada por IA es correcta?</h3>
<p>No. El agente escribió el código y, de la misma tirada, escribió los tests a su alrededor, así que verde significa que el código está de acuerdo consigo mismo, no que coincida con lo que querías. En 120 ejecuciones de este benchmark, con solo la petición de una línea, el 40% coló un fallo de corrección real con el build en verde y los tests pasando. Compilar y ser correcto son dos afirmaciones distintas, y un build en verde solo comprueba la primera.</p>
<h3 id="por-qué-el-mismo-modelo-pasa-una-tarea-en-una-ejecución-y-falla-en-la-siguiente">¿Por qué el mismo modelo pasa una tarea en una ejecución y falla en la siguiente?</h3>
<p>Porque los LLM no son deterministas, ni a temperatura 0; el orden en coma flotante y el batching del proveedor se encargan. Corre una tarea tres veces y puedes sacar correcto, correcto, roto. En este benchmark el 15% de las celdas se contradecían entre ejecuciones. Así que «ha funcionado cuando lo he probado» es una sola tirada de una distribución que no ves, y la ejecución que miraste no es la que mergeaste.</p>
<h3 id="usar-un-modelo-más-capaz-arregla-el-código-verde-pero-roto">¿Usar un modelo más capaz arregla el código verde-pero-roto?</h3>
<p>No por sí solo. Un modelo más fuerte falla menos veces pero de forma más plausible, lo que hace los fallos más difíciles de pillar, no más fáciles. Hasta la config más fuerte medida coló un fallo genuino en una parte de las ejecuciones en crudo y alternó entre ejecuciones en la feature dura. Ninguno llegó a cero sin un gate. Lo que llevó a todos los modelos a 0% de bugs genuinos fue escribir los criterios de aceptación por delante y comprobarlos ejecutando.</p>
<h3 id="cómo-hace-fiable-el-código-de-ia-el-desarrollo-guiado-por-especificaciones">¿Cómo hace fiable el código de IA el desarrollo guiado por especificaciones?</h3>
<p>Convirtiendo los criterios de aceptación del producto en un gate de ejecución. Escribes qué significa «hecho» antes de que el agente empiece, idealmente de forma ejecutable, y luego lo verificas ejecutando el código cuando termina, cada vez. En este benchmark la rama cruda coló un fallo en el 40% de las ejecuciones y la de criterios por delante en el 0%, y un modelo barato con spec igualó a uno puntero sin ella. No spec-driven, donde los criterios viven en un documento, sino spec-gated, donde mandan.</p>]]></content>
    <summary type="html"><![CDATA[Un agente de código dice que la tarea está hecha, el build en verde, los tests pasan. La pregunta nunca ha sido si el modelo es lo bastante listo. Es si puedes fiarte de que esta ejecución es correcta sin ejecutarla tú. Lo medí con cuatro modelos y 120 ejecuciones: un build en verde está mal el 40% de las veces, y el mismo modelo alterna entre bien y mal con prompts idénticos. El arreglo no es un modelo mejor, es escribir qué significa hecho y comprobarlo ejecutando. Cada diff y cada prompt son públicos.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="paelladoc"/><category term="spec-driven-development"/><category term="ai-coding"/><category term="verification"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/spec-driven-green-build-hero.png" />
  </entry>

  <entry>
    <title type="html">Patrones de arquitectura para sistemas con IA</title>
    <link href="https://paelladoc.com/es/blog/deja-de-improvisar-5-patrones-de-arquitectura-de-ia/" rel="alternate" type="text/html" title="Patrones de arquitectura para sistemas con IA"/>
    <published>2025-05-04T00:00:00+02:00</published>
    <updated>2025-05-04T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/deja-de-improvisar-5-patrones-de-arquitectura-de-ia/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/deja-de-improvisar-5-patrones-de-arquitectura-de-ia/"><![CDATA[<p>Los sistemas con IA añaden aspectos que la arquitectura habitual no resuelve por sí sola: output no determinista, gestión de contexto, deriva de datos y modelos, evaluación y revisión humana. Eso no exige una arquitectura universal. Cambia qué fronteras resultan útiles.</p>
<p>Los patrones siguientes son alternativas para restricciones distintas. Un producto pequeño puede guardar el contexto dentro de un monolito. Un sistema con varios modelos y fuentes de datos puede necesitar un pipeline separado. Una decisión de alto riesgo puede requerir una puerta humana explícita. La elección depende de las condiciones operativas, no de una escala de madurez.</p>
<p>Cada sección describe la estructura, cuándo encaja y qué cuesta operarla. Los <a href="/es/blog/principios-del-desarrollo-ai-first/">principios del desarrollo AI-First</a> explican cómo conectar contexto y evidencia entre esas decisiones.</p>
<hr>
<h2 id="el-monolito-consciente-del-contexto">El monolito consciente del contexto</h2>
<p><strong>El problema central:</strong> tu IA necesita contexto. Sin él, las interacciones se vuelven inconexas, repetitivas y, francamente, tontas. Como explican expertos en usabilidad y testing de IA (<a href="https://frankspillers.com/what-is-context-awareness-in-ai/">como Frank Spillers</a> o el equipo de <a href="https://testrigor.com/blog/ai-context/">testRigor</a>), entender el «quién, qué, dónde, cuándo, por qué» es crucial para que la IA dé respuestas útiles en lugar de adivinanzas genéricas. Pero cuando construyes una app más simple — un MVP de chatbot, un generador de contenido enfocado — saltar directo a una arquitectura de microservicios compleja para gestionar contexto es sobreingeniería. ¿Cómo embebes la conciencia de contexto desde el día uno <em>sin</em> sobreingenieriar?</p>
<p><strong>El patrón — integra el contexto internamente:</strong> el monolito consciente del contexto lo aborda de frente. En lugar de construir un pipeline aparte para el contexto, integras la gestión de contexto <em>directamente dentro de la lógica principal de la aplicación</em>. Piensa en darle a tu monolito una «memoria» dedicada. La aplicación se vuelve responsable de capturar, almacenar (quizás en un módulo interno dedicado, una clase o tablas concretas) y recuperar el contexto necesario (historial de usuario, datos de sesión, prompts/outputs previos) para cada interacción con la IA. Esto encaja con la necesidad fundamental de que <a href="https://towardsdatascience.com/generative-ai-design-patterns-a-comprehensive-guide-41425a40d7d0">los sistemas de IA tengan memoria o «cognición»</a> para ser efectivos.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/monolith_320.avif 320w, /assets/images/monolith_480.avif 480w, /assets/images/monolith_768.avif 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/monolith_320.webp 320w, /assets/images/monolith_480.webp 480w, /assets/images/monolith_768.webp 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/monolith_480.png" srcset="/assets/images/monolith_320.png 320w, /assets/images/monolith_480.png 480w, /assets/images/monolith_768.png 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Patrón Monolito Consciente del Contexto: una sola aplicación con almacenamiento de contexto integrado para IA, ideal para proyectos pequeños donde la simplicidad es esencial" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><strong>¿Por qué empezar aquí?</strong></p>
<ul>
<li><strong>Manténlo simple:</strong> mucho más fácil de implementar y gestionar para proyectos pequeños o versiones iniciales (MVPs). Menos partes móviles = desarrollo inicial más rápido.</li>
<li><strong>Latencia baja (al principio):</strong> el contexto está disponible inmediatamente dentro del proceso de la aplicación, reduciendo la sobrecarga de llamadas externas.</li>
<li><strong>Lógica unificada:</strong> desarrollo, funciones core y gestión de contexto viven juntos, simplificando codebase inicial y depuración.</li>
</ul>
<p><strong>Aviso:</strong> este patrón es mejor para aplicaciones de alcance y escala relativamente limitados. A medida que crece la complejidad, el acoplamiento estrecho entre lógica de aplicación y gestión de contexto puede convertirse en cuello de botella. Prepárate para evolucionar a patrones más desacoplados (como el Pipeline de Contexto siguiente) cuando lo necesites.</p>
<hr>
<h2 id="el-pipeline-de-contexto-desacoplado">El pipeline de contexto desacoplado</h2>
<p><strong>El problema que resuelve:</strong> tu sistema de IA necesita manejar contexto complejo desde múltiples fuentes (input de usuario, bases de datos, APIs externas), procesarlo, enriquecerlo y dejarlo disponible de forma consistente para varios modelos o agentes. El monolito consciente del contexto empieza a crujir.</p>
<p><strong>Cómo funciona:</strong> construyes un servicio o pipeline dedicado y separado cuyo único trabajo es gestionar contexto. Ese pipeline ingiere contexto en bruto, lo procesa (p. ej., generación de embeddings, summarization, extracción de entidades), lo almacena con eficacia (las bases vectoriales son habituales aquí) y lo sirve a los modelos cuando se necesita. Aquí es donde un <strong><a href="/es/blog/guia-del-framework-de-desarrollo-ai-first/#herramientas-y-tecnologias-los-engranajes-del-framework-con-lcf-como-pieza-central">Living Context Framework (LCF)</a></strong> brilla, ayudando a los equipos a lograr <a href="/es/blog/la-peligrosa-ilusion-de-la-productividad-con-ia-y-como-lograr-ganancias-reales/">ganancias sostenibles de productividad</a>.</p>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/pipeline_320.avif 320w, /assets/images/pipeline_480.avif 480w, /assets/images/pipeline_768.avif 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/pipeline_320.webp 320w, /assets/images/pipeline_480.webp 480w, /assets/images/pipeline_768.webp 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/pipeline_480.png" srcset="/assets/images/pipeline_320.png 320w, /assets/images/pipeline_480.png 480w, /assets/images/pipeline_768.png 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Patrón Pipeline de Contexto Desacoplado: servicios separados para ingesta, procesado y almacenamiento de contexto, habilitando escalabilidad para sistemas de IA complejos vía LCF" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><strong>Beneficios:</strong></p>
<ul>
<li><strong>Escalabilidad:</strong> el procesamiento de contexto escala independiente de la aplicación principal.</li>
<li><strong>Modularidad:</strong> más fácil actualizar o sustituir técnicas de procesado de contexto.</li>
<li><strong>Reutilización:</strong> el contexto procesado puede servir a varios modelos o aplicaciones.</li>
</ul>
<p><strong>Notas de implementación:</strong> introduce más complejidad arquitectónica y latencia potencial frente al monolito. Requiere diseño cuidadoso de las etapas y del almacenamiento.</p>
<hr>
<h2 id="el-bucle-agéntico-de-feedback">El bucle agéntico de feedback</h2>
<p><strong>El problema que resuelve:</strong> tu sistema de IA necesita aprender y adaptarse con el tiempo basándose en sus propios outputs o en feedback explícito del usuario. ¿Cómo construyes un sistema que no sea estático sino que mejore continuamente su rendimiento o corrija sus errores?</p>
<p><strong>Cómo funciona:</strong> este patrón diseña el sistema para que el output de la IA (o el feedback sobre ese output) se realimente al sistema para modificar el comportamiento futuro. Puede implicar:</p>
<ul>
<li>Almacenar pares prompt/output exitosos para few-shot learning.</li>
<li>Usar puntuaciones de usuario para hacer fine-tuning del modelo.</li>
<li>Que un agente de IA analice sus propios errores para generar prompts correctivos.</li>
</ul>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/loop_320.avif 320w, /assets/images/loop_480.avif 480w, /assets/images/loop_768.avif 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/loop_320.webp 320w, /assets/images/loop_480.webp 480w, /assets/images/loop_768.webp 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/loop_480.png" srcset="/assets/images/loop_320.png 320w, /assets/images/loop_480.png 480w, /assets/images/loop_768.png 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Patrón Bucle Agéntico de Feedback: diseño circular donde los outputs del sistema de IA se analizan, con feedback de usuario fluyendo de vuelta al sistema para mejora continua" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><strong>Beneficios:</strong></p>
<ul>
<li><strong>Auto-mejora:</strong> el sistema puede ir mejorando con el tiempo sin intervención manual constante.</li>
<li><strong>Adaptabilidad:</strong> puede ajustarse a patrones de datos cambiantes o preferencias de usuario.</li>
<li><strong>Resiliencia:</strong> puede aprender a recuperarse de ciertos tipos de errores.</li>
</ul>
<p><strong>Notas de implementación:</strong> requiere diseño cuidadoso para evitar bucles de feedback no deseados o sesgos. La monitorización es crucial. Puede ser complejo de implementar y depurar.</p>
<hr>
<h2 id="sistemas-estratificados">Sistemas estratificados</h2>
<p><strong>El problema que resuelve:</strong> quieres aprovechar modelos de fundamento potentes y de propósito general (GPT-4, Claude 3) pero necesitas aplicarlos a tareas o dominios muy específicos sin tener que hacer fine-tuning constantemente del modelo base. ¿Cómo añades inteligencia especializada sobre capacidades generales?</p>
<p><strong>Cómo funciona:</strong> creas capas arquitectónicas distintas.</p>
<ul>
<li><strong>Capa de fundamento:</strong> alberga el/los modelo(s) grande(s) de propósito general. Maneja comprensión y generación lingüística core u otras capacidades amplias.</li>
<li><strong>Capa de aplicación/tarea:</strong> contiene modelos especializados más pequeños, plantillas de prompt, lógica de negocio y contexto específico de tu aplicación. Esta capa orquesta llamadas a la capa de fundamento, añadiendo el contexto necesario y interpretando resultados. Implementa la <a href="/es/blog/guia-del-framework-de-desarrollo-ai-first/#arquitectura-ai-first-disenada-para-el-futuro-no-para-el-pasado">arquitectura guiada por intención</a> descrita en la <strong><a href="/es/blog/guia-del-framework-de-desarrollo-ai-first/">Guía del framework de desarrollo AI-First</a></strong>.</li>
</ul>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/layers_320.avif 320w, /assets/images/layers_480.avif 480w, /assets/images/layers_768.avif 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/layers_320.webp 320w, /assets/images/layers_480.webp 480w, /assets/images/layers_768.webp 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/layers_480.png" srcset="/assets/images/layers_320.png 320w, /assets/images/layers_480.png 480w, /assets/images/layers_768.png 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Patrón Sistemas Estratificados de IA: arquitectura por capas con modelos de fundamento en la base aportando capacidades generales y capas de aplicación especializadas encima para tareas de dominio" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><strong>Beneficios:</strong></p>
<ul>
<li><strong>Reutilización:</strong> aprovechas modelos de fundamento potentes en varias aplicaciones.</li>
<li><strong>Desarrollo más rápido:</strong> centras el desarrollo en la capa de tarea específica.</li>
<li><strong>Actualizaciones más fáciles:</strong> actualizar modelos de fundamento con menor impacto en la lógica de aplicación (aunque el prompt engineering puede necesitar ajustes).</li>
</ul>
<p><strong>Notas de implementación:</strong> requiere diseño claro de API entre capas. Gestionar prompts e inyección de contexto en la capa de aplicación se vuelve crítico.</p>
<hr>
<h2 id="orquestación-con-humano-en-el-bucle">Orquestación con humano en el bucle</h2>
<p><strong>El problema que resuelve:</strong> tu sistema de IA opera en un dominio de alto riesgo (médico, financiero) donde los errores son inaceptables, o se encuentra en situaciones de alta ambigüedad donde la IA por sí sola no puede tomar una decisión fiable. ¿Cómo combinas automatización de IA con el necesario juicio humano?</p>
<p><strong>Cómo funciona:</strong> diseñas explícitamente puntos del workflow donde se requiere o se solicita intervención humana. Puede ser:</p>
<ul>
<li>La IA marca predicciones de baja confianza para revisión humana.</li>
<li>Un humano debe aprobar acciones críticas propuestas por la IA.</li>
<li>Los usuarios aportan feedback que corrige o guía directamente los siguientes pasos de la IA en el proceso.</li>
<li>El sistema enruta casos ambiguos a una cola de expertos humanos.</li>
</ul>
<picture class="" style="--ri-aspect: 768 / 432;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/human_320.avif 320w, /assets/images/human_480.avif 480w, /assets/images/human_768.avif 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/human_320.webp 320w, /assets/images/human_480.webp 480w, /assets/images/human_768.webp 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/human_480.png" srcset="/assets/images/human_320.png 320w, /assets/images/human_480.png 480w, /assets/images/human_768.png 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Patrón Orquestación con Humano en el Bucle: workflow que integra puntos de decisión donde expertos humanos revisan, aprueban o corrigen outputs de IA en procesos críticos, garantizando seguridad y confianza" width="768" height="432" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p><strong>Beneficios:</strong></p>
<ul>
<li><strong>Seguridad y fiabilidad:</strong> reduce el riesgo de errores críticos en dominios sensibles.</li>
<li><strong>Confianza:</strong> aumenta la confianza de usuarios y stakeholders en el sistema.</li>
<li><strong>Manejo de ambigüedad:</strong> aprovecha el juicio humano en situaciones difíciles para la IA.</li>
<li><strong>Generación de datos:</strong> las interacciones humanas pueden generar datos valiosos para futuros entrenamientos de IA.</li>
</ul>
<p><strong>Notas de implementación:</strong> requiere diseñar interfaces eficientes para la interacción humana. Hay que gestionar potenciales cuellos de botella por tiempos de revisión. Define criterios claros para cuándo se dispara la intervención humana. Este patrón se alinea con las <a href="/es/blog/guia-del-framework-de-desarrollo-ai-first/#consideraciones-eticas-la-brujula-moral-indispensable-del-desarrollo-ai-first">consideraciones éticas</a> del desarrollo AI-First.</p>
<hr>
<h2 id="elegir-un-patrón">Elegir un patrón</h2>
<p>Construir con IA no tiene por qué sentirse como cruzar un campo de minas con los ojos vendados. Estos cinco patrones aportan estructuras probadas para abordar de frente los retos inherentes al desarrollo con IA. Convierten la incertidumbre en diseño intencional.</p>
<p>Elegir el patrón correcto (o la combinación) depende de la escala, complejidad y requisitos específicos de tu proyecto. Pero el principio se mantiene: <strong>la estructura previene el fracaso.</strong> Para una implementación efectiva, asegura estos patrones con herramientas adecuadas como las descritas en <a href="/es/blog/asegura-tu-codigo-de-ia-con-snyk/">Asegura tu código de IA con Snyk</a>.</p>
<p>Deja de dejar el éxito de tus proyectos de IA al azar. Explora estos patrones, entiende sus trade-offs y empieza a construir sistemas de IA no solo potentes hoy, sino sostenibles mañana. Una base arquitectónica sólida es clave para evitar las trampas del desarrollo con IA.</p>
<p>¿Listo para profundizar? Estos patrones son solo una parte del <strong><a href="/es/blog/guia-del-framework-de-desarrollo-ai-first/">framework AI-First integral</a></strong> diseñado para guiar todo tu ciclo de desarrollo. Descubre cómo <a href="/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/">La revolución PAELLADOC</a> está cambiando la forma en que los equipos abordan el desarrollo con IA.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-fracasan-tantos-proyectos-de-ia-después-del-prototipo">¿Por qué fracasan tantos proyectos de IA después del prototipo?</h3>
<p>Porque los equipos tratan los sistemas de IA como software tradicional e improvisan el diseño. La IA trae retos que la arquitectura corriente ignora: no determinismo, degradación del contexto, deriva de datos. Un prototipo prometedor se convierte en una maraña de deuda técnica que nadie entiende. El fallo suele ser estructural, no mala suerte: el sistema no tenía una arquitectura pensada para el desorden específico de la IA, así que no sobrevivió a la demo.</p>
<h3 id="cuáles-son-los-principales-patrones-de-arquitectura-de-ia">¿Cuáles son los principales patrones de arquitectura de IA?</h3>
<p>Esta guía cubre cinco patrones probados: el monolito consciente del contexto, que lo mantiene dentro de la aplicación para proyectos simples; el pipeline de contexto desacoplado para escalar su gestión; el bucle de retroalimentación agéntico, donde las salidas y el feedback mejoran el comportamiento futuro; los sistemas estratificados, que apilan lógica especializada sobre modelos fundacionales; y la orquestación con humano en el bucle para decisiones críticas. La mayoría de sistemas reales combinan varios al crecer.</p>
<h3 id="cómo-elegir-el-patrón-de-arquitectura-de-ia-adecuado">¿Cómo elegir el patrón de arquitectura de IA adecuado?</h3>
<p>Parte de la escala, complejidad y riesgo de tu proyecto, no del patrón más sofisticado. Un MVP acotado quizá solo necesite el contexto dentro de la aplicación; un sistema que sirve muchos modelos necesita un pipeline de contexto dedicado; los dominios críticos necesitan puntos explícitos de revisión humana. Lo constante en todos es que la estructura deliberada, y no el diseño improvisado, es lo que mantiene vivo un sistema de IA más allá del lanzamiento.</p>]]></content>
    <summary type="html"><![CDATA[Una comparación de arquitecturas habituales para sistemas con IA, con su modelo operativo, restricciones útiles y costes de implementación.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="paelladoc"/><category term="ai-architectures"/><category term="ai-first-development"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/hero.png" />
  </entry>

  <entry>
    <title type="html">Framework de desarrollo AI-First: contexto, ejecución y evidencia</title>
    <link href="https://paelladoc.com/es/blog/guia-del-framework-de-desarrollo-ai-first/" rel="alternate" type="text/html" title="Framework de desarrollo AI-First: contexto, ejecución y evidencia"/>
    <published>2025-04-27T00:00:00+02:00</published>
    <updated>2025-04-27T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/guia-del-framework-de-desarrollo-ai-first/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/guia-del-framework-de-desarrollo-ai-first/"><![CDATA[<h2 id="qué-significa-desarrollo-ai-first">Qué significa desarrollo AI-First</h2>
<p>Usar un asistente para escribir código no cambia por sí solo el proceso de desarrollo. El equipo sigue necesitando decidir qué comportamiento quiere, expresar las restricciones, revisar la implementación y comprobar el resultado.</p>
<p>El desarrollo AI-First adapta ese ciclo a una realidad concreta: una parte creciente de la implementación la producen agentes que no conservan una memoria estable del producto. Por eso el contexto, la intención y la evidencia deben existir fuera de cada sesión y viajar con el trabajo.</p>
<p>La unidad de trabajo deja de ser solo un diff. Incluye el motivo del cambio, el contrato que debe cumplir, el código resultante y la prueba obtenida al verificarlo.</p>
<h2 id="los-artefactos-del-framework">Los artefactos del framework</h2>
<p>Un flujo AI-First necesita pocas piezas, pero deben estar conectadas:</p>
<ul>
<li><strong>Evidencia de producto:</strong> observaciones, datos o conversaciones que justifican una necesidad.</li>
<li><strong>Decisión:</strong> la opción elegida, las alternativas descartadas y sus motivos.</li>
<li><strong>Especificación:</strong> comportamiento esperado, restricciones y criterios de aceptación.</li>
<li><strong>Contexto de código:</strong> componentes afectados, dependencias, interfaces e invariantes.</li>
<li><strong>Ejecución:</strong> tareas y cambios producidos por personas o agentes.</li>
<li><strong>Verificación:</strong> tests, logs, capturas u otras pruebas ligadas a la versión del contrato.</li>
</ul>
<p>El valor no está en acumular documentos. Está en poder recorrer los enlaces: desde una línea de código hasta la decisión que la autorizó, y desde un criterio hasta la evidencia que demuestra si se cumple.</p>
<h2 id="el-ciclo-operativo">El ciclo operativo</h2>
<h3 id="definir">Definir</h3>
<p>El equipo convierte una necesidad en un contrato comprobable. Antes de ejecutar, separa hechos de hipótesis, registra las decisiones abiertas y escribe criterios que permitan distinguir un resultado correcto de uno plausible.</p>
<p>El <a href="/es/blog/que-es-desarrollo-guiado-por-especificaciones/">desarrollo guiado por especificaciones</a> cubre esta parte con más detalle.</p>
<h3 id="preparar-contexto">Preparar contexto</h3>
<p>La tarea recibe solo el contexto relevante: reglas del repositorio, arquitectura afectada, interfaces, decisiones vigentes y ejemplos necesarios. Un contexto más largo no siempre es mejor; debe ser trazable y estar actualizado.</p>
<h3 id="ejecutar">Ejecutar</h3>
<p>El agente implementa contra el contrato. Si descubre una restricción nueva o necesita cambiar una interfaz compartida, esa información vuelve al contrato en lugar de quedar encerrada en la conversación del agente.</p>
<h3 id="verificar">Verificar</h3>
<p>La salida se comprueba con evidencia reproducible. Un mensaje que dice «los tests pasan» es estado; la ejecución, los logs y la versión de los criterios forman la prueba. La guía para <a href="/es/blog/verificar-codigo-generado-por-ia/">verificar código generado con IA</a> desarrolla esta distinción.</p>
<h3 id="aprender">Aprender</h3>
<p>El resultado actualiza el conocimiento del producto. Una hipótesis puede confirmarse o descartarse; una decisión puede cambiar; una especificación puede quedar obsoleta. El sistema debe mostrar esas revisiones sin borrar la procedencia.</p>
<h2 id="arquitectura-y-patrones">Arquitectura y patrones</h2>
<p>El framework no obliga a usar una arquitectura concreta. Un producto pequeño puede mantener contexto dentro de un monolito. Un sistema con varias fuentes y modelos puede separar la ingesta, el almacenamiento y la recuperación. Un dominio de alto riesgo puede requerir revisión humana antes de ejecutar o publicar.</p>
<p>La decisión depende del volumen, la sensibilidad de los datos, la latencia, el coste de una salida incorrecta y la capacidad operativa del equipo. La comparación de <a href="/es/blog/deja-de-improvisar-5-patrones-de-arquitectura-de-ia/">patrones de arquitectura para sistemas con IA</a> explica esos costes.</p>
<h2 id="inyección-de-contexto">Inyección de contexto</h2>
<p>La inyección de contexto entrega al agente las reglas y artefactos necesarios en el momento de ejecutar. No consiste en pegar toda la documentación en un prompt. Consiste en seleccionar contexto por tarea y conservar la procedencia de cada elemento.</p>
<picture class="" style="--ri-aspect: 768 / 768;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/ai-first-context-injection-pattern_320.avif 320w, /assets/images/ai-first-context-injection-pattern_480.avif 480w, /assets/images/ai-first-context-injection-pattern_768.avif 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/ai-first-context-injection-pattern_320.webp 320w, /assets/images/ai-first-context-injection-pattern_480.webp 480w, /assets/images/ai-first-context-injection-pattern_768.webp 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/ai-first-context-injection-pattern_480.png" srcset="/assets/images/ai-first-context-injection-pattern_320.png 320w, /assets/images/ai-first-context-injection-pattern_480.png 480w, /assets/images/ai-first-context-injection-pattern_768.png 768w" sizes="(max-width: 760px) calc(100vw - 48px), 760px" alt="Diagrama del patrón de inyección de contexto en el desarrollo AI-First" width="768" height="768" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Una implementación útil responde a estas preguntas:</p>
<ul>
<li>¿Qué regla o decisión necesita esta tarea?</li>
<li>¿De dónde procede y cuándo se actualizó?</li>
<li>¿Qué ocurre si dos fuentes se contradicen?</li>
<li>¿Cómo se registra una restricción descubierta durante la ejecución?</li>
</ul>
<h2 id="uso-responsable">Uso responsable</h2>
<p>El mismo rastro que ayuda a mantener el software sirve para gobernar el uso de IA. Conviene registrar las fuentes de datos y versiones de modelo, limitar el acceso a información sensible, evaluar sesgos relevantes para el dominio y definir quién aprueba decisiones de alto impacto.</p>
<p>Antes de automatizar una decisión, el equipo debe poder indicar a quién afecta, qué datos utiliza, cómo se revisa una salida y qué mecanismo permite detener o corregir el sistema. Estas preguntas forman parte del contrato, no de una revisión posterior.</p>
<h2 id="lo-que-el-framework-no-resuelve">Lo que el framework no resuelve</h2>
<p>El método no convierte una hipótesis en evidencia, no garantiza que una especificación sea correcta y no elimina la necesidad de juicio humano. Tampoco compensa un repositorio sin límites claros o una suite de tests que no observa el comportamiento importante.</p>
<p>Su función es más concreta: mantener conectados el motivo, la decisión, la ejecución y la verificación para que el equipo pueda revisar y cambiar el producto sin reconstruir su historia en cada iteración.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-el-desarrollo-ai-first">¿Qué es el desarrollo AI-First?</h3>
<p>Es un enfoque donde contexto, intención y evidencia son artefactos de primer nivel junto al código. El objetivo no es generar más, sino conservar un contrato que personas y agentes puedan ejecutar y verificar.</p>
<h3 id="en-qué-se-diferencia-de-usar-una-herramienta-de-ia-para-programar">¿En qué se diferencia de usar una herramienta de IA para programar?</h3>
<p>Una herramienta acelera una sesión de implementación. Un framework organiza el ciclo completo: cómo se decide, qué contexto recibe el agente, cómo se valida la salida y cómo vuelve el aprendizaje al producto.</p>
<h3 id="qué-necesita-un-equipo-para-empezar">¿Qué necesita un equipo para empezar?</h3>
<p>Un contrato pequeño y comprobable, reglas del repositorio, una forma de entregar contexto por tarea y evidencia reproducible al terminar. La complejidad adicional solo se justifica cuando esas piezas básicas ya funcionan.</p>]]></content>
    <summary type="html"><![CDATA[El desarrollo AI-First conecta el motivo de un cambio, su contrato, la ejecución y la prueba. Esta guía describe los artefactos y el ciclo operativo.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="ai-first-development"/><category term="context-preservation"/><category term="intent-driven-architecture"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/ai-first-method-revelation-hero.png" />
  </entry>

  <entry>
    <title type="html">Asegura tu código de IA con Snyk: una guía práctica</title>
    <link href="https://paelladoc.com/es/blog/asegura-tu-codigo-de-ia-con-snyk/" rel="alternate" type="text/html" title="Asegura tu código de IA con Snyk: una guía práctica"/>
    <published>2025-04-17T00:00:00+02:00</published>
    <updated>2025-04-17T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/asegura-tu-codigo-de-ia-con-snyk/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/asegura-tu-codigo-de-ia-con-snyk/"><![CDATA[<h2 id="aquel-código-de-ia-parecía-productivo-hasta-que-han-aparecido-los-fallos-ocultos">Aquel código de IA parecía productivo… hasta que han aparecido los fallos ocultos</h2>
<p>¿Recuerdas la subidón? Usar un asistente de IA, generar montañas de código, lanzar funcionalidades más rápido que nunca. <strong>Parecía acelerar el desarrollo de forma notable.</strong></p>
<p>Pero llega el aterrizaje. Un bug sutil aparece semanas después. Una auditoría de seguridad marca incidencias inesperadas. O simplemente necesitas modificar el código y te das cuenta de que… no entiendes del todo <em>cómo</em> funciona. ¿Por qué <em>esa</em> llamada concreta a esa librería? ¿Qué supuestos sostienen esa lógica generada?</p>
<p>Esa sensación de hundimiento es <strong>el reto común del desarrollo asistido por IA</strong>: velocidad inicial que enmascara fragilidad y contexto perdido. Las horas ahorradas generando se vuelven días depurando y parcheando agujeros. Según el <a href="https://snyk.io/blog/2024-open-source-security-report-slowing-progress-and-new-challenges-for/">State of Open Source Security 2024 de Snyk</a>, no es paranoia: aunque el <strong>80% de los equipos confía en las herramientas de IA</strong>, un significativo <strong>59% se preocupa simultáneamente por las nuevas vulnerabilidades</strong> que estas herramientas puedan introducir. Hacen bien.</p>
<p>El código de IA no existe en el vacío. Interactúa con librerías complejas, corre en entornos específicos y hereda los riesgos de sus dependencias. Confiar en la velocidad de la IA sin <strong>seguridad profunda y consciente del contexto</strong> es como construir un rascacielos sobre arena. <strong>Tus ganancias de productividad pueden hundirse si la base es insegura.</strong></p>
<p>El tooling de seguridad para desarrollo con IA ha evolucionado al ritmo de la propia tecnología. Aunque hay distintos enfoques y herramientas en el mercado, <strong>esta guía examina cómo el SAST integrado de Snyk, los principios de DAST y el SCA proporcionan un enfoque completo</strong> para los retos de seguridad de tus proyectos de IA. Veremos los mecanismos técnicos y la metodología, no solo los beneficios.</p>
<h2 id="por-qué-tu-caja-de-herramientas-de-seguridad-estándar-suele-fallar-con-código-de-ia">Por qué tu caja de herramientas de seguridad estándar suele fallar con código de IA</h2>
<p>Al grano. Tu setup de seguridad tradicional — quizás algunos linters básicos, un escáner genérico de vulnerabilidades o herramientas SAST de primera generación — está <strong>fundamentalmente mal preparado</strong> para los retos únicos y complejos del código de IA. No solo se trata de tipos nuevos de código; se trata de cómo <em>funciona</em> el desarrollo con IA y de las tecnologías concretas implicadas. Aquí va el <em>por qué</em> esas herramientas se quedan cortas:</p>
<ol>
<li>
<p><strong>Ceguera ante riesgos en runtime específicos de IA (p. ej., <code>pickle</code>):</strong></p>
<ul>
<li><strong>El problema:</strong> los modelos de ML se serializan a menudo con el módulo <code>pickle</code> de Python para guardarlos y cargarlos. Pero <code>pickle</code> es notoriamente inseguro: deserializar datos de fuentes no confiables puede ejecutar código arbitrario y comprometer todo el sistema (RCE). Está advertido explícitamente en la <a href="https://docs.python.org/3/library/pickle.html#security">documentación oficial de Python</a> y resaltado como vector mayor en recursos como el <a href="https://owasp.org/www-project-machine-learning-security-top-10/">OWASP ML Security Top 10 (ML04: Model Poisoning / ML08: Insecure Model Storage)</a>.</li>
<li><strong>Por qué fallan las herramientas estándar:</strong> muchos SAST básicos carecen de <strong>taint tracking</strong> y <strong>análisis de flujo de datos</strong> sofisticados. Pueden ver una llamada <code>pickle.load()</code> pero no determinar si los datos cargados vienen de una fuente no confiable (entrada de usuario, fichero descargado). No saben rastrear el camino de los datos a través de las pipelines complejas de ML, así que pierden la conexión crítica entre fuente no confiable y sink peligroso. Les falta el contexto.</li>
</ul>
</li>
<li>
<p><strong>Incapacidad de parsear y analizar notebooks (<code>.ipynb</code>) como es debido:</strong></p>
<ul>
<li><strong>El problema:</strong> los Jupyter notebooks están en todas partes para experimentación de IA y hasta en algunos workflows de producción. Su formato JSON mezcla código, markdown y, sobre todo, <strong>celdas de output</strong> que pueden contener información sensible: API keys, datos intermedios o mensajes de error que revelan rutas internas. Además, los notebooks suelen saltarse los procesos de control de versiones y revisión rigurosos que sí se aplican a <code>.py</code> estándar.</li>
<li><strong>Por qué fallan las herramientas estándar:</strong> la mayoría de SAST tradicionales están diseñados para parsear ficheros de código fuente estándar (<code>.py</code>, <code>.java</code>…). Carecen de parsers dedicados y robustos para la estructura JSON de <code>.ipynb</code>. Pueden ignorar el código de los notebooks, no escanear celdas de output con secretos o malinterpretar el orden de ejecución y el estado inherente al notebook. Encontrar secretos requiere más que una regex; necesita el contexto que solo un escáner consciente del notebook aporta.</li>
</ul>
</li>
<li>
<p><strong>Falta de comprensión semántica de las librerías AI/ML:</strong></p>
<ul>
<li><strong>El problema:</strong> el desarrollo con IA depende mucho de librerías especializadas como Pandas, NumPy, TensorFlow, PyTorch. Tienen APIs potentes, pero un uso inadecuado puede introducir vulnerabilidades. Por ejemplo, usar <code>pandas.read_sql</code> con input de usuario sin validar puede llevar a SQL injection. Manipular paths de fichero sin sanitizar puede llevar a path traversal. Procesar datasets enormes pasados por API sin chequeos puede provocar DoS. Las guías seguras para estas librerías insisten en la validación cuidadosa de entradas (<a href="https://pandas.pydata.org/docs/reference/api/pandas.read_sql.html">ver notas de seguridad de Pandas <code>read_sql</code></a> — aunque las advertencias evolucionen, el principio se mantiene).</li>
<li><strong>Por qué fallan las herramientas estándar:</strong> los SAST genéricos suelen carecer de «comprensión semántica» integrada de estas librerías. Pueden no reconocer que un parámetro concreto es un sink sensible (la query en <code>read_sql</code>, un argumento de path…). Modelan mal el comportamiento de la librería, generando falsos positivos (marcar uso seguro) y, más peligroso, <strong>falsos negativos</strong> (perder llamadas realmente inseguras).</li>
</ul>
</li>
<li>
<p><strong>Mapeo inadecuado de la «pesadilla» de dependencias:</strong></p>
<ul>
<li><strong>El problema:</strong> el ecosistema de IA está construido sobre torres altas de dependencias. Instalar <code>tensorflow</code> o <code>pytorch</code> arrastra <em>cientos</em> de dependencias transitivas. Una vulnerabilidad en cualquier punto de la cadena — incluso 4 o 5 niveles abajo — puede comprometer tu aplicación. No es teoría; los ataques a la cadena de suministro son una amenaza mayor, documentada por organismos como ENISA (<a href="https://www.enisa.europa.eu/publications/threat-landscape-for-supply-chain-attacks">informe sobre Supply Chain Attacks</a>). Aunque el <a href="https://snyk.io/reports/open-source-security/">informe Snyk 2023</a> detectó que el 86% de las vulnerabilidades en Node.js son transitivas, el principio aplica igual o más al stack Python de IA.</li>
<li><strong>Por qué fallan las herramientas estándar:</strong>
<ul>
<li><em>Escaneo superficial:</em> muchos checkers básicos solo miran las dependencias <em>directas</em> listadas en <code>requirements.txt</code> o <code>pyproject.toml</code>, ignorando completamente la red transitiva subyacente.</li>
<li><em>Mal grafado:</em> a menudo no aportan una visualización clara y navegable del grafo completo de dependencias, dejándote sin entender <em>cómo</em> ha entrado el paquete vulnerable.</li>
<li><em>Falta de contexto:</em> lo crucial — normalmente no hacen <strong>análisis de alcance (reachability)</strong>. Pueden marcar una vulnerabilidad en una dependencia profunda, pero no saben si la función vulnerable es realmente <em>llamable</em> desde tu código. Eso provoca fatiga de alertas: el equipo invierte tiempo investigando vulnerabilidades sin riesgo real.</li>
</ul>
</li>
</ul>
</li>
</ol>
<p><strong>La respuesta cruda sigue siendo <em>no</em>.</strong> Las herramientas estándar suelen carecer del <strong>análisis profundo de flujo de datos, comprensión semántica de librerías de IA, parsing robusto de notebooks, grafado completo de dependencias y análisis de reachability</strong> necesarios para asegurar el código de IA. No fueron pensadas para las complejidades específicas y la velocidad de este nuevo paradigma de desarrollo de software.</p>
<p>Los datos del sector confirman el peligro. El <a href="https://snyk.io/blog/2024-open-source-security-report-slowing-progress-and-new-challenges-for/">informe Snyk 2024</a>, donde el <strong>45% de las organizaciones</strong> parchea recientemente componentes de build vulnerables, no es un dato suelto: es un síntoma de tooling inadecuado luchando contra cadenas de suministro complejas e interconectadas, especialmente en IA. Ignorar esa cadena no solo es arriesgado; <strong>es desatender un aspecto fundamental de la seguridad moderna del software.</strong></p>
<h2 id="un-desarrollo-con-ia-realmente-seguro-con-snyk">Un desarrollo con IA realmente seguro con Snyk</h2>
<p>Imagina este flujo:</p>
<ol>
<li><strong>Mientras programas (o mientras genera la IA):</strong> Snyk Code identifica un patrón inseguro de manejo de datos en tu script Python <strong>dentro de tu VS Code o JetBrains</strong>. Te explica <em>por qué</em> es arriesgado en el contexto de posibles vectores de ataque a IA y ofrece una sugerencia segura concreta.</li>
<li><strong>Antes de hacer commit:</strong> un escaneo automatizado de Snyk revisa la nueva librería de ML que has añadido. Encuentra no solo una vulnerabilidad crítica en la dependencia directa sino también un problema de severidad alta <strong>tres niveles más abajo</strong> en una transitiva <em>y</em> señala una licencia AGPL restrictiva incompatible con los objetivos de tu proyecto. Snyk genera automáticamente un Pull Request para subir a las versiones compatibles más seguras.</li>
<li><strong>Durante CI/CD:</strong> Snyk Container escanea la imagen Docker que has construido para despliegue, marcando vulnerabilidades en el SO base <em>y</em> confirmando que los paquetes Python instalados coinciden con tu baseline SCA seguro.</li>
<li><strong>Post-despliegue (vía principios DAST):</strong> tests automatizados sondean tu API que sirve el modelo. Simulan intentos de saltar la autenticación en endpoints de gestión y envían datos malformados al endpoint de inferencia, verificando tus defensas en runtime.</li>
</ol>
<p>Este nivel de integración de seguridad es cada vez más necesario en desarrollo moderno con IA. Snyk implementa un enfoque de seguridad continua que combina SAST, SCA, escaneo de contenedores y seguridad de IaC en un flujo orientado a identificar y abordar riesgos relacionados con la IA durante todo el ciclo.</p>
<p><strong>Elimina la falsa dicotomía entre velocidad y seguridad.</strong> Con Snyk, <strong>aseguras tu velocidad.</strong></p>
<h2 id="examinando-enfoques-integrados-sast-dast-y-sca-para-seguridad-de-ia">Examinando enfoques integrados: SAST, DAST y SCA para seguridad de IA</h2>
<p>Veamos <em>cómo</em> atacan herramientas como Snyk los riesgos de seguridad de IA con la profundidad necesaria:</p>
<h3 id="1-snyk-code-sast-análisis-estático-profundo-para-codebases-de-ia">1. Snyk Code (SAST): análisis estático profundo para codebases de IA</h3>
<ul>
<li><strong>Función</strong>: <strong>prevenir</strong> que entren vulnerabilidades en tu codebase analizando código y configuración <em>antes</em> de la ejecución.</li>
<li><strong>Implementación técnica</strong>: Snyk Code, como otros SAST avanzados, va más allá del simple pattern matching. Como detalla el <a href="https://snyk.io/articles/application-security/static-application-security-testing/">overview técnico de SAST</a>, un SAST efectivo emplea:
<ul>
<li><strong>Ejecución simbólica y análisis de flujo de datos</strong>: rastrea el flujo de datos (incluida entrada potencialmente contaminada) por tu código para detectar vulnerabilidades complejas como deserialización insegura (p. ej., trazar input hasta <code>pickle.load()</code>) o inyecciones en queries construidas con outputs de modelo.</li>
<li><strong>Comprensión semántica</strong>: analiza el <em>significado</em> y el <em>contexto</em> del código, entendiendo el uso de librerías (p. ej., marcando configuraciones arriesgadas de Flask o FastAPI usadas para servir modelos) y patrones inseguros propios de las librerías Python de IA.</li>
<li><strong>Reglas con ML</strong>: usa machine learning entrenado con grandes corpus de código y vulnerabilidades para identificar problemas nuevos o complejos.</li>
</ul>
</li>
<li><strong>Casos de uso clave en IA y soluciones</strong>:
<ul>
<li><em>Problema</em>: carga insegura de modelos (<code>pickle</code>). <em>Enfoque</em>: detectar <code>pickle.load()</code> sobre datos no confiables, sugerir alternativas seguras como <code>joblib</code> con verificaciones o formatos más seguros (ONNX, Protobuf) cuando se pueda.</li>
<li><em>Problema</em>: secretos hardcodeados en notebooks/config. <em>Enfoque</em>: identificar API keys, contraseñas y credenciales cloud con pattern matching y análisis de entropía; recomendar variables de entorno o gestores de secretos (HashiCorp Vault, AWS Secrets Manager).</li>
<li><em>Problema</em>: uso inseguro de Pandas/NumPy. <em>Enfoque</em>: marcar operaciones como <code>pd.read_csv()</code> sobre paths sin validar o posibles inyecciones de comando vía argumentos inseguros si las fuentes son no confiables.</li>
<li><strong>Integración</strong>: los SAST modernos se integran con IDEs, flujos Git y pipelines CI/CD para feedback en tiempo real y quality gates automatizados.</li>
</ul>
</li>
</ul>
<h3 id="2-principios-dast-validar-servicios-y-apis-de-ia-en-ejecución">2. Principios DAST: validar servicios y APIs de IA en ejecución</h3>
<ul>
<li><strong>Función</strong>: <strong>verificar</strong> la postura de seguridad de tu aplicación de IA desplegada simulando ataques externos contra interfaces en ejecución.</li>
<li><strong>Implementación técnica</strong>: aunque Snyk se <em>integra con</em> DAST en lugar de serlo, aplicar principios DAST es vital en cualquier estrategia integral. Implica herramientas como OWASP ZAP, Burp Suite, Postman/Newman o K6 para:
<ul>
<li><strong>Sondear endpoints API</strong>: testear sistemáticamente endpoints de inferencia (<code>/predict</code>), de manejo de datos y mecanismos de auth para vulnerabilidades que el SAST no ve (p. ej., rate limiting flojo que permite agotar recursos del modelo, fallos de auth).</li>
<li><strong>Simular ataques específicos de IA</strong>: diseñar tests que envíen requests de inferencia malformadas (tipos inesperados, inputs sobredimensionados), intentar SSRF si los modelos se cargan vía URL, o testear controles de acceso en APIs de gestión/reentrenamiento.</li>
<li><strong>Fuzzing de inputs</strong>: usar fuzzing automatizado para enviar grandes volúmenes de inputs variados o inesperados a endpoints de inferencia y descubrir problemas de robustez o crashes.</li>
</ul>
</li>
<li><strong>Casos de uso clave y validación</strong>:
<ul>
<li><em>Problema</em>: auth/autorización inseguras de la API. <em>Enfoque DAST</em>: intentar acceder a endpoints protegidos sin tokens válidos, testear escalado de privilegios entre roles.</li>
<li><em>Problema</em>: fallos de validación de input que llevan a DoS o errores. <em>Enfoque DAST</em>: enviar requests grandes/malformadas a endpoints de inferencia; monitorizar crashes o consumo excesivo.</li>
<li><em>Problema</em>: CORS/headers HTTP mal configurados. <em>Enfoque DAST</em>: comprobar headers (CSP, HSTS), verificar políticas CORS no demasiado permisivas.</li>
<li><strong>Correlación</strong>: los enfoques más efectivos enlazan hallazgos DAST (p. ej., una SQLi confirmada) con la ubicación exacta del código mediante SAST para una remediación eficiente.</li>
</ul>
</li>
</ul>
<h3 id="3-snyk-open-source-sca-desenredar-la-red-de-dependencias-de-ia">3. Snyk Open Source (SCA): desenredar la red de dependencias de IA</h3>
<ul>
<li><strong>Función</strong>: <strong>asegurar</strong> toda tu cadena de suministro identificando, priorizando y arreglando vulnerabilidades y problemas de licencia en <em>todos</em> los componentes open source, directos y transitivos.</li>
<li><strong>Implementación técnica</strong>: SCA modernas como Snyk Open Source ofrecen análisis exhaustivo de dependencias, crítico en el mundo de IA cargado de librerías, como detalla este <a href="https://snyk.io/articles/open-source-security/software-composition-analysis-sca/">overview técnico de SCA</a>:
<ul>
<li><strong>Resolución de grafo completa</strong>: construir un mapa exacto y completo de <em>todas</em> las dependencias, incluidas las anidadas en librerías como <code>tensorflow</code> o <code>pytorch</code>, identificando la ruta exacta a las vulnerabilidades.</li>
<li><strong>Inteligencia de vulnerabilidades</strong>: aprovechar bases curadas que aportan avisos más tempranos y contexto más rico que fuentes públicas como NVD.</li>
<li><strong>Análisis de reachability</strong>: determinar si la <em>función</em> concreta vulnerable de la librería es realmente alcanzable (llamable) desde tu código. Esto <strong>reduce el ruido de alertas</strong> despriorizando vulnerabilidades en rutas no usadas.</li>
<li><strong>Cumplimiento de licencias</strong>: detectar licencias (AGPL, Apache 2.0…) y aplicar políticas para evitar riesgos legales, vital al distribuir modelos o servicios de IA.</li>
<li><strong>Generación de SBOM</strong>: crear SBOMs SPDX/CycloneDX para transparencia y compliance.</li>
</ul>
</li>
<li><strong>Casos de uso clave y remediación</strong>:
<ul>
<li><em>Problema</em>: vulnerabilidad crítica en lo profundo de la dependencia de una librería de procesamiento de datos. <em>Enfoque SCA</em>: identificar la vulnerabilidad, mostrar la ruta completa, evaluar reachability y guiar para subir la dependencia <em>directa</em> a una versión que resuelva el problema <em>transitivo</em>.</li>
<li><em>Problema</em>: usar una librería con licencia AGPL en un producto comercial. <em>Enfoque SCA</em>: marcar la licencia según la política, permitiendo al desarrollador escoger una alternativa o evaluar implicaciones legales.</li>
<li><em>Problema</em>: librerías desactualizadas sin parches. <em>Enfoque SCA</em>: monitorizar continuamente, alertar sobre nuevas vulnerabilidades en dependencias existentes y facilitar upgrades a tiempo.</li>
<li><em>Problema</em>: incertidumbre sobre la salud de una librería nueva. <em>Enfoque SCA</em>: evaluar mantenimiento, seguridad, comunidad y licencia <em>antes</em> de importarla.</li>
</ul>
</li>
</ul>
<h2 id="integrando-las-capas-hacia-una-seguridad-de-ia-holística">Integrando las capas: hacia una seguridad de IA holística</h2>
<p>SAST, DAST y SCA no son silos; son capas de una defensa integral. Las plataformas integradas como Snyk facilitan su coordinación:</p>
<ul>
<li><strong>Vista unificada</strong>: ver SAST, SCA (y posiblemente DAST integrado) en un solo lugar agiliza la gestión y reduce el cambio de contexto.</li>
<li><strong>Priorización contextual</strong>: combinar severidad, explotabilidad <em>y</em> reachability (de SAST+SCA) permite centrarse primero en los riesgos de mayor impacto.</li>
<li><strong>Integración MLOps</strong>: incrustar comandos de seguridad como quality gates automatizados en todo tu pipeline MLOps (ingesta de datos, entrenamiento, validación, despliegue, monitorización) aporta protección continua.</li>
</ul>
<h2 id="conexión-con-el-framework-paelladoc">Conexión con el framework PAELLADOC</h2>
<p>Este enfoque integrado encaja perfectamente con los <a href="/es/blog/principios-del-desarrollo-ai-first/">principios del desarrollo AI-First</a> en el corazón de PAELLADOC. Igual que PAELLADOC enfatiza preservar el contexto a lo largo del desarrollo, un tooling de seguridad adecuado preserva el contexto de vulnerabilidades, dependencias y factores de riesgo.</p>
<p>La <a href="/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/#el-momento-doloroso-en-el-que-tu-propio-codigo-se-vuelve-un-extrano">Crisis del Contexto</a> que he discutido respecto al código generado por IA se vuelve aún más crítica al considerar las implicaciones de seguridad. Sin contexto sobre orígenes, supuestos y dependencias, el análisis de seguridad se vuelve mucho más difícil.</p>
<p>Integrando un tooling como Snyk en tu flujo AI-First junto con PAELLADOC creas un bucle de feedback potente:</p>
<ol>
<li>PAELLADOC preserva el contexto de desarrollo y el razonamiento de las decisiones</li>
<li>Snyk identifica las implicaciones de seguridad de esas decisiones</li>
<li>Los hallazgos de seguridad informan futuras decisiones de desarrollo</li>
<li>El proceso entero se vuelve más resiliente y sostenible</li>
</ol>
<h2 id="conclusión-avanzar-hacia-una-seguridad-integral-de-ia">Conclusión: avanzar hacia una seguridad integral de IA</h2>
<p>El panorama de desarrollo con IA es complejo y evoluciona rápido. Apoyarte en prácticas obsoletas o herramientas fragmentadas aumenta la vulnerabilidad. Las cifras de informes como <a href="https://snyk.io/blog/2024-open-source-security-report-slowing-progress-and-new-challenges-for/">Snyk 2024</a> y <a href="https://snyk.io/reports/open-source-security/">Snyk 2023</a> reflejan riesgos reales encontrados por organizaciones que desarrollan sistemas de IA.</p>
<p><strong>Sin seguridad integrada:</strong> los equipos suelen enfrentarse a incertidumbre, tiempo perdido persiguiendo vulnerabilidades tarde en el ciclo, puntos ciegos en dependencias, fallos en runtime descubiertos por usuarios y preocupaciones constantes sobre la seguridad del código generado a toda velocidad.</p>
<p><strong>Con un enfoque integrado de seguridad:</strong> los equipos ganan control y confianza con detección temprana de fallos en código generado, visibilidad de la cadena de suministro de dependencias, priorización contextual centrada en riesgos reales y seguridad incrustada de forma natural en el flujo MLOps.</p>
<p>El paisaje moderno de desarrollo con IA no obliga a elegir entre velocidad de innovación y seguridad robusta. Herramientas como Snyk aportan profundidad e integración para conseguir ambas, complementando frameworks como PAELLADOC para crear proyectos AI-First realmente sostenibles.</p>
<p>Igual que he explorado cómo <a href="/es/blog/tus-proyectos-ia-son-insostenibles-y-este-es-el-porque/">tus proyectos de IA son insostenibles</a> sin preservación de contexto, también lo son sin integración de seguridad. Ambos aspectos deben trabajar juntos para crear sistemas de IA realmente resilientes. La misma disciplina aplica en cuanto publicas algo hecho con vibe coding — <a href="/es/blog/seguridad-vibe-coding/">los riesgos de seguridad del vibe coding</a> son justo donde el camino rápido muerde más fuerte.</p>
<p><strong>Considera cómo un enfoque integrado de seguridad puede reforzar tus proyectos de IA y hacer tu desarrollo AI-First verdaderamente sostenible.</strong></p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="cómo-se-asegura-el-código-generado-por-ia">¿Cómo se asegura el código generado por IA?</h3>
<p>Con capas de comprobaciones complementarias, no confiando en un solo escaneo. El análisis estático (SAST) detecta patrones inseguros mientras se escribe el código; el análisis de composición (SCA) mapea el árbol profundo de dependencias que arrastra el código de IA; y las pruebas al estilo DAST sondean el servicio en ejecución y sus APIs. Incrustar todo esto como puertas automáticas a lo largo del pipeline, no como una casilla final, es lo que evita que el código generado publique fallos ocultos.</p>
<h3 id="por-qué-las-herramientas-de-seguridad-estándar-no-detectan-las-vulnerabilidades-del-código-de-ia">¿Por qué las herramientas de seguridad estándar no detectan las vulnerabilidades del código de IA?</h3>
<p>Porque no se diseñaron para cómo funciona el desarrollo con IA. Muchos escáneres básicos no tienen el análisis de flujo de datos para rastrear entradas no confiables hasta sumideros peligrosos como la deserialización con pickle, no parsean bien los notebooks de Jupyter donde se esconden secretos en las celdas de salida, no entienden semánticamente las librerías de IA, y solo miran las dependencias directas ignorando el árbol transitivo profundo. El resultado son falsas alarmas y, peor, riesgos reales que se escapan.</p>
<h3 id="qué-son-sast-dast-y-sca">¿Qué son SAST, DAST y SCA?</h3>
<p>Tres capas complementarias de seguridad de aplicaciones. SAST (análisis estático) inspecciona el código fuente antes de ejecutarlo, detectando patrones inseguros y secretos incrustados. DAST (pruebas dinámicas) ataca la aplicación en ejecución desde fuera para encontrar fallos en APIs, autenticación y manejo de entradas. SCA (análisis de composición) examina las dependencias open source, directas y transitivas, en busca de vulnerabilidades conocidas y problemas de licencia. Juntas cubren código, ejecución y cadena de suministro.</p>]]></content>
    <summary type="html"><![CDATA[El código generado por IA introduce riesgos sutiles que las herramientas estándar pasan por alto. Descubre cómo el enfoque integrado de Snyk en SAST, DAST y SCA crea una estrategia integral para el desarrollo AI-First.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="security"/><category term="ml-pipeline-security"/><category term="snyk"/><category term="ai-first-development"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/snyk-ai-code-security-header.png" />
  </entry>

  <entry>
    <title type="html">Cuando programar más rápido con IA no mejora la entrega</title>
    <link href="https://paelladoc.com/es/blog/la-peligrosa-ilusion-de-la-productividad-con-ia-y-como-lograr-ganancias-reales/" rel="alternate" type="text/html" title="Cuando programar más rápido con IA no mejora la entrega"/>
    <published>2025-04-16T00:00:00+02:00</published>
    <updated>2025-04-16T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/la-peligrosa-ilusion-de-la-productividad-con-ia-y-como-lograr-ganancias-reales/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/la-peligrosa-ilusion-de-la-productividad-con-ia-y-como-lograr-ganancias-reales/"><![CDATA[<p>¿Recuerdas la sensación? La promesa de los asistentes de programación con IA. Escribir código más rápido. Lanzar funcionalidades antes. Dejar atrás a la competencia. Parecía haber encontrado el botón mágico de la productividad.</p>
<p>Pero ha llegado la resaca. Seis meses después, intentar entender aquella maravilla generada por IA es como descifrar jeroglíficos antiguos. Lo que debería ser un retoque mínimo se convierte en una excavación de una semana entre capas de código sin contexto. Los días se hacen noches. Crece la frustración.</p>
<p><strong>Esa es la peligrosa ilusión.</strong> Perseguiste velocidad y perdiste algo mucho más valioso: <strong>productividad sostenible.</strong> Ignorar este coste oculto no solo te frena — paraliza tus proyectos y convierte tu inversión en IA en un pasivo, no en un activo. Voy a diseccionar la ilusión y descubrir cómo aprovechar la IA para ganancias <em>reales</em> y duraderas.</p>
<h2 id="por-qué-el-volumen-producido-puede-falsear-la-productividad">Por qué el volumen producido puede falsear la productividad</h2>
<p>Visualízalo: el equipo Alpha, ingenieros agudos hambrientos de ventaja. Adoptan las últimas herramientas de IA — Copilot, CodeWhisperer, lo que sea. Los resultados iniciales son espectaculares. El boilerplate desaparece en segundos. Los tests aparecen casi por arte de magia. Las métricas de líneas de código se disparan. Dirección está eufórica. Las funcionalidades vuelan a velocidad warp. Se sienten imparables.</p>
<p>Avanza tres meses. Aparece un bug crítico en producción que afecta a clientes clave. Pánico. El módulo responsable lo ha generado en gran parte un asistente de IA, lanzado por un desarrollador que ya está en otro proyecto. El equipo restante se mete a fondo.</p>
<p>Miran ese código elegante, funcional y completamente extraño. Funciona, casi siempre. Pero ¿<em>por qué</em> funciona <em>así</em>? ¿Qué casos límite se han contemplado? ¿Qué restricciones arquitectónicas se han asumido? No hay comentarios explicando la intención, no hay enlaces a los requisitos originales (a diferencia de los principios discutidos en <a href="#">Documentación en la era de la IA</a>), no hay registro de los prompts. Solo… código. Lógica perfectamente formada y pelada de contexto.</p>
<p>Lo que iba a ser un hotfix rápido se convierte en una investigación forense dolorosa. Depurar es una pesadilla — recorrer una lógica desconocida, intentando adivinar las suposiciones implícitas de la IA. Integrar un cambio pequeño exige entender la caja negra entera, temiendo efectos colaterales imprevistos, un problema que insinúa que quizá <a href="#">tus proyectos de IA son insostenibles</a>. Días que se hacen semanas. ¿Aquella velocidad inicial? Un recuerdo lejano, evaporada por la fricción de mantener código sin contexto. El equipo se quema, la moral cae. Han generado código más rápido que nunca, sí. Pero han sacrificado comprensibilidad y mantenibilidad a largo plazo en el altar de la velocidad inmediata.</p>
<h2 id="qué-miden-los-datos-disponibles">Qué miden los datos disponibles</h2>
<p>La promesa de velocidad guiada por IA es embriagadora. Los estudios confirman ganancias notables: los desarrolladores que usan herramientas como GitHub Copilot o Amazon CodeWhisperer pueden completar ciertas tareas <strong>hasta un 55–57% más rápido</strong> (<a href="https://medium.com/@adnanmasood/rethinking-developer-productivity-in-the-age-of-ai-metrics-that-actually-matter-61834691c76e">Fuente: Medium (Adnan Masood, PhD.), marzo 2025</a>). Algunas organizaciones reportan mejoras de productividad medias del <strong>7–18% a lo largo del SDLC</strong>, con aceleraciones puntuales de tareas que pueden alcanzar el <strong>40%</strong> o más (<a href="https://www.capgemini.com/in-en/insights/expert-perspectives/enhancing-the-developer-experience-with-gen-ai/">Fuente: Capgemini, feb 2025, citando estudio del MIT</a>).</p>
<p><strong>Pero he aquí el coste oculto:</strong> esa velocidad bruta a menudo se paga con la salud y la mantenibilidad del código a largo plazo. Un estudio a gran escala de GitClear analizando código hasta 2024 detectó tendencias preocupantes desde la adopción masiva de herramientas de IA (<a href="https://www.gitclear.com/ai_assistant_code_quality_2025_research">Fuente: GitClear, resumen del informe 2025</a>).</p>
<ul>
<li><strong>Code churn y duplicación disparados:</strong> GitClear proyecta que el code churn (código descartado poco después de escribirse) se <strong>duplicará</strong> respecto a la línea base previa a la IA. Observan también un <strong>aumento de 4× en bloques de código clonados</strong> en 2024, donde el copy/paste superó por primera vez al refactor/move — un fuerte indicador de menor reutilización y más redundancia (<a href="https://devops.com/ai-in-software-development-productivity-at-the-cost-of-code-quality/">Fuentes: DevOps.com citando GitClear, feb 2025</a>; <a href="https://www.gitclear.com/ai_assistant_code_quality_2025_research">Informe GitClear 2025</a>).</li>
<li><strong>Más debug e inestabilidad:</strong> el informe State of Software Delivery 2025 detectó que los desarrolladores dedican <em>más</em> tiempo a depurar código generado por IA y a resolver problemas de seguridad. De forma similar, el informe DORA 2024 de Google asoció un aumento del 25% en uso de IA con un <strong>descenso del 7,2% en estabilidad de entrega</strong> (<a href="https://leaddev.com/software-quality/how-ai-generated-code-accelerates-technical-debt">Fuente: LeadDev, feb 2025</a>).</li>
<li><strong>Deuda técnica inducida por IA:</strong> la facilidad de generación sin contexto profundo actúa como acelerador de deuda técnica. Un profesor del MIT lo comparó con «una tarjeta de crédito recién estrenada… para acumular deuda técnica como nunca» (<a href="https://devops.com/ai-in-software-development-productivity-at-the-cost-of-code-quality/">Fuente: DevOps.com, feb 2025</a>). Los expertos prevén un posible «atasco sistémico» mientras los equipos desenredan funciones desordenadas generadas por IA (<a href="https://www.devopsdigest.com/exploring-the_power_of_ai_in_software_development-part-15-2025-predictions-and-beyond">Fuente: DevOps Digest, dic 2024</a>).</li>
</ul>
<p>Las preocupaciones sobre calidad y vulnerabilidades del código IA persisten en 2025 (<a href="https://zencoder.ai/blog/ai-code-generators-future-software-development">Fuente: Zencoder.ai, mar 2025</a>), y los desarrolladores, sobre todo los junior, temen reducir su aprendizaje por depender de la IA bajo plazos ajustados (<a href="https://dev.to/sshahriar/ai-hype-tight-deadlines-killing-my-vibe-as-a-junior-dev-need-advice-4oe3">Fuente: Dev.to, abr 2025</a>). Centrarse solo en la velocidad inicial de generación ignora el coste creciente de entender, depurar y mantener este código rápido y pobre en contexto. La misma ilusión tiene un gemelo en el lado de producto: el <a href="/es/blog/slop-de-ia-en-producto/">slop de IA en el trabajo de producto</a>, output que parece progreso en un dashboard pero que en silencio no mueve nada real.</p>
<h2 id="velocidad-de-implementación-y-velocidad-de-entrega-son-cosas-distintas">Velocidad de implementación y velocidad de entrega son cosas distintas</h2>
<p>¿Qué ha fallado entonces? Hemos caído en el canto de sirena de la velocidad, confundiendo <strong>generación rápida de código</strong> con <strong>productividad de ingeniería real y sostenible</strong>. Es como confundir el sprint con la resistencia del fondista. El cuello de botella real del desarrollo no es lo rápido que escribe un dev — es la <strong>carga cognitiva</strong> de entender, mantener y evolucionar de forma segura sistemas complejos durante años.</p>
<p>Los asistentes de IA son fenomenales emparejando patrones, generando código basado en miles de millones de líneas que han visto. Pero operan en gran medida sin <strong>contexto profundo del proyecto</strong>. No captan inherentemente:</p>
<ul>
<li><strong>El <em>por qué</em></strong>: la lógica de negocio, las necesidades del usuario o los objetivos estratégicos detrás de una funcionalidad.</li>
<li><strong>La arquitectura</strong>: principios de diseño, restricciones, trade-offs y patrones establecidos en tu sistema.</li>
<li><strong>La historia</strong>: por qué se han descartado enfoques previos, qué deuda técnica existe, qué bugs pasados informan las decisiones.</li>
<li><strong>Las dependencias</strong>: interacciones sutiles, efectos laterales potenciales o impactos aguas abajo en otros módulos.</li>
</ul>
<p>Sin ese contexto rico, la IA genera código en el vacío. Puede ser localmente correcto, incluso elegante, pero a menudo lleno de suposiciones implícitas y dependencias ocultas. Se vuelve una caja negra que aumenta la carga cognitiva de quien deba entender o modificarlo después, porque tiene que <em>reconstruir</em> el contexto desde cero.</p>
<p><strong>La productividad real no es escribir código más rápido hoy.</strong> Es minimizar el coste y esfuerzo total durante todo el ciclo de vida del software. Se mide por la rapidez y <em>seguridad</em> con la que tu equipo puede entender, modificar, probar y extender ese código mañana, el mes que viene, el año que viene. Engloba:</p>
<ul>
<li><strong>Mantenibilidad</strong>: poco esfuerzo para corregir bugs o adaptar a requisitos cambiantes.</li>
<li><strong>Comprensibilidad</strong>: alta claridad de propósito y lógica para devs actuales y futuros.</li>
<li><strong>Velocidad de colaboración</strong>: menos fricción cuando varios desarrolladores trabajan en paralelo.</li>
<li><strong>Carga cognitiva reducida</strong>: menos energía mental descifrando, más creando valor.</li>
</ul>
<p>Centrarte solo en velocidad de generación optimiza la parte fácil mientras acumulas peligrosamente deuda donde más duele: en la comprensibilidad y adaptabilidad a largo plazo de tu sistema.</p>
<h2 id="un-enfoque-de-medición-basado-en-contexto">Un enfoque de medición basado en contexto</h2>
<p>Deja la ilusión. Logra productividad <em>real</em> potenciada por IA integrando las herramientas con inteligencia en un flujo que prioriza <strong>contexto, claridad y salud a largo plazo</strong>.</p>
<p>Este es el blueprint:</p>
<h3 id="1-mide-lo-que-importa-tira-las-métricas-de-vanidad">1. Mide lo que importa: tira las métricas de vanidad</h3>
<ul>
<li><strong>Deja de medir LOC</strong>: ¿líneas de código generadas por IA? Irrelevante. Premia volumen sobre valor.</li>
<li><strong>Céntrate en flujo y estabilidad</strong>: adopta las métricas DORA (Lead Time, Deployment Frequency, Change Fail Rate, Time to Restore) y los insights del framework SPACE. Reflejan <em>salud del sistema</em>.</li>
<li><strong>Mide la fricción</strong>: monitoriza <strong>Code Churn</strong>, <strong>tasa de retrabajo</strong>, <strong>tiempo de resolución de bugs</strong> (compara generado por IA vs humano) y <strong>tiempo de ciclo de revisión</strong>. Cifras altas anulan la velocidad inicial. Profundizaremos en <a href="#">Medir la productividad real en desarrollo con IA</a> en un artículo futuro.</li>
<li><strong>Evalúa comprensibilidad</strong>: ¿con qué rapidez contribuyen nuevos devs? El feedback cualitativo dice más que cualquier contador de líneas.</li>
<li><strong>Beneficio</strong>: <strong>alinea incentivos con valor</strong>. Centra al equipo en entregar software estable y útil de forma eficiente a la larga.</li>
</ul>
<h3 id="2-incrusta-el-por-qué-con-el-qué-prioriza-la-preservación-del-contexto">2. Incrusta el <em>por qué</em> con el <em>qué</em>: prioriza la preservación del contexto</h3>
<ul>
<li><strong>Antes</strong>: documentación pudriéndose en una wiki aparte, ignorada y desconfiable.</li>
<li><strong>Ahora: contexto vivo con Paelladoc.</strong> Crea enlaces explícitos y duraderos entre el código y su <em>razón de ser</em> — requisitos, ADRs, discusiones de diseño, objetivos de rendimiento. Usa herramientas como <strong>Paelladoc</strong> para construir ese grafo de conocimiento vivo <em>dentro</em> del entorno de desarrollo.</li>
</ul>
<picture class="" style="--ri-aspect: 768 / 512;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/context-preservation-knowledge-graph_320.avif 320w, /assets/images/context-preservation-knowledge-graph_480.avif 480w, /assets/images/context-preservation-knowledge-graph_768.avif 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/context-preservation-knowledge-graph_320.webp 320w, /assets/images/context-preservation-knowledge-graph_480.webp 480w, /assets/images/context-preservation-knowledge-graph_768.webp 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/context-preservation-knowledge-graph_480.png" srcset="/assets/images/context-preservation-knowledge-graph_320.png 320w, /assets/images/context-preservation-knowledge-graph_480.png 480w, /assets/images/context-preservation-knowledge-graph_768.png 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px" alt="Ilustración de una línea de código conectada por líneas brillantes a iconos de requisitos, arquitectura y decisiones de diseño, simbolizando la preservación del contexto." width="768" height="512" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<ul>
<li><strong>Captura de contexto obligatoria</strong>: cuando la IA genere código relevante, capturar el <em>por qué</em> (el prompt, la decisión, el enlace al requisito) con Paelladoc no es opcional, es esencial.</li>
<li><strong>Beneficio</strong>: <strong>transforma el debug</strong>. Entiende el propósito en minutos, no en horas.</li>
<li><strong>Beneficio</strong>: <strong>permite evolución más segura</strong>. Refactoriza con confianza, conociendo las restricciones originales.</li>
<li><strong>Beneficio</strong>: <strong>acelera el onboarding</strong>. Las nuevas incorporaciones acceden al saber del proyecto al instante.</li>
<li><strong>Beneficio</strong>: <strong>democratiza el conocimiento</strong>. El contexto se vuelve activo compartido y persistente.</li>
</ul>
<h3 id="3-guía-al-asistente-exige-interacción-de-ia-consciente-del-contexto">3. Guía al asistente: exige interacción de IA consciente del contexto</h3>
<ul>
<li><strong>El prompting rico es clave</strong>: no preguntes solo <em>qué</em>, explica <em>por qué</em> y <em>cómo</em>. Aporta contexto arquitectónico, definiciones de interfaz, guías de estilo y enlaces a requisitos.</li>
<li><strong>Itera y valida</strong>: trata el output de la IA como un borrador. Refínalo con prompts de seguimiento sobre especificidades del proyecto, casos límite y adherencia a estándares.</li>
<li><strong>Aliméntala con tu mejor código</strong>: muéstrale ejemplos de <em>tu</em> código de calidad, rico en contexto, para guiar su salida.</li>
<li><strong>Beneficio</strong>: sugerencias adaptadas a <em>tu</em> proyecto, no código genérico de internet.</li>
</ul>
<h3 id="4-refuerza-el-firewall-humano-revisiones-de-código-guiadas-por-contexto">4. Refuerza el firewall humano: revisiones de código guiadas por contexto</h3>
<ul>
<li><strong>El código de IA no es magia</strong>: necesita <em>más</em> escrutinio, no menos, especialmente sobre suposiciones ocultas y huecos de contexto.</li>
<li><strong>Amplía tu checklist</strong>: pregunta: ¿la intención está clara? ¿Se ha capturado el contexto (p. ej. con Paelladoc)? ¿Las dependencias están bien gestionadas? ¿Encaja <em>de verdad</em> con la arquitectura? ¿Podría otra persona mantenerlo con seguridad?</li>
<li><strong>Usa herramientas de contexto en la review</strong>: aprovecha herramientas que muestren el razonamiento enlazado durante la revisión.</li>
<li><strong>Beneficio</strong>: atrapa la deuda y la ambigüedad inducidas por IA <em>antes</em> de que infecten tu codebase.</li>
</ul>
<h3 id="5-construye-una-cultura-de-ia-sostenible">5. Construye una cultura de IA sostenible</h3>
<ul>
<li><strong>Forma para uso crítico</strong>: pon el foco en <em>cuándo</em> y <em>por qué</em> usar IA, subrayando validación y captura de contexto.</li>
<li><strong>Valora guía sobre generación</strong>: premia el prompting eficaz y la validación, no las LOC.</li>
<li><strong>Comparte aprendizajes</strong>: crea canales para compartir buenas prácticas y errores.</li>
</ul>
<picture class="" style="--ri-aspect: 768 / 768;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/sustainable-ai-culture-collaboration_320.avif 320w, /assets/images/sustainable-ai-culture-collaboration_480.avif 480w, /assets/images/sustainable-ai-culture-collaboration_768.avif 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/sustainable-ai-culture-collaboration_320.webp 320w, /assets/images/sustainable-ai-culture-collaboration_480.webp 480w, /assets/images/sustainable-ai-culture-collaboration_768.webp 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/sustainable-ai-culture-collaboration_480.png" srcset="/assets/images/sustainable-ai-culture-collaboration_320.png 320w, /assets/images/sustainable-ai-culture-collaboration_480.png 480w, /assets/images/sustainable-ai-culture-collaboration_768.png 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px" alt="Ilustración de desarrolladores diversos colaborando ante una pantalla con código generado por IA enlazado a su contexto, discutiéndolo y revisándolo." width="768" height="768" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<ul>
<li><strong>Beneficio</strong>: cultiva una inteligencia colectiva para una augmentación responsable y eficaz con IA.</li>
</ul>
<p>Adoptar estas prácticas transforma la IA de fuente potencial de deuda técnica a poderoso amplificador de los desarrolladores humanos, impulsando velocidad sostenible y mayor calidad.</p>
<h2 id="cómo-conecta-paelladoc-el-trabajo-y-la-evidencia">Cómo conecta PaellaDoc el trabajo y la evidencia</h2>
<h3 id="p-prompt-engineering-construido-sobre-contexto-compartido">P: Prompt engineering construido sobre contexto compartido</h3>
<h3 id="a-asistencia-de-agentes-con-contexto-en-runtime">A: Asistencia de agentes con contexto en runtime</h3>
<h3 id="e-enriquecimiento-de-retrieval-recuperación-mejorado">E: Enriquecimiento de retrieval (recuperación) mejorado</h3>
<h3 id="l-evaluación-automatizada-de-llms">L: Evaluación automatizada de LLMs</h3>
<h3 id="l-recogida-de-telemetría-a-gran-escala">L: Recogida de telemetría a gran escala</h3>
<h3 id="a-gobernanza-de-las-herramientas-de-ia">A: Gobernanza de las herramientas de IA</h3>
<h3 id="d-documentación-amplificada">D: Documentación amplificada</h3>
<h3 id="o-monitorización-operativa">O: Monitorización operativa</h3>
<h3 id="c-mecanismos-continuos-de-feedback">C: Mecanismos continuos de feedback</h3>
<h2 id="medir-resultados-en-lugar-de-código-generado">Medir resultados en lugar de código generado</h2>
<h2 id="qué-conviene-medir">Qué conviene medir</h2>
<p>Perseguir velocidad de IA sin gestionar el contexto es una ilusión peligrosa. Ganas el sprint y pierdes el maratón, ahogado en código inmantenible.</p>
<p>El poder real está en <strong>augmentar a los desarrolladores humanos</strong>, aprovechar la IA para potenciar su comprensión y capacidades, no reemplazarlos. La productividad real entrega sistemas construidos no solo rápido, sino <em>bien</em> — claros, comprensibles, mantenibles y fáciles de evolucionar con seguridad.</p>
<p><strong>Detén la ilusión. Empieza a construir sosteniblemente.</strong> Preserva el contexto. Convierte tu código generado por IA en un activo, no en una bomba de relojería.</p>
<p>¿Listo para inyectar contexto otra vez en tu flujo de desarrollo con IA? Descubre cómo <a href="https://paelladoc.com/es/">Paelladoc</a> ayuda a los equipos a construir más rápido <em>y</em> más inteligente. <strong>¿Vas a seguir acumulando deuda técnica oculta, o vas a sentar bases para una productividad duradera? Tú decides.</strong></p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="la-ia-hace-de-verdad-más-productivos-a-los-desarrolladores">¿La IA hace de verdad más productivos a los desarrolladores?</h3>
<p>La IA acelera claramente la generación de código, pero generar es la parte fácil. La productividad real es el coste total a lo largo de la vida de un sistema: lo rápido y seguro que un equipo puede entender, cambiar y ampliar el código después. Cuando la IA produce rápido código pobre en contexto, esa velocidad inicial suele anularse con más depuración, más retrabajo y mayor carga cognitiva. Teclear más rápido no es productividad sostenible.</p>
<h3 id="por-qué-el-código-generado-por-ia-parece-más-rápido-de-lo-que-es">¿Por qué el código generado por IA parece más rápido de lo que es?</h3>
<p>Porque ves aparecer la salida en segundos y casi nunca ves el coste aplazado. La IA genera código localmente correcto y de aspecto elegante sin el contexto específico de tu proyecto: el porqué, la arquitectura, la historia, las dependencias. Quien lo modifique después tiene que reconstruir ese contexto desde cero. La victoria visible es la generación; el impuesto invisible llega meses más tarde, cuando ese código «rápido» se vuelve lento de tocar.</p>
<h3 id="cómo-se-mide-la-productividad-en-el-desarrollo-asistido-por-ia">¿Cómo se mide la productividad en el desarrollo asistido por IA?</h3>
<p>No por líneas de código, que premian el volumen sobre el valor. Mira el flujo y la estabilidad: lead time, frecuencia de despliegue, tasa de fallo de cambios, tiempo de recuperación. Sigue señales de fricción como el churn de código, la tasa de retrabajo y cuánto tarda el código generado por IA en depurarse o revisarse. Y pregúntate cuánto tarda un desarrollador nuevo en contribuir con seguridad. Eso revela si la IA aporta valor o deuda oculta.</p>]]></content>
    <summary type="html"><![CDATA[Generar más código no equivale a entregar antes. Este artículo separa el volumen producido de la mantenibilidad, el coste de revisión y los resultados verificados.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="productivity"/><category term="paelladoc"/><category term="productivity"/><category term="ai-first-development"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/ai-productivity-illusion-tangled-debt.png" />
  </entry>

  <entry>
    <title type="html">Por qué el código generado con IA se vuelve difícil de mantener</title>
    <link href="https://paelladoc.com/es/blog/tus-proyectos-ia-son-insostenibles-y-este-es-el-porque/" rel="alternate" type="text/html" title="Por qué el código generado con IA se vuelve difícil de mantener"/>
    <published>2025-04-14T00:00:00+02:00</published>
    <updated>2025-04-14T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/tus-proyectos-ia-son-insostenibles-y-este-es-el-porque/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/tus-proyectos-ia-son-insostenibles-y-este-es-el-porque/"><![CDATA[<h2 id="riesgos-que-introduce-el-código-generado-con-ia">Riesgos que introduce el código generado con IA</h2>
<p>Los asistentes de programación pueden reducir el tiempo de implementación, pero su output entra en el repositorio con la misma necesidad de revisión que cualquier contribución externa. Los modelos pueden reproducir patrones inseguros, proponer dependencias sin auditar o seguir instrucciones incluidas en texto que el equipo no pretendía considerar fiable.</p>
<p>La pregunta relevante no es si el código parece correcto. Es si el equipo puede rastrear sus dependencias, comprobar su comportamiento, analizar vulnerabilidades conocidas y explicar por qué forma parte del sistema. Sin esos controles, el tiempo ahorrado al generar vuelve como trabajo de revisión, depuración y corrección.</p>
<p>Este artículo describe esos fallos y los controles de ingeniería que los reducen.</p>
<h2 id="cuando-un-texto-no-fiable-se-convierte-en-instrucción">Cuando un texto no fiable se convierte en instrucción</h2>
<picture class="" style="--ri-aspect: 768 / 768;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/ai-assistant-security-investigation-1600x1200_320.avif 320w, /assets/images/ai-assistant-security-investigation-1600x1200_480.avif 480w, /assets/images/ai-assistant-security-investigation-1600x1200_768.avif 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/ai-assistant-security-investigation-1600x1200_320.webp 320w, /assets/images/ai-assistant-security-investigation-1600x1200_480.webp 480w, /assets/images/ai-assistant-security-investigation-1600x1200_768.webp 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/ai-assistant-security-investigation-1600x1200_480.png" srcset="/assets/images/ai-assistant-security-investigation-1600x1200_320.png 320w, /assets/images/ai-assistant-security-investigation-1600x1200_480.png 480w, /assets/images/ai-assistant-security-investigation-1600x1200_768.png 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px" alt="El avatar del autor investiga a un asistente de IA sospechoso, descubriendo código oculto mientras el robot mantiene su fachada" width="768" height="768" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Los repositorios, las descripciones de incidencias y los archivos de configuración pueden contener texto que un agente interpreta como instrucciones. Los caracteres Unicode y otras formas de ofuscación pueden hacer que ese texto resulte difícil de detectar durante una revisión.</p>
<p>El control consiste en tratar el contenido recuperado como datos no fiables: separarlo de las instrucciones del sistema, normalizar e inspeccionar el texto sospechoso, limitar las herramientas que puede usar el agente y revisar el código resultante antes de incorporarlo al repositorio.</p>
<h2 id="adopción-confianza-y-controles-de-seguridad">Adopción, confianza y controles de seguridad</h2>
<picture class="" style="--ri-aspect: 768 / 512;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/ai-data-privacy-protection-shield-1600x1200_320.avif 320w, /assets/images/ai-data-privacy-protection-shield-1600x1200_480.avif 480w, /assets/images/ai-data-privacy-protection-shield-1600x1200_768.avif 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/ai-data-privacy-protection-shield-1600x1200_320.webp 320w, /assets/images/ai-data-privacy-protection-shield-1600x1200_480.webp 480w, /assets/images/ai-data-privacy-protection-shield-1600x1200_768.webp 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/ai-data-privacy-protection-shield-1600x1200_480.png" srcset="/assets/images/ai-data-privacy-protection-shield-1600x1200_320.png 320w, /assets/images/ai-data-privacy-protection-shield-1600x1200_480.png 480w, /assets/images/ai-data-privacy-protection-shield-1600x1200_768.png 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px" alt="El avatar del autor protege activamente contra fugas de datos creando barreras de energía para proteger código propietario" width="768" height="512" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Según el <a href="https://snyk.io/reports/ai-code-security/">AI Code Security Report 2023 de Snyk</a>, <strong>el 96% de los equipos encuestados ya usaba herramientas de programación con IA</strong>. La <a href="https://survey.stackoverflow.co/2024/ai">Encuesta para Desarrolladores 2024 de Stack Overflow</a> registró <strong>un 76% que las usaba o pensaba usarlas</strong> ese año, y la <a href="https://survey.stackoverflow.co/2025/">edición de 2025</a> muestra que la adopción ha continuado.</p>
<p>Las mismas fuentes registran una confianza limitada en el resultado. Snyk detectó que <strong>el 56,4% de los desarrolladores encontraba habitualmente problemas de seguridad en las sugerencias de IA</strong>. Un <a href="https://snyk.io/blog/ai-tool-adoption-perceptions-and-realities/">análisis de Snyk de 2024</a> observó que los equipos de Application Security tenían el doble de probabilidades que los desarrolladores de calificar como mala la seguridad del código generado. La encuesta de Stack Overflow de 2024 también señaló que solo el 43% confiaba en la precisión del resultado y que <strong>el 45% de los profesionales valoraba mal estas herramientas en tareas complejas</strong>.</p>
<p>Los riesgos incluyen patrones obsoletos aprendidos de código público, dependencias sin revisar, prompt injection y un tratamiento de datos que no coincide con la política de la empresa. <a href="https://www.reversinglabs.com/blog/software-development-security-challenges-ai">ReversingLabs analizó estos riesgos de desarrollo en 2025</a>. Snyk también indicó que menos del 20% de las organizaciones realizó una prueba de concepto formal antes del despliegue, mientras seguían siendo frecuentes los saltos de las políticas de seguridad y la escasa automatización de análisis.</p>
<h2 id="las-herramientas-de-ia-necesitan-controles-de-ingeniería">Las herramientas de IA necesitan controles de ingeniería</h2>
<p>Los asistentes de programación con IA son herramientas de ingeniería. Su resultado necesita los mismos responsables, revisiones y controles que el código escrito por una persona o enviado por un colaborador externo.</p>
<p>Generar más rápido aumenta el volumen que el equipo debe evaluar. La capacidad de revisión, las comprobaciones de dependencias y los controles de seguridad deben crecer con la adopción.</p>
<h2 id="prácticas-para-integrar-ia-con-seguridad">Prácticas para integrar IA con seguridad</h2>
<picture class="" style="--ri-aspect: 768 / 768;">
  <!-- AVIF Format -->
  <source type="image/avif" srcset="/assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_320.avif 320w, /assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_480.avif 480w, /assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_768.avif 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- WebP Format -->
  <source type="image/webp" srcset="/assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_320.webp 320w, /assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_480.webp 480w, /assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_768.webp 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px">
  <!-- Original Format (Fallback) -->
  <img src="/assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_480.png" srcset="/assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_320.png 320w, /assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_480.png 480w, /assets/images/sustainable-vs-unsustainable-ai-development-1600x1200_768.png 768w" sizes="(max-width: 720px) calc(100vw - 40px), 600px" alt="Imagen partida que muestra al avatar del autor lidiando con una integración de IA caótica frente a otra estructurada y segura" width="768" height="768" fetchpriority="low" loading="lazy" decoding="async" class="">
</picture>
<p>Los controles son prácticas de ingeniería conocidas aplicadas a una fuente nueva de código:</p>
<ul>
<li><strong>Revisar prompts e instrucciones del agente:</strong> tratarlos como entradas ejecutables y mantener los datos sensibles fuera de los contextos que no los admitan.</li>
<li><strong>Exigir revisión humana:</strong> comprobar el comportamiento, las convenciones del proyecto y las rutas de error antes de fusionar el código generado.</li>
<li><strong>Automatizar la seguridad:</strong> ejecutar SAST, análisis de composición y las pruebas dinámicas pertinentes en CI. La <a href="/es/blog/asegura-tu-codigo-de-ia-con-snyk/">guía de implementación con Snyk</a> explica una configuración.</li>
<li><strong>Detectar ofuscación:</strong> señalar Unicode sospechoso e instrucciones ocultas en código, comentarios y configuración.</li>
<li><strong>Formar al equipo:</strong> documentar qué herramientas están aprobadas, qué datos pueden recibir y quién responde por los cambios generados.</li>
<li><strong>Aportar contexto acotado:</strong> dar al agente los requisitos y restricciones necesarios para la tarea sin exponer datos ajenos. Los <a href="/es/blog/principios-del-desarrollo-ai-first/">principios del desarrollo AI-First</a> describen ese modelo de contexto.</li>
</ul>
<p>La arquitectura puede reducir aún más el alcance de un fallo al separar componentes generados, limitar sus interfaces y probarlos en esos límites. El <a href="/es/blog/deja-de-improvisar-5-patrones-de-arquitectura-de-ia/">artículo sobre patrones de arquitectura</a> desarrolla esas opciones.</p>
<h2 id="la-velocidad-no-sustituye-la-revisión">La velocidad no sustituye la revisión</h2>
<p>La IA puede reducir el tiempo de implementación, pero no elimina el trabajo de revisión descrito arriba. Sin esos controles, el tiempo ahorrado vuelve como <a href="/es/blog/deuda-tecnica-vibe-coding/">deuda técnica</a>, respuesta a incidentes o limpieza de dependencias.</p>
<p>El enfoque mantenible se puede medir: definir quién responde por el resultado, exigir revisión, automatizar comprobaciones y conservar el <a href="/es/docs/getting-started/">contexto estructurado</a> de cada cambio.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-los-proyectos-hechos-con-ia-se-vuelven-insostenibles">¿Por qué los proyectos hechos con IA se vuelven insostenibles?</h3>
<p>Porque la velocidad va por delante y el coste se aplaza. La IA produce código que funciona muy rápido, pero a menudo sin contexto capturado y con fallos sutiles: patrones inseguros, dependencias ocultas, incluso instrucciones disfrazadas en los comentarios. Los equipos adoptan las herramientas sin adaptar sus procesos de revisión y seguridad, así que la deuda y las vulnerabilidades se acumulan en silencio. El esfuerzo ahorrado hoy vuelve después como depuración, retrabajo e incidentes de seguridad.</p>
<h3 id="es-seguro-el-código-generado-por-ia">¿Es seguro el código generado por IA?</h3>
<p>No por defecto. Los asistentes reproducen patrones del código público, incluidos los obsoletos o inseguros, y pueden ser manipulados por entradas maliciosas ocultas en el texto que procesan. Además difuminan la línea entre datos y comandos. El código generado por IA puede hacerse seguro, pero solo con la misma disciplina de ingeniería que aplicas en el resto: revisión humana de la salida, escaneo automatizado y tratar los prompts como instrucciones ejecutables.</p>
<h3 id="cómo-se-construyen-proyectos-de-ia-sostenibles">¿Cómo se construyen proyectos de IA sostenibles?</h3>
<p>Revisa la salida de la IA con el mismo cuidado que cualquier contribución externa, automatiza el análisis de seguridad en el pipeline, comprueba las instrucciones ofuscadas en código y configuración y aporta al modelo solo el contexto estructurado que necesita para la tarea.</p>]]></content>
    <summary type="html"><![CDATA[Los asistentes de IA pueden reducir el tiempo de implementación y, a la vez, añadir riesgos de seguridad, dependencias y contexto. Estas prácticas permiten detectarlos antes de publicar.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="security"/><category term="ai-first-development"/><category term="ml-pipeline-security"/><category term="knowledge-management"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/ai-security-risks-discovery-header-2048x1152.png" />
  </entry>

  <entry>
    <title type="html">Principios para un desarrollo con IA mantenible</title>
    <link href="https://paelladoc.com/es/blog/principios-del-desarrollo-ai-first/" rel="alternate" type="text/html" title="Principios para un desarrollo con IA mantenible"/>
    <published>2025-04-12T00:00:00+02:00</published>
    <updated>2025-04-12T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/principios-del-desarrollo-ai-first/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/principios-del-desarrollo-ai-first/"><![CDATA[<p>«¿Quién ha escrito esto?»</p>
<p>La funcionalidad seguía funcionando y sus tests pasaban. Sin embargo, pocas semanas después de construirla con ayuda de IA, modificarla exigía reconstruir decisiones que nunca se habían registrado.</p>
<p>El problema no era el código generado. Era la falta de conexión entre ese código, sus requisitos, las restricciones que lo condicionaban y la evidencia usada para aceptarlo.</p>
<h2 id="lo-que-deja-fuera-el-desarrollo-asistido-por-ia">Lo que deja fuera el desarrollo asistido por IA</h2>
<p>El <a href="https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/navigating-the-generative-ai-disruption-in-software">informe McKinsey 2024 sobre IA generativa en software</a> describe mejoras de productividad en implementación, documentación y refactorización. Esas métricas miden la velocidad de producción, no la facilidad con la que otra persona podrá entender o cambiar el resultado más tarde.</p>
<p>Un <a href="https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/unleashing-developer-productivity-with-generative-ai">estudio de McKinsey de 2023 sobre productividad de desarrolladores con IA generativa</a> también señala que las herramientas generalistas no conocen las necesidades específicas de un proyecto u organización. Ese contexto todavía tiene que aportarlo y revisarlo una persona.</p>
<h2 id="de-un-proceso-lineal-a-un-bucle-de-feedback">De un proceso lineal a un bucle de feedback</h2>
<p>Después de dedicar tres días a modificar esa funcionalidad, el artefacto que faltaba quedó claro: las razones de sus decisiones de diseño no habían viajado con el código.</p>
<p>La investigación sobre desarrollo asistido por IA aterriza una y otra vez en la misma asimetría: las ganancias de productividad se concentran en las tareas sencillas, mientras que el trabajo complejo necesita que su contexto y su intención de diseño se preserven para beneficiarse siquiera. En este paradigma emergente, el razonamiento detrás de las decisiones se vuelve tan crítico como el propio código.</p>
<p>Es un problema de flujo de trabajo. Si la intención desaparece después de implementar, el siguiente cambio empieza reconstruyéndola. El <a href="/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/">artículo sobre contexto en el desarrollo asistido por IA</a> explica cómo conservar esas conexiones.</p>
<h2 id="cinco-principios-operativos-para-el-desarrollo-ai-first">Cinco principios operativos para el desarrollo AI-First</h2>
<h3 id="1-contexto-como-creación-primaria">1. Contexto como creación primaria</h3>
<p>Según la <a href="https://survey.stackoverflow.co/2023/">Encuesta para Desarrolladores 2023 de Stack Overflow</a>, el 63% de los desarrolladores profesionales declara dedicar más de 30 minutos al día buscando respuestas o soluciones. Registrar el contexto como parte del trabajo reduce lo que habrá que reconstruir después.</p>
<p>En el desarrollo AI-First, el requisito, la decisión y la evidencia de aceptación son artefactos de primer nivel. El código es una implementación de ese contexto, no su único registro.</p>
<p>El cambio al que apunta esto va de «código como producto» a «conocimiento como producto»: las organizaciones que tratan lo que saben, y el porqué, como su activo principal son aquellas cuya inversión en IA se acumula en vez de pudrirse.</p>
<h3 id="2-arquitectura-guiada-por-intención">2. Arquitectura guiada por intención</h3>
<p>El <a href="https://www.mckinsey.com/features/mckinsey-center-for-future-mobility/our-insights/from-engines-to-algorithms-gen-ai-in-automotive-software-development">informe 2024 del McKinsey Center for Future Mobility</a> señala que los equipos que usan IA generativa para entender requisitos de negocio y diseñar arquitectura basada en la intención «ayudan a los desarrolladores a capturar y traducir necesidades de negocio en especificaciones técnicas con más precisión, lo que reduce malentendidos».</p>
<p>La arquitectura guiada por intención registra por qué existe un límite, además de cómo funciona. El propósito y las restricciones de un componente siguen disponibles cuando cambia su implementación.</p>
<p>Los analistas del sector llevan tiempo rastreando la misma deriva hacia sistemas basados en intención en la infraestructura. El reconocimiento de fondo es más amplio que cualquier informe: en entornos complejos habilitados por IA, la arquitectura debe diseñarse en torno a intención y propósito, no solo a funcionalidad técnica.</p>
<h3 id="3-conocimiento-como-entidad-viva">3. Conocimiento como entidad viva</h3>
<p>El <a href="https://github.blog/news-insights/octoverse/octoverse-2024/">informe Octoverse 2024 de GitHub</a> midió un crecimiento interanual del 98% en proyectos de IA generativa en la plataforma. La adopción de las herramientas ya está resuelta; lo que distingue a los equipos ahora es si el conocimiento que esas herramientas producen y consumen se mantiene vivo.</p>
<p>El conocimiento del proyecto cambia con el sistema. Por eso la documentación necesita responsables, versiones y enlaces al trabajo que describe, en lugar de vivir como una instantánea separada.</p>
<p>Según el <a href="https://www.mckinsey.com/capabilities/quantumblack/our-insights/the-state-of-ai-in-2023-generative-ais-breakout-year">informe McKinsey 2023 sobre el estado de la IA</a>, las organizaciones que han incrustado grafos de conocimiento en sus procesos junto con capacidades de IA muestran sistemáticamente mejor rendimiento. El estudio detecta que los «high-performers» de IA — aquellas empresas que atribuyen al menos un 20% de su EBIT a la IA — tienen «muchas más probabilidades que el resto de afirmar que sus organizaciones han incrustado grafos de conocimiento en al menos un producto o función de negocio», lo que permite mejor contextualización de la información y outputs de IA más precisos.</p>
<h3 id="4-revisión-humana-con-asistencia-de-ia">4. Revisión humana con asistencia de IA</h3>
<p>Una investigación del <a href="https://www.mckinsey.com/features/mckinsey-center-for-future-mobility/our-insights/from-engines-to-algorithms-gen-ai-in-automotive-software-development">estudio McKinsey 2024 sobre desarrollo de software automotriz</a> detectó que los desarrolladores con formación adecuada en IA «usaban gen AI un 60% más a la semana que cuando no contaban con esos programas. La participación mejoró y, tras la formación, el 95% de los desarrolladores afirmó que la gen AI tiene un impacto positivo en su experiencia como desarrollador».</p>
<p>La IA puede redactar y transformar la implementación, mientras las personas siguen siendo responsables de los requisitos, los trade-offs y la aceptación. El límite útil es la responsabilidad, no quién escribió cada línea.</p>
<p>Los años transcurridos desde entonces lo han confirmado en la práctica: los desarrolladores que más sacan de los agentes no son los que teclean más rápido, sino los que estructuran el contexto, la intención y la verificación alrededor de la colaboración.</p>
<h3 id="5-arquitectura-contextual-de-decisión">5. Arquitectura contextual de decisión</h3>
<p>El <a href="https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier">informe McKinsey 2023 sobre el potencial económico de la IA generativa</a> estima que esta tecnología podría aportar entre 2,6 y 4,4 billones de dólares anuales a la economía global. Capturar cualquier parte de ese valor con el tiempo depende de algo que la cifra esconde: saber, más tarde, por qué los sistemas que construiste son como son.</p>
<p>Los registros de decisión necesitan la razón, las restricciones y las alternativas descartadas, no solo la opción elegida.</p>
<p>Según el <a href="https://hbr.org/2023/11/keep-your-ai-projects-on-track">análisis 2023 de Harvard Business Review sobre implementación de IA</a>, las organizaciones que documentan no solo qué decisiones se han tomado sino por qué, son significativamente más exitosas manteniendo sistemas de IA a lo largo del tiempo y extrayendo valor sostenido de su inversión en IA.</p>
<h2 id="diferencias-frente-a-enfoques-cercanos">Diferencias frente a enfoques cercanos</h2>
<p>La diferencia práctica está en dónde coloca cada enfoque el contexto y las decisiones:</p>








































<table><thead><tr><th>Paradigma</th><th>Foco principal</th><th>Tratamiento del conocimiento</th><th>Enfoque de decisión</th><th>Output principal</th></tr></thead><tbody><tr><td>Cascada</td><td>Proceso secuencial</td><td>Documentación estática</td><td>Pre-implementación</td><td>Corrección del código</td></tr><tr><td>Ágil</td><td>Entrega iterativa</td><td>Documentación actualizada</td><td>Durante iteraciones</td><td>Software funcionando</td></tr><tr><td>DevOps</td><td>Pipeline de integración</td><td>Documentación automatizada</td><td>Continua</td><td>Velocidad de despliegue</td></tr><tr><td><strong>AI-First</strong></td><td><strong>Preservación del contexto</strong></td><td><strong>Conocimiento vivo</strong></td><td><strong>Guiada por intención</strong></td><td><strong>Contexto + código</strong></td></tr></tbody></table>
<p>El patrón de la tabla es consistente: los paradigmas tradicionales tratan el conocimiento como un subproducto del desarrollo, mientras que AI-First lo trata como el producto principal, con el código como su expresión.</p>
<h2 id="implicaciones-para-los-equipos-de-software">Implicaciones para los equipos de software</h2>
<p>El <a href="https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/enterprise-technologys-next-chapter-four-gen-ai-shifts-that-will-reshape-business-technology">informe McKinsey 2024 sobre el próximo capítulo de la tecnología empresarial</a> describe tres efectos que los equipos deben planificar:</p>
<ul>
<li>«A medida que aumenta la productividad del personal, la velocidad a la que IT puede concebir, construir y lanzar capacidades también se espera que aumente, mientras el coste de ese trabajo bajará».</li>
<li>Sin embargo, «la gen AI puede no reducir el presupuesto de tecnología empresarial de inmediato. En su lugar, impulsará una reasignación estratégica dentro de la cartera, con líderes tecnológicos centrándose cada vez más en proyectos de crecimiento en lugar de mantenimiento rutinario».</li>
<li>Las organizaciones necesitan «reforzar la planificación y la gestión del riesgo para sostener este ritmo acelerado».</li>
</ul>
<p>El informe también recomienda revisar el equilibrio entre patrones artesanales e industriales a medida que cambian las prioridades de negocio.</p>
<p>Para los equipos de software, eso significa conservar no solo qué se construyó, sino por qué se tomaron las decisiones y qué evidencia las respaldó.</p>
<h2 id="qué-cambian-estos-principios">Qué cambian estos principios</h2>
<p>Estos principios son operativos: registrar por qué existe un cambio, mantener los requisitos conectados con la implementación y adjuntar la verificación al mismo contexto. Así se reduce el trabajo de reconstrucción y se ofrece a personas y agentes una base mejor para los cambios futuros.</p>
<p>Para los equipos que quieran implementar estos principios en la práctica, el <a href="/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/">framework PAELLADOC</a> ofrece un sistema integral para preservar contexto a lo largo de todo el ciclo de desarrollo.</p>
<hr>
<p><em>Este artículo establece los fundamentos filosóficos del desarrollo AI-First. Fuentes revisadas por última vez en julio de 2026; las cifras que ya no se pudieron rastrear hasta su estudio original se eliminaron en lugar de mantenerlas por fe.</em></p>
<p>El <a href="/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/">artículo de PAELLADOC sobre contexto</a> muestra cómo estos principios se traducen en una estructura de trabajo.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="por-qué-el-código-generado-por-ia-se-vuelve-inmantenible">¿Por qué el código generado por IA se vuelve inmantenible?</h3>
<p>La IA genera código que funciona y pasa los tests, pero rara vez deja registrado por qué se tomó una decisión. Meses después, cambiar ese código obliga a reconstruir una intención que nunca se capturó: las restricciones, las alternativas descartadas, la razón de negocio. El código no es de baja calidad; lo que falta es el contexto a su alrededor. Ese hueco, no la IA, es lo que convierte una función rápida en un laberinto que nadie quiere tocar.</p>
<h3 id="cuáles-son-los-principios-del-desarrollo-ai-first">¿Cuáles son los principios del desarrollo AI-First?</h3>
<p>Este artículo plantea cinco: el contexto como creación primaria y no como subproducto; una arquitectura guiada por la intención, organizada en torno al propósito y no solo a la función; el conocimiento como entidad viva que evoluciona con el sistema; la colaboración humano-IA como una asociación real; y una arquitectura de decisiones que registra por qué se eligió algo, no solo qué se decidió. Juntos invierten el viejo orden donde el código era primario y el contexto secundario.</p>
<h3 id="el-código-generado-por-ia-necesita-documentación">¿El código generado por IA necesita documentación?</h3>
<p>Necesita algo mejor que la documentación tradicional: contexto ligado al código y mantenido vivo a medida que el código cambia. Los documentos estáticos en un wiki aparte se pudren y se ignoran. Lo que importa es capturar el razonamiento detrás de las decisiones generadas por IA — requisitos, trade-offs, caminos descartados — cerca del código, para que la siguiente persona, o la siguiente sesión de IA, actúe sobre la intención en lugar de adivinarla.</p>]]></content>
    <summary type="html"><![CDATA[El código generado con IA se vuelve difícil de mantener cuando desaparecen la intención y las decisiones. Estos principios conectan contexto, implementación y verificación.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="ai-first-development"/><category term="development-philosophy"/><category term="context-preservation"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/ai-first-dev.png" />
  </entry>

  <entry>
    <title type="html">PaellaDoc y el contexto en el desarrollo con IA</title>
    <link href="https://paelladoc.com/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/" rel="alternate" type="text/html" title="PaellaDoc y el contexto en el desarrollo con IA"/>
    <published>2025-04-08T00:00:00+02:00</published>
    <updated>2025-04-08T00:00:00+02:00</updated>
    <id>https://paelladoc.com/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/</id>
    <content type="html" xml:base="https://paelladoc.com/es/blog/la-revolucion-paelladoc-desarrollo-ai-first/"><![CDATA[<h2 id="el-código-conserva-el-qué-no-el-porqué">El código conserva el qué, no el porqué</h2>
<p>La IA permite escribir y modificar código con más rapidez. El problema aparece después: el repositorio contiene el resultado, pero no siempre conserva el requisito, la restricción o la decisión que lo produjo.</p>
<p>Cuando otra persona o agente vuelve sobre ese código, tiene que reconstruir la intención a partir de nombres, comentarios y comportamiento observado. Esa reconstrucción consume tiempo y puede reabrir decisiones ya resueltas.</p>
<h2 id="qué-se-pierde-cuando-falta-contexto">Qué se pierde cuando falta contexto</h2>
<p>El contexto no es una explicación larga alrededor del código. Son piezas concretas:</p>
<ul>
<li>el problema de usuario que justificó el cambio;</li>
<li>los requisitos y criterios de aceptación;</li>
<li>las alternativas descartadas y sus motivos;</li>
<li>las restricciones técnicas o de negocio;</li>
<li>la evidencia que demuestra que el resultado cumple el contrato.</li>
</ul>
<p>Sin esos enlaces, el onboarding se alarga, las revisiones repiten debates anteriores y los agentes trabajan con una versión incompleta del sistema.</p>
<h2 id="cómo-lo-organiza-paelladoc">Cómo lo organiza PaellaDoc</h2>
<p>PaellaDoc trata el contexto como parte del trabajo, no como un documento separado que hay que mantener después. Conecta discovery, decisiones, especificaciones, tareas, código y evidencia para que se pueda recorrer el camino entre una necesidad y su implementación.</p>
<p>La estructura cumple tres funciones:</p>
<ul>
<li>mantiene los artefactos relacionados bajo una identidad común;</li>
<li>entrega a cada agente las reglas y decisiones que necesita para su tarea;</li>
<li>guarda la verificación junto a la versión del contrato que se comprobó.</li>
</ul>
<h2 id="dónde-cambia-el-flujo">Dónde cambia el flujo</h2>
<h3 id="definición-de-producto">Definición de producto</h3>
<p>La investigación, la decisión y el requisito permanecen enlazados. Una historia de usuario deja de ser un resumen aislado y conserva la evidencia que la originó.</p>
<h3 id="diseño-técnico">Diseño técnico</h3>
<p>Las decisiones de arquitectura incluyen sus restricciones y alternativas. El equipo puede revisar por qué existe una frontera antes de modificarla.</p>
<h3 id="implementación-y-verificación">Implementación y verificación</h3>
<p>La tarea llega al agente con criterios comprobables. El resultado vuelve con logs, tests y otros artefactos de verificación conectados al mismo contrato.</p>
<h2 id="lo-que-paelladoc-no-sustituye">Lo que PaellaDoc no sustituye</h2>
<p>La estructura no decide por el equipo, no convierte una hipótesis en evidencia y no garantiza que una especificación sea correcta. Hace visibles las decisiones y sus pruebas para que puedan revisarse sin reconstruirlas desde cero.</p>
<p>Ese es el objetivo: que aumentar la velocidad de implementación no reduzca la capacidad de entender, revisar y cambiar el producto después. Los <a href="/es/blog/principios-del-desarrollo-ai-first/">principios del desarrollo AI-First</a> explican el modelo con más detalle.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="qué-es-paelladoc">¿Qué es PaellaDoc?</h3>
<p>PaellaDoc es un framework para preservar el contexto a lo largo de todo el ciclo de desarrollo, nacido de un dolor concreto: código generado por IA que se vuelve ilegible para su propio autor meses después. En lugar de documentación separada del trabajo, captura el razonamiento, los requisitos y las decisiones detrás del código y los mantiene conectados a él, para que el «porqué» sobreviva mucho después de que la IA produjera el «qué».</p>
<h3 id="qué-es-la-crisis-del-contexto-en-el-desarrollo-con-ia">¿Qué es la crisis del contexto en el desarrollo con IA?</h3>
<p>Es la brecha que abre la IA entre lo rápido que se escribe el código y lo rápido que desaparece su contexto. El código fluye deprisa, pero el razonamiento detrás — las decisiones, las restricciones, la intención — rara vez se captura. Meses después, ese contexto perdido hace que tu propio código te resulte ajeno, ralentiza el onboarding y las decisiones pasadas se vuelven a discutir. La crisis no es la calidad del código; es el conocimiento perdido.</p>
<h3 id="por-qué-se-pierde-el-contexto-en-el-desarrollo-asistido-por-ia">¿Por qué se pierde el contexto en el desarrollo asistido por IA?</h3>
<p>Porque la generación es instantánea y capturar el contexto no lo es. Cuando un asistente escribe una función en minutos, los prompts, los trade-offs y las opciones descartadas detrás suelen quedar sin registrar. La documentación tradicional vive en herramientas aparte y se pudre. Sin anclar deliberadamente el razonamiento al código, cada cambio futuro obliga a alguien a reconstruir la intención desde cero, que es justo donde el ahorro de tiempo se esfuma en silencio.</p>]]></content>
    <summary type="html"><![CDATA[La IA acelera la escritura de código, pero no conserva por sí sola los requisitos, las decisiones ni la evidencia. PaellaDoc mantiene esas piezas conectadas al trabajo.]]></summary>
    <author>
      <name>@jlcasesES</name>
    </author>
    <category term="framework"/><category term="ai-first-development"/><category term="context-preservation"/><category term="development-philosophy"/>
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://paelladoc.com/assets/images/context_crisis.png" />
  </entry>
</feed>