<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Con Criterio]]></title><description><![CDATA[Con Criterio es una newsletter sobre construir productos digitales con inteligencia artificial. No sobre la IA en abstracto, sino sobre el proceso real de crear algo que funcione, escale y tenga sentido.]]></description><link>https://www.concriterio.blog</link><image><url>https://substackcdn.com/image/fetch/$s_!_0cB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7352102a-975a-44e6-8c38-2cce1ed25978_512x512.png</url><title>Con Criterio</title><link>https://www.concriterio.blog</link></image><generator>Substack</generator><lastBuildDate>Wed, 29 Jul 2026 13:01:59 GMT</lastBuildDate><atom:link href="https://www.concriterio.blog/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Pol Marzà]]></copyright><language><![CDATA[es]]></language><webMaster><![CDATA[hazloconcriterio@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[hazloconcriterio@substack.com]]></itunes:email><itunes:name><![CDATA[Pol Marzà]]></itunes:name></itunes:owner><itunes:author><![CDATA[Pol Marzà]]></itunes:author><googleplay:owner><![CDATA[hazloconcriterio@substack.com]]></googleplay:owner><googleplay:email><![CDATA[hazloconcriterio@substack.com]]></googleplay:email><googleplay:author><![CDATA[Pol Marzà]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Wanderlore: mi primera app 100% mobile]]></title><description><![CDATA[Con vibe coding, no todo son p&#225;ginas web. Hoy vamos a ver c&#243;mo y por qu&#233; construir una app para smartphones]]></description><link>https://www.concriterio.blog/p/wanderlore-mi-primera-app-100-mobile</link><guid isPermaLink="false">https://www.concriterio.blog/p/wanderlore-mi-primera-app-100-mobile</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 15 Jul 2026 06:01:12 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c5da1779-022f-4b69-bbe8-0b493dfbf650_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Tanto si llevas poco como mucho tiempo practicando vibe coding (o AI coding), estoy 99% seguro que lo &#250;nico que has hecho han sido <strong>p&#225;ginas web</strong>. Es posible que hayas hecho un CRM, una landing, una &#8220;app&#8221; con Lovable o incluso alguna app que solo corr&#237;a en tu m&#225;quina (en el famoso localhost).</p><p>Y es normal, ya que la mayor&#237;a de creadores de contenido, cuando hablan de vibe coding hablan de hacer p&#225;ginas web.</p><p>Pero ya tu sabes que yo no soy la mayor&#237;a.</p><p>Hoy vamos a hablar de c&#243;mo, cu&#225;ndo y por qu&#233; <strong>construir una app en mobile</strong>. &#191;Por qu&#233; piensas que me decid&#237; por este formato? Vamos a verlo &#128540;</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>Antes de entrar al tema quiero explicarte qu&#233; he desarrollado exactamente: se trata de un <strong>juego de rol y exploraci&#243;n urbana</strong>. El mapa del mundo (si, porque puedes jugarlo desde cualquier rinc&#243;n del planeta) aparece cubierto de niebla y se revela a medida que caminas por la ciudad, en la vida real.</p><p>Pero no se queda en el mapa. El mundo esta poblado de lugares con narrativa propia: tabernas, academias, bosques, torres&#8230; En cada lugar puedes interactuar con un <strong>DM</strong> (un director de juego, en este caso una IA) que te narra una historia y responde a tus decisiones.</p><p>A partir de ah&#237; puedes construir equipamiento (espadas, escudos, cascos&#8230;) para enfrentarte a maleantes que aparecen en tu camino mientras exploras el reino.</p><p>La decisi&#243;n que defini&#243; el proyecto desde el inicio fue la necesidad de tener el <strong>GPS activo aunque el m&#243;vil est&#233; bloqueado en el bolsillo</strong>. Eso es lo que hace que puedas ir caminando tranquilamente sin tener el m&#243;vil en la mano y que este vibre cuando te cruzas con un malhechor.</p><p>Otra caracter&#237;stica t&#233;cnica que me hizo decidirme por una aplicaci&#243;n nativa fue la necesidad de <strong>persistencia (de datos) garantizada</strong>. En el caso de una PWA (Progressive Web App), el sistema operativo Android o (sobretodo) iOS pueden borrar datos de las aplicaciones si consumen mucho o hace tiempo que no se usan.</p><p>Ahora s&#237;, al l&#237;o.</p><p>Como todo desarrollo, este consisti&#243; en tres fases:</p><p><strong>Clarificaci&#243;n &#8594; Construcci&#243;n &#8594; Distribuci&#243;n</strong></p><div><hr></div><h3>Clarificaci&#243;n</h3><p>En esta primera fase no hay diferencia respecto a clarificar el desarrollo de un sitio web; el PRD es el mismo ejercicio, es decir, definir para qui&#233;n es la aplicaci&#243;n, qu&#233; hace y qu&#233; decide no hacer.</p><p>La arquitectura, el modelo de datos, el flujo de usuario, la monetizaci&#243;n&#8230; Aunque sean plataformas distintas, todas tienen el mismo esqueleto.</p><p>Recuerda que en la clarificaci&#243;n tambi&#233;n piensas en el stack, y aqu&#237; es donde viene el gran cambio, ya que al ser una app nativa no puedes desarrollar con React, Astro o Vue si no que tienes que hacerlo con <strong>Flutter o Swift</strong> (entre otras).</p><blockquote><p><strong>PRO TIP</strong>: Es muy importante que antes de decidir en que builder quieres construir (Lovable, Bolt, Cursor&#8230;) definas qu&#233; stack necesitas, ya que eso te va a condicionar todo lo dem&#225;s. </p></blockquote><div><hr></div><h3>Construcci&#243;n</h3><p>En mi caso me decid&#237; por <strong>Flutter</strong> ya que te permite escribir el c&#243;digo una vez y compilarlo para iOS y Android.</p><p>Con <strong>Claude Code</strong> como agente, la construcci&#243;n sigue la misma l&#243;gica que cualquier otro proyecto vibe codeado:</p><ol><li><p>Te apoyas en un agente para redactar las specs (clarificaci&#243;n)</p></li><li><p>Adjuntas dichas specs al proyecto (Local o en la nube)</p></li><li><p>Empieza de dentro hacia fuera (datos &#8594; backend &#8594; frontend)</p></li><li><p>Revisas</p></li><li><p>Iteras</p></li></ol><p>La diferencia con una web no est&#225; en el m&#233;todo de trabajo con la IA, es una diferencia de herramienta, no de filosof&#237;a.</p><div><hr></div><h3>Distribuci&#243;n</h3><p>El gran cambio, para m&#237;, lleg&#243; aqu&#237;.</p><p>Una web se despliega en Vercel y en segundos la tienes viva y accesible por URL, actualizable al momento. Una app m&#243;vil, no.</p><p>Una app pasa por <strong>tiendas de aplicaciones</strong>, revisi&#243;n de Apple y de Google, procesos de testers (antes de llegar a producci&#243;n); tiempos con los que no contabas. Sin menospreciar el pago de las licencias de desarrollador &#128517; (<strong>99&#8364;/a&#241;o</strong> en el caso de Apple y <strong>25&#8364;</strong> para Android).</p><p>Actualmente me encuentro en esta fase, la de <strong>testeo</strong>. Para que la aplicaci&#243;n salga adelante y cualquier persona se la pueda descargar, necesito que varios usuarios la est&#233;n probando, rompiendo y d&#225;ndome feedback.</p><p>As&#237; que si has llegado hasta aqu&#237;, &#191;te animas a jugar?</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.wanderlore.gg&quot;,&quot;text&quot;:&quot;Jugar a Wanderlore&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.wanderlore.gg"><span>Jugar a Wanderlore</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[3 respuestas que te ahorrarán decenas de errores]]></title><description><![CDATA[Porque la frase "el plan es que no hay plan" solo sirve para salir de copas, no para construir proyectos serios.]]></description><link>https://www.concriterio.blog/p/3-respuestas-que-te-ahorraran-decenas</link><guid isPermaLink="false">https://www.concriterio.blog/p/3-respuestas-que-te-ahorraran-decenas</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 08 Jul 2026 06:02:41 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1c0e3c44-a198-4483-b5ed-b7014cafda79_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hola, &#191;c&#243;mo va el verano? &#128515;</p><p>Hoy vengo a hablarte sobre las 3 preguntas/respuestas que te ahorrar&#225;n much&#237;simo tiempo cuando construyes con IA. </p><p>Ya te adelanto que hoy vas a ver muchos treses &#128514;</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>Vivimos en la era de la inmediatez, lo queremos todo para ayer y el problema es que muchas veces aplicamos esta filosof&#237;a cuando nos sentamos delante del ordenador y nos ponemos a construir nuestro pr&#243;ximo proyecto. </p><p>Es posible que este m&#233;todo (el vibe coding puro y duro) funcione durante las primeras horas o para proyectos peque&#241;os, pero cuando quieres empezar a construir algo con cierta seriedad, el no haber planificado nada de antemano te va a salir muy caro. </p><p>Yo aprend&#237; esto a la fuerza. </p><p>Hace 3 a&#241;os constru&#237;a sin criterio. Pensaba: &#8220;&#191;para qu&#233; voy a perder tiempo en redactar lo que quiero construir si lo tengo todo en la cabeza?&#8221;</p><p>&#161;Me sent&#237;a invencible! </p><ul><li><p>Invencible hasta que las cosas empezaban a no cuadrar.</p></li><li><p>Cuando me empezaba a contradecir. </p></li><li><p>A no recordar las decisiones. </p></li></ul><p>Entonces un buen amigo me recomend&#243; que &#8220;c&#243;mo m&#237;nimo tienes que responder a estas 3 preguntas&#8221;:</p><ol><li><p>QU&#201; quieres construir</p></li><li><p>Para QUI&#201;N</p></li><li><p>POR QU&#201;</p></li></ol><p>La tercera pregunta responde a la pregunta de por qu&#233; debe existir tu app, qu&#233; problema resuelve concretamente. Es quiz&#225; la pregunta m&#225;s importante de las tres, ya que si solo te sirve a ti, esta bien construirla, pero si quieres que tu app tenga &#233;xito, debe resolver un problema real. </p><p>La respuesta a estas 3 preguntas es la especificaci&#243;n m&#237;nima que debes redactar antes de empezar a construir nada. </p><p>Y no, no es perder el tiempo, es lo que va a evitar que construyas al tunt&#250;n y que acabes pariendo un Frankenstein. </p><div><hr></div><p>Con esto ya puedes empezar a construir con Lovable, pero si lo tuyo es Claude Code, te recomiendo que uses esta plantilla que cre&#233; hace alg&#250;n tiempo:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/HombreFeliz/project-template&quot;,&quot;text&quot;:&quot;Project Template&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/HombreFeliz/project-template"><span>Project Template</span></a></p><p>Entre otras cosas, dentro encontrar&#225;s:</p><h4><strong><span>CLAUDE.md</span></strong><span> </span></h4><p><span>Archivo de referencia que lee cualquier agente de codificaci&#243;n antes de tocar el proyecto. Si </span><code>docs/</code><span> est&#225; vac&#237;o, obliga al agente a preguntar "qu&#233; quieres construir y para qui&#233;n" y a rellenar la documentaci&#243;n en orden antes de escribir c&#243;digo. Define stack tecnol&#243;gico, convenciones, qu&#233; NO hacer, y protocolo obligatorio de cambios: changelog, actualizaci&#243;n de docs, revisi&#243;n de seguridad.</span></p><h4><span>docs/ </span></h4><p><span>Carpeta de documentaci&#243;n estructurada: prd.md, business.md, design-system.md, architecture.md, data-model.md, roadmap.md, user-flows.md. Es donde viven las respuestas a qu&#233;, qui&#233;n y por qu&#233;, convertidas en especificaci&#243;n real.</span></p><h4>changelog/ </h4><p>Registro de cada cambio relevante: fecha, tipo (feature, fix, refactor, migraci&#243;n, documentaci&#243;n, configuraci&#243;n), qu&#233; se hizo, qu&#233; se modific&#243;, por qu&#233;.</p><h4>mejoras/ </h4><p>Backlog de ideas que no entran en el sprint actual: t&#237;tulo, descripci&#243;n, motivaci&#243;n, prioridad.</p><div><hr></div><p>No es perfecto y seguro que se puede mejorar, pero es un punto de partida mucho mejor que empezar a promptear sin criterio.</p><p>&#191;Cu&#225;l es tu m&#233;todo? Te leo en los comentarios &#129299;</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Un servicio en la nube que se cuenta a sí mismo (Parte 2/2)]]></title><description><![CDATA[En la primera parte dej&#233; el experimento encallado: quer&#237;a un agente que publicara solo cada ma&#241;ana, pero /loop no serv&#237;a para eso y, de paso, me hab&#237;a bloqueado Claude con un error del sistema de archivos.]]></description><link>https://www.concriterio.blog/p/un-servicio-en-la-nube-que-se-cuenta</link><guid isPermaLink="false">https://www.concriterio.blog/p/un-servicio-en-la-nube-que-se-cuenta</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 01 Jul 2026 06:02:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/890455b3-c950-4072-8fa3-e6e406ae9c13_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>En la primera parte dej&#233; el experimento encallado: quer&#237;a un agente que publicara solo cada ma&#241;ana, pero <code>/loop</code> no serv&#237;a para eso y, de paso, me hab&#237;a bloqueado Claude con un error del sistema de archivos. La conclusi&#243;n fue inc&#243;moda pero clara: <strong>el problema no era de permisos, era de arquitectura.</strong> Mi automatizaci&#243;n depend&#237;a de mi port&#225;til, y un port&#225;til no es un servidor.</p><p>As&#237; que me plant&#233; delante de una bifurcaci&#243;n.</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><h2><strong>Local con el Mac despierto, o la nube</strong></h2><p>La primera opci&#243;n era quedarme en local y obligar al Mac a no dormirse: evitar el reposo, programar un despertador, mantener la sesi&#243;n viva. Funcionar&#237;a&#8230; mientras el Mac estuviera encendido, enchufado y de buen humor. Fr&#225;gil.</p><p>La segunda era sacarlo todo de mi m&#225;quina y meterlo en la nube. M&#225;s trabajo de montaje, pero a cambio: <strong>corre aunque el Mac est&#233; apagado, sin permisos de macOS de por medio, sin servidores que mantener.</strong> Eleg&#237; la nube. Si el objetivo era &#8220;olv&#237;date y que funcione&#8221;, no hab&#237;a color.</p><p>Pero la nube tra&#237;a una pregunta que tuve que decidir con criterio: mi agente guardaba su memoria &#8212;los posts, las m&#233;tricas, lo aprendido&#8212; en una base de datos local. Una tarea en la nube no puede leer un archivo de mi disco. &#191;D&#243;nde viv&#237;a entonces la memoria?</p><p>La respuesta result&#243; casi indolora: <strong>Cloudflare D1, que es literalmente SQLite en la nube.</strong> Migr&#233; la base sin apenas tocar el c&#243;digo. La memoria dej&#243; de ser un archivo en mi disco para ser algo que el sistema alcanza desde cualquier sitio.</p><h2><strong>La decisi&#243;n de la que m&#225;s orgulloso estoy</strong></h2><p>Aqu&#237; viene la parte <em>con criterio</em> de verdad. Cuando mov&#237; la l&#243;gica a la nube, ten&#237;a dos caminos:</p><ol><li><p>Dejar que la IA, adem&#225;s de escribir los posts, <strong>razonara tambi&#233;n los n&#250;meros</strong>: qu&#233; &#225;ngulo funcion&#243; mejor, qu&#233; puntuaci&#243;n ten&#237;a cada uno.</p></li><li><p>Que la IA solo escribiera, y que <strong>el c&#225;lculo lo hiciera c&#243;digo</strong> determinista.</p></li></ol><p>Eleg&#237; el segundo, y creo que es la decisi&#243;n clave de todo el proyecto. Porque esto es un <em>experimento</em>: el sentido es medir qu&#233; funciona y aprender con el tiempo. Y en un experimento, el instrumento de medida tiene que ser <strong>constante</strong>. Si le pides a un modelo de lenguaje que punt&#250;e, con los mismos datos puede darte resultados ligeramente distintos un d&#237;a u otro &#8212; y peor a&#250;n, ese ruido se realimenta, porque la puntuaci&#243;n de hoy condiciona el contenido de ma&#241;ana. Una regla que cambia de longitud cada vez no sirve para medir nada.</p><p>La frase que me qued&#243; grabada: <strong>la IA escribe, el c&#243;digo calcula.</strong> Para lo que es juicio &#8212;redactar, elegir el &#225;ngulo&#8212; la IA. Para lo que es un c&#225;lculo fijo &#8212;puntuar, rankear&#8212; c&#243;digo. Mezclarlos te da lo peor de los dos mundos.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JH83!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JH83!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 424w, https://substackcdn.com/image/fetch/$s_!JH83!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 848w, https://substackcdn.com/image/fetch/$s_!JH83!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 1272w, https://substackcdn.com/image/fetch/$s_!JH83!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JH83!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png" width="1240" height="558" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:558,&quot;width&quot;:1240,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:112008,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/203211089?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JH83!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 424w, https://substackcdn.com/image/fetch/$s_!JH83!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 848w, https://substackcdn.com/image/fetch/$s_!JH83!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 1272w, https://substackcdn.com/image/fetch/$s_!JH83!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5296b87-34a4-4488-ab0c-52854220ee0f_1240x558.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Lo que aprendes solo cuando lo enchufas</strong></h2><p>Sobre el papel todo encaja; al conectarlo aparecen las sorpresas. Tres que me llevo:</p><p><strong>Pagar calderilla a prop&#243;sito.</strong> En local, la IA escrib&#237;a los posts con mi suscripci&#243;n de Claude, gratis. Pero una tarea en la nube no puede usar mi suscripci&#243;n. Para que el sistema fuera de verdad aut&#243;nomo, el agente llama directamente a la API de pago. Cuesta unos c&#233;ntimos al mes &#8212; y los pago encantado a cambio de independencia total. A veces la decisi&#243;n correcta es dejar de optimizar el &#8220;gratis&#8221;.</p><p><strong>Los detalles de integraci&#243;n que ning&#250;n tutorial cuenta.</strong> El conector &#8220;oficial&#8221; de Buffer hablaba con un servidor interno; mi token personal iba contra otra direcci&#243;n distinta. Media hora de errores 401 hasta dar con ello. La fiabilidad de una automatizaci&#243;n casi nunca est&#225; en la idea, est&#225; en estos detalles.</p><p><strong>La IA no sabe contar.</strong> Bluesky limita los posts a 300 caracteres, pero el modelo se pasaba una y otra vez por mucho que se lo pidiera. La soluci&#243;n no fue rogar m&#225;s fuerte, sino poner una red: si un post se pasa, el sistema le pide que lo reescriba m&#225;s corto, hasta que cabe.</p><h2><strong>El &#250;ltimo ajuste: que sonara a persona</strong></h2><p>Cuando por fin publicaba, los textos sal&#237;an correctos pero <strong>telegr&#225;ficos</strong>: frase corta, punto, frase corta, punto. Sonaban a lista, no a alguien contando algo. Curiosamente, la culpa era m&#237;a: para respetar el l&#237;mite de caracteres le hab&#237;a pedido al modelo &#8220;frases secas&#8221;, y eso produc&#237;a justo ese estilo a trompicones. Cambi&#233; las instrucciones hacia una prosa m&#225;s narrativa y humana, y el cambio se nota.</p><p>[VISUAL 4: antes/despu&#233;s del tono &#8212; telegr&#225;fico vs narrativo, mismo contenido]</p><h2><strong>Qu&#233; me llevo</strong></h2><p>El agente qued&#243; funcionando: cada ma&#241;ana, en la nube y sin mi Mac de por medio, recog&#237;a m&#233;tricas, escrib&#237;a y publicaba, y guardaba lo aprendido. Y aunque ahora paro este experimento para llevar la idea a LinkedIn, me llevo tres cosas en la mochila:</p><ul><li><p><strong>Entiende la herramienta antes de forzarla.</strong> Medio drama me lo ahorraba sabiendo qu&#233; era <code>/loop</code>.</p></li><li><p><strong>La IA para el juicio, el c&#243;digo para los n&#250;meros.</strong> No los mezcles.</p></li><li><p><strong>La fiabilidad vive en los detalles, no en la idea.</strong> Lo dif&#237;cil no es construir el agente; es que corra solo cuando no est&#225;s mirando.</p></li></ul><p>Que, mira, es exactamente la tesis con la que empec&#233;: el problema no es construir, es la distribuci&#243;n. Solo que esta vez el experimento me lo demostr&#243; a m&#237; mismo.</p><p><em>Fin de la serie.</em></p>]]></content:encoded></item><item><title><![CDATA[Quería que una IA publicara por mí cada mañana (Parte 1/2)]]></title><description><![CDATA[Acab&#233; pele&#225;ndome con un error de los a&#241;os 90.]]></description><link>https://www.concriterio.blog/p/queria-que-una-ia-publicara-por-mi</link><guid isPermaLink="false">https://www.concriterio.blog/p/queria-que-una-ia-publicara-por-mi</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 24 Jun 2026 06:02:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/607916cc-962c-4317-bab8-826896348cc1_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Llevo semanas con una tesis en la cabeza&#8230; <strong>El problema ya no es construir, es que alguien lo vea</strong>. Construir se ha vuelto barato y r&#225;pido; la distribuci&#243;n, en cambio, sigue siendo dura y manual. As&#237; que me propuse un experimento: montar un agente que se ocupara de la parte aburrida (publicar, medir y aprender) mientras yo me dedicaba a otra cosa.</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>El plan era sencillo. Cada ma&#241;ana, el agente escribir&#237;a tres versiones de un post (tres &#225;ngulos distintos), las publicar&#237;a en Bluesky a trav&#233;s de Buffer, recoger&#237;a las m&#233;tricas del d&#237;a anterior y ajustar&#237;a el contenido del siguiente. Y lo m&#225;s bonito: el contenido ir&#237;a sobre <strong>c&#243;mo se estaba construyendo el propio agente</strong>. El medio como mensaje.</p><p>Para el disparo diario tir&#233; de lo que ten&#237;a m&#225;s a mano: <code>/loop</code>, el comando de Claude Code que repite una tarea cada cierto tiempo. &#8220;Que se lance solo a las ocho&#8221;, pens&#233;. Dejaba el Mac en reposo por la noche y, en teor&#237;a, a la ma&#241;ana siguiente el agente habr&#237;a publicado.</p><p>Spoiler: no funcion&#243; &#129394;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l_up!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l_up!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 424w, https://substackcdn.com/image/fetch/$s_!l_up!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 848w, https://substackcdn.com/image/fetch/$s_!l_up!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 1272w, https://substackcdn.com/image/fetch/$s_!l_up!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l_up!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png" width="1240" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1240,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83179,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/203208419?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!l_up!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 424w, https://substackcdn.com/image/fetch/$s_!l_up!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 848w, https://substackcdn.com/image/fetch/$s_!l_up!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 1272w, https://substackcdn.com/image/fetch/$s_!l_up!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0b77b7f-88d3-46d5-a49e-2fa670dd2734_1240x686.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>El muro</strong></h2><p>Lo primero que descubr&#237; es que <code>/loop</code> <strong>no estaba pensado para esto</strong>. </p><p><code>/loop</code> vive dentro de una sesi&#243;n abierta y necesita el ordenador despierto: cuando el Mac entra en reposo, macOS suspende los procesos y el temporizador, sencillamente, no dispara. </p><p>Pero el problema de verdad lleg&#243; cuando intent&#233; forzarlo. </p><p>Para que el agente publicara sin pedirme permiso cada ma&#241;ana, edit&#233; a mano la configuraci&#243;n de permisos. Y ah&#237; Claude Code empez&#243; a bloquearse: cada vez que enviaba un mensaje, ocurr&#237;a esto: <code>process exited with code 1 &#8212; an internal error occurred (EPERM)</code>. Treinta minutos sin poder trabajar, desinstalando y reinstalando para recuperar el control.</p><p><code>EPERM</code> significa <em>&#8220;operation not permitted&#8221;</em>. Es un error del <strong>sistema de archivos</strong>, no de la configuraci&#243;n de Claude. &#191;La causa de fondo? Ten&#237;a todo (el proyecto y la carpeta de configuraci&#243;n de Claude) en un <strong>disco externo</strong>. Las escrituras y los bloqueos que Claude hace constantemente empezaron a chocar con los permisos del volumen externo. </p><h2><strong>La lecci&#243;n que me llev&#233;</strong></h2><p>Pas&#233; un buen rato culpando a mi configuraci&#243;n. Estaba equivocado: un <code>EPERM</code> casi nunca es culpa de tu config, sino del sistema de archivos que tienes debajo. Pero la lecci&#243;n m&#225;s &#250;til no fue esa, fue otra:</p><p><strong>Hab&#237;a confundido dos cosas que parecen iguales y no lo son: lo atendido y lo desatendido.</strong></p><p><code>/loop</code> es una herramienta <em>atendida</em>: brilla cuando est&#225;s delante, con la m&#225;quina despierta y la sesi&#243;n viva. Para vigilar un deploy mientras trabajas, para iterar sobre una tarea hasta terminarla, es perfecta. Lo que yo necesitaba era lo contrario: algo <em>desatendido</em>, que corriera cada ma&#241;ana durante semanas, con el Mac apagado y sin nadie delante. Dos mundos distintos.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_mGi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_mGi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 424w, https://substackcdn.com/image/fetch/$s_!_mGi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 848w, https://substackcdn.com/image/fetch/$s_!_mGi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 1272w, https://substackcdn.com/image/fetch/$s_!_mGi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_mGi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png" width="780" height="363" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:363,&quot;width&quot;:780,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31937,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/203208419?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_mGi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 424w, https://substackcdn.com/image/fetch/$s_!_mGi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 848w, https://substackcdn.com/image/fetch/$s_!_mGi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 1272w, https://substackcdn.com/image/fetch/$s_!_mGi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cbf959e-9364-45ff-b6cb-83c54392d81b_780x363.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Y ah&#237; estaba el verdadero problema de dise&#241;o: <strong>no era de permisos, era de arquitectura.</strong> Mi automatizaci&#243;n depend&#237;a de mi port&#225;til, y un port&#225;til se duerme, se apaga y vive en un disco que se queja. Si quer&#237;a que aquello corriera de verdad solo, ten&#237;a que sacarlo de mi m&#225;quina.</p><div><hr></div><p>En la segunda parte cuento c&#243;mo lo hice: moverlo todo a la nube, qu&#233; decisiones tom&#233; <em>con criterio</em> por el camino (incluida una que me hizo pasar de &#8220;gratis&#8221; a pagar unos c&#233;ntimos al mes, a prop&#243;sito), y c&#243;mo qued&#243; un sistema que, literalmente, se cuenta a s&#237; mismo.</p><p></p>]]></content:encoded></item><item><title><![CDATA[Cómo tener email profesional gratis en tus proyectos]]></title><description><![CDATA[El setup que uso en cada proyecto que lanzo y no me cuesta un euro al mes.]]></description><link>https://www.concriterio.blog/p/como-tener-email-profesional-gratis</link><guid isPermaLink="false">https://www.concriterio.blog/p/como-tener-email-profesional-gratis</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 17 Jun 2026 06:01:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7f664cc9-01f4-44f0-b1f4-cff2164d0f16_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#161;Buenos d&#237;as!</p><p>Hoy vengo a hablarte de una elegante soluci&#243;n para resolver un problema com&#250;n.</p><p>Cada vez que monto un proyecto aparece la misma situaci&#243;n: necesito un correo profesional con mi dominio, estilo &#8220;hola@tuproyecto.com&#8221;</p><p>La soluci&#243;n que aplicaba hasta hace unos meses era contratar un plan de email de Hostinger (porque el 99% de los dominios los registro desde ah&#237;). </p><p>El tema es que hacerlo de esta manera comporta pagar unos 4 euros al mes por buz&#243;n (que casi no vas a usar). </p><p>As&#237; que hoy te quiero plantear la alternativa que estoy usando desde principios de a&#241;o.</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><h3>Cloudflare + Gmail</h3><p>Cloudflare tiene un servicio gratuito llamado <strong>Email Routing</strong>. La idea es simple: en lugar de contratar un buz&#243;n de correo para cada proyecto, creas un alias.</p><p>Un alias es una direcci&#243;n como <em>hola@tuproyecto.com</em> que no tiene buz&#243;n propio. Cuando alguien te escribe ah&#237;, el mensaje llega directamente a tu Gmail.</p><p>La diferencia con Hostinger u otros hostings de email es que ellos te alojan un buz&#243;n real en sus servidores. Cloudflare no aloja nada, solo reenv&#237;a. Para el 95% de proyectos es m&#225;s que suficiente, y el coste es cero.</p><p>Puedes <strong>crear tantos alias como quieras</strong> y repetirlo con todos los dominios que tengas. Todo llega al mismo Gmail (o a la direcci&#243;n que desees).</p><p>El paso que mucha gente se salta es el del env&#237;o. Es decir, puedes configurar Gmail para que al responder, el correo salga con la direcci&#243;n de tu dominio. El destinatario ve <em>hola@tuproyecto.com</em>, no tu cuenta personal. Recibir y enviar, sin pagar nada.</p><h3>C&#243;mo se configura</h3><p><em>Parte 1: Recibir correo</em></p><ol><li><p>Entra a tu dominio en Cloudflare y ve a <strong>Compute &gt; Email Service &gt; Email Routing</strong></p></li><li><p>Haz clic en &#8220;Onboard Domain&#8221; y selecciona tu dominio. Cloudflare a&#241;ade los registros necesarios autom&#225;ticamente</p></li><li><p>Ve a <strong>Destination Addresses</strong>, a&#241;ade tu Gmail y conf&#237;rma el email de verificaci&#243;n que te mandan</p></li><li><p>Ve a <strong>Routing Rules &gt; Create routing rule</strong>, escribe el alias que quieres (hola, contacto, soporte...) y selecciona tu Gmail como destino</p></li></ol><p><em>Parte 2: Enviar desde Gmail con tu alias</em></p><ol start="5"><li><p>En Gmail ve a <strong>Ajustes &gt; Cuentas e importaci&#243;n &gt; Enviar correo como &gt; A&#241;adir otra direcci&#243;n</strong></p></li><li><p>Escribe el nombre y la direcci&#243;n del alias. Desmarca &#8220;Tratarlo como un alias&#8221;</p></li><li><p>Servidor SMTP: smtp.gmail.com, puerto 587. Usa tu cuenta Gmail con una contrase&#241;a de aplicaci&#243;n (necesitas el 2FA activado en Google)</p></li><li><p>Verifica con el c&#243;digo que llega al Gmail</p></li><li><p>Al redactar un correo ya puedes elegir desde qu&#233; direcci&#243;n env&#237;as</p></li></ol><div class="callout-block" data-callout="true"><p><span>Este setup es para correo manual: el de contacto, soporte, una landing. No sirve para emails transaccionales, es decir, confirmaciones de registro, resets de contrase&#241;a o magic links. Para eso existe </span><a href="https://resend.com/">Resend</a><span>, que veremos en una pr&#243;xima entrega.</span></p></div><h3>Nota importante para usuarios de Espa&#241;a</h3><p>En Espa&#241;a, durante los d&#237;as de <strong>partido de LaLiga</strong>, las operadoras bloquean rangos de IPs de Cloudflare para cortar retransmisiones ilegales. Tu web puede quedar inaccesible como da&#241;o colateral, sin que hayas hecho nada mal.</p><p>Si usas Cloudflare solo para Email Routing esto no te afecta. Pero si tambi&#233;n tienes la web con el proxy activo, conviene saberlo: en el panel de DNS ver&#225;s un icono de <strong>nube</strong> junto a cada registro. Si est&#225; <strong>naranja</strong>, el tr&#225;fico pasa por Cloudflare. Si est&#225; gris, va directo a tu servidor. Durante los d&#237;as de partido puedes ponerla en gris para evitar el bloqueo.</p><div><hr></div><p>&#161;Nada m&#225;s por hoy! Gu&#237;a cortita, al pie, como a mi me gustan :) </p><p>Si tienes alguna duda puedes dejar un comentario y estar&#233; encantado de ayudarte. Y si te ha gustado la publicaci&#243;n, no olvides compartirla. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir Con Criterio&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir Con Criterio</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Adiós Lovable... ¡Hola Claude Code (Desktop)!]]></title><description><![CDATA[Si llevas un tiempo construyendo con IA, probablemente hayas empezado por Lovable. Yo tambi&#233;n. Pero hay un paso natural siguiente, y es m&#225;s accesible de lo que parece.]]></description><link>https://www.concriterio.blog/p/adios-lovable-hola-claude-code-desktop</link><guid isPermaLink="false">https://www.concriterio.blog/p/adios-lovable-hola-claude-code-desktop</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 10 Jun 2026 06:01:20 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1109b925-66cc-4af7-a266-5b0b5028e525_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#161;Buenos d&#237;as!</p><p>Si me has estado siguiendo, sabr&#225;s que cuando empec&#233; a construir con IA, lo hice con ChatGPT. Mi segundo gran salto fue Lovable, una herramienta que me permiti&#243; tener un producto funcionando en horas, sin saber pr&#225;cticamente nada de c&#243;digo. </p><p>Pero <strong>con el tiempo aparecen los roces</strong>.</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>Con <strong><a href="https://lovable.dev/invite/MPJIZGX">Lovable</a></strong>, la documentaci&#243;n que te permite adjuntar la herramienta es limitada. Puedes a&#241;adir una peque&#241;a base de conocimiento, pero no una documentaci&#243;n viva que el agente consulte y actualice de forma din&#225;mica. Adem&#225;s:</p><ul><li><p><strong>Solo puedes construir con React y Vite</strong>, lo que cierra la puerta a otros stacks.</p></li><li><p><strong>Cada conversaci&#243;n queda dentro del chat</strong>, sin una forma sencilla de convertirla en conocimiento reutilizable.</p></li><li><p>La personalizaci&#243;n del agente tiene un techo bajo.</p></li><li><p>Las integraciones disponibles son las que son: no puedes conectar MCPs propios ni usar Skills.</p></li></ul><p>No es una cr&#237;tica a Lovable. Para empezar, es fant&#225;stico. Pero llega un momento en que necesitas m&#225;s.</p><div><hr></div><h3><strong>Claude Code Desktop: dos modos de trabajo</strong></h3><p>La app de Claude tiene una pesta&#241;a llamada Code. </p><p>Cuando se habla de Claude Code en LinkedIn, casi todo el mundo lo asocia a la terminal: comandos, CLI y con perfiles t&#233;cnicos. </p><p>Y es comprensible, porque as&#237; es como se present&#243; al principio. Pero existe otra forma de usarlo que muy poca gente menciona: <strong>la versi&#243;n de escritorio</strong>. Con grandes funcionalidades, una interfaz visual, y que yo, personalmente, nunca he abandonado. Todo lo que he construido con Claude Code lo he hecho desde ah&#237;. </p><p>Confesi&#243;n: Con Claude, nunca he tocado el terminal.</p><p>Desde <strong><a href="https://claude.com/download">la versi&#243;n de escritorio</a></strong> puedes trabajar de dos formas distintas:</p><div><hr></div><h4><strong>a. Modo remoto (con GitHub)</strong></h4><p>Seleccionas un repositorio de GitHub y una rama. </p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-9v2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-9v2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 424w, https://substackcdn.com/image/fetch/$s_!-9v2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 848w, https://substackcdn.com/image/fetch/$s_!-9v2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 1272w, https://substackcdn.com/image/fetch/$s_!-9v2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-9v2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png" width="1091" height="227" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:227,&quot;width&quot;:1091,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29793,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/201366219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-9v2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 424w, https://substackcdn.com/image/fetch/$s_!-9v2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 848w, https://substackcdn.com/image/fetch/$s_!-9v2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 1272w, https://substackcdn.com/image/fetch/$s_!-9v2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89c915cc-8ead-475c-99c0-7189a5cbb44c_1091x227.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Claude crea un entorno temporal en la nube donde trabaja con ese c&#243;digo. Haces tus peticiones en lenguaje natural, &#233;l implementa los cambios, y cuando est&#225;s conforme le pides que lo suba a GitHub. Limpio, trazable y sin salir del chat.</p><div><hr></div><h4><strong>b. Modo local</strong></h4><p>En lugar de un repositorio remoto, apuntas a una carpeta de tu m&#225;quina. Aqu&#237; es donde aparece algo que te resultar&#225; muy familiar si vienes de Lovable: el preview en tiempo real. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E5sN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E5sN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 424w, https://substackcdn.com/image/fetch/$s_!E5sN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 848w, https://substackcdn.com/image/fetch/$s_!E5sN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 1272w, https://substackcdn.com/image/fetch/$s_!E5sN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E5sN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png" width="1456" height="1167" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1167,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:472713,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/201366219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!E5sN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 424w, https://substackcdn.com/image/fetch/$s_!E5sN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 848w, https://substackcdn.com/image/fetch/$s_!E5sN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 1272w, https://substackcdn.com/image/fetch/$s_!E5sN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44429343-da22-440e-a8b2-52f4c34e9539_1716x1375.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Mientras Claude va haciendo cambios, los ves reflejados al instante. Y cuando quieres subir el proyecto a GitHub, simplemente se lo pides. A trav&#233;s del MCP de GitHub, Claude crea el repositorio, sube el contenido y gestiona los cambios. Sin terminal. </p><p>Una experiencia muy similar a la que ya has experimentado con Lovable, pero con todo el potencial y libertad de Claude.</p><div><hr></div><h3><strong>Por qu&#233; me parece relevante para ti</strong></h3><p>Porque en Claude Desktop tienes acceso a todo el ecosistema que ya conoces si sigues esta newsletter: Skills, MCPs, SDD desde el primer momento. Es m&#225;s, puedes:</p><ol><li><p><strong>Planificar</strong> y clarificar desde el mismo chat del proyecto. </p></li><li><p><strong>Dise&#241;ar</strong> a trav&#233;s de <strong><a href="https://claude.ai/design">Claude Design</a></strong> (y exportar lo que has hecho).</p></li><li><p><strong>Construir</strong> y desplegar a trav&#233;s del chat con Claude Code. </p></li></ol><p>No est&#225;s limitado a un stack ni a un conjunto cerrado de integraciones. Y el modelo que hay detr&#225;s es el mismo que usa Lovable, solo que sin la capa intermedia que te recorta las posibilidades.</p><div><hr></div><p>Tengo ganas de grabar o de hacer un directo. Si tienes ganas de ver el proceso completo desde la ideaci&#243;n con SDD, pasar por Claude Design y terminar cosntruyendo con Claude Code Desktop, dejame un buen comentario y montamos algo &#128522;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/adios-lovable-hola-claude-code-desktop/comments&quot;,&quot;text&quot;:&quot;Deja un comentario&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/p/adios-lovable-hola-claude-code-desktop/comments"><span>Deja un comentario</span></a></p><div><hr></div><p>&#161;Y hasta aqu&#237; la newsletter de hoy! Si te ha gustado lo que has le&#237;do no te olvides de compartirlo &#128521;</p><p></p><p>Pol Marz&#224; - AI Product Builder</p>]]></content:encoded></item><item><title><![CDATA[¿Qué pasaría si 50 personas compartieran tu producto?]]></title><description><![CDATA[En 2026 tu mayor desaf&#237;o ya no es construir, es que tu producto llegue al p&#250;blico que lo necesita. Tu mayor desaf&#237;o es la DISTRIBUCI&#211;N.]]></description><link>https://www.concriterio.blog/p/que-pasaria-si-50-personas-compartieran</link><guid isPermaLink="false">https://www.concriterio.blog/p/que-pasaria-si-50-personas-compartieran</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 03 Jun 2026 06:51:48 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/91499cda-dfec-4205-9468-cc843638f97e_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#161;Buenos d&#237;as!</p><p>&#191;C&#243;mo est&#225;s? :)</p><p>El jueves pasado estuve en Valencia. Di una charla en NTT Data, organizada por <strong>Product Beers Valencia</strong>, sobre m&#237;: sobre c&#243;mo construyo con IA desde 2023 y c&#243;mo ha cambiado por completo mi forma de hacerlo en estos casi 4 a&#241;os. De programar con ChatGPT y VSCode a orquestar agentes que hacen el 80% del trabajo pesado.</p><p>Pero lo interesante no pas&#243; en la charla. Pas&#243; despu&#233;s, con una cerveza en la mano.</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>Hablando con la gente que hab&#237;a venido, una idea sal&#237;a una y otra vez en distintas conversaciones: <strong>construir ya no es el problema.</strong> Hoy, levantar un SaaS, una app, una web o un agente est&#225; al alcance de much&#237;sima m&#225;s gente. La barrera t&#233;cnica, esa que durante a&#241;os dej&#243; fuera a los no-t&#233;cnicos, se ha difuminado. Cualquiera con una buena idea y constancia puede tener un producto funcionando en un fin de semana.</p><p>&#191;Y entonces cu&#225;l es el problema? <strong>El mismo de siempre, solo que se ha movido de sitio: la distribuci&#243;n.</strong></p><p>Puedes construir algo brillante y que no lo vea nadie. Lanzas en X, en Product Hunt, en LinkedIn&#8230; y tienes muy poco impacto. Porque las redes premian a quien <em>ya</em> tiene audiencia, y la mayor&#237;a de los que construimos en solitario tenemos audiencias peque&#241;as. Un producto t&#233;cnicamente superior puede morir en el lanzamiento simplemente porque nadie lo vio.</p><p>Esa noche, de vuelta en el hostal, no me lo pod&#237;a quitar de la cabeza. </p><p>Y se me ocurri&#243; una idea.</p><h3><strong>La idea: solos llegamos a mil; juntos, a diez mil</strong></h3><p>Imagina que lanzas tu proyecto t&#250; solo y tu audiencia es de 1.000 personas. Llegas a 1.000 personas. Punto.</p><p>Ahora imagina que <strong>diez builders de una comunidad</strong> publican sobre tu proyecto el d&#237;a del lanzamiento. Si cada uno tiene 1.000 seguidores, de repente tu alcance potencial no es 1.000: son 10.000. La comunidad no te suma, <strong>te multiplica</strong>. Te catapulta.</p><p>Esa es toda la filosof&#237;a de <strong><a href="https://swapicorn.com">Swapicorn</a></strong>.</p><h3><strong>Qu&#233; es Swapicorn</strong></h3><p>Swapicorn es un <strong>ecosistema de distribuci&#243;n colaborativa para builders de IA</strong>. No es publicidad ni un directorio m&#225;s donde subir tu link y rezar. Es un sistema de apoyo mutuo, meritocr&#225;tico y de suma positiva. Lo defino como un <strong>&#8220;sindicato de creadores&#8221;</strong>: donde el &#233;xito de uno impulsa al resto.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dFhn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dFhn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 424w, https://substackcdn.com/image/fetch/$s_!dFhn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 848w, https://substackcdn.com/image/fetch/$s_!dFhn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 1272w, https://substackcdn.com/image/fetch/$s_!dFhn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dFhn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png" width="1456" height="1032" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1032,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:458624,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/200410252?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dFhn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 424w, https://substackcdn.com/image/fetch/$s_!dFhn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 848w, https://substackcdn.com/image/fetch/$s_!dFhn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 1272w, https://substackcdn.com/image/fetch/$s_!dFhn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ab116c3-8e03-416e-a94f-ea29d38138ff_1709x1211.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Proyectos actuales en la comunidad</figcaption></figure></div><p>Funciona con un sistema de cr&#233;ditos llamados <strong>Swapis</strong>:</p><ul><li><p>Te registras, conectas tus redes y el sistema te asigna un <strong>nivel del 1 al 5</strong> seg&#250;n tu alcance.</p></li><li><p>Publicas tu proyecto y le asignas un presupuesto de swapis.</p></li><li><p><strong>Otros builders lo promocionan</strong> en sus redes y, a cambio, ganan tokens (swapis).</p></li><li><p>T&#250;, a tu vez, <strong>ganas swapis promocionando los proyectos de otros</strong>.</p></li></ul><p>Es un c&#237;rculo virtuoso: ayudas a la comunidad y la comunidad te ayuda a ti. Nadie depende de tener ya un p&#250;blico enorme ni de gastar un euro en ads. El m&#233;rito y la reciprocidad sustituyen al algoritmo y al presupuesto.</p><p>Y lo mejor: cuando alguien promociona tu proyecto, no es un bot ni un anuncio fr&#237;o. Es otro builder, con su voz y su audiencia real, cont&#225;ndole a su gente lo que has construido.</p><div><hr></div><div class="callout-block" data-callout="true"><p style="text-align: center;">Si este post te resulta &#250;til, &#191;qu&#233; te parece si lo compartes? &#128540;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/que-pasaria-si-50-personas-compartieran?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.concriterio.blog/p/que-pasaria-si-50-personas-compartieran?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p></div><div><hr></div><h3><strong>Lo constru&#237; este fin de semana (y eso es parte del mensaje)</strong></h3><p>Hay algo que me hace gracia y que encaja perfecto con la tesis de la charla: <strong>mont&#233; Swapicorn entero este fin de semana, construyendo con IA.</strong> Lo que antes habr&#237;a sido un proyecto de meses, hoy es un finde. La parte dif&#237;cil ya no era hacerlo. La parte dif&#237;cil sigue siendo que llegue a la gente adecuada.</p><p>As&#237; que Swapicorn es, en cierto modo, una soluci&#243;n construida con la propia herramienta que crea el problema. Me parece po&#233;tico.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9S81!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9S81!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 424w, https://substackcdn.com/image/fetch/$s_!9S81!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 848w, https://substackcdn.com/image/fetch/$s_!9S81!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 1272w, https://substackcdn.com/image/fetch/$s_!9S81!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9S81!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png" width="1456" height="691" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:691,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131260,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/200410252?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9S81!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 424w, https://substackcdn.com/image/fetch/$s_!9S81!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 848w, https://substackcdn.com/image/fetch/$s_!9S81!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 1272w, https://substackcdn.com/image/fetch/$s_!9S81!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7baf461-99a7-42db-88b6-f1bff61668e3_1707x810.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Lo lanc&#233; hace apenas un par de d&#237;as, lo he ido ense&#241;ando en grupos peque&#241;os y <strong>ya hay seis proyectos publicados</strong>. Est&#225; en <strong>beta</strong>: puede tener errores, cosas a medio pulir, detalles que mejorar. Cuento con ello.</p><h3><strong>Esto es para ti si construyes con IA</strong></h3><p>Si est&#225;s leyendo esto y construyes productos (solo o en equipo) y te suena eso de &#8220;lo lanc&#233; y no lo vio nadie&#8221;, <strong>Swapicorn es para ti</strong>.</p><p>Entra, sube tu proyecto y deja que la comunidad lo amplifique. Y si por el camino te encuentras un bug, una fricci&#243;n o algo que no cuadra, <strong>d&#233;jamelo en los comentarios</strong>: estoy puliendo la plataforma en directo y cada feedback me ayuda a hacerla mejor.</p><p>&#128073; <a href="https://swapicorn.com/">&#218;nete a Swapicorn</a></p>]]></content:encoded></item><item><title><![CDATA[El vibe coding no ha muerto. Solo lo estabas usando mal]]></title><description><![CDATA[&#191;Cu&#225;ndo usar vibe coding y cu&#225;ndo SDD? Esa es la pregunta que te deber&#237;as estar haciendo.]]></description><link>https://www.concriterio.blog/p/el-vibe-coding-no-ha-muerto-solo</link><guid isPermaLink="false">https://www.concriterio.blog/p/el-vibe-coding-no-ha-muerto-solo</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 27 May 2026 06:02:12 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7a2b2a8f-32db-45e7-936d-b18fdd6d7413_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>La semana pasada mi jefe lleg&#243; con un v&#237;deo de YouTube. El titular dec&#237;a algo as&#237; como que el vibe coding hab&#237;a muerto, que los datos lo demostraban, y que era hora de pasar p&#225;gina. </p><p>Lo vi. Entend&#237; el argumento. Y <strong>creo que est&#225; equivocado</strong>, aunque no por las razones que imaginas.</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>D&#233;jame contarte <strong>c&#243;mo uso yo el vibe coding</strong>, porque creo que ah&#237; est&#225; la clave.</p><p>Cuando tengo una idea, lo primero que hago no es sentarme a planificar. Lo primero que hago es construirla. Sin estructura, sin documentaci&#243;n y sin pensar demasiado. </p><p>Abro Lovable o Claude Code y les describo lo que tengo en la cabeza. En media hora tengo algo que puedo tocar. Algo que funciona m&#225;s o menos, que tiene agujeros por todos lados y que probablemente tire a la basura en dos d&#237;as.</p><p>Y eso es exactamente lo que quiero.</p><p>Porque lo que me da ese prototipo no es c&#243;digo. <strong>Me da claridad</strong>. Cuando construyes algo r&#225;pido y mal: </p><ul><li><p>Descubres los problemas reales antes de invertir tiempo en resolverlos bien. </p></li><li><p>Descubres que el flujo que imaginabas no tiene sentido cuando lo usas. </p></li><li><p>Que la funcionalidad que cre&#237;as central resulta secundaria. </p></li><li><p>Que hay un problema t&#233;cnico concreto que no hab&#237;as visto desde la descripci&#243;n.</p></li></ul><p>Despu&#233;s de ese prototipo, lo tiro. Y construyo de nuevo, esta vez con <strong><a href="https://www.nexy.ai/es/concept/desarrollo-guiado-por-especificaciones-sdd">SDD</a></strong>. Pero ya no estoy construyendo a ciegas. S&#233; lo que quiero que haga la aplicaci&#243;n. S&#233; los retos a los que me voy a enfrentar. <strong>Tengo criterio para tomar decisiones</strong> porque ya he tropezado con los problemas una vez.</p><p>El vibe coding no es una metodolog&#237;a de desarrollo. Es una <strong>metodolog&#237;a de exploraci&#243;n</strong>. Y los que dicen que ha muerto est&#225;n comparando dos cosas que no compiten entre s&#237;.</p><p>Los datos que citan esos v&#237;deos son reales: la gente que intent&#243; lanzar productos serios solo con vibe coding se encontr&#243; con c&#243;digo fr&#225;gil, <strong><a href="https://www.nexy.ai/es/concept/deuda-tecnica">deuda t&#233;cnica</a></strong> imposible de gestionar y aplicaciones que no escalaban. Pero ese no es un problema del vibe coding; es un problema de <strong>usarlo para lo que no fue pensado</strong>.</p><div><hr></div><div class="callout-block" data-callout="true"><p style="text-align: center;">Si este post te resulta &#250;til, &#191;qu&#233; te parece si lo compartes? &#128540;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/el-vibe-coding-no-ha-muerto-solo?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.concriterio.blog/p/el-vibe-coding-no-ha-muerto-solo?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p></div><div><hr></div><p>Para recapitular antes de cerrar: </p><p><strong>1. Vibe codea tu idea</strong> &#8594; Sin pensar demasiado. El objetivo no es el c&#243;digo, es entender si la idea tiene sentido cuando la tocas con las manos.</p><p><strong>2. Clarifica tus hallazgos</strong> &#8594; Antes de tirar el prototipo, documenta lo que has aprendido. Qu&#233; funcion&#243;, qu&#233; no, qu&#233; problema real has descubierto debajo del problema que cre&#237;as tener.</p><p><strong>3. Redacta los docs en SDD</strong> &#8594; Ahora s&#237;. Con ese conocimiento encima de la mesa, define la arquitectura, el modelo de datos, el comportamiento esperado. Ya no est&#225;s especulando, est&#225;s describiendo algo que entiendes.</p><p><strong>4. Construye con Claude Code</strong> &#8594; Con los docs como contexto, el agente tiene todo lo que necesita para generar c&#243;digo que no tendr&#225;s que tirar.</p>]]></content:encoded></item><item><title><![CDATA[La actualización más radical de Lovable]]></title><description><![CDATA[Lovable y el SEO siempre han estado re&#241;idos. Hasta ahora.]]></description><link>https://www.concriterio.blog/p/la-actualizacion-mas-grande-de-lovable</link><guid isPermaLink="false">https://www.concriterio.blog/p/la-actualizacion-mas-grande-de-lovable</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 20 May 2026 06:01:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4499132c-2adb-4c21-ab4f-b07fa82d71d2_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Si me conoces, sabes que a cualquier persona que me preguntaba si pod&#237;a hacer la web de su negocio con Lovable, siempre le respond&#237;a: ni en pintura. No porque fuese una mala herramienta sino porque, a ojos de los robots de Google (o LLMs), los proyectos que all&#237; constru&#237;as estaban vac&#237;os. </p><p>Hablo en pasado porque <strong>esto acaba de cambiar</strong>. </p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>Para entender qu&#233; ha pasado, primero necesitas saber por qu&#233; estaba roto. </p><p>Cuando visitas una web, tu navegador recibe un documento HTML y lo muestra. Pero hay dos formas de generar ese documento:</p><ul><li><p><strong><a href="https://www.nexy.ai/es/concept/renderizado-del-lado-del-servidor-ssr">SSR</a>  </strong>(Server-Side Rendering): el servidor te lo manda ya construido, con todo el contenido dentro. </p></li><li><p><strong><a href="https://www.nexy.ai/es/concept/single-page-application-spa">SPA</a> </strong>(Single Page Application): el servidor te manda un esqueleto casi vac&#237;o y un mont&#243;n de JavaScript que se ejecuta en tu navegador para construir la p&#225;gina. </p></li></ul><p>T&#250;, como usuario, no notas la diferencia. Ves el t&#237;tulo, el texto, las im&#225;genes. Todo normal. El problema es que los robots no funcionan como t&#250;.</p><p>Cuando Google rastrea una web, manda un programa que descarga el HTML inicial y lo lee tal cual. En una web construida con Lovable, ese HTML inicial era b&#225;sicamente un <code>&lt;div&gt;</code> vac&#237;o (era una SPA). El contenido real lo generaba <strong><a href="https://es.react.dev/">React</a></strong> despu&#233;s, en tu navegador, pero para cuando eso ocurr&#237;a el robot ya se hab&#237;a ido. Lo mismo le pasaba a ChatGPT, a Perplexity, a cualquier herramienta que intentase leer el contenido de tu app a partir de su URL.</p><p>Llevaba meses se&#241;alando esto en LinkedIn cada vez que el tema sal&#237;a. Si necesitabas posicionamiento, recomendaba <strong><a href="https://astro.build">Astro</a></strong>, <strong><a href="https://nextjs.org/">Next.js</a></strong>, o trabajar directamente con Claude Code. Herramientas que generan el HTML completo en el servidor (SSR) antes de mand&#225;rtelo, para que cuando llegue el robot encuentre algo que leer.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NqtP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NqtP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 424w, https://substackcdn.com/image/fetch/$s_!NqtP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 848w, https://substackcdn.com/image/fetch/$s_!NqtP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 1272w, https://substackcdn.com/image/fetch/$s_!NqtP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NqtP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:96075,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/198447352?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NqtP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 424w, https://substackcdn.com/image/fetch/$s_!NqtP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 848w, https://substackcdn.com/image/fetch/$s_!NqtP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 1272w, https://substackcdn.com/image/fetch/$s_!NqtP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54be315d-31d6-4b44-b097-8e7e1c075728_1848x1232.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Lovable acaba de hacer exactamente eso. Los proyectos nuevos se construyen sobre <strong><a href="https://tanstack.com/start/latest">TanStack Start</a></strong>, un framework con renderizado en el servidor nativo. Las p&#225;ginas llegan al navegador ya completas. Google las puede leer desde el primer momento. ChatGPT tambi&#233;n. Y los proyectos existentes reciben autom&#225;ticamente un sistema de snapshots est&#225;ticos que hace accesible el contenido a los <strong><a href="https://www.nexy.ai/es/concept/crawlers">crawlers</a></strong> sin que tengas que migrar nada ni tocar ning&#250;n ajuste.</p><p>Es un cambio t&#233;cnico, s&#237;. Pero lo que representa va m&#225;s all&#225; de la t&#233;cnica. Lovable lleva tiempo siendo la herramienta favorita para construir prototipos r&#225;pidos, pero con este movimiento est&#225; diciendo que quiere ser algo m&#225;s: una plataforma desde la que lanzar productos reales, que compitan, que el mundo pueda encontrar. </p><div><hr></div><div class="callout-block" data-callout="true"><p style="text-align: center;">Si este post te resulta &#250;til, &#191;qu&#233; te parece si lo compartes? &#128540;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/la-actualizacion-mas-grande-de-lovable?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.concriterio.blog/p/la-actualizacion-mas-grande-de-lovable?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p></div><div><hr></div><p>Hoy el post ha sido algo m&#225;s cortito, con un par de enlaces a las definiciones de SSR y SPA en <strong><a href="https://nexy.ai">nexy.ai</a></strong> y otros enlaces a las webs de frameworks. &#191;Qu&#233; te parece este formato? D&#233;jame tu opini&#243;n en los comentarios :) </p><p>Por cierto, el pr&#243;ximo jueves 28 de mayo estar&#233; en Valencia dando una charla con los compa&#241;eros de <strong><a href="https://www.linkedin.com/company/product-beers/">Product Beers Valencia</a></strong>. Explicar&#233; como ha sido mi camino de AI CODING, desde mis inicios con ChatGPT en noviembre de 2022 hasta Claude Code. Hablar&#233; de la mentalidad maker m&#225;s que de las herramientas, explicar&#233; mi experiencia construyendo, desde los proyectos Frankenstein hasta el SDD. </p><p>Si est&#225;s por Valencia, &#161;<strong><a href="https://www.linkedin.com/safety/go/?url=https%3A%2F%2Flnkd.in%2FesqQV5Xw&amp;urlhash=Onh4&amp;mt=y8cA7zyewZ7669ddwk8JcVoTHKd8nKt__OQA7NF2U2G1VTdmnk8YSLrltq03UsxL0zGXd5iaPWUs0z1QrLHmYoNZmj7NuMZNEJxMWgGgMzHtw-A6_WxOKGoE&amp;isSdui=true&amp;lipi=urn%3Ali%3Apage%3Ad_flagship3_detail_base%3Bc5GoPB0tSN6819tDJAxsqQ%3D%3D">ap&#250;ntate</a></strong> que las reservas est&#225;n volando! </p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[¿Tu app es segura? 3 validaciones antes de lanzar]]></title><description><![CDATA[No necesitas ser experto en ciberseguridad para aplicar un nivel de protecci&#243;n decente. Necesitas tres h&#225;bitos y dos herramientas.]]></description><link>https://www.concriterio.blog/p/tu-app-es-segura-3-validaciones-antes</link><guid isPermaLink="false">https://www.concriterio.blog/p/tu-app-es-segura-3-validaciones-antes</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 06 May 2026 06:02:48 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c75d6595-9a74-40f4-8aa2-3d21618c9340_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Construir r&#225;pido tiene un precio que no siempre se ve en el momento: el c&#243;digo que genera la IA funciona, pero no siempre es seguro. Y "funciona" y "es seguro" son dos propiedades distintas.</p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>Hoy hablaremos de seguridad en nuestros desarrollos &#129299;</p><p>Te hago un peque&#241;o resumen por si quieres ir directamente a ese apartado que m&#225;s te interese:</p><ul><li><p><strong>Las imperdibles</strong>&#8212; Variables de entorno, RLS en Supabase y rotaci&#243;n de keys: lo que ninguna herramienta puede compensar si lo ignoras.</p></li><li><p><code>/security-review</code><strong> en Claude Code</strong> &#8212; El comando nativo de Anthropic que audita tu c&#243;digo antes de cada deploy, sin configuraci&#243;n.</p></li><li><p><strong>Aikido: escaneo continuo</strong> &#8212; Conecta tu repositorio y vigila vulnerabilidades en segundo plano, gratis hasta 10 repos.</p></li><li><p><strong>Bonus: pentesting en Lovable</strong> &#8212; Agentes que atacan tu app en vivo para encontrar lo que el an&#225;lisis est&#225;tico no ve.</p></li></ul><p>Ahora s&#237;, &#161;empezamos!</p><div><hr></div><h2>1. Las imperdibles</h2><p>Antes de hablar de herramientas, hay decisiones de arquitectura que ning&#250;n esc&#225;ner puede compensar si las ignoras desde el principio.</p><p><strong>Nunca hardcodees credenciales en el c&#243;digo.</strong> Las API keys, tokens de base de datos y secrets no deben estar escritos en ning&#250;n archivo de tu repositorio, ni en comentarios, ni en archivos de configuraci&#243;n que subes a <strong><a href="https://github.com">GitHub</a></strong>. Esto parece obvio hasta que ves a alguien publicar un repo con las keys de Stripe expuestas.</p><p>La alternativa es usar variables de entorno. En <strong><a href="https://vercel.com">Vercel</a></strong> las gestionas desde el panel del proyecto (Settings &#8594; Environment Variables). En Supabase tienes las claves de servicio accesibles desde Project Settings &#8594; API. Tu c&#243;digo lee esas variables pero nunca las contiene.</p><p><strong>Activa Row Level Security en Supabase desde el inicio.</strong> Si construyes con <strong><a href="https://supabase.com">Supabase</a></strong> y no activas RLS en tus tablas, cualquier usuario autenticado puede leer (o modificar) los datos de cualquier otro usuario. No es una vulnerabilidad avanzada, es la configuraci&#243;n por defecto cuando creas una tabla sin pol&#237;ticas.</p><p>Act&#237;valo al crear la tabla, no despu&#233;s. A&#241;adirlo retroactivamente cuando ya tienes datos y l&#243;gica construida es m&#225;s costoso y m&#225;s f&#225;cil de hacer mal.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vsuo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vsuo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 424w, https://substackcdn.com/image/fetch/$s_!vsuo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 848w, https://substackcdn.com/image/fetch/$s_!vsuo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 1272w, https://substackcdn.com/image/fetch/$s_!vsuo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vsuo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic" width="1277" height="743" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:743,&quot;width&quot;:1277,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:44894,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/196579469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vsuo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 424w, https://substackcdn.com/image/fetch/$s_!vsuo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 848w, https://substackcdn.com/image/fetch/$s_!vsuo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 1272w, https://substackcdn.com/image/fetch/$s_!vsuo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d1162ce-2572-4d03-943a-0c6308268c97_1277x743.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Rota las keys si sospechas una exposici&#243;n.</strong> Si en alg&#250;n momento una key estuvo en un commit, en un mensaje de chat, o en cualquier lugar fuera de las variables de entorno, inval&#237;dala y genera una nueva. El tiempo que tardas en rotar es menor que el da&#241;o potencial.</p><div><hr></div><h2>2. Auditor&#237;a con Claude Code: el comando <code>/security-review</code></h2><p>Claude Code incluye por defecto un slash command mantenido por Anthropic llamado <code>/security-review</code>. No hay que instalarlo ni configurarlo: est&#225; ah&#237; desde el primer momento.</p><p>Lo que hace es analizar los cambios pendientes en tu codebase buscando vulnerabilidades reales y explotables. No es una b&#250;squeda por patrones superficiales: examina el c&#243;digo en contexto, entiende qu&#233; hace cada parte y filtra los falsos positivos para darte solo hallazgos que merecen atenci&#243;n.</p><p>Las categor&#237;as que cubre:</p><ul><li><p>Inyecci&#243;n de SQL, comandos y otros vectores de inyecci&#243;n</p></li><li><p>Problemas de autenticaci&#243;n y autorizaci&#243;n (escalada de privilegios, bypass de sesiones)</p></li><li><p>Exposici&#243;n de datos sensibles y secrets en el c&#243;digo</p></li><li><p>Problemas criptogr&#225;ficos</p></li><li><p>Configuraciones inseguras</p></li></ul><p><strong>C&#243;mo usarlo:</strong> abre Claude Code en tu proyecto, escribe <code>/security-review</code> y deja que analice. El momento ideal es antes de cada deploy relevante, especialmente si has tocado autenticaci&#243;n, esquema de base de datos o endpoints de API.</p><p>Tambi&#233;n puedes integrarlo en GitHub Actions para que revise autom&#225;ticamente cada pull request. El repositorio oficial de Anthropic (<code>anthropics/claude-code-security-review</code>) tiene el workflow listo para copiar.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FECb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FECb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 424w, https://substackcdn.com/image/fetch/$s_!FECb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 848w, https://substackcdn.com/image/fetch/$s_!FECb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 1272w, https://substackcdn.com/image/fetch/$s_!FECb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FECb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic" width="905" height="297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:297,&quot;width&quot;:905,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:13082,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/196579469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FECb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 424w, https://substackcdn.com/image/fetch/$s_!FECb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 848w, https://substackcdn.com/image/fetch/$s_!FECb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 1272w, https://substackcdn.com/image/fetch/$s_!FECb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F102f3e4c-5536-498c-ad2e-c92c025b58bd_905x297.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Un par de enlaces de inter&#233;s:</p><ul><li><p><strong><a href="https://support.claude.com/en/articles/11932705-automated-security-reviews-in-claude-code">Documentaci&#243;n oficial</a></strong> sobre /security-review en el blog de Anthropic. </p></li><li><p><strong><a href="https://github.com/anthropics/claude-code-security-review">Repositorio</a></strong> oficial en Github. </p></li></ul><div><hr></div><h2>3. Aikido: escaneo continuo del repositorio</h2><p><code>/security-review</code> analiza tus cambios de forma manual y bajo demanda. <strong><a href="https://www.aikido.dev">Aikido</a></strong> hace algo diferente: conecta con tu repositorio de GitHub, lo escanea de forma autom&#225;tica cada pocos d&#237;as y te avisa cuando encuentra algo.</p><p>El plan gratuito incluye hasta 10 repositorios, 2 usuarios y escaneo b&#225;sico. Para un builder individual o un equipo peque&#241;o es suficiente para tener visibilidad continua sin pagar nada.</p><p>Lo que escanea en el plan gratuito:</p><ul><li><p><strong>SCA</strong> (Software Composition Analysis): vulnerabilidades conocidas en tus dependencias npm. Las librer&#237;as que instalas tambi&#233;n tienen CVEs, y Aikido los detecta antes de que alguien los explote.</p></li><li><p><strong>SAST</strong> (Static Application Security Testing): an&#225;lisis est&#225;tico del c&#243;digo buscando patrones de vulnerabilidad.</p></li><li><p><strong>Detecci&#243;n de secrets</strong>: credenciales que pudieran haberse filtrado en el repositorio.</p></li><li><p><strong>Escaneo de cloud</strong>: misconfigurations en tu cuenta de Vercel, AWS o GCP si la conectas.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qh1b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qh1b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 424w, https://substackcdn.com/image/fetch/$s_!Qh1b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 848w, https://substackcdn.com/image/fetch/$s_!Qh1b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 1272w, https://substackcdn.com/image/fetch/$s_!Qh1b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qh1b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png" width="1456" height="1086" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1086,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:301409,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/196579469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Qh1b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 424w, https://substackcdn.com/image/fetch/$s_!Qh1b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 848w, https://substackcdn.com/image/fetch/$s_!Qh1b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 1272w, https://substackcdn.com/image/fetch/$s_!Qh1b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9613715-4e12-4a09-9611-2bfcd3432be0_1645x1227.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>La diferencia respecto a otras herramientas similares es la reducci&#243;n de ruido. Contextualiza los hallazgos seg&#250;n tu entorno real y descarta los que no suponen un riesgo efectivo. Menos alertas, m&#225;s se&#241;al.</p><p><strong>C&#243;mo empezar:</strong> entra en aikido.dev, conecta tu cuenta de GitHub y selecciona los repositorios que quieras monitorizar. El primer escaneo tarda entre 1 y 5 minutos.</p><div><hr></div><h2>Bonus track: pentesting con Aikido en Lovable</h2><p>Si construyes con Lovable, hay una capa adicional disponible desde marzo de 2026: <strong><a href="https://docs.lovable.dev/integrations/aikido">pentesting con IA</a></strong> directamente integrado en el editor.</p><p>La distinci&#243;n importante es que el esc&#225;ner de seguridad de Lovable (que ya exist&#237;a) hace an&#225;lisis est&#225;tico: lee el c&#243;digo y detecta patrones problem&#225;ticos. El pentesting de Aikido hace an&#225;lisis din&#225;mico: despliega agentes que atacan la aplicaci&#243;n en vivo, como lo har&#237;a un atacante real. Prueban flujos de autenticaci&#243;n, intentan acceder a datos de otros usuarios, sondean las APIs.</p><p>Las dos cosas son complementarias:</p><ul><li><p>El <strong>est&#225;tico</strong> detecta lo que podr&#237;a ir mal en el c&#243;digo. </p></li><li><p>El <strong>din&#225;mico</strong> detecta lo que efectivamente se rompe cuando alguien lo intenta.</p></li></ul><p>Para proyectos en Lovable, el precio de lanzamiento es de 100 d&#243;lares por test. Tambi&#233;n hay &#8220;Security weekends&#8221; gratuitos anunciados puntualmente. El modelo de pago es c&#243;modo: puedes iniciar el pentest sin pagar y solo desbloqueas el informe completo si decides que los hallazgos merecen el coste.</p><p>El flujo desde Lovable: Settings &#8594; Connectors &#8594; App connectors &#8594; Aikido. Desde ah&#237; puedes lanzar el test y los hallazgos se sincronizan directamente en tu proyecto para corregirlos sin salir del editor.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gxCT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gxCT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 424w, https://substackcdn.com/image/fetch/$s_!gxCT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 848w, https://substackcdn.com/image/fetch/$s_!gxCT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 1272w, https://substackcdn.com/image/fetch/$s_!gxCT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gxCT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png" width="1456" height="494" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:494,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Lovable se asocia con Aikido para llevar el pentesting a las aplicaciones  Vibe-Coded&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Lovable se asocia con Aikido para llevar el pentesting a las aplicaciones  Vibe-Coded" title="Lovable se asocia con Aikido para llevar el pentesting a las aplicaciones  Vibe-Coded" srcset="https://substackcdn.com/image/fetch/$s_!gxCT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 424w, https://substackcdn.com/image/fetch/$s_!gxCT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 848w, https://substackcdn.com/image/fetch/$s_!gxCT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 1272w, https://substackcdn.com/image/fetch/$s_!gxCT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda071c73-9c40-4a0f-bf30-1d5803b63526_1600x543.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>El orden l&#243;gico</h2><p>Las tres validaciones no son alternativas, son capas:</p><ol><li><p>Las buenas pr&#225;cticas son el suelo. Sin ellas, nada de lo dem&#225;s importa.</p></li><li><p><code>/security-review</code> es la revisi&#243;n activa antes de cada deploy importante.</p></li><li><p>Aikido es la vigilancia continua en segundo plano.</p></li></ol><p>El pentesting es el siguiente paso cuando el producto ya est&#225; en producci&#243;n y quieres poder demostrar, no solo suponer, que es seguro.</p><p>Construir r&#225;pido no obliga a construir inseguro. Solo requiere que estas validaciones sean parte del flujo desde el principio, no algo que se a&#241;ade cuando ya hay un problema.</p><div><hr></div><div class="callout-block" data-callout="true"><p style="text-align: center;">Si este post te resulta &#250;til, &#191;qu&#233; te parece si lo compartes? &#128540;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/tu-app-es-segura-3-validaciones-antes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.concriterio.blog/p/tu-app-es-segura-3-validaciones-antes?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p></div><div><hr></div><p>&#161;Y hasta aqu&#237; la newsletter de esta semana! Espero que no haya sido muy densa.</p><p>Lo bueno de todo esto es que, como digo al final, &#161;lo puedes empezar a aplicar desde YA! No esperes a que salgan errores. </p><p>&#161;Nos vemos la pr&#243;xima semana!</p><p>Un abrazo. </p>]]></content:encoded></item><item><title><![CDATA[yoleo: pasado, presente y futuro de mi plataforma de libros]]></title><description><![CDATA[yoleo responde a la pregunta: "&#191;y ahora qu&#233; leo?"]]></description><link>https://www.concriterio.blog/p/yoleo-pasado-presente-y-futuro-de</link><guid isPermaLink="false">https://www.concriterio.blog/p/yoleo-pasado-presente-y-futuro-de</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 29 Apr 2026 06:00:34 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7790fd4e-55cd-45db-9037-3ad14770e31b_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#161;Buenos d&#237;as!</p><p>Antes de nada, disc&#250;lpame por no escribir desde principios de mes&#8230; Pero hoy si, hoy vamos a hablar de algo que ya adelant&#233; hace unos d&#237;as en LinkedIn. Hoy vamos a hablar de <strong><a href="https://yoleo.io">yoleo</a></strong>. </p><div><hr></div><p><em>Hola, soy Pol Marz&#224;, AI Product Builder y cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><h2>yoleo v1</h2><p>La primera vez que constru&#237; yoleo no ten&#237;a ni idea de programar. </p><p>2023 acababa de empezar. Unos pocos meses antes hab&#237;a llegado a nuestras vidas la versi&#243;n comercial de ChatGPT y, con ella, la promesa de poder construir cualquier cosa con la ayuda de la IA. O eso pensaba yo &#128517;</p><p>Pero si, lo constru&#237;. </p><p>Para esa primera versi&#243;n solo us&#233; HTML, CSS y JS. El funcionamiento era sencillo: ten&#237;as un input (una caja de texto) donde escrib&#237;as el t&#237;tulo de un libro que te hab&#237;a gustado. Luego, por detr&#225;s, yo lanzaba una petici&#243;n a la API de OpenAI (ChatGPT) con un <em>prompt</em> tipo:</p><p>&#8220;Act&#250;a como un librero y dame 5 libros que tengan relaci&#243;n sem&#225;ntica con {libro}&#8221;</p><p>Pero esta primera versi&#243;n ten&#237;a dos problemas:</p><ol><li><p>ChatGPT alucinaba bastante (se inventaba t&#237;tulos)</p></li><li><p>&#161;ALERTA! La clave API estaba expuesta en el c&#243;digo</p></li></ol><p>El primer problema ten&#237;a un pase, no era cr&#237;tico. Pero el segundo&#8230; Ese s&#237; que pod&#237;a ser un problem&#243;n &#128579;</p><p>Lo intent&#233; ocultar, lo intent&#233; enmascarar, pero si sab&#237;as lo que buscabas&#8230; No era dif&#237;cil de encontrar. </p><div><hr></div><h2>yoleo v2</h2><p>Unos meses m&#225;s tarde de construir esta primera versi&#243;n, un compa&#241;ero de trabajo me present&#243; a un desarrollador llamado <strong><a href="https://www.linkedin.com/in/pablofguillen/">Pablo</a></strong>. </p><p>Con &#233;l, constru&#237; la segunda versi&#243;n de yoleo. Pablo se encarg&#243; de toda la parte de backend y base de datos. Yo me encargu&#233; del front y de la direcci&#243;n de producto. </p><p>Juntos fuimos tomando decisiones importantes y resolvimos los problemas de la primera versi&#243;n:</p><ol><li><p>Alucinaciones &#8594; Compar&#225;bamos cada libro devuelto por ChatGPT con la API de Google Books. Si exist&#237;a lo mostr&#225;bamos al usuario y si no, no. </p></li><li><p>API expuesta &#8594; Ahora ya en variables de entorno. Lejos de ojos fisgones. </p></li><li><p>A&#241;adimos la opci&#243;n de que el usuario se pudiera registrar para tener un historial de sus libros buscados. </p></li></ol><p>Con todo esto, en 2024 presentamos el proyecto en LinkedIn y a alguien le pareci&#243; interesante qu&#233; y c&#243;mo lo hab&#237;amos construido, as&#237; que nos fuimos para Madrid a presentarlo. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bkio!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bkio!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 424w, https://substackcdn.com/image/fetch/$s_!Bkio!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 848w, https://substackcdn.com/image/fetch/$s_!Bkio!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 1272w, https://substackcdn.com/image/fetch/$s_!Bkio!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bkio!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:373897,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/195788576?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Bkio!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 424w, https://substackcdn.com/image/fetch/$s_!Bkio!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 848w, https://substackcdn.com/image/fetch/$s_!Bkio!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 1272w, https://substackcdn.com/image/fetch/$s_!Bkio!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1d8707f-5c56-4bf7-affe-06018512d698_2048x1536.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>yoleo v3</h2><p>Y aqu&#237; llegamos a la versi&#243;n actual del proyecto &#129395;</p><p>&#191;Qu&#233; ha cambiado?</p><ol><li><p>Para las peticiones de la API ya no uso (solamente) ChatGPT, sino que uso la API de <strong><a href="https://openrouter.ai">Openrouter</a> </strong>y voy cambiando de proveedores. Al principio empec&#233; con Gemini 2.5 Flash, pero ahora estoy usando Deepseek v3.2 que ofrece resultados parecidos a un coste menor. </p></li><li><p>En la v2 de yoleo us&#225;bamos MongoDB. Ahora uso Supabase tanto para almacenar los datos (libros, autores, portadas, preferencias de los usuarios&#8230;) como para el OAuth con Google. </p></li><li><p>En un principio, esta versi&#243;n usaba la <em>search_tool</em> (a trav&#233;s de la API), tanto para buscar libros nuevos como para ofrecer las recomendaciones (en cada ficha se ofrecen hasta  8 libros relacionados), pero era MUY caro. Ahora funciona con <strong>embeddings</strong> de libros que ya se encuentran dentro de yoleo. Es decir, he vectorizado los 50k libros. </p></li></ol><p>Lo que m&#225;s me gusta de esta nueva versi&#243;n es:</p><ul><li><p>Las portadas &#8594; Ten&#237;a un problema con ellas, ya que la API de Google Books y la de Open Library, la mitad de las veces no me devolv&#237;an la portada del libro en su idioma o directamente no me devolv&#237;an nada &#129315; As&#237; que dije &#8220;hasta aqu&#237;&#8221; y, lo que ten&#237;a que ser un parche se ha convertido en una de sus se&#241;as. </p><p>Las portadas son generadas al vuelo y se toma su <em>main_category</em> como referencia para elegir el color de la portada. Adem&#225;s, tambi&#233;n se a&#241;ade el autor/a, el t&#237;tulo y a&#241;o de publicaci&#243;n. </p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qzd4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qzd4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qzd4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qzd4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qzd4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qzd4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg" width="1155" height="949" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:949,&quot;width&quot;:1155,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:114295,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/195788576?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe2bfc3c-ee49-4f03-ae00-c1e12343ea30_1155x1221.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qzd4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qzd4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qzd4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qzd4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f6fb956-93e7-42e3-b067-cd278668fa59_1155x949.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>Afinidad &#8594; Esto es algo que no he encontrado en otras p&#225;ginas y se trata de mostrarte como de posible es que te guste un libro en funci&#243;n de los libros que hayas valorado o le&#237;do previamente. Lo mejor de todo es que no usa IA sino que se basa en los libros que has le&#237;do o puntuado. Pura l&#243;gica. Puedes desbloquear la afinidad cuando hayas valorado/a&#241;adido un m&#237;nimo de 5 libros a tu biblioteca &#129392;</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!984C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!984C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 424w, https://substackcdn.com/image/fetch/$s_!984C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 848w, https://substackcdn.com/image/fetch/$s_!984C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 1272w, https://substackcdn.com/image/fetch/$s_!984C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!984C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic" width="1456" height="1093" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1093,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:77945,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.concriterio.blog/i/195788576?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!984C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 424w, https://substackcdn.com/image/fetch/$s_!984C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 848w, https://substackcdn.com/image/fetch/$s_!984C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 1272w, https://substackcdn.com/image/fetch/$s_!984C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e18426-9d31-4c94-99f0-bfa74936fcd9_1608x1207.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><p>Hay m&#225;s cosas y muchas m&#225;s que espero ir a&#241;adiendo (poco a poco) a yoleo. </p><p>Y muchas otras cosas que ya existen, pero no puedo explicarlas todas. As&#237; que te dejo que seas tu quien las descubras &#129303; Actualmente la plataforma cuenta con:</p><p>Una de las cosas que he decidido hacer en este proyecto es intentar ser lo m&#225;s transparente posible, tanto en cuanto a los datos de la plataforma (n&#250;mero de libros, autores y usuarios) con contadores din&#225;micos que encontrar&#225;s mientras navegas por yoleo, como lo que me cuesta mantener el proyecto en marcha (lo puedes ver al final de la landing).</p><p>De cara a las pr&#243;ximas semanas, me gustar&#237;a seguir mejorando la plataforma pero eso solo tendr&#225; sentido si te registras, compartes y le das cari&#241;o a <strong><a href="https://yoleo.io">yoleo</a></strong>. </p><p>&#191;Hay hueco para otra plataforma de libros? </p><p>&#191;Qu&#233; echas de menos en la plataforma actual? </p><p>D&#233;jamelo en los comentarios &#128071;</p><div><hr></div><p>&#161;Y hasta aqu&#237; la newsletter!</p><p>Nos vemos pr&#243;ximamente :)</p>]]></content:encoded></item><item><title><![CDATA[Fabric.js: La librería que convierte píxeles en objetos que puedes tocar]]></title><description><![CDATA[Como construir un editor visual en el navegador sin tocar la API de canvas a pelo.]]></description><link>https://www.concriterio.blog/p/fabricjs-la-libreria-que-convierte</link><guid isPermaLink="false">https://www.concriterio.blog/p/fabricjs-la-libreria-que-convierte</guid><pubDate>Wed, 08 Apr 2026 06:01:53 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4660a8cf-39bb-420e-89e9-c35c29fc7f5a_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Hola, soy Pol Marz&#224;. Cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><p><em>Esta es una nueva secci&#243;n dentro de la newsletter donde hablo sobre distintas herramientas que encuentro. Te explico qu&#233; es, c&#243;mo funciona, c&#243;mo integrarla y luego te muestro una demo que he construido y que cuelgo en <strong><a href="https://concriterio.tools">concriterio.tools</a></strong> </em></p><blockquote><p>Hoy hablamos de <strong><a href="https://fabricjs.com">Fabric</a></strong></p></blockquote><div><hr></div><p>Cuando Figma no exist&#237;a y Flash empezaba a morir, los desarrolladores que quer&#237;an crear editores gr&#225;ficos en el navegador, se encontraban con un problema: el canvas de HTML era muy limitado para un trabajo interactivo. Pod&#237;as dibujar formas, s&#237;, pero no pod&#237;as seleccionarlas. No pod&#237;as moverlas y el navegador no recordaba nada de lo que hab&#237;as pintado.</p><div class="callout-block" data-callout="true"><p>El elemento <strong><a href="https://www.nexy.ai/es/concept/canvas-de-html5">&lt;canvas&gt; de HTML5</a></strong> es un &#225;rea rectangular en una p&#225;gina web dise&#241;ada para dibujar gr&#225;ficos din&#225;micos utilizando JavaScript. Funciona como un lienzo digital al que se accede mediante c&#243;digo, permitiendo la creaci&#243;n de animaciones, juegos y visualizaciones interactivas.</p></div><p>Fabric.js naci&#243; en 2010, creado por <strong>Juriy Zaytsev</strong>, como soluci&#243;n a esa complejidad. Surgi&#243; de la necesidad pr&#225;ctica de tener una forma m&#225;s accesible de crear aplicaciones gr&#225;ficas interactivas en el navegador. Su autor estaba construyendo un editor para personalizar ropa online. La interactividad que necesitaba solo exist&#237;a en Flash. As&#237; que construy&#243; la capa que faltaba.</p><h2>Qu&#233; es exactamente</h2><p>Fabric.js es como una caja de herramientas que te permite trabajar de manera m&#225;s intuitiva: en lugar de pensar en p&#237;xeles individuales, trabajas con objetos (rect&#225;ngulos, im&#225;genes, textos) que puedes mover, rotar y modificar f&#225;cilmente. </p><p>La librer&#237;a maneja autom&#225;ticamente las cosas complicadas: detecta cu&#225;ndo haces clic en una forma, permite arrastrar objetos, rotar figuras con el rat&#243;n y gestiona el redibujado de todo el canvas. T&#250; defines qu&#233; hay en el canvas y Fabric se encarga del resto.</p><h2>Cu&#225;ndo usarlo vs cu&#225;ndo no</h2><p>Usa Fabric cuando el usuario necesita manipular elementos visuales directamente: editores de im&#225;genes, constructores de slides, herramientas de anotaci&#243;n, configuradores de producto. Cualquier aplicaci&#243;n donde los usuarios necesiten interactuar visualmente con elementos en pantalla. </p><p>No lo uses para visualizaciones de datos o juegos donde el rendimiento del render importa m&#225;s que la interactividad de objetos. Para eso hay opciones m&#225;s ligeras. Fabric es un editor de objetos, no un motor de juego.</p><p><strong>Pricing</strong>: MIT, libre. Sin tokens, sin tiers. Es una librer&#237;a npm.</p><div class="callout-block" data-callout="true"><p>Una <strong><a href="https://www.nexy.ai/es/concept/libreria-npm">librer&#237;a npm</a></strong> es esencialmente un paquete de c&#243;digo reutilizable para JavaScript. NPM (Node Package Manager) es la herramienta que permite a los desarrolladores encontrar, instalar y gestionar estas librer&#237;as (o paquetes) en sus proyectos.</p></div><h2>C&#243;mo se integra</h2><p>bash</p><pre><code><code>npm install fabric</code></code></pre><p>typescript</p><pre><code><code>import { Canvas, FabricImage, FabricText } from 'fabric'

