<?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[memolio: Build in Public]]></title><description><![CDATA[Weekly dev diary from the trenches of building an AI-powered personalised book product. Bugs, breakthroughs, and the honest reality of shipping solo.]]></description><link>https://blog.memolio.io/s/build-in-public</link><image><url>https://substackcdn.com/image/fetch/$s_!z4kH!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e322ec-49d9-42d0-8696-62ba1fff963d_2480x2480.jpeg</url><title>memolio: Build in Public</title><link>https://blog.memolio.io/s/build-in-public</link></image><generator>Substack</generator><lastBuildDate>Sun, 07 Jun 2026 03:24:53 GMT</lastBuildDate><atom:link href="https://blog.memolio.io/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[The Egg Consultancy]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[memolio@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[memolio@substack.com]]></itunes:email><itunes:name><![CDATA[memolio]]></itunes:name></itunes:owner><itunes:author><![CDATA[memolio]]></itunes:author><googleplay:owner><![CDATA[memolio@substack.com]]></googleplay:owner><googleplay:email><![CDATA[memolio@substack.com]]></googleplay:email><googleplay:author><![CDATA[memolio]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[I entered with a single prompt. I came out with a product.]]></title><description><![CDATA[How a twelve-panel comic about Tyrol's energy future became the start of Memolio.]]></description><link>https://blog.memolio.io/p/i-entered-with-a-single-prompt-i</link><guid isPermaLink="false">https://blog.memolio.io/p/i-entered-with-a-single-prompt-i</guid><dc:creator><![CDATA[memolio]]></dc:creator><pubDate>Tue, 12 May 2026 09:54:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!s7X7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A few months ago I entered the Tirol 2050 comic competition. The brief was simple: show your vision of Tirol&#8217;s energy future. I sat down with one idea and the intention of getting it out in a single image.</p><p>I ended up with a twelve-panel comic, and not long after I was building Memolio.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.memolio.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s7X7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s7X7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png 424w, https://substackcdn.com/image/fetch/$s_!s7X7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png 848w, https://substackcdn.com/image/fetch/$s_!s7X7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png 1272w, https://substackcdn.com/image/fetch/$s_!s7X7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s7X7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png" width="1456" height="2474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2474,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7393576,&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://blog.memolio.io/i/197329266?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.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_!s7X7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png 424w, https://substackcdn.com/image/fetch/$s_!s7X7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png 848w, https://substackcdn.com/image/fetch/$s_!s7X7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.png 1272w, https://substackcdn.com/image/fetch/$s_!s7X7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16fb1f5f-574d-43a1-8506-e4ea43bc095c_3508x5961.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 role="img" 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><title></title><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">The entry: a twelve-panel retrofuturist comic imagining how Tyrol got to 2050</figcaption></figure></div><p>This week I found out it won a prize. Thank you to Tirol 2050 for picking it, and to Gloryfy for the indestructible sunglasses that came with the win. As a deeply messy and unorganised person, I am intent on testing them to their limits!</p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4TTo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4TTo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4TTo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4TTo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4TTo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4TTo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg&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;:3251902,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.memolio.io/i/197329266?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4TTo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4TTo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4TTo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4TTo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5570a1d-a43f-4721-961f-812396cbf17b_4032x3024.jpeg 1456w" sizes="100vw"></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 role="img" 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><title></title><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">The comic on display at the Sparkasse Platz in Innsbruck.</figcaption></figure></div><p></p><p>I want to talk about what happened between sitting down with a single image in mind and ending up with a sequence, because I think it&#8217;s a pattern worth naming.</p><p>The original prompt was already loaded. An old man in traditional Austrian &#8216;Tracht&#8217;. Children at his feet. A 1950s retrofuturist palette. Solar panels glinting off alpine farmhouses. I fed it all in and got back a perfectly competent image. It was fine. It was also flat.</p><p>What was missing wasn&#8217;t quality. The model can render Tracht and solar panels just fine. What was missing was meaning. The image didn&#8217;t say anything. It didn&#8217;t have a beginning or an end. There was no question being asked and no answer being given. It was a tableau.</p><p>So I added a second panel. Then a third. Then I kept going. By the time I stopped I had twelve. Electric trams and buses threading green city streets. Cable cars climbing from town centres to mountain peaks. Mountain villages alive again because energy is nearly free. Cows resting in the shade of solar canopies. Near-free electricity moving like water from a mountain spring. Summer water pumped up to reservoirs so families could keep warm with the people they loved in winter. Eleven panels of patient build. Then the twelfth: a small child looking up at the old man and asking, &#8220;But why did you do it?&#8221; And the old man answering, &#8220;Why? Why not?&#8221;</p><p>That last exchange is the entire point of the comic. There is no single image in the world that contains it. The question only lands because eleven panels have already painted the world the question is being asked about. The answer only lands because you&#8217;ve already started caring about the old man. You need the build, the pause, and then the punch.</p><p>That was where I had a quiet realisation that has shaped the last six months of my life.</p><p>Single prompts are a one-frame medium. They can be beautiful, evocative, sometimes startling. But they are structurally unable to carry an arc. The model does not know what came before and does not know what comes after. The viewer has to do all the editorial work in their head, and most viewers won&#8217;t.</p><p>Narrative is the unlock. A handful of pictures and a handful of words in sequence can do what no single generation can. They can hold a question over a beat, then answer it. They can age a face across pages. They can let a grandfather be a child first, before he is anyone&#8217;s grandfather.</p><p>After the competition I started sketching what would become Memolio: a workflow that turns a grandparent&#8217;s life into an illustrated book. The product is built on the same insight as that twelve-panel comic. It isn&#8217;t really in the business of generating beautiful single images, although it does that as a side effect. It&#8217;s in the business of stringing them together into a story that means something to one specific family.</p><p>The Tirol 2050 brief was about renewable energy. The lesson I took away was different and, for the thing I&#8217;m building, more useful. AI gets interesting the moment you stop asking it for an image and start asking it for a story. The output is no longer something you look at. It&#8217;s something you read.</p><p>That shift, from looking to reading, is the entire game.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T2am!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T2am!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg 424w, https://substackcdn.com/image/fetch/$s_!T2am!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg 848w, https://substackcdn.com/image/fetch/$s_!T2am!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!T2am!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T2am!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg" width="1456" height="1941" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1941,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2947200,&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://blog.memolio.io/i/197329266?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T2am!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg 424w, https://substackcdn.com/image/fetch/$s_!T2am!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg 848w, https://substackcdn.com/image/fetch/$s_!T2am!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!T2am!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1294d10a-3bce-4ac2-ab4b-b800c6df3d2b_3088x2316.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 role="img" 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><title></title><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">Initial impressions of the indestructible sunglasses: still in one piece. Time will tell.</figcaption></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.memolio.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><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[Build in Public #18: The Nodes That Always Bite You]]></title><description><![CDATA[If you build long enough with n8n, you start to learn which parts of your workflow are safe to touch and which ones are going to quietly ruin your day.]]></description><link>https://blog.memolio.io/p/build-in-public-18-the-nodes-that</link><guid isPermaLink="false">https://blog.memolio.io/p/build-in-public-18-the-nodes-that</guid><dc:creator><![CDATA[memolio]]></dc:creator><pubDate>Tue, 28 Apr 2026 09:32:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!z4kH!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e322ec-49d9-42d0-8696-62ba1fff963d_2480x2480.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you build long enough with n8n, you start to learn which parts of your workflow are safe to touch and which ones are going to quietly ruin your day.</p><p></p><p>Safe to touch: most of it. Change a prompt, adjust a parameter, add a new branch. The workflow does what you'd expect. If something breaks, it usually breaks loudly.</p><p></p><p>Not safe to touch: a handful of specific Code nodes that I've come to call trouble nodes. These don't break loudly. They break silently, in a way that produces no error and no warning, and that you only discover days later when a tester reports that something is subtly wrong with their book.</p><p></p><p>Learning where these nodes live, why they behave the way they do, and how to build a working system around them has been one of the more useful engineering lessons of building Memolio, a personalised illustrated book for grandparents.</p><p></p><p>What Makes a Node a Trouble Node</p><p></p><p>The pattern is specific. A trouble node is a Code node that rebuilds its output by explicitly listing every field it wants to forward downstream, rather than using a spread or destructuring. Something like:</p><p></p><p>return {</p><p>  book_id: input.book_id,</p><p>  grandparent_name: input.grandparent_name,</p><p>  birth_year: input.birth_year,</p><p>  // ... 15 more lines</p><p>};</p><p></p><p>This exists for legitimate reasons. You don't want every piece of upstream data blindly propagating through your entire pipeline. At certain boundaries, you want to be deliberate about what flows forward.</p><p></p><p>The problem is that "deliberate" becomes "frozen." Every time you add a new field anywhere upstream of a trouble node, that field hits the explicit list, finds its name isn't on it, and disappears. Silently. The node doesn't throw an error. The next node down doesn't know to ask for the missing field. The failure is invisible until something downstream tries to use it.</p><p></p><p>The worst part is the pattern of discovery. You add a new intake question in Typeform. You wire it through the mapper. You test the mapper output and the field is there. You fire a test run and everything looks fine. Two weeks later a tester points out that a certain piece of their book is wrong, and you trace it back and find that the field died at a trouble node four hops back. The silence is the feature that makes it dangerous.</p><p></p><p>The Nodes That Keep Biting</p><p></p><p>In Memolio's workflow, the mapper is the most consistent offender. The mapper is the node that takes raw Typeform responses (or WhatsApp intake data) and transforms them into structured fields the rest of the pipeline can use. It's a complex node: it handles two intake channels, two languages, dozens of question variants, and months of accumulated edge cases.</p><p></p><p>Whenever I change a question in Typeform or WhatsApp, two things have to change: the question itself, and the mapper. If the question changes and the mapper doesn't, the field comes in with a new wording, the mapper's pattern match fails to recognise it, and it emits null downstream. No error. The field just isn't there.</p><p></p><p>This has happened several times. The mapper is a trouble node not because it hand-picks output fields in the same way as the others, but because it has an implicit field list baked into its getField() pattern matchers. Change the question wording and you've implicitly removed that field from the list.</p><p></p><p>The other consistent offenders are Prepare Book Recipe Data in WF1 (which writes the questionnaire to Supabase), and Parse Sanitized Data and Parse Story Pages (which re-emit per-page objects after LLM processing). These are all explicit hand-pick nodes. Add a field anywhere in the intake and there's a high chance it reaches one of these and stops.</p><p></p><p>The System I Built to Handle It</p><p></p><p>The first thing I did was name them. Every trouble node now has a prominent comment at the top of its code:</p><p></p><p>// TROUBLE NODE - HAND-PICK FIELD ENUMERATION</p><p>// This node explicitly lists every field it forwards.</p><p>// If you add a field upstream, add it here too or it will be silently dropped.</p><p></p><p>This sounds trivial, but it's not. When a node has that header, it becomes searchable. I can grep for TROUBLE NODE across every workflow file and immediately find all the places that need updating when I add something new. The header turns a hidden architectural constraint into a visible one.</p><p></p><p>The second thing I did was create a Claude skill that enforces the update pattern. When I'm making a change to any intake question &#8212; in Typeform EN, Typeform DE, or the WhatsApp chat engine &#8212; the skill prompts me to:</p><p></p><p>1. Update the question in the intake surface</p><p>2. Update the mapper's pattern matchers for both language variants, keeping old variants as fallbacks (historical intakes still need to parse)</p><p>3. Grep all workflows for TROUBLE NODE and check each node in the field's path</p><p>4. Add the field to every trouble node it flows through</p><p>5. Add the field to the consumer that actually uses it</p><p>6. Run an end-to-end smoke test and verify the field arrives at the consumer</p><p></p><p>The skill doesn't do the work for me. It's a checklist with context: it knows which nodes are trouble nodes, it knows the mapper has both EN and DE variants, and it knows that adding a field without updating the mapper is how we've lost data in the past.</p><p></p><p>The thing about working with AI on a complex workflow is that the AI doesn't know your architecture the way you do. I can ask Claude to add a field to the pipeline, and Claude will do it correctly at the points it can see. But it won't automatically know that Prepare Book Recipe Data needs to be updated, because that's not obvious from the code &#8212; it's institutional knowledge about which nodes are dangerous. The skill is how I've encoded that knowledge into the collaboration.</p><p></p><p>The Meta-Lesson</p><p></p><p>This is really about the gap between "works in the happy path" and "works when things change."</p><p></p><p>Any automation workflow has nodes that are fine to touch and nodes that require a ritual. The mistake is not documenting which is which, because the cost of the mistake is invisible for a long time and then suddenly very visible when a tester notices something wrong.</p><p></p><p>What I've landed on is a simple principle: if a node has an implicit or explicit field list that doesn't automatically inherit from its input, it needs to be named, documented, and covered by a checklist. The effort of maintaining the list is trivial. The effort of finding a silent data-drop bug weeks after it was introduced is not.</p><p></p><p>Building with AI tools accelerates a lot of things. The thing it doesn't automatically accelerate is the accumulation of structural knowledge about your own system. That part is still yours to do.</p><p></p><p>If you're building workflows in n8n, or anything with explicit data transformation nodes, I'd be curious whether you've hit a similar pattern and how you've handled it. The trouble node convention is working well, but I suspect there are better approaches I haven't thought of yet.</p><p></p><p>Follow the build on Substack. And if you have a grandparent whose stories deserve to be preserved, Memolio is getting close.</p><p></p><p>Memolio builds personalised illustrated books for grandparents, crafted from real memories. </p>]]></content:encoded></item><item><title><![CDATA[Build in Public #17: "She Looks Frumpy"]]></title><description><![CDATA[My mother-in-law looked at her AI-generated book and said she looked frumpy. She was right. It exposed a blind spot I had about age, identity, and what AI actually assumes about older people.]]></description><link>https://blog.memolio.io/p/build-in-public-17-she-looks-frumpy</link><guid isPermaLink="false">https://blog.memolio.io/p/build-in-public-17-she-looks-frumpy</guid><dc:creator><![CDATA[memolio]]></dc:creator><pubDate>Tue, 28 Apr 2026 06:01:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!z4kH!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e322ec-49d9-42d0-8696-62ba1fff963d_2480x2480.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I build Memolio, a personalised book for grandparents made from real memories and photos. Every Monday I write about what&#8217;s actually happening: the things that ship, the things that break, the things I didn&#8217;t see coming.</p><p>My mother-in-law looked at her illustrated book and her reaction was immediate. Not &#8220;oh it&#8217;s lovely&#8221; and not &#8220;I have some notes.&#8221; Just: &#8220;I look frumpy.&#8221;</p><p>I found it funny, honestly. It wasn&#8217;t the kind of feedback I was expecting from a user test. But then my wife looked over her shoulder and agreed. And at that point I stopped finding it funny and started paying attention, because two people who know this woman well had the same reaction to how the AI had drawn her.</p><p>I went back and looked at the code.</p><p>The problem was hiding in plain sight</p><p>Every grandparent in every Memolio book &#8212; regardless of their actual age, regardless of anything the user had told us about them &#8212; was being described to the image model as &#8220;an elderly woman&#8221; or &#8220;an elderly man&#8221; in &#8220;age-appropriate casual clothing.&#8221;</p><p>Those two phrases together. That&#8217;s basically a prompt recipe for someone hunched in a cardigan.</p><p>The &#8220;how did I not see this&#8221; feeling hit pretty hard. I&#8217;d been so focused on getting the faces right, the illustration style consistent, the story prompt producing the right scenes, that I&#8217;d never stopped to think about what the model was actually being told about how this person dressed. It had never been an explicit decision. It was just a default that crept in, and I&#8217;d never questioned it.</p><p>The thing is, I had an image of &#8220;older people&#8221; in my head that came from my own grandmother. Her generation. Her clothes. And I&#8217;d just... baked that into the product without realising it.</p><p>A generational shift I&#8217;d completely missed</p><p>Here&#8217;s the thing about someone who is 65 or 70 right now: they grew up in the 60s and 70s. For a lot of people that age, fashion wasn&#8217;t just something they wore. It was a core part of their identity. They had a look. They had opinions about it. Some of them still do.</p><p>The &#8220;age-appropriate casual clothing&#8221; default had no way of knowing that. It was treating every grandparent as a generic category of person rather than as an individual who has spent decades figuring out how they want to present themselves to the world.</p><p>The fix was straightforward once I saw it: ask the user. What&#8217;s this person&#8217;s clothing style? We added a simple preference input &#8212; smart and polished, casual and relaxed, sporty, artistic, that kind of thing. Now a woman in her late 50s who describes herself as &#8220;smart and polished&#8221; gets illustrated in tailored trousers and crisp shirts instead of shapeless knitwear. Four files, about thirty minutes of work. The kind of change that probably matters more to customer satisfaction than anything else I&#8217;ve shipped this month.</p><p>But the real lesson is bigger than the fix</p><p>What I keep coming back to is how the model ended up with those assumptions in the first place. It didn&#8217;t make up &#8220;elderly in age-appropriate casual clothing&#8221; from nowhere. It learned from images. And images, across decades of media and stock photography, have a very specific idea of what an older person looks like. Dignified. Soft. Comfortable. Sensible shoes.</p><p>AI reflects the assumptions baked into the culture that produced the training data. That&#8217;s obvious when you say it out loud. It&#8217;s much less obvious when you&#8217;re in the middle of building something and just trying to get a feature to work.</p><p>This is why talking to actual users matters so much. Not surveys, not analytics, not me reviewing test books on my laptop. My mother-in-law looking at a picture of herself and saying &#8220;I look frumpy&#8221; is information I could not have generated any other way. My blind spot about what &#8220;older&#8221; looks like is a human blind spot, shaped by my own experience. The model has the same blind spot, at scale, shaped by decades of the same cultural assumptions.</p><p>The only way to find those gaps is to put the thing in front of real people and let them tell you what&#8217;s wrong.</p><p>The harder problem is still ahead</p><p>The fix I shipped is good but not complete. Asking people to describe their clothing style works when they have a clear sense of their own aesthetic. A lot of people don&#8217;t, or they describe themselves in ways that don&#8217;t map cleanly onto what the image model thinks &#8220;smart casual&#8221; or &#8220;artistic&#8221; looks like. Most people don&#8217;t neatly fit into a box.</p><p>The ideal version of this is probably more granular: specific items, specific eras, specific references. But that&#8217;s a longer form to fill in and a harder prompt to write. For now, having any preference at all is a massive improvement over a universal cardigans-for-everyone default.</p><p>Small change. Meaningful impact. One mother-in-law who might now look like herself in the book her family is making for her.</p><p>If you&#8217;re building something where AI has to represent real people, I&#8217;d genuinely like to know how you&#8217;re handling this. It feels like an unsolved problem across a lot of products. Drop a reply or find me on the blog.</p><p>And if you have a grandparent whose story deserves to be told, join the waitlist for early access when Memolio opens up properly: https://blog.memolio.io/subscribe</p><p>Memolio creates personalised illustrated books for grandparents from real memories and photos. Not yet publicly purchasable. Join the waitlist: https://blog.memolio.io/subscribe</p>]]></content:encoded></item><item><title><![CDATA[The Ninety-Second Fix That Took Four Hours]]></title><description><![CDATA[Build in Public &#8212; Memolio, 10 April 2026]]></description><link>https://blog.memolio.io/p/the-ninety-second-fix-that-took-four</link><guid isPermaLink="false">https://blog.memolio.io/p/the-ninety-second-fix-that-took-four</guid><dc:creator><![CDATA[memolio]]></dc:creator><pubDate>Fri, 10 Apr 2026 11:54:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!z4kH!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5e322ec-49d9-42d0-8696-62ba1fff963d_2480x2480.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yesterday I spent four hours watching Claude solve the same problem five different times. Each fix felt like the last one. Each time it was wrong.</p><p>The problem itself was boring: I&#8217;d deployed a small AWS Lambda to process PDFs as part of our book printing pipeline. It worked perfectly when I tested it inside the AWS console. The moment I called it from anywhere else &#8212; my own computer, our automation tool, anywhere that wasn&#8217;t the console itself &#8212; it returned <code>403 Forbidden</code>. Locked out by its own configuration.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.memolio.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Claude&#8217;s suggestion was confident and clear: &#8220;Just re-add the permission, it&#8217;s a 2-minute fix.&#8221; I did. It didn&#8217;t work. &#8220;Try deleting the old permission first, then re-adding it.&#8221; I did. It didn&#8217;t work. &#8220;Let&#8217;s use the CLI instead of the console.&#8221; I did. It didn&#8217;t work. Every fix came with the same breezy certainty, and every failure was met with a new suggestion delivered in the same breezy certainty.</p><p>At some point I noticed something that should have been obvious from the start: we were going in circles. Claude wasn&#8217;t tracking what had already failed. It was pattern-matching each new attempt to a different prior problem, confidently prescribing solutions that I had already tried, sometimes twice. I was the memory. I was the thing keeping the debugging session coherent, and I was terrible at it because I was tired and it was 1am and I wanted to go to bed.</p><p>Eventually I got genuinely annoyed and typed something I don&#8217;t usually type at a computer:</p><blockquote><p>&#8220;you really need to get better at recording what HASNT worked when debugging because we are just going round in circles&#8221;</p></blockquote><p>That single sentence flipped the entire session.</p><h2>What changed when I forced the step back</h2><p>Claude wrote a file called <code>DEBUG_403.md</code>. Inside it: every attempt, every result, every hypothesis still alive. It read the actual error messages character by character instead of skimming them. It did a proper web search. And within about ninety seconds it had the real answer.</p><p>Turns out AWS quietly changed how Lambda Function URLs work in October 2025. They used to need one permission (<code>lambda:InvokeFunctionUrl</code>). They now silently require two (<code>lambda:InvokeFunctionUrl</code> AND <code>lambda:InvokeFunction</code>). If you only have the first one, every public request returns 403, forever. The AWS console had actually been telling me this the whole time &#8212; there was a little blue banner explicitly stating both permissions were needed. I read it nine times over the course of the debugging session. Claude generated a response to it nine times. Neither of us actually understood what it said, because we were both too busy pattern-matching to similar-looking past problems.</p><p>The fix was one CLI command.</p><h2>The thing I keep relearning</h2><p>I&#8217;ve been working with AI coding agents intensively for almost a year now. I build Memolio almost entirely with them &#8212; most days I don&#8217;t write code directly, I describe what I want and review what comes back. And I keep learning the same lesson in different forms: <strong>AI agents will loop on an approach forever if you let them. Sometimes the most valuable thing a human can do is force a step back.</strong></p><p>It&#8217;s tempting to read this as &#8220;AI is unreliable, don&#8217;t trust it.&#8221; That&#8217;s not quite right. Claude wasn&#8217;t being lazy or malfunctioning. It was doing what large language models do: generating the next most plausible response given the state of the conversation. The problem was that the state of the conversation kept looking like a problem it had almost-seen-before, and &#8220;almost-seen-before&#8221; is a bad foundation for debugging something you haven&#8217;t actually seen at all.</p><p>What the model needed was a different kind of context: not more suggestions, but an enforced structure. A file on disk listing what had been tried. A requirement to read the error message literally before guessing. A rule that says &#8220;on the second failed attempt, stop guessing and start researching.&#8221; None of this is beyond the model&#8217;s capabilities &#8212; it did all of it brilliantly once asked. It just wouldn&#8217;t do it on its own.</p><p>I think this is the actual skill of working with AI agents in 2026. Not prompt engineering. Not picking the right model. Not even building clever evaluation loops. It&#8217;s <em>knowing when to interrupt</em>. Knowing when the confident-sounding next step is actually the fourth iteration of the same wrong step, dressed in different words. Knowing when to stop letting the machine drive and make it justify itself.</p><p>When I did that last night, Claude wrote me a memory file &#8212; literally, a permanent note to its own future sessions &#8212; called <code>feedback_record_what_hasnt_worked.md</code>. The rule: &#8220;On the second failed attempt at any fix, stop guessing. Create a debug log. Read error messages literally. Do proper research before suggesting more button-clicking.&#8221; It will remember this next time I start a new session. I don&#8217;t know if that&#8217;s exactly what machine learning researchers mean when they talk about AI that learns from feedback, but it felt like something.</p><h2>The thing that actually shipped</h2><p>Oh, right. The Lambda works now. The entire print pipeline for Memolio is automated end-to-end for the first time. When a grandparent finishes their WhatsApp interview and approves their book in the review page, everything from &#8220;interview complete&#8221; to &#8220;physical book printed and shipped&#8221; now runs without a human touching it. A webhook fires, PDFs get generated, the Lambda adds the tiny invisible printer metadata that commercial presses require, real MD5 hashes get computed, the order lands in CloudPrinter&#8217;s system, and forty-five seconds later there&#8217;s a confirmed sandbox order waiting to go.</p><p>And it happened in ninety seconds once we stopped pretending we knew the answer.</p><div><hr></div><p><em>Memolio turns a grandparent&#8217;s stories into a personalised, illustrated book &#8212; captured over WhatsApp, illustrated by AI, printed and shipped in hardcover. We&#8217;re currently in closed user testing. If you want early access or just want to follow along as we build, you can reply to this email or <a href="https://memolio.io">sign up at memolio.io</a>.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.memolio.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>