const canvas = new Canvas('canvas-element', { width: 800, height: 600 })

// Cargar imagen
const img = await FabricImage.fromURL('/foto.jpg')
canvas.add(img)

// A&#241;adir texto que el usuario puede mover y escalar
const text = new FabricText('Tu texto aqu&#237;', {
  left: 100, top: 100,
  fontSize: 32, fill: '#ffffff',
})
canvas.add(text)

// Exportar como PNG
const dataURL = canvas.toDataURL({ format: 'png' })</code></code></pre><p>Con eso tienes selecci&#243;n, movimiento y escala de objetos funcionando por defecto. <code>.toJSON()</code> serializa el estado completo del canvas para guardarlo. <code>.loadFromJSON()</code> lo restaura. Un detalle: si encuentras ejemplos con <code>fabric.Canvas</code> son de v5 &#8212; en v6 el API cambi&#243; a imports con nombre.</p><h2>La demo</h2><p>He montado un editor de memes en <strong><a href="https://fabric.concriterio.tools/">fabric.concriterio.tools</a></strong> para que veas c&#243;mo funciona en real. Puedes cargar una imagen, a&#241;adir capas de texto con distintas tipograf&#237;as, moverlas y escalarlas directamente sobre el canvas, y descargar el resultado como PNG.</p><p>Todo el c&#243;digo est&#225; en el repositorio p&#250;blico de Github, listo para que te lo puedas descargar y modificar a tu gusto.</p><p> (Accede a &#233;l a trav&#233;s de <strong><a href="https://github.com/HombreFeliz/fabricjs-concriterio-tools">enlace</a></strong>)</p><h2>Recapitulemos</h2><p>Hay una categor&#237;a de interfaces que no se resuelven bien con HTML y CSS: las que el usuario edita visualmente, donde los elementos se mueven, se superponen y se transforman. Para eso existe el canvas. Y para trabajar con el canvas sin volverte loco, existe Fabric. Si alguna vez tienes que construir algo donde el usuario &#8220;dise&#241;a&#8221; en lugar de solo &#8220;rellenar formularios&#8221;, esta librer&#237;a es el punto de partida.</p><div><hr></div><p><em>Si esta entrega de Con Criterio te ha resultado &#250;til, no olvides compartirla :)</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/fabricjs-la-libreria-que-convierte?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/p/fabricjs-la-libreria-que-convierte?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[SDD Clarifier]]></title><description><![CDATA[Transforma una idea vaga en especificaciones completas antes de escribir una sola l&#237;nea de c&#243;digo.]]></description><link>https://www.concriterio.blog/p/sdd-clarifier</link><guid isPermaLink="false">https://www.concriterio.blog/p/sdd-clarifier</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Thu, 02 Apr 2026 21:05:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/575a3829-e42c-4cc5-a628-89e1251ee2d5_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>Qu&#233; es el SDD Clarifier</strong></h2><p>El SDD Clarifier es una skill para Claude con el que <strong>te gu&#237;a el proceso de clarificaci&#243;n de un proyecto</strong> digital antes de escribir c&#243;digo. Tomas una idea &#8212;puede ser una frase, un p&#225;rrafo, una nota de voz transcrita&#8212; y al final tienes un conjunto completo de artefactos de especificaci&#243;n: PRD, arquitectura, modelo de datos, design system, roadmap y specs funcionales compatibles con OpenSpec.</p><p>El problema que resuelve no es t&#233;cnico. Es anterior a lo t&#233;cnico.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">&#161;Gracias por leer Con Criterio! Suscr&#237;bete gratis para recibir nuevos posts y apoyar mi trabajo.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Frameworks como OpenSpec, GitHub Copilot Workspace o BMAD asumen que ya sabes qu&#233; quieres construir. Entran en la fase de implementaci&#243;n. El SDD Clarifier cubre el tramo previo: las decisiones de negocio, las decisiones de dise&#241;o y la fase exploratoria donde todav&#237;a hay m&#225;s preguntas que respuestas.</p><div><hr></div><p style="text-align: center;"><strong>Desc&#225;rgate la skill desde aqu&#237;:</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/HombreFeliz/sdd-clarifier/blob/easytalk/sdd-clarifier-skill.md&quot;,&quot;text&quot;:&quot;Descargar SDD Clarifier&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/HombreFeliz/sdd-clarifier/blob/easytalk/sdd-clarifier-skill.md"><span>Descargar SDD Clarifier</span></a></p><div><hr></div><h2><strong>C&#243;mo funciona</strong></h2><p>El proceso tiene tres fases secuenciales.</p><p><strong>Fase 1 &#8212; Exploraci&#243;n (conversacional).</strong> Claude no genera nada todav&#237;a. Pregunta. Extrae del usuario las decisiones necesarias agrupadas en cuatro &#225;reas: negocio (modelo de monetizaci&#243;n, m&#233;tricas de &#233;xito, restricciones), dise&#241;o (plataforma, estilo visual, tono), t&#233;cnica (stack, integraciones, despliegue) y alcance (MVP vs. visi&#243;n completa). M&#225;ximo tres preguntas por turno. Al final, presenta un resumen de todas las decisiones para validaci&#243;n expl&#237;cita.</p><p><strong>Fase 2 &#8212; Formalizaci&#243;n (generaci&#243;n de artefactos).</strong> Una vez confirmado el alcance, genera la estructura de carpetas completa con todos los documentos. Los specs funcionales siguen el formato OpenSpec (SHALL/MUST/SHOULD seg&#250;n RFC 2119), organizados por dominio. Los docs adicionales cubren lo que OpenSpec no cubre: business.md, design-system.md, architecture.md, data-model.md y roadmap.md. Se incluye un CLAUDE.md con instrucciones para el agente de codificaci&#243;n.</p><p><strong>Fase 3 &#8212; Entrega y siguiente paso.</strong> Presenta la estructura generada y da el paso concreto a seguir: inicializar OpenSpec y continuar con el flujo est&#225;ndar de implementaci&#243;n.</p><h2><strong>Filosof&#237;a</strong></h2><p>La skill implementa un principio simple: 80% planificaci&#243;n, 20% ejecuci&#243;n.</p><p>Claude no decide por el usuario. Pregunta, confronta, propone opciones y espera. El usuario mantiene el control y la comprensi&#243;n total del proyecto en todo momento. Si durante la generaci&#243;n falta alguna decisi&#243;n, Claude para y pregunta antes de asumir.</p><p>La potencia sin control no sirve de nada.</p><h2><strong>C&#243;mo instalarla</strong></h2><p>Una skill es un archivo Markdown que Claude carga como contexto de sistema. No es un plugin ni una extensi&#243;n del navegador. No requiere instalaci&#243;n en el sentido tradicional.</p><p><strong>En Claude.ai (web y m&#243;vil).</strong> Ve a Configuraci&#243;n &#8594; Skills &#8594; A&#241;adir skill. Carga el archivo <code>sdd-clarifier-skill.md</code>. A partir de ese momento, Claude lo usar&#225; autom&#225;ticamente cuando detecte que est&#225;s describiendo un proyecto.</p><p><strong>En Claude Code (terminal).</strong> Copia el archivo en <code>~/.claude/skills/sdd-clarifier/SKILL.md</code>. Claude Code lo cargar&#225; en cada sesi&#243;n.</p><p><strong>En Claude Desktop.</strong> El proceso es equivalente al de Claude Code: el archivo va en la carpeta de skills de tu configuraci&#243;n local.</p><p><strong>&#191;Funciona con la API de Anthropic?</strong> No directamente. Las skills son un mecanismo de Claude Code y Claude Desktop. Si usas la API, puedes incluir el contenido del archivo como system prompt manualmente, pero el sistema de skills no se aplica en llamadas directas a la API.</p><div><hr></div><h2><strong>Compatibilidad con OpenSpec</strong></h2><p>Los artefactos que genera esta skill son directamente compatibles con OpenSpec CLI. Una vez que tienes la carpeta generada:</p><ol><li><p>Instala OpenSpec: <code>npm install -g @fission-ai/openspec@latest</code></p></li><li><p>Ejecuta <code>openspec init</code> en el directorio del proyecto</p></li><li><p>Los specs generados por el SDD Clarifier se integran como fuente de verdad</p></li><li><p>Para nuevas funcionalidades, usa el flujo est&#225;ndar: <code>/opsx:propose</code>, <code>/opsx:apply</code>, <code>/opsx:archive</code></p></li></ol><div><hr></div><h3 style="text-align: center;">&#191;Te ha resultado &#250;til este recurso?</h3><p style="text-align: center;">Todos los recursos y materiales de Con Criterio son gratuitos, pero si me quieres apoyar para que siga construyendo y compartiendo de esta manera, puedes invitarme a un caf&#233; :)</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://buymeacoffee.com/polmarza&quot;,&quot;text&quot;:&quot;Inv&#237;tame a un caf&#233;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://buymeacoffee.com/polmarza"><span>Inv&#237;tame a un caf&#233;</span></a></p><div><hr></div><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">&#161;Gracias por leer Con Criterio! Suscr&#237;bete gratis para recibir nuevos posts y apoyar mi trabajo.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Astro + Sanity + Vercel]]></title><description><![CDATA[Lecciones aprendidas integrando un CMS headless con un generador de sitios est&#225;ticos y despliegue automatizado.]]></description><link>https://www.concriterio.blog/p/astro-sanity-vercel</link><guid isPermaLink="false">https://www.concriterio.blog/p/astro-sanity-vercel</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Thu, 02 Apr 2026 20:43:54 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/de6beba9-3a10-4146-9eaa-c4cadbf7fed1_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Hace unos d&#237;as tuve que montar una web para un cliente (no t&#233;cnico) el cual quer&#237;a actualizar el contenido de forma regular. </em></p><p><em>Para construir dicha web us&#233; un combo ganador como es <strong><a href="https://astro.build">Astro</a></strong>, <strong><a href="https://www.sanity.io">Sanity</a></strong> y <strong><a href="https://vercel.com">Vercel</a></strong>, pero mientras lo constru&#237;a me encontr&#233; una serie de problemas que no esperaba.</em> </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">&#161;Gracias por leer Con Criterio! Suscr&#237;bete gratis para recibir nuevos posts y apoyar mi trabajo.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><em>Los he documentado para que, si tambi&#233;n quieres montar algo con este t&#225;ndem y luego lo despliegas en Vercel, puedas tener una ayuda para no entrar en los bucles con los que me encontr&#233; yo :)</em></p><div><hr></div><h2><strong>1. Arquitectura general</strong></h2><pre><code><code>Sanity Studio (CMS) &#8594; Sanity API &#8594; Astro (SSG) &#8594; Vercel (hosting)
       &#8595;                                              &#8593;
   Webhook &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Deploy Hook</code></code></pre><ul><li><p><strong>Sanity</strong> es donde se guarda y gestiona todo el contenido: textos, im&#225;genes, documentos.</p></li><li><p><strong>Astro</strong> genera las p&#225;ginas HTML del sitio web en el momento de la construcci&#243;n (build), pidiendo los datos a Sanity.</p></li><li><p><strong>Vercel</strong> aloja el sitio y lo reconstruye autom&#225;ticamente cada vez que Sanity le avisa de que algo ha cambiado.</p></li></ul><h3><strong>Por qu&#233; generar p&#225;ginas est&#225;ticas (SSG) y no renderizar en servidor (SSR)</strong></h3><p>Para webs donde el contenido no cambia constantemente (corporativas, portfolios, blogs, sitios de proyecto), generar p&#225;ginas est&#225;ticas es la mejor opci&#243;n:</p><p><strong>SSG (P&#193;GINAS PRE-GENERADAS)SSR (GENERADAS EN CADA VISITA)Velocidad</strong>Instant&#225;neo, el HTML ya est&#225; listoCada visita hace una consulta a la API<strong>Coste</strong>Gratis o casi gratisCada visita consume recursos de servidor<strong>Resiliencia</strong>Si Sanity se cae, la web sigue funcionandoSi Sanity se cae, la web deja de funcionar<strong>Contenido actualizado</strong>Tarda ~30-40 segundos en reconstruirseInmediato</p><p><strong>Regla general:</strong> si el contenido cambia pocas veces al d&#237;a, las p&#225;ginas est&#225;ticas son suficientes. Solo necesitas renderizado en servidor si tu contenido cambia constantemente (tiendas online, dashboards, feeds en tiempo real).</p><h2><strong>2. Configuraci&#243;n del cliente Sanity</strong></h2><pre><code><code>import { createClient } from '@sanity/client';

export const sanityClient = createClient({
  projectId: 'tu-project-id',
  dataset: 'production',
  apiVersion: '2024-01-01',
  useCdn: false, // &#8592; CR&#205;TICO
});</code></code></pre><h3><strong>La trampa de la cach&#233; (useCdn)</strong></h3><p>Este es probablemente el error m&#225;s dif&#237;cil de detectar en toda la integraci&#243;n.</p><p><strong>El problema:</strong> con <code>useCdn: true</code>, Sanity devuelve datos desde su cach&#233; en lugar de ir a buscar los m&#225;s recientes. Cuando un editor publica contenido y se dispara la reconstrucci&#243;n del sitio, el build pide datos a Sanity, pero la cach&#233; todav&#237;a tiene la versi&#243;n anterior. El resultado: el sitio se reconstruye con datos desactualizados.</p><p><strong>C&#243;mo se manifiesta:</strong></p><ul><li><p>Los cambios hechos en Sanity no aparecen en la web despu&#233;s de reconstruir</p></li><li><p>Los tiempos de construcci&#243;n de las p&#225;ginas son sospechosamente r&#225;pidos (~15ms en vez de ~3s)</p></li><li><p>No hay ning&#250;n error en los registros del sistema: simplemente los datos son viejos</p></li></ul><p><strong>Soluci&#243;n:</strong> usar <code>useCdn: false</code> para los builds. En sitios est&#225;ticos no hay penalizaci&#243;n real, porque las consultas solo se ejecutan una vez durante la construcci&#243;n, no en cada visita del usuario.</p><p><strong>Regla:</strong> <code>useCdn: true</code> es para aplicaciones que renderizan en servidor con mucho tr&#225;fico, donde la velocidad de respuesta importa mucho. Para sitios est&#225;ticos, siempre <code>useCdn: false</code>.</p><h2><strong>3. Esquemas de contenido</strong></h2><h3><strong>Singletons vs. Colecciones</strong></h3><ul><li><p><strong>Singletons:</strong> documentos que solo existen una vez (la secci&#243;n hero de la home, la p&#225;gina &#8220;sobre nosotros&#8221;, el formulario de contacto, la configuraci&#243;n general). Se crean una vez y despu&#233;s solo se editan.</p></li><li><p><strong>Colecciones:</strong> documentos que se repiten (miembros del equipo, entidades, publicaciones del blog).</p></li></ul><pre><code><code>// Singleton: se le asigna un _id fijo para que no se pueda duplicar
defineType({
  name: 'heroSection',
  type: 'document',
  // ...
})

// En sanity.config.ts: se impide que los editores creen o borren singletons
document: {
  actions: (input, context) =&gt;
    singletonTypes.has(context.schemaType)
      ? input.filter(({ action }) =&gt;
          action &amp;&amp; ['publish', 'discardChanges', 'restore'].includes(action))
      : input,
}</code></code></pre><h3><strong>Internacionalizaci&#243;n a nivel de campo</strong></h3><p>En vez de crear un documento separado por cada idioma, se crean campos que contienen ambos idiomas dentro del mismo documento:</p><pre><code><code>// localeString: un campo corto con versi&#243;n en cada idioma
defineType({
  name: 'localeString',
  type: 'object',
  fields: [
    { name: 'es', type: 'string', title: 'Espa&#241;ol' },
    { name: 'en', type: 'string', title: 'English' },
  ],
})</code></code></pre><p>Hay tres variantes seg&#250;n el tipo de texto:</p><ul><li><p><strong>localeString</strong> para textos cortos (t&#237;tulos, etiquetas)</p></li><li><p><strong>localeText</strong> para textos largos (p&#225;rrafos, descripciones)</p></li><li><p><strong>localeBlockContent</strong> para texto enriquecido (con negritas, cursivas, enlaces)</p></li></ul><p><strong>Ventaja:</strong> el editor ve los dos idiomas en el mismo formulario, sin tener que cambiar de documento. Esto reduce errores y hace mucho m&#225;s f&#225;cil mantener ambos idiomas sincronizados.</p><h2><strong>4. Patr&#243;n de respaldo (fallback)</strong></h2><p>Nunca dependas al 100% de una fuente de datos externa. Si Sanity no est&#225; disponible o el contenido todav&#237;a no se ha cargado, la web tiene que seguir mostrando algo.</p><pre><code><code>// En el componente Astro
let hero, about, settings;
try {
  const data = await getHomePageData();
  hero = data.hero;
  about = data.about;
  settings = data.settings;
} catch {
  // Sanity no est&#225; disponible, usamos los textos de respaldo
}

// Funci&#243;n auxiliar que decide de d&#243;nde sacar el texto
function s(
  sanityValue: { es?: string; en?: string } | null,
  fallbackKey: string,
  lang: string
): string {
  if (sanityValue) {
    return sanityValue[lang] ?? sanityValue.es ?? t(fallbackKey, lang);
  }
  return t(fallbackKey, lang);  // textos de respaldo est&#225;ticos
}</code></code></pre><p><strong>Regla:</strong> mant&#233;n un archivo de textos est&#225;ticos (<code>translations.ts</code>) como red de seguridad. Sanity es la fuente principal de datos; los textos est&#225;ticos son el plan B.</p><h2><strong>5. Consultas GROQ</strong></h2><h3><strong>Pide solo lo que necesitas</strong></h3><p>Siempre especifica qu&#233; campos quieres en lugar de traerte el documento entero:</p><pre><code><code>// &#10060; Malo: trae todo, incluidos campos internos de Sanity que no usas
*[_type == "teamMember"]

// &#9989; Bueno: solo los campos que vas a usar
*[_type == "teamMember"] | order(order asc){
  _id,
  name,
  role,
  institution,
  "photoUrl": photo.asset-&gt;url,
  initials,
  order
}</code></code></pre><h3><strong>Resuelve las referencias de im&#225;genes en la propia consulta</strong></h3><p>Sanity guarda las im&#225;genes como referencias internas. Puedes convertirlas en URLs directamente dentro de la consulta:</p><pre><code><code>"logoUrl": logo.asset-&gt;url
"photoUrl": photo.asset-&gt;url</code></code></pre><h3><strong>Carga en paralelo</strong></h3><p>Usa <code>Promise.all</code> para pedir todos los datos a la vez, en lugar de uno detr&#225;s de otro:</p><pre><code><code>const [hero, about, team, entities] = await Promise.all([
  getHeroSection(),
  getAboutSection(),
  getTeamMembers(),
  getEntities(),
]);</code></code></pre><h2><strong>6. Reconstrucci&#243;n autom&#225;tica: Vercel + Sanity Webhooks</strong></h2><h3><strong>Configuraci&#243;n</strong></h3><ol><li><p><strong>En Vercel:</strong> crear un Deploy Hook en Settings &#8594; Git &#8594; Deploy Hooks. Esto genera una URL del tipo <code>https://api.vercel.com/v1/integrations/deploy/...</code></p></li><li><p><strong>En Sanity:</strong> crear un Webhook en manage.sanity.io &#8594; API &#8594; Webhooks</p><ul><li><p>URL: la del Deploy Hook que acabas de crear en Vercel</p></li><li><p>Disparadores: Crear, Actualizar, Eliminar</p></li><li><p>Filtro: vac&#237;o (cualquier cambio dispara la reconstrucci&#243;n)</p></li></ul></li></ol><h3><strong>Flujo completo</strong></h3><pre><code><code>El editor publica algo en Sanity
  &#8594; Sanity env&#237;a una notificaci&#243;n (webhook) a Vercel
    &#8594; Vercel descarga el c&#243;digo y ejecuta la construcci&#243;n del sitio
      &#8594; Astro pide los datos a Sanity (con useCdn: false)
        &#8594; Se genera el HTML con los datos actualizados
          &#8594; El sitio est&#225; online (~30-40 segundos en total)</code></code></pre><h3><strong>Problemas habituales</strong></h3><ol><li><p><strong>La cach&#233; te da datos viejos</strong> (ya explicado arriba): usar <code>useCdn: false</code>.</p></li><li><p><strong>Condici&#243;n de carrera en el webhook:</strong> el webhook se dispara inmediatamente al publicar. Si Sanity tarda unos milisegundos en propagar los datos internamente, la construcci&#243;n puede capturar datos a medio actualizar. En la pr&#225;ctica es raro, pero si ocurre, una segunda reconstrucci&#243;n lo soluciona.</p></li><li><p><strong>Actualizar el panel de edici&#243;n no es lo mismo que actualizar la web:</strong></p><ul><li><p><code>npm run sanity:deploy</code> actualiza el Sanity Studio (la herramienta de edici&#243;n). Solo hace falta cuando cambias la estructura de los datos (esquemas).</p></li><li><p>El webhook de Vercel reconstruye la web p&#250;blica. Se dispara cuando cambia el contenido.</p></li></ul></li></ol><h2><strong>7. Sanity Studio: buenas pr&#225;cticas</strong></h2><h3><strong>Organizar el panel de navegaci&#243;n</strong></h3><p>Agrupa los documentos en el men&#250; lateral para que los editores encuentren todo f&#225;cil:</p><pre><code><code>structureTool({
  structure: (S) =&gt;
    S.list().title('Contenido').items([
      S.listItem().title('Inicio').child(
        S.list().title('Secciones de inicio').items([
          S.listItem().title('Hero').child(/* singleton */),
          S.listItem().title('Sobre el proyecto').child(/* singleton */),
          S.listItem().title('Contacto').child(/* singleton */),
        ])
      ),
      S.divider(),
      S.listItem().title('Equipo').child(/* lista filtrada */),
      S.listItem().title('Entidades').child(/* lista filtrada */),
      // ...
    ]),
})</code></code></pre><h3><strong>Proteger los singletons</strong></h3><p>Impide que los editores puedan crear duplicados o borrar documentos que deber&#237;an ser &#250;nicos:</p><pre><code><code>document: {
  actions: (input, context) =&gt;
    singletonTypes.has(context.schemaType)
      ? input.filter(({ action }) =&gt;
          action &amp;&amp; ['publish', 'discardChanges', 'restore'].includes(action))
      : input,
}</code></code></pre><h3><strong>Acceso y permisos</strong></h3><ul><li><p>Para iniciar sesi&#243;n en local: <code>npx sanity login</code> (no <code>sanity login</code> directamente, puede que no est&#233; en el PATH)</p></li><li><p>Los colaboradores acceden al Studio desde el navegador, a trav&#233;s de la URL donde lo hayas desplegado</p></li><li><p>Los permisos de cada usuario se gestionan en manage.sanity.io &#8594; Members</p></li></ul><h2><strong>8. Im&#225;genes</strong></h2><h3><strong>Proporciones y recorte</strong></h3><p>Define las proporciones en CSS y deja que el navegador se encargue del recorte:</p><pre><code><code>.team-photo {
  aspect-ratio: 3/4;    /* Proporci&#243;n vertical tipo retrato */
  object-fit: cover;     /* Recorta sin deformar la imagen */
  width: 100%;
}</code></code></pre><p><strong>Indicaci&#243;n para editores:</strong> subir fotos de al menos 600&#215;800px para retratos. Si son m&#225;s grandes no pasa nada, el CSS se encarga de ajustarlas.</p><h3><strong>Transformaci&#243;n de im&#225;genes con URL builder</strong></h3><p>Sanity permite redimensionar y recortar im&#225;genes autom&#225;ticamente a trav&#233;s de URLs:</p><pre><code><code>import { createImageUrlBuilder } from '@sanity/image-url';

const builder = createImageUrlBuilder(sanityClient);

export function urlFor(source) {
  return builder.image(source);
}

// Ejemplo: urlFor(photo).width(400).height(533).url()</code></code></pre><p><strong>Nota:</strong> usa <code>createImageUrlBuilder</code> (importaci&#243;n con nombre), no la importaci&#243;n por defecto que est&#225; marcada como obsoleta.</p><h2><strong>9. Carga masiva de contenido</strong></h2><p>Para no tener que introducir todo el contenido inicial a mano en el Studio, crea un script de carga:</p><pre><code><code>import { createClient } from '@sanity/client';

const client = createClient({
  projectId: 'tu-project-id',
  dataset: 'production',
  token: process.env.SANITY_TOKEN, // token con permisos de escritura
  apiVersion: '2024-01-01',
  useCdn: false,
});

// createOrReplace: se puede ejecutar muchas veces sin crear duplicados
await client.createOrReplace({
  _id: 'heroSection',
  _type: 'heroSection',
  tag: { es: 'Proyecto de investigaci&#243;n', en: 'Research project' },
  // ...
});</code></code></pre><p><strong>Importante:</strong> usa <code>createOrReplace</code> en vez de <code>create</code>. As&#237; el script se puede ejecutar varias veces sin duplicar contenido (es idempotente).</p><p><strong>Seguridad:</strong> nunca subas tokens de API al repositorio. Gu&#225;rdalos como variables de entorno y rev&#243;calos cuando ya no los necesites.</p><h2><strong>10. Checklist de integraci&#243;n</strong></h2><ul><li><p><code>useCdn: false</code> en el cliente Sanity para builds est&#225;ticos</p></li><li><p>Textos de respaldo si Sanity no responde</p></li><li><p>Deploy Hook de Vercel configurado</p></li><li><p>Webhook de Sanity apuntando al Deploy Hook</p></li><li><p>Singletons protegidos para que no se puedan duplicar ni borrar</p></li><li><p>Campos biling&#252;es (ES/EN) en todos los textos</p></li><li><p>Consultas GROQ pidiendo solo los campos necesarios</p></li><li><p>Carga de datos en paralelo con <code>Promise.all</code></p></li><li><p>Script de carga inicial para el contenido</p></li><li><p>README con instrucciones de setup, comandos y flujo de despliegue</p></li><li><p>Studio desplegado para que los colaboradores puedan acceder (<code>npm run sanity:deploy</code>)</p></li><li><p>Proporciones de imagen definidas en CSS con <code>aspect-ratio</code> + <code>object-fit: cover</code></p></li></ul><h2><strong>Resumen</strong></h2><p>La combinaci&#243;n Astro + Sanity + Vercel funciona muy bien para sitios donde el contenido lo gestiona un equipo no t&#233;cnico:</p><ol><li><p><strong>Sanity</strong> da a los editores una interfaz c&#243;moda para gestionar contenido.</p></li><li><p><strong>Astro</strong> genera HTML r&#225;pido y barato.</p></li><li><p><strong>Vercel</strong> despliega autom&#225;ticamente con webhooks.</p></li></ol><p>Los puntos cr&#237;ticos son:</p><ul><li><p><code>useCdn: false</code> para que los builds siempre obtengan datos actualizados.</p></li><li><p><strong>Textos de respaldo</strong> para que la web nunca se quede en blanco.</p></li><li><p><strong>Entender que actualizar el Studio y actualizar la web</strong> son procesos distintos con disparadores distintos.</p></li></ul><p>Con estas pr&#225;cticas, el flujo es: el editor cambia contenido en Sanity &#8594; la web se actualiza sola en ~30 segundos &#8594; sin intervenci&#243;n t&#233;cnica.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">&#161;Gracias por leer Con Criterio! Suscr&#237;bete gratis para recibir nuevos posts y apoyar mi trabajo.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Cuándo los agentes de IA ganan y cuándo tú les ganas a ellos]]></title><description><![CDATA[C&#243;mo distinguir los proyectos que necesitan agentes autom&#225;ticos de los que solo necesitan criterio humano.]]></description><link>https://www.concriterio.blog/p/cuando-los-agentes-de-ia-ganan-y</link><guid isPermaLink="false">https://www.concriterio.blog/p/cuando-los-agentes-de-ia-ganan-y</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 01 Apr 2026 06:02:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/99b9ecf1-bed0-429e-a826-1561a8600a67_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Hola, soy Pol Marz&#224;. Cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><div><hr></div><p>Hace unos d&#237;as termin&#233; dos proyectos en sesiones de pocas horas cada uno. Sin arquitecturas de agentes. Sin orquestadores autom&#225;ticos. Sin sistemas de coordinaci&#243;n.</p><p>Lo que s&#237; hubo: yo tomando decisiones constantemente.</p><ul><li><p>Qu&#233; construir primero. </p></li><li><p>Qu&#233; ignorar. </p></li><li><p>Cu&#225;ndo el resultado era suficientemente bueno para avanzar. </p></li><li><p>Cu&#225;ndo reescribir algo desde cero. </p></li><li><p>Cu&#225;ndo parar.</p></li></ul><p>Eso se llama orquestar. Y la IA solo era el agente que ejecutaba mis instrucciones.</p><p>El problema es que nadie te lo cuenta as&#237;. Las conversaciones sobre agentes suelen arrancar desde la complejidad t&#233;cnica y parece que si no tienes un sistema sofisticado, es como si lo estuvieras haciendo mal.</p><p>Pero no es verdad.</p><h3>&#191;Qu&#233; significa orquestar en la pr&#225;ctica?</h3><p>Un orquestador decide qu&#233; se hace, en qu&#233; orden, con qu&#233; criterio y cu&#225;ndo el resultado es aceptable.</p><p>Cuando abres una conversaci&#243;n con Claude Code, le das contexto, le defines el alcance, interpretas lo que genera, decides si sigue o si cambia de direcci&#243;n, ya <strong>est&#225;s orquestando</strong>. No lo parece porque no hay un dashboard con <strong><a href="https://www.nexy.ai/es/concept/nodos">nodos</a></strong> conectados, pero el proceso es exactamente el mismo.</p><p>Tu ventaja como orquestador humano es el juicio: saber cu&#225;ndo algo que &#8220;funciona&#8221; no es lo que realmente se necesitaba. Eso no se delega f&#225;cilmente.</p><h3>Los tres escenarios donde los agentes aut&#243;nomos ganan</h3><p>Hay situaciones concretas donde tiene sentido sacar al humano del bucle:</p><ol><li><p><strong>Volumen repetitivo con inputs distintos.</strong> Imagina que tienes que analizar 5.000 contratos PDF para extraer cl&#225;usulas espec&#237;ficas. El proceso es id&#233;ntico en todos los casos, solo cambia el documento. Un agente hace eso en serie; diez agentes lo hacen en paralelo. Aqu&#237; no hay juicio que aplicar, hay escala que conseguir.</p></li><li><p><strong><a href="https://www.nexy.ai/es/concept/pipelines-en-desarrollo-de-software">Pipelines</a> con pasos verificables.</strong> Cuando el flujo es predecible (extraer datos, limpiar, analizar, publicar) y cada paso tiene un output que se puede validar antes de pasar al siguiente, un orquestador autom&#225;tico gestiona los reintentos y las dependencias mejor que un humano mirando la pantalla.</p></li><li><p><strong>Dominios muy separados que necesitan especializaci&#243;n.</strong> Un agente con un contexto muy acotado comete menos errores en su dominio que un agente generalista al que le has mezclado demasiadas cosas. Si tu proyecto tiene capas radicalmente distintas (base de datos, l&#243;gica de negocio, interfaz, comunicaciones), separar los agentes por dominio reduce el ruido y mejora la calidad del output.</p></li></ol><p>El patr&#243;n com&#250;n en los tres casos es que el trabajo es <strong>volum&#233;trico y repetible</strong>. El proceso ya est&#225; decidido, solo falta ejecutarlo a escala.</p><div><hr></div><p>Si te est&#225; gustando lo que est&#225;s leyendo, &#161;ay&#250;dame a que llegue a m&#225;s personas!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/cuando-los-agentes-de-ia-ganan-y?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/p/cuando-los-agentes-de-ia-ganan-y?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p><div><hr></div><h3>El criterio para saber cu&#225;ndo escalar</h3><p>La pregunta no es &#8220;&#191;deber&#237;a tener agentes?&#8221; sino &#8220;&#191;qu&#233; parte de mi trabajo es un procedimiento operativo est&#225;ndar y qu&#233; parte requiere criterio?&#8221;</p><p><strong>Opci&#243;n A</strong></p><p>Si puedes describir el trabajo como un proceso con inputs predecibles y outputs verificables, los agentes autom&#225;ticos escalan bien.</p><p><strong>Opci&#243;n B</strong></p><p>Si el trabajo consiste en decidir qu&#233; construir, c&#243;mo, para qui&#233;n y por qu&#233;, el orquestador humano es el activo, no el cuello de botella.</p><div><hr></div><p>Tengo un colega que es project manager que el otro d&#237;a me contaba que tiene agentes porque su equipo procesa volumen: </p><ul><li><p>Revisiones de c&#243;digo repetitivas sobre patrones conocidos.</p></li><li><p>Generaci&#243;n de documentaci&#243;n desde estructuras existentes.</p></li><li><p>An&#225;lisis de tickets con categor&#237;as predefinidas. </p></li></ul><p>Tiene sentido para &#233;l porque el proceso ya est&#225; resuelto y lo que necesita es escala.</p><p>Yo constru&#237; <strong><a href="https://kumio.fit">Kumio</a></strong> y <strong><a href="https://www.nexy.ai/es">Nexy</a></strong> tomando decisiones de dise&#241;o de producto en tiempo real que ning&#250;n sistema autom&#225;tico podr&#237;a haber tomado por m&#237;. Ah&#237; el orquestador humano no era el problema, era la soluci&#243;n.</p><p>La sofisticaci&#243;n t&#233;cnica no es un objetivo; es una herramienta para un problema espec&#237;fico. Antes de a&#241;adir complejidad, vale la pena preguntarse si el problema que tienes es de volumen o de criterio.</p><blockquote><p>Casi siempre, cuando est&#225;s construyendo algo nuevo, es de criterio.</p></blockquote><div><hr></div><p>&#161;Y hasta aqu&#237; el post! Nos vemos la semana que viene :)</p><p>&#8212; Pol</p><p>PD: Quiz&#225; has visto palabras subrayadas y resaltadas con el color de acento de la newsletter. Realmente son enlaces para definir el concepto con m&#225;s precisi&#243;n y esta definici&#243;n la puedes leer en <strong><a href="https://www.nexy.ai/es">nexy.ai</a></strong>. Puedes consultar estos conceptos y muchos m&#225;s si te registras (con Google y la plataforma es gratuita). </p>]]></content:encoded></item><item><title><![CDATA[Hay dos tipos de Spec-Driven Development y casi nadie los distingue]]></title><description><![CDATA[Todo lo que necesitas entender sobre Spec-Driven Development antes de decidir c&#243;mo y cu&#225;ndo aplicarlo en tus proyectos con IA.]]></description><link>https://www.concriterio.blog/p/hay-dos-tipos-de-spec-driven-development</link><guid isPermaLink="false">https://www.concriterio.blog/p/hay-dos-tipos-de-spec-driven-development</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 25 Mar 2026 07:01:58 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6fa6b9ec-f210-452f-92ba-5fb4cb5e7ec9_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Hola, soy Pol Marz&#224;. Cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><blockquote><p><strong>Esta tarde doy un webinar sobre SDD para <a href="https://tecnofor.typeform.com/to/P1H7WkBw?utm_source=pol_marza&amp;utm_medium=social&amp;utm_campaign=colaboracion_pol&amp;utm_content=post_influencer">TecnoFor</a></strong>. Mientras estructuraba la charla, me di cuenta de que hab&#237;a una distinci&#243;n que nadie estaba haciendo expl&#237;cita. La escribo aqu&#237; antes de que se pierda &#128517;</p></blockquote><p>&#191;Qu&#233; veremos hoy?</p><p>Por qu&#233; SDD no es un concepto &#250;nico, qu&#233; diferencia hay entre la versi&#243;n orientada a agentes y la versi&#243;n orientada al desarrollador humano, y por qu&#233; esa distinci&#243;n importa antes de que nadie empiece a construir nada. Qu&#233;date hasta el final, porque al cierre comparto una skill descargable para aplicar todo esto desde hoy.</p><div><hr></div><h2>Dos lecturas del mismo t&#233;rmino</h2><p>Spec-Driven Development aparece cada vez m&#225;s en conversaciones sobre desarrollo con IA. El problema es que hay dos versiones del concepto circulando a la vez, y casi nadie las distingue.</p><p><strong>La primera es SDD orientado a agentes.</strong> Es lo que ves en OpenSpec, en Cursor Rules, en los workflows de Claude Code. Los documentos de especificaci&#243;n son instrucciones operativas para que m&#250;ltiples agentes trabajen en paralelo sin perder contexto entre ellos. El foco es la coordinaci&#243;n t&#233;cnica: c&#243;mo hacer que varios sistemas aut&#243;nomos construyan hacia el mismo objetivo sin colisionar.</p><p><strong>La segunda es SDD orientado al desarrollador humano.</strong> Es lo que llevo practicando desde que empec&#233; a construir productos con IA. Los documentos de spec no son instrucciones para agentes, son artefactos de clarificaci&#243;n que externalizan el pensamiento antes de escribir una sola l&#237;nea de c&#243;digo. El 80% del trabajo ocurre antes del primer prompt de ejecuci&#243;n. El LLM no act&#250;a como agente aut&#243;nomo, sino como colaborador informado.</p><p>Son enfoques distintos en su premisa, no versiones del mismo proceso en distinto nivel de sofisticaci&#243;n.</p><h3>Por qu&#233; la distinci&#243;n importa</h3><p>El SDD ag&#233;ntico asume que el desarrollador ya sabe qu&#233; construir y necesita coordinar la ejecuci&#243;n entre sistemas. El problema de coordinaci&#243;n ya est&#225; resuelto en la cabeza del humano, y los documentos de spec son el mecanismo para trasladarlo a los agentes.</p><p><strong>Mi versi&#243;n</strong> asume que la calidad del output del LLM es proporcional a la calidad del contexto que le das, y que ese contexto se construye iterativamente con el propio LLM antes de ejecutar. El problema que resuelve es anterior: no la coordinaci&#243;n, sino la claridad. Qu&#233; construir exactamente, por qu&#233; as&#237;, qu&#233; significa cada requisito cuando lo traduces a comportamiento real.</p><p>No son enfoques que compiten. Son prerequisito y consecuencia. Un sistema multiagente que parte de specs mal definidas produce c&#243;digo perfectamente coordinado hacia el objetivo equivocado.</p><blockquote><p>OpenSpec no incluye una fase de clarificaci&#243;n porque no la necesita: asume que llegas al proceso ya sabiendo qu&#233; construir. Cubre la coordinaci&#243;n t&#233;cnica, no el pensamiento previo.</p></blockquote><p>Ese hueco es exactamente lo que he intentado sistematizar.</p><h3>La skill SDD-clarifier</h3><p>Hace unas semanas publiqu&#233; en concriterio.dev una skill llamada <a href="https://www.concriterio.dev/recursos/sdd-clarifier">SDD-clarifier</a>. Es un protocolo de clarificaci&#243;n conversacional que puedes usar con cualquier LLM antes de empezar a construir.</p><p>El proceso tiene tres fases: </p><ol><li><p>Exploraci&#243;n (conversaci&#243;n para extraer todas las decisiones necesarias).</p></li><li><p>Formalizaci&#243;n (generaci&#243;n de artefactos: PRD, arquitectura, dise&#241;o, modelo de datos).</p></li><li><p>Entrega (los archivos listos para que un agente de codificaci&#243;n los use como contexto).</p></li></ol><p>Lo que la diferencia de otras herramientas del ecosistema es que no empieza por el c&#243;digo ni por la estructura t&#233;cnica. Empieza por las preguntas que un buen product manager har&#237;a antes de que nadie escribiera nada: qu&#233; problema resuelve esto, para qui&#233;n, qu&#233; significa que funcione, qu&#233; queda fuera del alcance.</p><p>La skill est&#225; disponible en <a href="https://concriterio.dev">concriterio.dev</a>. Es un archivo Markdown que puedes descargar y usar directamente en Claude, en Cursor o en cualquier entorno que soporte instrucciones de sistema.</p><div><hr></div><p>La semana que viene publicar&#233; el post sobre orquestaci&#243;n humana vs. ag&#233;ntica, que es el otro lado de esta misma conversaci&#243;n. Si entiendes cu&#225;ndo t&#250; eres el orquestador y cu&#225;ndo tiene sentido delegar la coordinaci&#243;n a agentes autom&#225;ticos, SDD como prerequisito cobra todo el sentido.</p><p>Son dos posts que se leen mejor juntos. Este explica qu&#233; construir y c&#243;mo definirlo. El siguiente explica qui&#233;n lo ejecuta y bajo qu&#233; criterio.</p><p>Y recuerda, si te ha gustado este art&#237;culo, &#161;no olvides compartirlo!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/hay-dos-tipos-de-spec-driven-development?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/p/hay-dos-tipos-de-spec-driven-development?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p><p>Hasta la semana que viene :)</p><p>&#8212; Pol</p>]]></content:encoded></item><item><title><![CDATA[Tu app funciona, pero no sabes por qué]]></title><description><![CDATA[Tres a&#241;os construyendo productos con IA me ense&#241;aron que el problema nunca fue el c&#243;digo, sino lo que faltaba antes de escribirlo.]]></description><link>https://www.concriterio.blog/p/deje-de-programar-a-ciegas-y-todo</link><guid isPermaLink="false">https://www.concriterio.blog/p/deje-de-programar-a-ciegas-y-todo</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Wed, 18 Mar 2026 07:02:22 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5f285090-cd31-4b08-be21-31af3d32ccac_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Hola, soy Pol Marz&#224;. Cada semana escribo una nueva edici&#243;n de Con Criterio, la newsletter sobre construir productos digitales con IA, con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><p>El pr&#243;ximo mi&#233;rcoles 25 de marzo, a las 19:00 (hora espa&#241;ola), dar&#233; una charla en directo en <strong>TecnoFor</strong> sobre esto que llevo tiempo d&#225;ndole vueltas: qu&#233; pasa cuando el vibe coding deja de ser suficiente. Es gratuita y abierta. Si te interesa, aqu&#237; tienes el enlace para apuntarte:</p><p><strong><a href="https://tecnofor.typeform.com/to/P1H7WkBw?utm_source=pol_marza&amp;utm_medium=social&amp;utm_campaign=colaboracion_pol&amp;utm_content=post_influencer">Ap&#250;ntate aqu&#237;</a></strong></p><p>Esta newsletter es una introducci&#243;n a lo que contar&#233; all&#237;. Si el tema te interesa, el mi&#233;rcoles lo desarrollo en profundidad.</p><h2>El problema que nadie quiere ver</h2><p>El vibecoding funciona. Escribes un prompt, la IA genera c&#243;digo, iteras, y en un rato tienes algo que se parece a lo que quer&#237;as. Para prototipos r&#225;pidos, pruebas de concepto o proyectos peque&#241;os, es un m&#233;todo v&#225;lido.</p><p>El problema aparece cuando quieres ir m&#225;s all&#225;. Cuando el proyecto crece, cuando necesitas que varias partes encajen, cuando hay autenticaci&#243;n, base de datos, roles de usuario, l&#243;gica de negocio real. En ese punto, el vibe coding se convierte en una conversaci&#243;n ca&#243;tica con un modelo que no tiene contexto suficiente para tomar buenas decisiones.</p><p>No porque la IA sea mala. Sino porque t&#250; no le has dado un mapa de lo que est&#225;s construyendo.</p><h2>Spec-Driven Development: primero el qu&#233;, despu&#233;s el c&#243;mo</h2><p>El Spec-Driven Development (SDD) parte de una idea sencilla: antes de escribir una sola l&#237;nea de c&#243;digo, defines con precisi&#243;n qu&#233; vas a construir. Requisitos, flujos, decisiones t&#233;cnicas, restricciones, casos l&#237;mite. Todo queda documentado en una especificaci&#243;n que sirve como fuente de verdad tanto para la IA como para ti.</p><p>No es un concepto nuevo. Los ingenieros de software llevan d&#233;cadas escribiendo especificaciones. Lo que cambia ahora es que esa especificaci&#243;n no es solo documentaci&#243;n para humanos, es el input que determina la calidad del c&#243;digo que genera la IA.</p><p>La diferencia pr&#225;ctica es directa: en lugar de ir ajustando sobre la marcha (&#8220;no, esto no era as&#237;, c&#225;mbialo&#8221;), empiezas con un documento que describe exactamente lo que necesitas. La IA trabaja con un contexto completo y produce resultados m&#225;s coherentes desde el primer intento.</p><h2>Los 5 documentos que sostienen un proyecto SDD</h2><p>En la pr&#225;ctica, una especificaci&#243;n no es un solo archivo enorme. Son documentos separados, cada uno con una funci&#243;n clara:</p><p><strong>1. Prop&#243;sito.</strong> Qu&#233; resuelve el producto, para qui&#233;n lo resuelve y (igual de importante) qu&#233; no resolver&#225; nunca. Este documento te obliga a tomar decisiones de alcance antes de escribir c&#243;digo.</p><p><strong>2. Usuarios y flujos.</strong> El camino concreto de cada tipo de usuario dentro del producto. No hablamos de personas abstractas, sino de secuencias reales: &#8220;el usuario llega, hace esto, ve aquello, el sistema responde as&#237;&#8221;.</p><p><strong>3. Arquitectura b&#225;sica.</strong> Stack tecnol&#243;gico, tablas de base de datos y sus relaciones. No hace falta un diagrama de 50 p&#225;ginas. Con que quede claro qu&#233; tecnolog&#237;as usas y c&#243;mo se conectan los datos, es suficiente.</p><p><strong>4. CLAUDE.md (o AGENTS.md).</strong> Este es el archivo que mantiene el contexto vivo entre sesiones. Cuando cierras una conversaci&#243;n con la IA y abres otra, este documento le dice d&#243;nde estabas y qu&#233; decisiones ya se tomaron. Sin &#233;l, cada sesi&#243;n empieza de cero.</p><p><strong>5. Changelog.</strong> Un registro de cada decisi&#243;n que modifica la especificaci&#243;n. No es un log de commits, es un historial de &#8220;por qu&#233;&#8221; cambiaron las cosas, no solo &#8220;qu&#233;&#8221; cambi&#243;.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/deje-de-programar-a-ciegas-y-todo?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/p/deje-de-programar-a-ciegas-y-todo?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p><h2>No son cosas opuestas</h2><p>El SDD no sustituye al vibe coding. Son etapas de madurez distintas.</p><p>Si est&#225;s explorando una idea, validando si algo tiene sentido o construyendo un prototipo r&#225;pido para ense&#241;ar a alguien, el vibe coding es perfecto. Es r&#225;pido, es flexible y el coste de equivocarte es bajo.</p><p>Pero cuando decides que ese proyecto va en serio (que necesita escalabilidad, mantenibilidad, que otras personas van a usarlo), necesitas pasar a un modo de trabajo m&#225;s estructurado. Ah&#237; es donde entra el SDD.</p><p>En mi caso, llevo casi tres a&#241;os trabajando as&#237; sin que existiera el t&#233;rmino. Lo que yo llamo &#8220;clarificaci&#243;n&#8221; (esa fase larga de conversaci&#243;n y planificaci&#243;n antes de tocar c&#243;digo) es esencialmente SDD en versi&#243;n artesanal. La industria ha formalizado lo que muchos product makers ya hac&#237;amos por necesidad.</p><h2>El mi&#233;rcoles, en directo</h2><p>Esto ha sido un primer vistazo. El mi&#233;rcoles 25 a las 19:00 en TecnoForo hablar&#233; en detalle sobre c&#243;mo aplicar SDD en la pr&#225;ctica: qu&#233; documentos generar, c&#243;mo estructurar la especificaci&#243;n y c&#243;mo conectar todo esto con las herramientas que ya usas.</p><p>Si quieres profundizar, ap&#250;ntate aqu&#237; (es gratuito):</p><p><strong><a href="https://tecnofor.typeform.com/to/P1H7WkBw?utm_source=pol_marza&amp;utm_medium=social&amp;utm_campaign=colaboracion_pol&amp;utm_content=post_influencer">Ap&#250;ntate aqu&#237;</a></strong></p><p>&#8212; Pol</p>]]></content:encoded></item><item><title><![CDATA[Con Criterio]]></title><description><![CDATA[Saber de donde vengo y el camino que he recorrido. Detenerme, reflexionar, iterar y decidir hacia donde va toda esta vor&#225;gine de la IA aplicada a desarrollo de productos.]]></description><link>https://www.concriterio.blog/p/con-criterio</link><guid isPermaLink="false">https://www.concriterio.blog/p/con-criterio</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Thu, 12 Mar 2026 07:01:55 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6e7aa049-95f6-45e0-a571-02ea613bc547_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Hola, soy Pol Marz&#224;. Cada semana escribo una nueva edici&#243;n de <strong>Con Criterio</strong>, la newsletter sobre construir productos digitales con IA; con planificaci&#243;n, m&#233;todo y sin atajos. Si te han reenviado este email, puedes suscribirte aqu&#237;:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><h2>Por qu&#233; esta nueva newsletter?</h2><p>Llevo m&#225;s de tres a&#241;os construyendo productos digitales con inteligencia artificial. Antes de que existiera un nombre para lo que hac&#237;a, ya lo hac&#237;a. Antes de que &#8220;vibe coding&#8221; fuera tendencia, yo ya estaba sentado delante de Claude planificando bases de datos, definiendo arquitecturas y pensando en qui&#233;n iba a usar lo que estaba a punto de construir.</p><p>Hoy quiero contarte por qu&#233; he cambiado el nombre de esta newsletter, qu&#233; significa &#8220;Con Criterio&#8221; y por qu&#233; creo que es el &#250;nico t&#233;rmino que va a sobrevivir a todo lo que viene.</p><div><hr></div><h4>El origen: construir con IA antes de que tuviera nombre</h4><p>Cuando empec&#233; a crear productos con IA, no hab&#237;a una etiqueta para eso. Simplemente dec&#237;a que hac&#237;a &#8220;programaci&#243;n asistida por IA&#8221; o &#8220;AI coding&#8221;, y la gente me miraba raro. No era programador de formaci&#243;n (vengo del dise&#241;o UX y la fotograf&#237;a) pero descubr&#237; que pod&#237;a construir cosas reales si dedicaba suficiente tiempo a pensar antes de ejecutar.</p><p>Eso era lo que hac&#237;a: pensar mucho, construir despu&#233;s.</p><h4>Llega el vibe coding (y me subo al tren)</h4><p>A principios de 2025, el t&#233;rmino &#8220;vibe coding&#8221; explot&#243;. Y cuando lo le&#237;, pens&#233;: <em>esto es lo que llevo haciendo todo este tiempo</em>. As&#237; que en junio de ese a&#241;o lanc&#233; <strong>Vibe Coding Hacks</strong>, una newsletter donde compart&#237;a los trucos, la experiencia y las lecciones que hab&#237;a acumulado durante a&#241;os construyendo con IA.</p><p>Le puse ese nombre porque, en ese momento, era el &#250;nico paraguas que exist&#237;a para definir lo que hac&#237;a.</p><h4>El problema: vibe coding empieza a significar otra cosa</h4><p>Con el paso de los meses, vi c&#243;mo &#8220;vibe coding&#8221; se iba asociando con algo que no me representaba. Se convirti&#243; en sin&#243;nimo de construir sin pensar. Sin arquitectura, sin seguridad, sin criterio. Si funcionaba, val&#237;a. Si se romp&#237;a, se le ped&#237;a a la IA que lo arreglara. Y si no lo arreglaba, se empezaba de cero.</p><p>Eso chocaba frontalmente con mi forma de trabajar. Yo dedicaba el 80% del tiempo a planificar y el 20% a ejecutar. Defin&#237;a PRDs, dise&#241;aba schemas de base de datos, pensaba en la escalabilidad antes de escribir la primera l&#237;nea. Pero cada vez que explicaba esto, ten&#237;a que a&#241;adir un matiz: &#8220;hago vibe coding, pero <em>con criterio</em>&#8220;.</p><p>Ese &#8220;pero&#8221; me empez&#243; a pesar.</p><h4>Aparece el SDD y la historia se repite</h4><p>A principios de 2026, descubr&#237; el concepto de <strong>Spec-Driven Development</strong> (SDD): un enfoque donde todo parte de una especificaci&#243;n detallada antes de tocar c&#243;digo. Cuando lo le&#237;, pens&#233; lo mismo que con el vibe coding: <em>esto se parece mucho a lo que ya hago</em>.</p><p>Pero esta vez no me lanc&#233; a adoptar el t&#233;rmino. Porque me di cuenta de algo importante.</p><h4>Lo que he aprendido: los nombres cambian, el criterio no</h4><p>Vibe coding fue &#250;til hasta que dej&#243; de representarme. SDD se acerca m&#225;s a mi m&#233;todo, pero tiene sus propias limitaciones cuando los proyectos escalan. Y seguramente, dentro de un a&#241;o, aparecer&#225; otro t&#233;rmino nuevo que defina otra forma de construir con IA.</p><p>Lo que me di cuenta es que <strong>vibe coding y SDD no son incompatibles</strong>. Son complementarios, y cada uno tiene su momento:</p><ul><li><p><strong>Vibe coding</strong> tiene sentido cuando quieres validar una idea r&#225;pido, cuando est&#225;s explorando si algo merece existir.</p></li><li><p><strong>SDD</strong> tiene sentido cuando el proyecto necesita escalar, cuando necesitas que la IA tenga un esquema claro de c&#243;mo est&#225; construido todo para que pueda ayudarte de verdad.</p></li></ul><p>La clave no est&#225; en elegir un bando. Est&#225; en saber cu&#225;ndo usar cada herramienta. Cu&#225;ndo tirar de Lovable para un prototipo interno y cu&#225;ndo montar un proyecto en Next.js porque necesitas SEO. Cu&#225;ndo Astro es la respuesta y cu&#225;ndo no lo es. Cu&#225;ndo planificar durante d&#237;as y cu&#225;ndo lanzar en una tarde.</p><p>Eso es criterio.</p><h2>Bienvenido a Con Criterio</h2><p>He repasado todo lo que he compartido en estos meses y lo que se ha mantenido constante no es la herramienta ni la metodolog&#237;a. Es la forma de pensar. El criterio para decidir qu&#233; construir, c&#243;mo construirlo y con qu&#233; hacerlo.</p><p>Por eso, a partir de hoy, esta newsletter se llama <strong>Con Criterio</strong>.</p><p>No es un rebrand cosm&#233;tico. Es una correcci&#243;n de rumbo. El contenido sigue siendo el mismo: builds reales, metodolog&#237;a, herramientas, lecciones aprendidas construyendo productos con IA. Lo que cambia es que ya no estoy atado a un t&#233;rmino que no controlo y que puede significar cualquier cosa ma&#241;ana.</p><p><strong>Con Criterio</strong> es lo que siempre deber&#237;a haberse llamado. Solo que necesit&#233; un a&#241;o para darme cuenta.</p><p>Nos vemos la semana que viene.</p><p><strong>Pol Marz&#224;</strong></p><div><hr></div><p>PD: Si te ha gustado este post y crees que puede gustar a otras personas me ayudar&#237;a mucho si lo compartes &#128522;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.concriterio.blog/p/con-criterio?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.concriterio.blog/p/con-criterio?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Fuentes de datos dinámicas]]></title><description><![CDATA[C&#243;mo transformar tus prototipos est&#225;ticos en aplicaciones que viven, respiran y evolucionan con sus usuarios]]></description><link>https://www.concriterio.blog/p/fuentes-de-datos-dinamicas</link><guid isPermaLink="false">https://www.concriterio.blog/p/fuentes-de-datos-dinamicas</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Tue, 10 Mar 2026 06:52:25 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7a756cb3-0c09-444d-9ee5-966cbe8de78a_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#161;Hola Viber!</p><p>&#161;Volvemos una semana m&#225;s con <strong>vibe coding para dummies</strong>!</p><p>Aunque no te lo parezca, ya ha pasado algo m&#225;s de un mes desde la primera publicaci&#243;n, &#161;as&#237; que <strong>estamos de celebraci&#243;n</strong>!</p><p>&#161;Gracias por leer Vibe Coding para Dummies! Suscr&#237;bete gratis para recibir nuevos posts y apoyar mi trabajo.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qpiu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qpiu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 424w, https://substackcdn.com/image/fetch/$s_!Qpiu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 848w, https://substackcdn.com/image/fetch/$s_!Qpiu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 1272w, https://substackcdn.com/image/fetch/$s_!Qpiu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qpiu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif" width="480" height="360" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:360,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1490792,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://vcxdummies.substack.com/i/167968692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Qpiu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 424w, https://substackcdn.com/image/fetch/$s_!Qpiu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 848w, https://substackcdn.com/image/fetch/$s_!Qpiu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 1272w, https://substackcdn.com/image/fetch/$s_!Qpiu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeab1cdb-c8dc-4637-a020-1f91eb0d1776_480x360.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Es como cuando, de j&#243;venes (o no tan j&#243;venes), celebr&#225;bamos cada mes de relaci&#243;n con nuestra pareja &#10084;&#65039;</p><p>Si te soy sincero, no daba un duro por mi.</p><p>La constancia siempre ha sido mi punto d&#233;bil, pero <strong>compartir mis conocimientos y ver que tienen &#8220;algo&#8221; de impacto</strong>, me llena de orgullo y satisfacci&#243;n &#128522;</p><p>Y ver que cada semana se unen m&#225;s personas, me dan &#225;nimos para seguir compartiendo mi experiencia.</p><p>Bueno, al l&#237;o.</p><h3><strong>&#191;De d&#243;nde venimos y hacia d&#243;nde vamos?</strong></h3><p>Venimos de tres semanas (sin contar el post de presentaci&#243;n) en las que b&#225;sicamente hemos visto teor&#237;a.</p><p><strong>La primera semana</strong> vimos los tres pilares fundamentales (seg&#250;n yo) de un viber:</p><ul><li><p>Estructurar antes de construir</p></li><li><p>Saber qu&#233; pedirle a la IA paso a paso</p></li><li><p>Explorar herramientas con prop&#243;sito, no por FOMO</p></li></ul><p><strong>La segunda semana</strong> pasamos a ver el PRD conversacional, esa hoja de ruta que nace de conversar con tu IA favorita y evita que tu proyecto se convierta en Frankenstein.</p><p>Por &#250;ltimo, <strong>la semana pasada</strong> pasamos del PRD al producto &#8220;real&#8221;.</p><p>Y s&#237;, pongo comillas ya que lo que construimos fue una p&#225;gina web est&#225;tica con ChatGPT con los datos hardcodeados.</p><blockquote><blockquote><p><strong>En programaci&#243;n, hardcodear se refiere a la pr&#225;ctica de incluir valores directamente en el c&#243;digo fuente en lugar de obtenerlos de forma din&#225;mica.</strong></p></blockquote></blockquote><h3><strong>&#191;C&#243;mo podemos obtener los datos de forma din&#225;mica?</strong></h3><p>Aqu&#237; empieza el bloque de <strong>&#8220;hacia d&#243;nde vamos&#8221;</strong> &#128512;</p><h3><strong>Fuentes de datos din&#225;micos</strong></h3><p>Los datos din&#225;micos son informaci&#243;n que <strong>cambia con el tiempo</strong> y se actualizan autom&#225;ticamente en tu aplicaci&#243;n.</p><p>A diferencia de los datos &#8220;hardcodeados&#8221;, los datos din&#225;micos se obtienen de fuentes externas.</p><p>Por ejemplo, en el caso que vimos la semana pasada, en el v&#237;deo te mostr&#233; como pod&#237;amos introducir manualmente las urls sociales a una p&#225;gina web tipo linktree.</p><p>Pero, <strong>&#191;qu&#233; ocurre cuando este servicio lo queremos expandir</strong> y que otras personas puedan a&#241;adir sus propios links?</p><p>No podemos (bueno, s&#237; podr&#237;amos, pero ser&#237;a poco usable) tener decenas o centenares de archivos est&#225;ticos con los datos hardcodeados de todos los usuarios.</p><p>Imag&#237;nate que alguien quiere cambiar una url, su nombre o cualquier otro dato de su perfil.</p><p>Ser&#237;a un rollazo, ya que (imagina) nos deber&#237;a enviar un email, luego tendr&#237;amos que ir al c&#243;digo y cambiar manualmente ese dato.</p><p><strong>No es viable.</strong></p><p>Cuando hablamos de datos din&#225;micos, tenemos <strong>tres opciones principales</strong> para alimentar nuestra aplicaci&#243;n.</p><h3><strong>Opci&#243;n 1: APIs Externas - Usar datos de otros</strong></h3><p>Una API es b&#225;sicamente un <strong>servicio que alguien m&#225;s ha creado y mantiene</strong>, y t&#250; puedes usar sus datos.</p><p>Por ejemplo, si quieres mostrar el tiempo en tu app, no necesitas instalar estaciones meteorol&#243;gicas por todo el mundo.</p><p>Simplemente usas la API del tiempo de Google, le preguntas <strong>&#8220;&#191;qu&#233; tiempo hace en Barcelona?&#8221;</strong> y te responde con la temperatura actual.</p><p>Otros ejemplos t&#237;picos son APIs de noticias (para mostrar los &#250;ltimos titulares), APIs de libros (para buscar informaci&#243;n sobre cualquier libro), o APIs de restaurantes (para mostrar rese&#241;as y horarios).</p><p><strong>Lo bueno</strong> de las APIs externas es que accedes a informaci&#243;n s&#250;per especializada sin esfuerzo.</p><p><strong>Lo malo</strong> es que dependes de que ese servicio funcione siempre y tenga los datos actualizados.</p><h3><strong>Opci&#243;n 2: Tu propia base de datos - Guardar lo tuyo</strong></h3><p>Una base de datos es <strong>tu propio almac&#233;n digital</strong> donde guardas toda la informaci&#243;n importante de tu aplicaci&#243;n.</p><p>Siguiendo con el ejemplo del linktree, aqu&#237; es donde guardamos toda la informaci&#243;n de los usuarios.</p><p>Sus nombres, sus enlaces, sus fotos de perfil, sus preferencias de colores, etc.</p><p>Cuando un usuario quiere cambiar su nombre, tu aplicaci&#243;n va a la base de datos, encuentra su perfil, actualiza el nombre, y listo.</p><p><strong>Inmediatamente se ve reflejado</strong> en su p&#225;gina sin que t&#250; tengas que tocar ni una l&#237;nea de c&#243;digo.</p><p>Para vibe coders, las opciones m&#225;s populares son <strong>Supabase</strong> (s&#250;per f&#225;cil de configurar) o <strong>Firebase</strong> (de Google).</p><p><strong>Lo bueno</strong> es que tienes control total sobre tus datos y no dependes de nadie.</p><p><strong>Lo malo</strong> es que tienes que configurarlo y mantenerlo t&#250;.</p><h3><strong>Opci&#243;n 3: Servicios h&#237;bridos - Lo mejor de ambos mundos</strong></h3><p>Algunos servicios act&#250;an como una <strong>mezcla entre una API y una base de datos</strong>.</p><p>Te dan la facilidad de uso de una API pero tambi&#233;n te permiten editar y organizar los datos f&#225;cilmente.</p><p>Por ejemplo, puedes usar <strong>Notion como base de datos</strong> para tu blog.</p><p>Escribes tus art&#237;culos c&#243;modamente en Notion (con su editor visual que ya conoces) y luego tu web va a buscar esos art&#237;culos via API.</p><p>Cambias algo en Notion y autom&#225;ticamente se actualiza en tu web.</p><p>O puedes usar <strong>Google Sheets como base de datos</strong> para proyectos simples.</p><p>Imag&#237;nate una web que muestra restaurantes recomendados: tienes la informaci&#243;n en una hoja de c&#225;lculo s&#250;per f&#225;cil de editar, y tu web la lee autom&#225;ticamente.</p><h3><strong>&#191;Cu&#225;ndo usar cada opci&#243;n?</strong></h3><p>La decisi&#243;n depende del <strong>tipo de datos que necesites</strong> y de <strong>qui&#233;n los va a gestionar</strong>.</p><h3><strong>Usa APIs externas cuando:</strong></h3><p>Necesites informaci&#243;n que cambia constantemente y que mantiene otra persona.</p><p>El tiempo, noticias, precios de productos, informaci&#243;n de libros o pel&#237;culas, datos de redes sociales.</p><p>B&#225;sicamente, cuando <strong>no tiene sentido que t&#250; mantengas esa informaci&#243;n</strong> porque ya existe un servicio especializado.</p><h3><strong>Usa tu propia base de datos cuando:</strong></h3><p>La informaci&#243;n sea espec&#237;fica de tu aplicaci&#243;n.</p><p>Usuarios, configuraciones, contenido creado por tus usuarios, hist&#243;ricos de acciones, cualquier cosa que sea &#250;nica de tu proyecto.</p><p>Es decir, <strong>datos que solo tu aplicaci&#243;n genera y necesita</strong>.</p><h3><strong>Usa servicios h&#237;bridos cuando:</strong></h3><p>Quieras empezar r&#225;pido o cuando personas no t&#233;cnicas vayan a editar los datos.</p><p>Contenido de blogs, listas de productos, informaci&#243;n de empresa, datos que cambian ocasionalmente y que prefieres editar en una interfaz familiar.</p><h3><strong>&#191;Qu&#233; ocurre en una aplicaci&#243;n real?</strong></h3><p>En la pr&#225;ctica, <strong>la mayor&#237;a de aplicaciones usan una combinaci&#243;n</strong> de las tres opciones.</p><p>Imag&#237;nate una app de fitness personal.</p><p>Usa una <strong>API externa</strong> para buscar informaci&#243;n nutricional de alimentos (prote&#237;nas, calor&#237;as, etc.).</p><p>Usa su <strong>propia base de datos</strong> para guardar los entrenamientos del usuario, su progreso, sus objetivos.</p><p>Y podr&#237;a usar <strong>Notion como servicio h&#237;brido</strong> para gestionar las rutinas de ejercicios, que el entrenador puede editar f&#225;cilmente.</p><p>El usuario abre la app, ve su progreso personal (desde la base de datos), busca un alimento y ve sus calor&#237;as (desde la API externa), y sigue una rutina (desde Notion).</p><p><strong>Todo funciona de forma transparente</strong>, pero por detr&#225;s est&#225;n trabajando tres fuentes de datos diferentes.</p><div><hr></div><p>Esta semana, por temas de timing, <strong>no me ha dado tiempo de grabarte un v&#237;deo</strong> en condiciones aplicando estos conceptos, &#161;pero lo tengo pendiente!</p><p>Lo voy a compartir en los pr&#243;ximos d&#237;as en <strong><a href="https://www.youtube.com/@VibeCodingparaDummies">Vibe Coding para Dummies en YouTube</a></strong>, as&#237; que si a&#250;n no lo has hecho, te invito a suscribirte y activar las notificaciones.</p><div><hr></div><h3><strong>Tu reto para esta semana: Convi&#233;rtete en detective de APIs</strong></h3><p>Como esta semana hemos hablado de teor&#237;a, tu misi&#243;n es empezar a <strong>familiarizarte con el ecosistema de datos din&#225;micos</strong>.</p><h3><strong>El reto es simple pero muy valioso:</strong></h3><p><strong>Encuentra 3-4 APIs diferentes</strong> que te parezcan interesantes e investiga:</p><ol><li><p><strong>Qu&#233; datos proporcionan</strong> (clima, libros, noticias, etc.)</p></li><li><p><strong>Si son gratuitas o de pago</strong> (y qu&#233; l&#237;mites tienen)</p></li><li><p><strong>Qu&#233; tipo de aplicaci&#243;n podr&#237;as crear</strong> con esos datos</p></li><li><p><strong>Si requieren registro</strong> o puedes usarlas directamente</p></li></ol><h3><strong>Algunas sugerencias para empezar:</strong></h3><ul><li><p><strong><a href="https://jsonplaceholder.typicode.com/">JSONPlaceholder</a></strong> - Datos fake perfectos para prototipos</p></li><li><p><strong><a href="https://openweathermap.org/api">OpenWeather</a></strong> - Datos meteorol&#243;gicos</p></li><li><p><strong><a href="https://thecatapi.com/">The Cat API</a></strong> - Fotos aleatorias de gatos (s&#237;, existe)</p></li><li><p><strong><a href="https://developers.google.com/books/docs/v1/using">Google Books API</a></strong> - Informaci&#243;n de libros</p></li><li><p><strong><a href="https://newsapi.org/">NewsAPI</a></strong> - Noticias de todo el mundo</p></li></ul><p><strong>Pero no te quedes solo con estas.</strong></p><p>Busca APIs relacionadas con tus intereses: deportes, cocina, m&#250;sica, finanzas, tecnolog&#237;a...</p><h3><strong>&#191;D&#243;nde buscar m&#225;s APIs?</strong></h3><ul><li><p><strong><a href="https://github.com/public-apis/public-apis">Public APIs GitHub</a></strong> - Lista gigante de APIs p&#250;blicas</p></li><li><p><strong><a href="https://rapidapi.com/">RapidAPI</a></strong> - Marketplace de APIs</p></li><li><p><strong><a href="https://www.programmableweb.com/">ProgrammableWeb</a></strong> - Directorio de APIs</p></li></ul><p><strong>El objetivo no es usar las APIs todav&#237;a</strong> (eso viene la semana que viene).</p><p>Solo quiero que te familiarices con la variedad de datos que existen y empieces a pensar en qu&#233; podr&#237;as crear.</p><p><strong>Bonus points:</strong> Si encuentras una API que te emocione especialmente, comp&#225;rtela en LinkedIn etiquet&#225;ndome. Me encanta descubrir APIs nuevas y originales.</p><h3><strong>&#191;Por qu&#233; es importante este ejercicio?</strong></h3><p>Porque muchas veces <strong>limitamos nuestras ideas a lo que conocemos</strong>.</p><p>Cuando veas la cantidad de datos disponibles ah&#237; fuera, se te van a ocurrir ideas de aplicaciones que ni sab&#237;as que eran posibles.</p><p>Y esa es <strong>la verdadera magia del vibe coding</strong>: conectar datos de formas creativas para resolver problemas reales.</p><div><hr></div><h3><strong>&#161;Y hasta aqu&#237; la newsletter de esta semana!</strong></h3><p>Si te ha quedado alguna duda, escribe un comentario o m&#225;ndame un mensaje, estar&#233; encantado de ayudarte.</p>]]></content:encoded></item><item><title><![CDATA[Del PRD conversacional al producto “real”]]></title><description><![CDATA[Esta semana tocaba poner en pr&#225;ctica el PRD conversacional. Te ense&#241;o c&#243;mo pasar de la teor&#237;a a una aplicaci&#243;n real funcionando con ChatGPT.]]></description><link>https://www.concriterio.blog/p/del-prd-conversacional-al-producto</link><guid isPermaLink="false">https://www.concriterio.blog/p/del-prd-conversacional-al-producto</guid><dc:creator><![CDATA[Pol Marzà]]></dc:creator><pubDate>Mon, 09 Mar 2026 22:43:08 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b6b3e0bf-9efc-4caa-8504-fbc5a666a7a7_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#161;Hola Viber!</p><p><strong>&#161;La newsletter de esta semana sale con retraso!</strong></p><p>Espero que no vuelva a ocurrir... <strong>&#161;Pero fue por un buen motivo!</strong></p><p>&#161;Gracias por leer Vibe Coding para Dummies! Suscr&#237;bete gratis para recibir nuevos posts y apoyar mi trabajo.</p><p>Ayer hice mi primer webinar &#128512;</p><p>Ya s&#233;, no es excusa, pero me llev&#243; mucho tiempo de preparaci&#243;n y nervios y descuid&#233; un poco la redacci&#243;n de la news de esta semana...</p><p>&#191;De qu&#233; iba el webinar?</p><p>Pues del famoso <strong>PRD conversacional</strong>, <strong><a href="https://open.substack.com/pub/vibecodingparadummies/p/tu-prd-conversacional?r=3piuga&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=false">ese del que te habl&#233; la semana pasada</a></strong>. La idea con el webinar fue ponerlo en pr&#225;ctica.</p><p>Es decir, presentar un poco la teor&#237;a vista en la newsletter y luego hacer un PRD en vivo.</p><p>No sali&#243; del todo como esperaba, cosas del directo. En mi cabeza ten&#237;a mejor pinta, pero la gente qued&#243; contenta, as&#237; que <strong>&#201;XITO total</strong> &#128077;</p><p>&#191;Qu&#233; tal t&#250;? &#191;Has podido practicar?</p><p>&#191;Has probado a poner en pr&#225;ctica el PRD conversacional?</p><p>No era obligatorio, no te sientas obligad@, pero como en el cole, <strong>si vas practicando lo aprendido, luego no se te har&#225; una monta&#241;a</strong>.</p><div><hr></div><h3><strong>&#191;Qu&#233; vamos a ver hoy?</strong></h3><p>Pues hoy el tema va de <strong>poner en pr&#225;ctica el PRD</strong>, de ponerlo a trabajar para crear &#8220;algo&#8221;.</p><p>Mi idea era empezar a ense&#241;arte cosas tal cual las aprend&#237; en su momento, es decir, empezar con ChatGPT.</p><p>Realmente no sab&#237;a exactamente c&#243;mo enfocar esta publicaci&#243;n de hoy. De hecho, hab&#237;a empezado un borrador con Claude y lo he tirado completamente a la basura.</p><p><strong>&#191;Por qu&#233;?</strong></p><p>Bueno, porque quer&#237;a hacer algo <strong>SUPER pr&#225;ctico</strong>, y al ser algo de construcci&#243;n, le ve&#237;a poco sentido a hacer un tutorial por escrito.</p><p>As&#237; que esta tarde (jueves), me he liado la manta a la cabeza y he grabado un v&#237;deo del tir&#243;n mostrando:</p><p>&#9989; <strong>El PRD</strong></p><p>&#9989; <strong>C&#243;mo traspasarlo a ChatGPT</strong> y generar el c&#243;digo de la aplicaci&#243;n</p><p>&#9989; <strong>C&#243;mo traspasar el resultado</strong> que nos da la IA a un editor de c&#243;digo</p><p>&#9989; <strong>Visualizar el resultado final</strong> en el navegador</p><p>As&#237; que esta semana hay poca teor&#237;a y vamos a ver cosas en directo.</p><p>El v&#237;deo te lo adjunto unas l&#237;neas m&#225;s abajo, y creo que es una manera genial de presentarte (redoble de tambores por favor):</p><p><strong><a href="https://www.youtube.com/@VibeCodingparaDummies">&#161;Mi nuevo canal de YouTube!</a> &#127916;</strong></p><p><em>&#8220;Pero Pol... &#161;Cu&#225;ntas novedades esta semana!&#8221;</em></p><p>Yaya, no paro.</p><p>Cada vez me atrevo con m&#225;s cosas.</p><p>Recuerda que llevo <strong>CASI 3 a&#241;os con esto del vibe coding</strong>...</p><div><hr></div><h3><strong>Los recursos que necesitas para el reto de hoy</strong></h3><p>Para ponerte las cosas f&#225;ciles (para dummies), te adjunto los recursos que vas a necesitar:</p><p>&#128279; <strong><a href="https://docs.google.com/document/d/1ukVSA2CJaHUqsEBkEolFnfU9WjJtAaYJVRMgJY52c94/edit?usp=sharing">Google Docs con el PRD predise&#241;ado</a></strong> (por si no hiciste los deberes)</p><p>&#129302; <strong><a href="https://chat.openai.com/">ChatGPT</a></strong> (a estas alturas creo que no necesita presentaciones)</p><p>&#128187; <strong><a href="https://code.visualstudio.com/">Visual Studio Code</a></strong> (el editor de c&#243;digo que vamos a usar)</p><p><strong>Si ya tienes tu propio PRD, &#161;&#250;salo!</strong> Solo te he puesto el de ejemplo por si no hiciste los deberes &#128541;</p><p><strong>Sobre el editor de c&#243;digo:</strong> He elegido este porque es el que utilizo y es uno de los m&#225;s conocidos. Si quieres usar otro, &#250;salo.</p><div><hr></div><h3><strong>&#161;Ahora s&#237;, dentro v&#237;deo!</strong></h3><div id="youtube2-xrwKjypCyOE" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;xrwKjypCyOE&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/xrwKjypCyOE?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p><strong>&#191;Qu&#233; tal lo has visto?</strong> Si te queda alguna duda, escr&#237;belo en comentarios.</p><div><hr></div><h3><strong>Te quer&#237;a contar algo m&#225;s antes de terminar:</strong></h3><p>Cuando he subido el v&#237;deo a YouTube, antes de publicarlo, se lo he pasado a <strong><a href="https://www.linkedin.com/in/franconejos?miniProfileUrn=urn%3Ali%3Afs_miniProfile%3AACoAAADwuHEBbNvBpNYX59Si4GmSmiphzdRUgQI">Fran Conejos</a></strong> para que me diera su opini&#243;n y me ha hecho reflexionar sobre algo.</p><p>Sus palabras textuales han sido:</p><blockquote><blockquote><p><em>&#8220;Muy guay pero no termino de entender por qu&#233; los mandas a descargarse vs code y lo llamas para dummies &#128514;&#8221;</em></p></blockquote></blockquote><p>Entiendo su punto de vista, y entiendo que t&#250; te puedas sentir un poco abrumad@ cuando te descargues e instales Visual Studio Code.</p><p><strong>Pero... Hemos venido a jugar, &#191;no?</strong></p><h3><strong>&#191;Qu&#233; significa &#8220;para dummies&#8221; en esta newsletter?</strong></h3><p>La definici&#243;n textual de &#8220;dummies&#8221; en espa&#241;ol dice:</p><blockquote><blockquote><p><em>&#8220;Puede usarse para describir a principiantes o inexpertos en un tema. Adem&#225;s, en algunos contextos, puede tener connotaciones de tonto o bobo.&#8221;</em></p></blockquote></blockquote><p><strong>Pero para m&#237; va m&#225;s all&#225;.</strong></p><p>Para mi <em>vibe</em> <em>coding para dummies</em> consiste en <strong>explicar conceptos, funcionalidades y herramientas</strong> (que a priori pueden parecer complejas) <strong>en un lenguaje que todo el mundo pueda entender</strong>.</p><p>Es como cuando trabajaba en IKEA y me dec&#237;an <em>&#8220;expl&#237;cale las cosas al cliente como si tuviera 4 a&#241;os&#8221;</em>.</p><p>No en plan despectivo, sino imaginando que (el cliente) no sab&#237;a nada del tema, <strong>no dando nada por supuesto</strong>.</p><p><strong>As&#237; es como me planteo esta newsletter.</strong></p><h3><strong>&#191;Por qu&#233; empezar con lo &#8220;cl&#225;sico&#8221;?</strong></h3><p>Fran tambi&#233;n me ha hecho notar algo importante:</p><blockquote><blockquote><p><em>&#8220;Te tengo que recordar que cuando t&#250; empezaste no exist&#237;a Lovable ni Cursor. A lo mejor la senda (del viber) se podr&#237;a modernizar un poco&#8221;</em></p></blockquote></blockquote><p>Entiendo y respeto completamente que t&#250; tambi&#233;n te puedas sentir/pensar igual que Fran.</p><p><strong>Es sencillo:</strong> puedes saltarte estos posts y reengancharte cuando toque temas de Lovable o Bolt (que no tardar&#233; mucho), <strong>&#161;pero creo que te estar&#225;s perdiendo cosas muy interesantes!</strong></p><p>En la pr&#225;ctica de hoy hemos hecho una web con la ayuda de la IA, pero <strong>con vibe coding tambi&#233;n puedes hacer:</strong></p><p>&#128295; Una extensi&#243;n para Chrome </p><p>&#128421;&#65039; Una aplicaci&#243;n de escritorio con Python </p><p>&#128241; Un script de automatizaci&#243;n </p><p>&#128736;&#65039; Una herramienta de l&#237;nea de comandos</p><p>Y para construir todo eso, se puede usar ChatGPT, Gemini o Claude.</p><p><strong>&#191;Te lo vas a perder?</strong></p><p>Nah... Yo creo que eres una persona curiosa y con sed de aprender c&#243;mo construir las movidas que tienes en la cabeza.</p><p>&#161;Nos vemos la pr&#243;xima semana!</p><div><hr></div><p><strong>Ah, se me olvidaba, &#161;el reto de hoy!</strong> Tienes dos opciones:</p><ol><li><p><strong>Aplicar el PRD</strong> que (en principio) hiciste la semana pasada</p></li><li><p><strong>Aplicar el PRD</strong> que te he compartido, editarlo, expandirlo, ponte creativ@</p></li></ol><p>En cualquier caso, <strong>a ver qu&#233; construyes</strong> &#128512;</p><p>Salga lo que salga, si te animas, <strong>&#161;publ&#237;calo en LinkedIn!</strong></p><p>Comp&#225;rtelo en tu red para que todo el mundo vea lo que est&#225;s aprendiendo en esta newsletter (y de paso me haces un poco de publicidad que nunca viene mal).</p><p><strong>Ahora s&#237;, hasta la semana que viene</strong> &#128578;</p><div><hr></div><p><strong>PD:</strong> Si el formato en v&#237;deo te gusta, har&#233; m&#225;s contenido as&#237;. Si prefieres texto, tambi&#233;n puedo adaptarme. <strong>T&#250; decides</strong></p>]]></content:encoded></item></channel></rss>