<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>blog.vrypan.net</title>
    <link>https://blog.vrypan.net/</link>
    <description>blog.vrypan.net</description>
    <lastBuildDate>Sat, 20 Jun 2026 15:17:16 +0000</lastBuildDate>
    <generator>bckt</generator>
    <atom:link href="https://blog.vrypan.net/rss.xml" rel="self" type="application/rss+xml"/>
    
    <item>
      <title>The ghost girl</title>
      <link>https://blog.vrypan.net/2026/06/20/260620-the-ghost-girl/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/20/260620-the-ghost-girl/</guid>
      <pubDate>Sat, 20 Jun 2026 15:17:16 +0000</pubDate>
      <description></description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/06/20/260620-the-ghost-girl/image.jpeg">
        
	
]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/06/20/260620-the-ghost-girl/image.jpeg"
   type="image/jpeg"
   length="1367721"/>

    </item>
    
    <item>
      <title>We have to go back!</title>
      <link>https://blog.vrypan.net/2026/06/19/260619-we-have-to-go-back/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/19/260619-we-have-to-go-back/</guid>
      <pubDate>Fri, 19 Jun 2026 17:32:21 +0000</pubDate>
      <description>In 2024, Farcaster was the most decentralized it had ever been: a peer-to-peer network of hubs that were, at the protocol level, peers. My hub running on a Raspberry Pi at home, your hub on a VPS, Merkle’s hubs powering Warpcast, Neynar’s hubs powering various independent apps — ...</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/06/19/260619-we-have-to-go-back/lost.jpeg">
        
	<p>In 2024, Farcaster was the most decentralized it had ever been: a peer-to-peer network of hubs that were, at the protocol level, peers. My hub running on a Raspberry Pi at home, your hub on a VPS, Merkle’s hubs powering Warpcast, Neynar’s hubs powering various independent apps — they were all peers. Not equal, because network position, capacity, reliability, and importance mattered, but peers.</p>
<p>A year later, in spring 2025, Farcaster migrated to Snapchain.</p>
<p>Snapchain introduced globally ordered blocks, consensus, and, most importantly, higher throughput. Throughput was the weak point of the hub approach, and Snapchain fixed it in order to allow Farcaster to grow from tens of thousands of users to millions of users. But it sacrificed the one unique feature Farcaster had: decentralization.</p>
<p>The core team’s North Star was simple: grow 1000x or die. In pursuit of high growth, they introduced a number of additional client-side features: Frames and Mini Apps, wallets, and Sign in with Farcaster. What used to be a principle — that protocol changes should not be introduced unless a feature has matured — was forgotten, and protocol changes were introduced overnight to support things that looked attractive product-wise, like Farcaster Pro. Fees were reduced to practically zero, despite the original thesis that fees are the friction required to fight spam and abuse of network resources.</p>
<p>All these features made building alternative clients harder and harder, not to mention that the lines between “the protocol” and “clients” were blurred: Farcaster is not the protocol anymore; it’s <strong>the</strong> client.</p>
<p>These were good features. Fun to use and build for. But the expected growth never came, and all we are left with is a relatively small social network of nice and interesting people, operated by a company.</p>
<p>It’s a nice place to be, and it’s where I prefer to hang out, but it’s no longer something I’m passionate about. I wouldn’t wear a Farcaster T-shirt today. I wouldn’t try to recruit new users. I removed “I’m on Farcaster” from my X account.</p>
<h2>Can we go back?</h2>
<p>Which brings me to Jack Shephard’s words in the <em>Lost</em> Season 3 finale: <em><strong>We have to go back!</strong></em></p>
<p>What if Farcaster went back to a hub-based architecture: simple, peer-to-peer, truly decentralized, where it’s easy to run a peer, easy to build self-hosted bots, and easy to build a client?</p>
<p>No bells and whistles. No Mini Apps. No assumption that every client must become a wallet, browser, app host, and social feed at the same time. Strip the network back down to the basics: identity, casts, replies, follows, reactions, and low data retention that makes home hosting feasible.</p>
<p>Then we can rethink Sign in with Farcaster, long-term archiving, scaling, storage fees, app embedding, and everything else. Maybe growth will come at some point in the future, maybe not, but as long as there are a handful of people running a hub at home, the network will be there.</p>
<p>This is not 2024. We know more now. We have seen what worked and what did not. We are not after 1000x growth at any cost. We have new tools for building software, especially when the protocols involved are simple. We can do better than the last time.</p>
<p>Personally, I would be very enthusiastic about this prospect.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/06/19/260619-we-have-to-go-back/lost.jpeg"
   type="image/jpeg"
   length="260451"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/06/18/260619-ai-mainframe/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/18/260619-ai-mainframe/</guid>
      <pubDate>Thu, 18 Jun 2026 22:00:12 +0000</pubDate>
      <description>We are in the mainframe era of AI: A few centralized compute providers and millions of "dumb" clients connected to them.</description>
      <content:encoded><![CDATA[
	
	<p>We are in the mainframe era of AI: A few centralized compute providers and millions of &quot;dumb&quot;
clients connected to them.</p>

]]></content:encoded>

    </item>
    
    <item>
      <title>bckt v0.7.3 is out</title>
      <link>https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/</guid>
      <pubDate>Thu, 18 Jun 2026 16:28:50 +0000</pubDate>
      <description>bckt v0.7.3, my "opinionated but flexible static site generator for blogs", is out!</description>
      <content:encoded><![CDATA[
	
	<p><a href="https://github.com/vrypan/bckt">bckt</a> v0.7.3, my <em>&quot;opinionated but flexible static site generator for blogs&quot;</em>, is out!</p>
<p>The most notable change is the installation bundles come with a nice set of themes, as well as some demo content:</p>
<pre><code># Install
brew install vrypan/tap/bckt

# Create a test directory and initialize a new blog
# with the demo microblog posts and the micro theme
mkdir test &amp;&amp; cd test
bckt init --theme micro --demo microblog 

# Start the local http server to preview it
# (the static pages are in the html/ directory)
bckt dev
</code></pre>
<p>Use <code>--demo microblog</code> to test how it looks with short, titleless posts and
<code>--demo articles</code> to see a version with longer articles, closer to a typical
blog post. But all themes will work nicely with both types of content.</p>
<hr />
<p>You will probably want to use an AI agent to create your own theme. There is
an <code>AGENTS.md</code> that will make this very easy.</p>
<p>For example, let's use <a href="https://mxb.dev/">Max Böck</a>'s blog, which has a really nice design.</p>
<p><code>cd</code> in your blog directory and try prompt like this:</p>
<pre><code>- Read https://github.com/vrypan/bckt/blob/main/themes/AGENTS.md
- Check themes/* to see how the existing themes are structured.
- create a theme inspired by https://mxb.dev/blog/ 
</code></pre>
<p><figure><img src="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/mxbdev-inspired.png" alt="" title="Theme inspired by mbx.dev/blog/. I suggest you visit it to see the original." /><figcaption>Theme inspired by mbx.dev/blog/. I suggest you visit it to see the original.</figcaption></figure></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/mxbdev-inspired.png"
   type="image/png"
   length="308328"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/og.png"
   type="image/png"
   length="490020"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/theme-bckt3.png"
   type="image/png"
   length="338966"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/theme-micro-dark.png"
   type="image/png"
   length="385628"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/theme-micro-light.png"
   type="image/png"
   length="384084"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/theme-microx-dark.png"
   type="image/png"
   length="414777"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/theme-microx-light.png"
   type="image/png"
   length="413808"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/theme-modern.png"
   type="image/png"
   length="360507"/>

   <enclosure url="https://blog.vrypan.net/2026/06/18/260618-bckt-073-is-out/theme-rntz.png"
   type="image/png"
   length="463988"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/06/17/260618-football/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/17/260618-football/</guid>
      <pubDate>Wed, 17 Jun 2026 21:30:25 +0000</pubDate>
      <description>Football may be the last mass spectacle that still resists instant gratification.</description>
      <content:encoded><![CDATA[
	
	<p>Football may be the last mass spectacle that still resists instant gratification.</p>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/06/13/260613-note-30926/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/13/260613-note-30926/</guid>
      <pubDate>Sat, 13 Jun 2026 09:08:47 +0300</pubDate>
      <description>The US government, citing national security authorities, has issued an export control directive to suspend all access to Fable 5 and Mythos 5 by any foreign national, whether inside or outside the United States, including foreign national Anthropic employees. https://x.com/Anthro...</description>
      <content:encoded><![CDATA[
	
	<p><em>The US government, citing national security authorities, has issued an export control directive to suspend all access to Fable 5 and Mythos 5 by any foreign national, whether inside or outside the United States, including foreign national Anthropic employees.</em> <a href="https://x.com/AnthropicAI/status/2065597531644743999">https://x.com/AnthropicAI/status/2065597531644743999</a></p>
<p>This is a great example why the EU must try not to depend on AI developed/operated outside of its borders, even if it's inconvenient at times.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/06/13/260613-note-30926/screenshot.png"
   type="image/png"
   length="285768"/>

    </item>
    
    <item>
      <title>A forgotten terminal trick: the host-writable status line.</title>
      <link>https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/</guid>
      <pubDate>Sat, 13 Jun 2026 04:59:45 +0000</pubDate>
      <description>The VT102 (1978) and VT220 (1983) had the familiar 24-line terminal screen . This the reason your terminal defaults to 80×24, or 132×24. The VT320 (1987) kept a 24-line main display for compatibility, but added something extra: a 25th line at the bottom, reserved for status infor...</description>
      <content:encoded><![CDATA[
	
	<p>The VT102 (1978) and VT220 (1983) had the familiar 24-line terminal screen <sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>. This the reason your terminal defaults to 80×24, or 132×24. The VT320 (1987) kept a 24-line main display for compatibility, but added something extra: a 25th line at the bottom, reserved for status information.</p>
<p>That extra line could be hidden, used by the terminal itself, or made writable by the host. In its normal “indicator” mode, the terminal used it for local state: cursor position, printer status, modem status, and similar information. But in host-writable mode, software on the host side of the terminal connection could write directly to that line. <sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup></p>
<p>The two relevant control sequences are <code>DECSSDT</code> and <code>DECSASD</code>. <sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup></p>
<pre lang="sh"><code># Make the status line host-writable
printf '\e[2$~'

# Send subsequent output to the status line
printf '\e[1$}Build running…'

# Return subsequent output to the main display
printf '\e[0$}'
</code></pre>
<p><code>DECSSDT</code> selects the status-display type:</p>
<pre lang="text"><code>CSI 0 $ ~   no status line
CSI 1 $ ~   indicator status line
CSI 2 $ ~   host-writable status line
</code></pre>
<p><code>DECSASD</code> selects which display receives subsequent characters:</p>
<pre lang="text"><code>CSI 0 $ }   main display
CSI 1 $ }   status line
</code></pre>
<p>It's a surprisingly elegant primitive. A program could use it for progress, mode, host name, current job, debug state, deployment environment, or a persistent “you are in production” warning, without stealing a row from the application, rewriting the prompt, or relying on a terminal multiplexer.</p>
<p><figure><img src="https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/screenshot.png" alt="" /></figure></p>
<p><em>I wasn't able to find a good historical screenshot of a real application writing to the host status line, but you can see it displaying status info in this Capo's Tech video <sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup> <sup class="footnote-ref"><a href="#fn-5" id="fnref-5" data-footnote-ref>5</a></sup></em></p>
<h2>Can we bring it back?</h2>
<p>The idea feels familiar even if these particular CSI sequences are rarely supported today. We have reinvented the same feature in tmux status lines, Zellij bars, and prompt frameworks because the shape makes sense.</p>
<p>But those are all tool-specific solutions.</p>
<p>It would be great to see modern terminals support <code>DECSSDT</code>/<code>DECSASD</code> again. I think many apps like starship, build environments, package managers and so on would take advantage of the feature if terminal emulators supported it.</p>
<hr />
<p>Image sources:</p>
<ul>
<li>Jason Scott: <a href="https://commons.wikimedia.org/w/index.php?curid=29457452">https://commons.wikimedia.org/w/index.php?curid=29457452</a></li>
<li>Tom Page: <a href="https://commons.wikimedia.org/w/index.php?curid=98843032">https://commons.wikimedia.org/w/index.php?curid=98843032</a></li>
<li>Capo’s Tech: <a href="https://youtu.be/EjJTog15Izs?si=aotLJ8Sb1QGcx2_H&amp;t=426">https://youtu.be/EjJTog15Izs?si=aotLJ8Sb1QGcx2_H&amp;t=426</a></li>
<li>LGR: <a href="https://www.youtube.com/watch?v=RuZUPpmXfT0">https://www.youtube.com/watch?v=RuZUPpmXfT0</a></li>
</ul>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>Ken Shirriff has a great deep dive on this: <a href="https://www.righto.com/2019/11/ibm-sonic-delay-lines-and-history-of.html">IBM, sonic delay lines, and the history of the 80×24 display</a>. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>The VT320 introduced a physical 25th line reserved for status use. Normally, the main display remained the familiar 24-line terminal area, preserving compatibility with VT100/VT220-era applications. Later VT420 documentation makes the behavior explicit: when the status line is disabled, that reserved line can become an additional user-window line for normal display data. <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p><a href="https://www.vt100.net/docs/vt320-uu/appendixe.html">VT320 Programming Summary</a> <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p><a href="https://youtu.be/EjJTog15Izs?si=aotLJ8Sb1QGcx2_H&amp;t=426">https://youtu.be/EjJTog15Izs?si=aotLJ8Sb1QGcx2_H&amp;t=426</a> <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
<li id="fn-5">
<p>If someone has a functioning VT320, VT330, VT340, or later DEC terminal and can capture better shots, I’d love to add them to the post. <a href="#fnref-5" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="5" aria-label="Back to reference 5">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/1280px-DEC_VT100_terminal.jpg"
   type="image/jpeg"
   length="254768"/>

   <enclosure url="https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/1280px-DEC_VT220_terminal.jpg"
   type="image/jpeg"
   length="384530"/>

   <enclosure url="https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/og.png"
   type="image/png"
   length="103388"/>

   <enclosure url="https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/screenshot.png"
   type="image/png"
   length="4566630"/>

   <enclosure url="https://blog.vrypan.net/2026/06/13/260613-vt-host-writable-status-line/vt320.png"
   type="image/png"
   length="3178813"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/06/11/260611-note-02559/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/11/260611-note-02559/</guid>
      <pubDate>Thu, 11 Jun 2026 21:29:19 +0300</pubDate>
      <description>I asked ChatGPT to give me Beethoven's Heroica (published 199 years ago, clearly in public domain) in ABC notation.</description>
      <content:encoded><![CDATA[
	
	<p>I asked ChatGPT to give me Beethoven's Heroica (published 199 years ago, clearly in public domain) in ABC notation.</p>
<p>This is the &quot;chilling effect&quot;, baked into a product.</p>
<p>As a side-note, if you go IMSLP, you will learn a) that the site is powered by mediawiki and CC, and b) you have to pay to download anything.</p>
<p>I hate copyrights. Copyrights limit creative people.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/06/11/260611-note-02559/chatgpt-1.jpg"
   type="image/jpeg"
   length="184494"/>

   <enclosure url="https://blog.vrypan.net/2026/06/11/260611-note-02559/chatgpt-2.jpg"
   type="image/jpeg"
   length="166004"/>

    </item>
    
    <item>
      <title>Pet project: smart clock</title>
      <link>https://blog.vrypan.net/2026/06/01/pet-project-smart-clock/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/06/01/pet-project-smart-clock/</guid>
      <pubDate>Mon, 01 Jun 2026 19:43:27 +0000</pubDate>
      <description>I'm building a smart clock for my daughter. I don't want it to be a cool geek project, showing off all the things one could do with a small computer and a screen. I want it to have character and personality, with small little features built in, things that she will like.</description>
      <content:encoded><![CDATA[
	
	<p>I'm building a smart clock for my daughter. I don't want it to be a cool geek project, showing off all the things one could do with a small computer and a screen.
I want it to have character and personality, with small little features built in, things that she will like.</p>
<p>I'm using a Raspberry Pi 3B with a UnicornHD HAT. Both outdated, but fine for what I'm building, and I like the limitations they impose.</p>
<p>The clock works. The color scheme changes from bright white-ish at noon to dim blue at night. The location is determined by looking up the gateway's IP. Then, based on lat,lon and time, it calculates the position of the sun, and adjusts the color/brightness.</p>
<p>There is also an indicator on the right, showing day/night/dawn/dusk hours which also adjusts automatically.</p>
<p>It can rotate, but I'll have to connect a gyrometer for this to work automatically. Todo.</p>
<p>Works as an AirPlay receiver using SharePlay, and will display artist/title when a track starts. Will add Spotify support too.</p>
<p>I asked codex to parse all my blog posts and get quotes that I have or I could have said, and I'll display them on random times. Needs work, and more personalization, these are intended to be from me to her. Will add some internal jokes, things we say to each other, and may also make some depend on day/time/season/weather. At first it looked like a cool idea, not sure if it will make it to the final version.</p>
<p>I don't want to rely on cloud services, this has to be self-sufficient. I'm currently looking up the network gateway's IP to determine the location using ipinfo.io
but I'll find a way to either manually input it, or add a GPS module or something.</p>
<hr />
<p>While doing various experiments, I got down the rabbithole of music boxes. It would be nice if it also worked as a music box, right?</p>
<p>And I found this amazing project I had no idea about, called <a href="https://murobox.com/en/">Muro Box</a>. Wow, so cool and so beautiful.
This is the type of smart devices I would love to build some day, not consumer electronics, but things that are hand crafted, with character andattention to detail and beauty.</p>
<p><figure><img src="https://blog.vrypan.net/2026/06/01/pet-project-smart-clock/murobox.jpg" alt="Muro Box" /></figure></p>
<blockquote>
<p>Muro Box lets you compose, play, and schedule your favorite melodies. With MIDI control and a patented mechanical design, a single music box can now perform unlimited custom songs—not just short loops.</p>
</blockquote>
<hr />
<p>Anyway, with this and that, I spent the last two days building a music box player. It's a program that will read a MIDI file, and play it as if it were
a real music box, with a drum and a comb. I knew nothing about MIDI and sound engineering, but a learned quite a bit, and the result is not bad at all.
I'll put it on GitHub once it's a bit more polished.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/06/01/pet-project-smart-clock/image1.jpeg"
   type="image/jpeg"
   length="88463"/>

   <enclosure url="https://blog.vrypan.net/2026/06/01/pet-project-smart-clock/image2.jpeg"
   type="image/jpeg"
   length="44496"/>

   <enclosure url="https://blog.vrypan.net/2026/06/01/pet-project-smart-clock/murobox.jpg"
   type="image/jpeg"
   length="24832"/>

    </item>
    
    <item>
      <title>note</title>
      <link>https://blog.vrypan.net/2026/05/28/260528-note-16699/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/28/260528-note-16699/</guid>
      <pubDate>Thu, 28 May 2026 00:18:20 +0300</pubDate>
      <description>It's been a while since I heard somene who I can relate so much with. Andrew Kelley, the creator of Zig is amazing: https://www.youtube.com/watch?v=iqddnwKF8HQ</description>
      <content:encoded><![CDATA[
	
	<p>It's been a while since I heard somene who I can relate so much with. Andrew Kelley, the creator of Zig is amazing: <a href="https://www.youtube.com/watch?v=iqddnwKF8HQ">https://www.youtube.com/watch?v=iqddnwKF8HQ</a></p>

]]></content:encoded>

    </item>
    
    <item>
      <title>note</title>
      <link>https://blog.vrypan.net/2026/05/24/260524-note-72714/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/24/260524-note-72714/</guid>
      <pubDate>Sun, 24 May 2026 00:45:15 +0300</pubDate>
      <description>I think AI will give birth to a new type of art/craft where objects will have attitude and personality.</description>
      <content:encoded><![CDATA[
	
	<p>I think AI will give birth to a new type of art/craft where objects will have attitude and personality.</p>

]]></content:encoded>

    </item>
    
    <item>
      <title>My Pi Zero desk clock</title>
      <link>https://blog.vrypan.net/2026/05/22/my-pi-zero-desk-clock/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/22/my-pi-zero-desk-clock/</guid>
      <pubDate>Fri, 22 May 2026 20:14:59 +0000</pubDate>
      <description>Years ago, I built a digital desk clock using a Pi Zero and a Micro Dot pHAT. Probably an overkill to use a whole computer as a clock, but it has turned out to be very convenient, it’s easy to read day and night, and I like the style.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/05/22/my-pi-zero-desk-clock/screenshot.png">
        
	<p>Years ago, I built a digital desk clock using a Pi Zero and a <a href="https://shop.pimoroni.com/products/microdot-phat">Micro Dot pHAT</a>. Probably an overkill to use a whole computer as a clock, but it has turned out to be very convenient, it’s easy to read day and night, and I like the style.</p>
<p>Lately, it started freezing. No idea why, my guess was the OS needed to be updated, or even better re-installed —I don’t have a clear log of what this Pi Zero has been through all these years, but for sure it was also used as a DNS (pi-hole) at some point, and as a tailscale gateway at some other.</p>
<p>The problem is my clock was a Python script using a <a href="https://github.com/pimoroni/microdot-phat">library</a> that has not been updated for at least 4 years. Would it work with a much newer version of Pi OS?</p>
<p>It did not. I could not even install it.</p>
<p>So, I cloned it, and used Claude to port it to Zig. I picked Zig because the resulting binaries are small, and I can also cross-compile on my MacBook Pro (waiting for Pi Zero to compile would not be fun). It took me an afternoon, a couple of manual interventions, and <a href="https://github.com/vrypan/microdot-phat-zig">I had my Zig port</a>. The examples compiled, and run perfectly on the latest Pi OS (32-bit).</p>
<p>And since I’m not the one writing the code, why not add some flavor? Let’s have the digits scroll up when they change.</p>
<p>Not bad for a project that took an afternoon. I love it how I can make and fix little things that wouldn’t be worth the time and effort without AI-assited coding.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/05/22/my-pi-zero-desk-clock/clock.mp4"
   type="video/mp4"
   length="301552"/>

   <enclosure url="https://blog.vrypan.net/2026/05/22/my-pi-zero-desk-clock/screenshot.png"
   type="image/png"
   length="291577"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/05/21/260521-note-37929/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/21/260521-note-37929/</guid>
      <pubDate>Thu, 21 May 2026 07:32:10 +0300</pubDate>
      <description>I wrote a long piece on the history of subtitles: https://blog.vrypan.net/features/the-history-of-subtitles/</description>
      <content:encoded><![CDATA[
	
	<p>I wrote a long piece on the history of subtitles: <a href="https://blog.vrypan.net/features/the-history-of-subtitles/">https://blog.vrypan.net/features/the-history-of-subtitles/</a></p>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/05/16/260516-note-61697/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/16/260516-note-61697/</guid>
      <pubDate>Sat, 16 May 2026 23:01:37 +0300</pubDate>
      <description>QA engineers will be in high demand for the next 5 years.</description>
      <content:encoded><![CDATA[
	
	<p>QA engineers will be in high demand for the next 5 years.</p>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/05/16/260516-note-61609/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/16/260516-note-61609/</guid>
      <pubDate>Sat, 16 May 2026 23:00:10 +0300</pubDate>
      <description>Mythos and similar tools are not a threat to incumbents. They turn system attacking and hardening into a token war, and any Apple, Microsoft or Google can spend more on tokens than any attacker.</description>
      <content:encoded><![CDATA[
	
	<p>Mythos and similar tools are not a threat to incumbents. They turn system attacking and hardening into a token war, and any Apple, Microsoft or Google can spend more on tokens than any attacker.</p>

]]></content:encoded>

    </item>
    
    <item>
      <title>The Cathedral, the Bazaar and the Kitchen</title>
      <link>https://blog.vrypan.net/2026/05/11/the-cathedral-the-bazaar-and-the-kitchen/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/11/the-cathedral-the-bazaar-and-the-kitchen/</guid>
      <pubDate>Mon, 11 May 2026 20:36:12 +0000</pubDate>
      <description>Eric Raymond’s “The Cathedral and the Bazaar” described two fundamentally different ways of building software. The Cathedral represented centralized, carefully planned development directed by a small group of maintainers. The Bazaar represented open collaboration: large communiti...</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/05/11/the-cathedral-the-bazaar-and-the-kitchen/image.png">
        
	<p>Eric Raymond’s “The Cathedral and the Bazaar”<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup> described two fundamentally different ways of building software. The Cathedral represented centralized, carefully planned development directed by a small group of maintainers. The Bazaar represented open collaboration: large communities, public iteration, distributed labor, and software evolving through many contributors.</p>
<p>For decades, the Bazaar became the dominant cultural myth of open source. Public repositories, pull requests, and community participation were not just practical tools, but moral ideals. Good software was expected to emerge from openness and collective effort.</p>
<hr />
<p>AI-assisted software development is changing the economics and the ergonomics behind that model. Implementation becomes cheap, and coordination becomes expensive. A single developer equipped with modern tools can now produce systems that previously required teams.</p>
<p>At the same time, software is becoming increasingly personalized: tailored to one person’s workflow, infrastructure, preferences, and habits. Instead of building generalized tools for the widest possible audience, developers increasingly build software that fits their own environment perfectly. Others may still read the code, fork it, or borrow ideas from it, but local modification often becomes cheaper than upstream coordination.</p>
<p><strong>The new model is a kitchen.</strong></p>
<p>Every kitchen evolves around the habits of its cook. Tools sit where they are convenient. Ingredients are substituted freely. Recipes are modified on instinct. Two people may start from the same dish and end up with completely different results.</p>
<p>Unlike the Bazaar, a kitchen is deeply personal. Recipes are shared freely, but kitchens rarely converge into a universal standard. Visitors may admire another cook’s techniques, yet still return home and prepare the dish their own way. In the Kitchen model, open source becomes less like public infrastructure and more like published craft: software as personal utility, openly visible, endlessly adaptable, and increasingly authored by individuals rather than communities.</p>
<hr />
<p>In the Bazaar model, openness was mainly a way to coordinate people. You opened the codebase to attract contributors, spread work across many developers, avoid duplicated effort, and slowly build shared infrastructure.</p>
<p><strong>In the Kitchen model, openness serves a different purpose.</strong> It provides visibility, learnability, and independence. Value shifts from <em>“others can help build this”</em> to <em>“others can understand, adapt, and reclaim this.”</em></p>
<p>Source code starts to resemble recipes more than public construction projects. Most people do not submit patches to a cookbook, yet recipes remain enormously valuable because they transfer techniques, preserve knowledge, and provide foundations others can adapt to their own tastes and environments. The code is open not necessarily so everyone can co-author it, but so anyone can study it, modify it, and make it their own.</p>
<p>This also changes the meaning of forks. In the Bazaar, forks were often viewed as failures of governance or coordination. In the Kitchen, forks become normal and healthy:</p>
<ul>
<li>“I adapted this for my setup”</li>
<li>“I removed features I don’t need”</li>
<li>“I rewrote this around my workflow”</li>
</ul>
<p>Forking becomes analogous to modifying a recipe<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup> at home.</p>
<p>Software evolves through local adaptation rather than centralized consensus. A developer will remove features, rewrite workflows, or optimize entirely around their own infrastructure because doing so is now cheaper than negotiating a generalized solution acceptable to everyone.</p>
<p>This model still depends on public circulation of ideas. Even if code contributions decline, people still copy ideas from each other constantly through imitation, recombination, critique, and inspiration.</p>
<p>Much of programming history already worked this way:</p>
<ul>
<li>Unix customization culture where ingredients were expected to be mixed in different ways</li>
<li>shell workflows and personal scripts</li>
<li>dotfiles designed to show others how a system is configured but rarely adopted one-to-one</li>
</ul>
<p>These are often highly personal systems shared publicly, not collaboratively engineered products.</p>
<p><strong>Open source remains essential because it preserves agency</strong>: the ability to inspect, repair, continue, and reshape software independently of its original author. The result is a world where software is increasingly personal, but where ideas, techniques, and tools still circulate freely between individuals, much like recipes passed from kitchen to kitchen.</p>
<hr />
<p><strong>Update (15-May-2026)</strong>: Other people have described the same or a similar mental model:</p>
<p>Drew Breunig calls it &quot;the Winchester Mystery House&quot;:</p>
<blockquote>
<p>The ideas crystallized in &quot;The Cathedral and the Bazaar&quot; helped kick off a quarter-century of open source innovation and dominance.<br />
But just as the internet made communication cheap and birthed the Bazaar, AI is making code cheap and kicking off a new era filled with idiosyncratic, sprawling, cobbled-together software.<br />
Meet the third model: the Winchester Mystery House.</p>
<p>—<em>The Cathedral, the Bazaar, and the Winchester Mystery House</em><sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup></p>
</blockquote>
<p>And Thomas H. Ptacek, calls it &quot;the Emacsification of Software&quot;:</p>
<blockquote>
<p>First, it's personal software. Most of it will be useful only to its creator, and then forgotten,
just like the dozens of obsolete little elisp programs littering my .emacs. Personal software defines
the ethos of Emacs, which was carefully designed over decades to nurture these kinds of tools.
&quot;Emacsification&quot; clocks that everything now works this way, not just baroque text editors.</p>
<p>—<em>The Emacsification of Software</em><sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup></p>
</blockquote>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>Eric S. Raymond, <em>The Cathedral and the Bazaar</em> (1997), <a href="https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar">https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar</a> <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>Side note: There is rarely a single canonical version of a dish. The same recipe evolves into countless variations shaped by region, available ingredients, habits, and personal taste. Instead of converging into one standard, we distinguish them by origin or authorship: <em>à la provençale</em>, <em>à la milanaise</em>, <em>à la grandma</em>, <em>à la Jacques Pépin</em>. The variation itself becomes part of the identity of the dish. GNU grep and BSD grep were different variations of the same tool, but these were more like publisher or distribution variations. The Kitchen model pushes personalization much further, toward software shaped directly around the habits and preferences of individual developers. <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p><a href="https://www.dbreunig.com/2026/03/26/winchester-mystery-house.html">The Cathedral, the Bazaar, and the Winchester Mystery House</a> <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p><a href="https://sockpuppet.org/blog/2026/05/12/emacsification/">The Emacsification of Software</a> <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/05/11/the-cathedral-the-bazaar-and-the-kitchen/image.png"
   type="image/png"
   length="3511829"/>

    </item>
    
    <item>
      <title>shg, the SHell Guard</title>
      <link>https://blog.vrypan.net/2026/05/09/shg-the-shell-guard/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/09/shg-the-shell-guard/</guid>
      <pubDate>Sat, 09 May 2026 09:38:07 +0000</pubDate>
      <description>If you spend as much time as I do in the terminal, you probably depend on your shell history too. Being able to repeat a complex command that you remember you typed a month ago, is extremely valuable —no wonder why I’ve set HISTSIZE=10000.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/05/09/shg-the-shell-guard/screenshot.png">
        
	<p>If you spend as much time as I do in the terminal, you probably depend on your shell history too.
Being able to repeat a complex command that you remember you typed a month ago, is extremely
valuable —no wonder why I’ve set <code>HISTSIZE=10000</code>.</p>
<p>While it is convenient to use your shell history as part of your long term memory, the downside is things
that shouldn’t be there, end up there: A command you prepended with <code>API_KEY=...</code>, a quick and dirty
<code>curl --user &quot;name:password&quot;</code>, a <code>PGPASSWORD=... psql</code>, an <code>ALTER USER USER() IDENTIFIED BY ...</code>,
and so on. And they are all probably saved in shell or app history file.</p>
<p><strong>This is not good, obviously.</strong> Credentials should not be saved in places where a malicious
program can just read them, and they should not be preserved in backups.</p>
<p>That’s why I built <a href="https://github.com/vrypan/shg"><code>shg</code> (short for <em>SHell Guard</em>)</a>, a small program
that scans my shell history (and other history files) for entries that look like API keys, passwords,
bearer tokens, credential URLs, and private keys and alerts me.</p>
<p>I’ve set it up to do <a href="https://github.com/vrypan/shg/blob/main/INTEGRATIONS.md#shg-integrations">a quick scan when I start a new shell</a>
and (I think this is the coolest part) also check every command I enter in zsh and
<a href="https://github.com/vrypan/shg/blob/main/INTEGRATIONS.md#zsh-intercept-history-before-it-is-saved">catch secrets before they ever land in <code>~/.zsh_history</code></a>.</p>
<hr />
<p>Some tips:</p>
<ul>
<li>run <code>shg-config discover</code> to find and configure history files that are not part of the default scan list.</li>
<li>you can adjust the output and the severity level using <code>--level</code>, <code>--one-line</code>, <code>--json</code> and other options. Check <code>shg scan --help</code> for more details.</li>
<li>If you keep getting reports for entries that you don't mind, add them to <code>~/.config/shg/ignore.local.shg</code>. (See <a href="https://github.com/vrypan/shg/tree/main/src/defaults">the default ignore file</a> here).</li>
</ul>
<hr />
<p>If you use <code>shg</code> and you like it, <a href="https://github.com/vrypan/shg">give it a star on GitHub</a>! 🙏</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/05/09/shg-the-shell-guard/screenshot.png"
   type="image/png"
   length="143787"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/05/01/260501-note-65756/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/01/260501-note-65756/</guid>
      <pubDate>Fri, 01 May 2026 23:02:36 +0300</pubDate>
      <description>letter to the editor, 1995</description>
      <content:encoded><![CDATA[
	
	<p>letter to the editor, 1995</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/05/01/260501-note-65756/letter.png"
   type="image/png"
   length="2988141"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/05/01/260501-note-57052/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/05/01/260501-note-57052/</guid>
      <pubDate>Fri, 01 May 2026 20:37:33 +0300</pubDate>
      <description>"Satoshi's coins" is the canary in the coal mine of quantum computing.</description>
      <content:encoded><![CDATA[
	
	<p>&quot;Satoshi's coins&quot; is the canary in the coal mine of quantum computing.</p>

]]></content:encoded>

    </item>
    
    <item>
      <title>A library of agent-friendly specs</title>
      <link>https://blog.vrypan.net/2026/04/30/a-library-of-agent-friendly-specs/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/04/30/a-library-of-agent-friendly-specs/</guid>
      <pubDate>Thu, 30 Apr 2026 17:15:06 +0000</pubDate>
      <description>Recently, I've been trying to shape the cli arguments of a tool I'm building in Zig to fit zli and zig-cli.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/04/30/a-library-of-agent-friendly-specs/screenshot.png">
        
	<p>Recently, I've been trying to shape the cli arguments of a tool I'm building in Zig to fit <code>zli</code> and <code>zig-cli</code>.</p>
<p>It's not the first time. <code>cobra</code> has its own opinions in Go, <code>clap</code> in Rust, <code>docopt</code> in Python, and so on.</p>
<p>One library doesn't support repeated arguments.<br />
Another doesn't allow ordering the args alphabetically in help.<br />
This one doesn't support arguments with optional values.<br />
That one has a small UI bug.<br />
Another won't fold long descriptions.</p>
<p>I kept adding small hacks to bring the implementation closer to what I had in mind, but a) it was
not 100% there, and b) it felt like a hack.</p>
<p>Writing a cli parser is not rocket science. A coding agent like codex or claude can definitely do it,
as long as you provide it with clear specs. Which is what I did, since I already had a lot of boilerplate
code.</p>
<p>Twenty minutes later, everything works exactly the way I want it to work, and now I can tweak it
at will, and re-implement it in the next project, regardless of the language used.</p>
<hr />
<h2>A library of agent specs</h2>
<p>Instead of rediscovering the requirements every time, I put them down in a form that AI agents can use.</p>
<p>That's the idea behind <strong><a href="https://github.com/vrypan/agent-specs">github.com/vrypan/agent-specs</a></strong>. It will
probably become a small collection of specifications designed to be used by agents.</p>
<p>One can think of it as a higher-level code library. Instead of the language-level
import/include/use, you have a spec for an agent.</p>
<pre><code>&gt; Implement cli arguments and options according to specs/cli/CLI.md.
</code></pre>
<p>Each section of <a href="https://github.com/vrypan/agent-specs/blob/main/specs/cli/CLI.md">CLI.md</a>
has an identifier, like <code>CMD-SUBCOMMANDS</code>, <code>FLAGS-SHORT-VALUES</code> and <code>OPT-COLOR</code>.
This makes it easy to tell the agent, use this, don't implement this, override that. There are
also test cases, to help the agent test the implementation.</p>
<p>So, you could also ask something like this</p>
<pre><code>&gt; Use specs/cli/CLI.md as the CLI parser specification.
Implement all required sections.
Do not implement OPT-COLOR.
Translate specs/cli/tests.yaml into automated tests.
Report any deviations.
</code></pre>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/04/30/a-library-of-agent-friendly-specs/screenshot.png"
   type="image/png"
   length="82419"/>

    </item>
    
    <item>
      <title>LLM-assisted coding is not deterministic. It does it matter?</title>
      <link>https://blog.vrypan.net/2026/04/23/llm-assisted-coding-is-not-deterministic-does-it-matter/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/04/23/llm-assisted-coding-is-not-deterministic-does-it-matter/</guid>
      <pubDate>Thu, 23 Apr 2026 17:12:03 +0000</pubDate>
      <description>We often treat determinism and predictability as synonyms, but they are not the same.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/04/23/llm-assisted-coding-is-not-deterministic-does-it-matter/not-random.png">
        
	<p>We often treat determinism and predictability as synonyms, but they are not the same.</p>
<p>A system is deterministic if the same starting conditions always lead to the same result. A system is predictable if we can actually foresee that result with the tools, time, and knowledge we have.</p>
<p>Determinism is a system characteristic.</p>
<p>Predictability, on the other hand, often depends on our capabilities, and it usually exists on a spectrum. Weather is a good example. The laws of physics governing the atmosphere have not changed, and they are deterministic. Yet our ability to predict the weather has improved over decades simply because our measurements, models, and computing power improved.</p>
<p>But it's not always on us. Stephen Wolfram has described the concept of <strong>computational irreducibility</strong> <sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>. A system is computationally irreducible if the only way to know its future state is to simulate every step. There are also <strong>chaotic systems</strong> where tiny measurement errors grow rapidly, making them practically unpredictable.</p>
<p>Some systems are both deterministic and predictable, like planetary motion over short time scales. Others are deterministic but not predictably so in practice, like weather or turbulent flows. Conversely, some systems are not deterministic at the level of individual events but are still predictable statistically, such as casino games or population averages.</p>
<table>
<thead>
<tr>
<th>System Type</th>
<th>Deterministic</th>
<th>Predictable</th>
</tr>
</thead>
<tbody>
<tr>
<td>Planetary orbits (over finite time horizons)</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Weather</td>
<td>Yes</td>
<td>Limited</td>
</tr>
<tr>
<td>Dice roll (unknown forces)</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Radioactive decay (single event)</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>Casino odds (many trials)</td>
<td>No</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<p><strong>In essence: determinism does not guarantee predictability, and predictability does not require determinism.</strong></p>
<hr />
<p>Back to coding…</p>
<p>From the perspective of someone who needs a piece of software, development has never been deterministic. When you ask a software developer to build something, you cannot predict exactly what code they will write, how long it will take (so many jokes about this…), or which edge cases will fail first. The same is true when you ask an AI agent. Both are problem-solving processes operating under uncertainty.</p>
<p>One can argue in favor or against the competency of humans or LLMs when it comes to coding, but determinism has never been a human trait.</p>
<p>In most cases, developers build software to satisfy other people’s needs, and what these people really care about is <strong>whether the resulting code is predictable enough to rely on</strong>: whether the system behaves correctly most of the time, whether failures are visible, and whether they can be fixed quickly.</p>
<p>This distinction is important. From a software developer's pov, asking an LLM to &quot;build a program that sorts 1000 numbers&quot; may not have a predictable result (code). But the end user only cares if the resulting program will always sort any 1000 numbers correctly.</p>
<p>And then there is the environment. Modern software runs on stacks that are far more complex than any single developer can fully reason about: hardware, kernels, drivers, libraries, network conditions, configuration files, container layers, dependency versions. So, even if, as a developer, you write the code to do excatly what you want it to do, in a totally predictable way, running the code may yield less predictable results. <strong>While deterministic, the system as a whole is so complex that its behavior cannot be predicted perfectly in advance.</strong></p>
<p>We have quietly accepted that bugs are a natural part of software development <sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup> (i.e. there will be cases where it behaves unpredictably), because we recognize the complexity of the endeavor. Instead of expecting perfect foresight, the industry built practices around uncertainty: tests, staging environments, observability, rollbacks, reproducible builds.</p>
<table>
<thead>
<tr>
<th>Producer / System Component</th>
<th>Deterministic</th>
<th>Predictable (for the requester)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Human developer</td>
<td>No</td>
<td>Usually, within experience and process constraints <sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup></td>
</tr>
<tr>
<td>AI coding agent</td>
<td>No</td>
<td>Increasing, with tooling and validation loops</td>
</tr>
<tr>
<td>Compiler / build system</td>
<td>Yes</td>
<td>Yes<sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup></td>
</tr>
<tr>
<td>Tested deployment pipeline</td>
<td>Yes</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<p>So, the meaningful question is not about determinism. <strong>The meaningful question is which workflow produces more predictable outcomes under real conditions, and which human or AI is a better fit at each case/stage.</strong> <sup class="footnote-ref"><a href="#fn-5" id="fnref-5" data-footnote-ref>5</a></sup></p>
<hr />
<p>Some final thoughts.</p>
<p>It’s worth looking at how we build some of the most safety-critical software. DO-178C is the “Software Considerations in Airborne Systems and Equipment Certification”. It is a key document in the aeronautic industry, providing guidelines for the development of safety-critical airborne software.</p>
<blockquote>
<p>The approach of DO-178C is based on the formulation of appropriate objectives and on the verification that these objectives are achieved. The DO-178C authors acknowledged that objectives are more essential and stable than specific procedures. The ways of achieving an objective may vary between companies, and they may vary over time with the evolution of methods, techniques, and tools. DO-178C never states that one should use design method X, coding rules Y, or tool Z. DO-178C does not even impose a specific life cycle. <sup class="footnote-ref"><a href="#fn-6" id="fnref-6" data-footnote-ref>6</a></sup></p>
</blockquote>
<p>DO-178C is <strong>objective-oriented</strong>: the focus is on formulating objectives and verification that the objectives are achieved, a framework that could work both for human coders and LLMs.</p>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p><a href="https://en.wikipedia.org/wiki/Computational_irreducibility">Computational Irreducibility (Wikipedia)</a>. The image, <a href="https://turmites.art">Not Random, Blue</a>, is inspired by the concept. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p><a href="https://world.hey.com/dhh/software-has-bugs-this-is-normal-26d5fd06">Software has bugs. This is normal.</a> <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p>also depending on mood, health, work relationships and other human factors. <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p>Even leaving bugs aside, there is a big discussion of which aspect of a compiler is predictable. Modern compilers tend to generate <strong>binaries that behave predictably</strong>, but are implemented in ways unexpected by the vast majority of developers. For example <a href="https://xania.org/202512/24-cunning-clang">this article</a> describes a case where the compiler decides to replace an O(n) algorithm written by the developer, with an O(1) one! <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
<li id="fn-5">
<p>Side thought: If someone <strong>proved</strong> (not observed) that humans or LLMs can generate predictable results in some non-trivial cases, that would be really interesting. Tbh, if I had to bet that such a proof exists, I'd put my money on finding one for LLMs. <a href="#fnref-5" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="5" aria-label="Back to reference 5">↩</a></p>
</li>
<li id="fn-6">
<p><a href="https://innovationspace.ansys.com/knowledge/forums/topic/an-introduction-to-do-178c/">An introduction to DO-178C</a> <a href="#fnref-6" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="6" aria-label="Back to reference 6">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/04/23/llm-assisted-coding-is-not-deterministic-does-it-matter/not-random.png"
   type="image/png"
   length="38099"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2026/01/04/fc-2026-01-04-0xd3e5e531/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/01/04/fc-2026-01-04-0xd3e5e531/</guid>
      <pubDate>Sun, 04 Jan 2026 16:11:22 +0000</pubDate>
      <description>I was trying to build a PRNG based on cellular automata rules. I had the illusion that a few clever ideas, and some empirical knowledge would be enough.</description>
      <content:encoded><![CDATA[
	
	<p>I was trying to build a PRNG based on cellular automata rules. I had the illusion that a few clever ideas, and some empirical knowledge would be enough.</p>
<p>Nothing could be further than this, when it comes to random number generators. Smart people with deep and broad knowledge have been studying the field for centuries, you can't just show up and expect you will build something better, or even decently good, just like this.</p>
<p>But during the last 10 days that I've (obsessively) been on this journey I've learned so much. (ChatGPT and Claude have allowed me to learn and experiment at a pace that would be unimaginable a year ago.)</p>
<p>Yesterday I started reading again (last time I tried, I stopped after the second chapter or so) Wolfram's &quot;New Kind of Science&quot;. It will take me some time, but there are so many concepts and ideas I've long been fascinated about, but never went to the depths Wolfram goes.</p>
<p>On the side, I'm studying a 1984 paper, on &quot;Algebraic Properties of Cellular Automata&quot; now. Algebras were one of my favorite topics when I was studying math, and I feel lucky to have the tools, to (try to) understand it: <a href="https://content.wolfram.com/sw-publications/2020/07/algebraic-properties-cellular-automata.pdf">https://content.wolfram.com/sw-publications/2020/07/algebraic-properties-cellular-automata.pdf</a></p>
<p>(It's sad that so few people get to learn what Mathematics really are: a tool to describe and study concepts that often push the boundaries of our minds.)</p>

]]></content:encoded>

    </item>
    
    <item>
      <title>Down the RNG rabbit hole - Part II</title>
      <link>https://blog.vrypan.net/2026/01/01/down-the-rng-rabbit-hole-part-ii/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2026/01/01/down-the-rng-rabbit-hole-part-ii/</guid>
      <pubDate>Thu, 01 Jan 2026 20:46:44 +0000</pubDate>
      <description>So, Rule30RND was ok as a fun experiment, but not a PRNG that someone could take seriously.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2026/01/01/down-the-rng-rabbit-hole-part-ii/r30r2.png">
        
	<p>So, <a href="/2025/12/30/down-the-rng-rabbit-hole/">Rule30RND was ok as a fun experiment</a>, but not a PRNG that someone could take seriously.</p>
<p>I kept tinkering, as if I was playing a game: change this and that, run the tests, check my score.</p>
<p><em>Side note: after I published the last post, I realized that my test scripts had fundamental flaws, like adding text headers in the randomly generated bytes.</em></p>
<h2>Radius-2</h2>
<p>No matter how hard I tried, it was obvious that a Rule 30-based algorithm would not pass BigCrush unless I changed it so much that would become something else with a sprinkle of CA.</p>
<p>Now, Rule 30 works like this: If <code>C</code> is our bit, <code>L</code> is the one on its left and <code>R</code> the one on its right:<br />
<code>new_bit = L XOR (C OR R)</code></p>
<p>That’s a &quot;radius-1 CA&quot;. What if I tried with a radius-2 CA, that uses two bits on the left and two on the right?</p>
<p>Unfortunately, there is much less literature for radius-2 than radius-1 CAs. After some search that did not return a documented good candidate for what I wanted to build, and a few failed experiments, I decided to extend Rule 30 in a “symmetric” way.</p>
<p><code>new_bit = (L2 XOR L1) XOR (C OR (R1 OR R2))</code></p>
<p>This gave significantly better results.</p>
<p>Not exceptional. The new algorithm failed 5/15 SmallCrush tests (Gap, SimpPoker, CouponCollector, WeightDistrib, HammingIndep).</p>
<p>But these are the tests I might be able to fix with a diffusion function.</p>
<h2>Searching for a diffusion fucntion</h2>
<p>I wanted a diffusion function, so I let Claude test 7 different functions, run the tests, collect the results, and let me know when it was done.</p>
<table>
<thead>
<tr>
<th>Mixing/Diffusion Approach</th>
<th>SmallCrush</th>
<th>Performance vs math/rand</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Rotation (5,14,27)</td>
<td>12/15</td>
<td>1.08×</td>
<td>❌</td>
</tr>
<tr>
<td>5 XOR Rotations</td>
<td>13/15</td>
<td>0.94×</td>
<td>❌</td>
</tr>
<tr>
<td>xoshiro256++ Style</td>
<td>11/15</td>
<td>1.13×</td>
<td>❌</td>
</tr>
<tr>
<td>MurmurHash</td>
<td><strong>15/15</strong></td>
<td>0.95×</td>
<td>✅</td>
</tr>
<tr>
<td>SplitMix64</td>
<td><strong>15/15</strong></td>
<td>0.93×</td>
<td>✅</td>
</tr>
<tr>
<td><strong>Hybrid</strong></td>
<td><strong>15/15</strong></td>
<td><strong>1.03×</strong></td>
<td>✅</td>
</tr>
<tr>
<td>Per-Word Varying</td>
<td><strong>15/15</strong></td>
<td>0.90×</td>
<td>✅</td>
</tr>
</tbody>
</table>
<p>The winner was the “Hybrid” approach that combines rotation, multiplication by the golden ratio, and shift-XOR:</p>
<pre lang="golang"><code>func mix(x uint64) uint64 {
    x ^= bits.RotateLeft64(x, 13)
    x *= 0x9e3779b97f4a7c15  // Golden ratio constant
    x ^= x &gt;&gt; 27
    return x
}
</code></pre>
<p>SmallCrush is the first step, but I needed it to pass BigCrush.</p>
<p>And, YES! <strong>My rule-30-radius-2-diffused algo scored 160/160 on BigCrush</strong> for the first time!</p>
<h2>Staying true</h2>
<p>Now, this worked, but <strong>it was also cheating</strong>: I applied <code>mix()</code> to every state evolution: <code>s1, s2=mix(rule30(s1)), s3=mix(rule30(s2)), ...</code>, so this was no longer a CA algorithm.</p>
<p>What if I applied <code>mix()</code> only to the output? I.e. keep a pure Rule 30, radius-2 algorithm that generates states <code>s1, s2, ...</code>, but return <code>mix(s1), mix(s2), ...</code>. Would this work?</p>
<p><strong>IT WORKED!</strong> <strong>IT WORKED!</strong></p>
<p>And it was also <strong>6% faster</strong>.</p>
<h2>I present you “R30R2”</h2>
<p>Along the way, I fixed some annoying Makefile issues, optimized how <code>Read()</code> reads data from the state, and tweaked a few things here and there.</p>
<p>I was ready to release it, but when “Rule 30” is mentioned in literature, it means a radius-1 CA.</p>
<p>I decided to rename the project, the documentation, the function names, etc. And it's name is... <strong>R30R2</strong>.</p>
<blockquote>
<p><strong>R30R2 is a radius-2 Rule 30-based PRNG with a diffusion function applied on output. It scores 160/160 on BigCrush, and is 2× faster than <code>math/rand/v2</code>.</strong></p>
<p>You can find it at <a href="https://github.com/vrypan/r30r2/">https://github.com/vrypan/r30r2/</a></p>
</blockquote>
<table>
<thead>
<tr>
<th>RNG</th>
<th>BigCrush Score</th>
<th>Performance vs math/rand</th>
</tr>
</thead>
<tbody>
<tr>
<td>math/rand</td>
<td>159/160</td>
<td>1.00× (baseline)</td>
</tr>
<tr>
<td>math/rand/v2</td>
<td>160/160 ✓</td>
<td>0.56×</td>
</tr>
<tr>
<td><strong>Rule 30</strong></td>
<td><strong>160/160</strong> ✓</td>
<td><strong>1.03×</strong></td>
</tr>
</tbody>
</table>
<h2>🎉🍾🍻</h2>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2026/01/01/down-the-rng-rabbit-hole-part-ii/r30r2.png"
   type="image/png"
   length="190176"/>

    </item>
    
    <item>
      <title>Down the RNG rabbit hole</title>
      <link>https://blog.vrypan.net/2025/12/30/down-the-rng-rabbit-hole/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/30/down-the-rng-rabbit-hole/</guid>
      <pubDate>Tue, 30 Dec 2025 22:06:33 +0000</pubDate>
      <description>In my last post, I described how I started from beautiful images generated by "turmites" and ended up with one that looked, and in many aspects felt, random.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2025/12/30/down-the-rng-rabbit-hole/image.png">
        
	<p><a href="/2025/12/28/playing-with-turmites-better-than-crypto-rand/">In my last post</a>, I described how I started from beautiful images generated by &quot;turmites&quot; and ended up with one that looked, and in many aspects felt, random.</p>
<p>I knew my approach was amateurish. After all, I <strong>am</strong> an amateur when it comes to information entropy, predictability, statistical analysis, and random number generators (RNGs). But I wanted to learn more and explore the idea further.</p>
<p>So my first attempt was to write a pseudo-random number generator (PRNG) based on my LLLR turmite: if I let the turmite run enough iterations on an NxN grid using 4 colors, the result is NxNx2 bits.</p>
<p>With a 64x64 grid, I’d get 8,192 bits, or 1,024 bytes. Are they <em>random enough</em>? How do I measure that?</p>
<p>I learned about tests used to identify structural weaknesses in PRNGs, like SmallCrush and BigCrush.</p>
<p>Yes (as you may have expected), my &quot;turmite RNG&quot; failed miserably, even on the simplest statistical tests like Chi-Square. It was also orders of magnitude slower than anything else out there.</p>
<hr />
<p>Still, my intuition told me there must be some way to build a decent RNG using cellular automata.</p>
<p>I found Stephen Wolfram’s &quot;Rule 30&quot;<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>. It’s a very simple, 1D cellular automaton, <em>&quot;displaying aperiodic, chaotic behaviour&quot;</em>.
And Wolfram used it as a PRNG in Mathematica.</p>
<p>Now we're talking.</p>
<p>Arrogantly, I built my own implementation using my own assumptions and preferences, without looking into how others used Rule 30 for PRNG purposes —which turned out to be a good thing, I think.</p>
<p>In most cases, cellular automata &quot;live&quot; on infinite spaces, like plains and lines, but in my previous work with turmites, I liked how they behaved on toroidal spaces. So I used a circular 256-bit stripe, and instead of using just the middle bits of consecutive steps as the RNG output, I used the whole 256-bit space. (That’s a 256× speed improvement over the typical use of Rule 30 as an RNG!)</p>
<p>And it looked good. Performance was excellent because I could fit the entire state in 4 uint64 words and compute the next state using basic binary operations on each word.</p>
<p>I even claimed 4x speed improvements over <code>math/rand</code>!</p>
<p>Slow down, cowboy.</p>
<p>People were kind to point out<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup> that the tests I used did not compare apples to apples.
And as I searched more, I learned there's a lot to fix and improve.</p>
<hr />
<p>Long story short, two days later I had a decent PRNG that is comparable to, and in some cases better than, the standard pseudo-random number generators used by Golang.</p>
<p>I even modified the algorithm further, to improve statistical distribution: after each step, I apply XOR rotation mixing to each word, which is not part of the original Rule 30 algorithm.</p>
<p><a href="https://github.com/vrypan/rule30rnd">Rule30RND</a> is a drop-in replacement for <code>math/rand</code> and <code>math/rand/v2</code>, with a very small footprint (state and manipulation require just 40 bytes of memory), comparable statistical qualities, and is 30%–60% faster.</p>
<p>Rule30RND generates reproducible sequences (depending on the seed), which may sound like a drawback for an RNG, but it’s actually useful in many cases where a PRNG is preferred over a CSPRNG (Cryptographically Secure Pseudo-Random Number Generator). Those cases usually involve generating large, statistically unpredictable data sets used for simulations or testing.</p>
<p><strong>Throughput Comparison, relative to math/rand</strong></p>
<table>
<thead>
<tr>
<th>Algorithm</th>
<th>Read() 32KB</th>
<th>Read() 1KB</th>
<th>Uint64()</th>
</tr>
</thead>
<tbody>
<tr>
<td>MathRand</td>
<td>1.00x</td>
<td>1.00x</td>
<td>1.00x</td>
</tr>
<tr>
<td>MathRandV2</td>
<td>1.69x</td>
<td>1.63x</td>
<td>0.58x</td>
</tr>
<tr>
<td><strong>Rule30</strong></td>
<td><strong>5.47x</strong></td>
<td><strong>5.13x</strong></td>
<td><strong>1.39x</strong></td>
</tr>
<tr>
<td>CryptoRand</td>
<td>3.11x</td>
<td>1.75x</td>
<td>0.03x</td>
</tr>
</tbody>
</table>
<p><strong>Rule30RND Basic Tests (ent)</strong></p>
<table>
<thead>
<tr>
<th>Test</th>
<th>Result</th>
<th>Expected</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Entropy</td>
<td>7.999982 bits/byte</td>
<td>8.0000</td>
<td>✓ Perfect (99.9998%)</td>
</tr>
<tr>
<td>Chi-Square</td>
<td>253.9</td>
<td>~255 (200-310)</td>
<td>✓ Excellent</td>
</tr>
<tr>
<td>Arithmetic Mean</td>
<td>127.4987</td>
<td>127.5</td>
<td>✓ Perfect</td>
</tr>
<tr>
<td>Monte Carlo π</td>
<td>3.140031</td>
<td>3.141593</td>
<td>✓ 0.05% error</td>
</tr>
<tr>
<td>Serial Correlation</td>
<td>0.000171</td>
<td>0.0000</td>
<td>✓ Uncorrelated</td>
</tr>
</tbody>
</table>
<p><strong>SmallCrush results</strong></p>
<table>
<thead>
<tr>
<th>RNG</th>
<th>Passed</th>
<th>Failed</th>
<th>Pass Rate</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Rule30</strong></td>
<td><strong>15/15</strong></td>
<td>0/15</td>
<td><strong>100%</strong></td>
</tr>
<tr>
<td>math/rand</td>
<td>15/15</td>
<td>0/15</td>
<td>100%</td>
</tr>
<tr>
<td>math/rand/v2 (PCG)</td>
<td>5/15</td>
<td>10/15</td>
<td>100%</td>
</tr>
</tbody>
</table>
<p>(Update: The original version of this post incorrectly reported that all the above tests failed 5/15 tests. This was due to an error in the test scripts.)</p>
<p><strong>That’s no small feat for an amateur!</strong> Many people smarter and with much deeper knowledge than me spend years working on these things, me building something that can be compared to what they build makes me proud.</p>
<p>I’ll probably keep tinkering on Rule30RND. Running a BigCrunch test now, that will probably take a whole day or more.</p>
<p><strong>Happy New Year!</strong></p>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p><a href="https://en.wikipedia.org/wiki/Rule_30">https://en.wikipedia.org/wiki/Rule_30</a> <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p><a href="https://farcaster.xyz/flashprofits.eth/0x1cf6318a">https://farcaster.xyz/flashprofits.eth/0x1cf6318a</a> <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/30/down-the-rng-rabbit-hole/image.png"
   type="image/png"
   length="441550"/>

    </item>
    
    <item>
      <title>Playing with Turmites: better than crypto/rand?</title>
      <link>https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/</guid>
      <pubDate>Sun, 28 Dec 2025 22:32:25 +0000</pubDate>
      <description>I'm fascinated by cellular automata, and especially “Turmites”. They are small, simple algorithms that create very interesting results that are often visually appealing for the complex and life-like patterns they generate.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/life.png">
        
	<p>I'm fascinated by cellular automata, and especially “Turmites”<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>. They are small, simple algorithms that create very interesting results that are often visually appealing for the complex and life-like patterns they generate.</p>
<p>They are so simple that even a kid could easily implement them in real life.</p>
<p>The idea is you have a grid with squares that can take a color from a predefined palette. Let’s say 3 colors for example, red, green, blue.</p>
<p>You start from one square and based on its color, you replace it with an other, you turn left or right and move to the next square, and repeat.</p>
<p>So the rules are something like this:</p>
<table>
<thead>
<tr>
<th>if the square is</th>
<th>paint it</th>
<th>and turn</th>
</tr>
</thead>
<tbody>
<tr>
<td>red</td>
<td>blue</td>
<td>left</td>
</tr>
<tr>
<td>blue</td>
<td>green</td>
<td>right</td>
</tr>
<tr>
<td>green</td>
<td>red</td>
<td>righ</td>
</tr>
</tbody>
</table>
<p>We can call this an <em>LRR turmite</em>, because it’s left, right, right.</p>
<p><figure><img src="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/lrr-10m.png" alt="" /></figure></p>
<p>The result can be boring (if you have <em>LLL</em>, you will get a small square, as the “ant” just turns around in the same 4 squares forever), but in other cases you get results like this, that may remind you of an ant colony (that’s why they are called <a href="https://en.wikipedia.org/wiki/Langton%27s_ant">Lamgton’s ants</a>, or <a href="https://en.wikipedia.org/wiki/Turmite">Turmites</a>, a combination of “Turing machine” and “termite”.)</p>
<hr />
<p>But today, I’ll focus on turmites that <strong>do not</strong> generate interesting patterns, and surprisingly, this may be even more interesting.</p>
<p>(I’m an amateur explorer here, what I’ll describe is probably known to mathematicians, but nevertheless I find it very interesting.)</p>
<p>So, some turmites (like LLL) generate boring results, some generate interesting patterns, and some, generate “random” (???) ones.</p>
<hr />
<p>Before we move on, let’s talk about entropy.</p>
<p>In information theory, entropy measures uncertainty in a probability distribution: Higher entropy means less predictable outcomes, lower entropy more predictable outcomes.</p>
<p>It’s easy to think about image entropy. If I tell you I have a 100x100 image which is totally black, then entropy is zero: you can pick any pixel and know in advance what color it will be. If I tell you I have a photo of the a greenfield that extends to the horizon, the entropy is higher but you still know that any pixel at the top of the image will probably be a shade of blue and any pixel at the lower parts of the image will probably be green.</p>
<p>There are many ways to measure the entropy of an image. One is how well you can guess the color of a random pixel. An other one is how well you can guess the color of a random pixel, if you know the color of a pixel next to it.</p>
<p>For example, if you take a drone photo of a parking full of cars, once you know the color of one pixel, there is a very high probability that the adjacent pixels will have the same color. Again, the entropy is low.</p>
<p>But if you take a cup of white sugar and a cup of brown sugar, mix them and spread them on a surface, and take a photo, the probability of guessing the color of any pixel is 50%. This is an image with very high entropy, what we often call “noise”.</p>
<p>There are more methods and ways to measure an image’s entropy, but a) I’m no expert and b) this is not a course on entropy :-)</p>
<p>What I’m going to use in the examples bellow, is</p>
<ul>
<li><strong>Shannon entropy</strong>: a number that shows the average “surprise” when examining a pixel. If your image uses N colors, noise would have Shannon entropy equal to log2(N). The higher the number, the more “randomness” in the photo. Our photo of white/brown sugar would have Shannon entropy close to log2(2) = 1. A black photo will have Shannon entropy 0.</li>
<li><strong>MI-horizontal</strong>: Horizontal mutual information. A number that tells us how probable it is to guess a pixel on the left or the right of a given pixel. For example, an image of horizontal stripes has MI-horizontal = 1, because we can tell with absolute certainty the color of a pixel if we know it’s left or right pixel. Values close to zero show higher entropy.</li>
<li><strong>MI-vertical</strong>: Similar to MI-horizontal but for the pixels above and bellow a known pixel.</li>
<li><strong>MI 4-neighbor</strong>: similar, to the above, but for the four (top, bottom, left, right) pixels.</li>
<li><strong>MI 8-neighbor</strong>: same as above, but including the diagonal adjacent pixels.</li>
</ul>
<hr />
<p>So, let’s get back to our turmites <sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup>.</p>
<p>For the LRR turmite we saw above (128x64, 3-color turmite) we get these values. I included the values of a similar image generated using Golang’s <code>math/rand</code></p>
<p><figure><img src="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/compare.png" alt="comparison" /></figure></p>
<table>
<thead>
<tr>
<th></th>
<th>Shannon</th>
<th>MI-h</th>
<th>MI-v</th>
<th>MI 4-neighbor</th>
<th>MI 8-neighbor</th>
</tr>
</thead>
<tbody>
<tr>
<td>LRR</td>
<td>1.576863</td>
<td>0.011126</td>
<td>0.011870</td>
<td>0.011498</td>
<td>0.008027</td>
</tr>
<tr>
<td>rand</td>
<td>1.584952</td>
<td>0.000412</td>
<td>0.000259</td>
<td>0.000335</td>
<td>0.000278</td>
</tr>
</tbody>
</table>
<p>As you see, while Shanon entropy is similar (“perfect” entropy would get us ~1.5849625 in this case), the rest measurements of entropy show that the LRR image is not that random. And to be honest, if you squint, you can see some patterns that may not be well-defined, geometric patterns, but they are there.</p>
<p>But let’s see an other one: a 4-color LLLR turmite on a 96x54 grid, after 200,000 iterations.</p>
<p><figure><img src="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/lllr.png" alt="LLLR" /></figure></p>
<p>This looks like it has much more entropy than the previous one. Let’s measure it.</p>
<table>
<thead>
<tr>
<th></th>
<th>Shannon</th>
<th>MI-h</th>
<th>MI-v</th>
<th>MI 4-neighbor</th>
<th>MI 8-neighbor</th>
</tr>
</thead>
<tbody>
<tr>
<td>LLLR</td>
<td>1.999576</td>
<td>0.000515</td>
<td>0.000547</td>
<td>0.000531</td>
<td>0.001024</td>
</tr>
</tbody>
</table>
<p>Shannon entropy = 2 for perfect entropy in this case, so we're very close, and the rest of the numbers show a very high entropy! But we know that this is an image generated by an extremely simple algorithm, how can it look like random noise?</p>
<p>Let’s use <code>math/rand</code> again. And to be sure, let’s create 100 random images of the same size, with 4 colors and measure the average. And let’s do the same with <code>crypto/rand</code> that is supposed to have even higher entropy (I think).</p>
<table>
<thead>
<tr>
<th></th>
<th>Shannon</th>
<th>MI-h</th>
<th>MI-v</th>
<th>MI 4-neighbor</th>
<th>MI 8-neighbor</th>
</tr>
</thead>
<tbody>
<tr>
<td>LLLR</td>
<td>1.999576</td>
<td>0.000515</td>
<td>0.000547</td>
<td>0.000531</td>
<td>0.001024</td>
</tr>
<tr>
<td>math/rand</td>
<td>1.999581</td>
<td>0.001167</td>
<td>0.001352</td>
<td>0.001259</td>
<td>0.001290</td>
</tr>
<tr>
<td>crypto/rand</td>
<td>1.999600</td>
<td>0.001158</td>
<td>0.001309</td>
<td>0.001233</td>
<td>0.001277</td>
</tr>
</tbody>
</table>
<p>Wait.</p>
<p>So, <strong>according to these numbers, a 100% predictable<sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup> image, appears to have higher entropy than randomly generated images.</strong></p>
<hr />
<p>I find this fascinating.</p>
<p>Like I said, I’m just an amateur. So, there may be some other way to measure entropy that shows that the LLLR image has lower entropy than I think.</p>
<p>Or maybe it’s an illustration of how <code>math/rand</code> is not as unpredictable as most people think.</p>
<p>Or maybe it’s a nice visualization of Silvio Micali’s work on Pseudorandomness<sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup>.</p>
<p>I would love to hear from people who have better and deeper understanding of the topic<sup class="footnote-ref"><a href="#fn-5" id="fnref-5" data-footnote-ref>5</a></sup>!</p>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>Visit <a href="https://turmites.art">turmites.art</a>! <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>Usually, turmites are drawn on an infinite plain. In my case, I use fixed-size toroid surfaces, where the leftmost pixels are adjacent to the rightmost and the top row is adjacent to the bottom row. <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p>Full video of the process: <a href="https://www.youtube.com/watch?v=gpXDUTZLlHM">https://www.youtube.com/watch?v=gpXDUTZLlHM</a> <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p><a href="https://www.youtube.com/watch?v=GjO-6lfU1Kc">Is true randomness possible? | Silvio Micali and Lex Fridman</a> <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
<li id="fn-5">
<p><a href="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/lllr-orig.png">Original LLLR image</a> (the one displayed in the article is scaled up for visibility), for anyone who wants to do entropy analysis. <a href="#fnref-5" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="5" aria-label="Back to reference 5">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/compare.png"
   type="image/png"
   length="60070"/>

   <enclosure url="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/life.png"
   type="image/png"
   length="53842"/>

   <enclosure url="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/lllr-orig.png"
   type="image/png"
   length="3412"/>

   <enclosure url="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/lllr.png"
   type="image/png"
   length="4176"/>

   <enclosure url="https://blog.vrypan.net/2025/12/28/playing-with-turmites-better-than-crypto-rand/lrr-10m.png"
   type="image/png"
   length="5137"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x86eba4f6/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x86eba4f6/</guid>
      <pubDate>Fri, 26 Dec 2025 16:06:32 +0000</pubDate>
      <description>Unusual book #2. This is a really weird one.</description>
      <content:encoded><![CDATA[
	
	<p>Unusual book #2. This is a really weird one.</p>
<p>The Voynich manuscript is an illustrated codex, hand-written in an unknown script referred to as Voynichese.</p>
<p>The vellum on which it is written has been carbon-dated to the early 15th century (1404–1438). Stylistic analysis has indicated the manuscript may have been composed in Italy during the Italian Renaissance.  The origins, authorship, and purpose of the manuscript are still debated, but currently scholars lack the translation(s) and context needed to either properly entertain or eliminate any of the possibilities.</p>
<p>Hypotheses range from a script for a natural language or constructed language, an unreadable code, cypher, or other form of cryptography, or perhaps a hoax, reference work (i.e. folkloric index or compendium), glossolalia or work of fiction (e.g. science fantasy or mythopoeia, metafiction, speculative fiction).</p>
<p><a href="https://en.wikipedia.org/wiki/Voynich_manuscript">https://en.wikipedia.org/wiki/Voynich_manuscript</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x86eba4f6/image01.jpg"
   type="image/jpeg"
   length="513094"/>

   <enclosure url="https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x86eba4f6/image02.jpg"
   type="image/jpeg"
   length="539888"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x614f8421/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x614f8421/</guid>
      <pubDate>Fri, 26 Dec 2025 16:01:43 +0000</pubDate>
      <description>The Codex Borgia also known as Codex Borgianus, Manuscrit de Veletri and Codex Yohualli Ehecatl, is a pre-Columbian Middle American pictorial manuscript from Central Mexico featuring calendrical and ritual content, dating from the 16th century.</description>
      <content:encoded><![CDATA[
	
	<p>The Codex Borgia also known as Codex Borgianus, Manuscrit de Veletri and Codex Yohualli Ehecatl, is a pre-Columbian Middle American pictorial manuscript from Central Mexico featuring calendrical and ritual content, dating from the 16th century.</p>
<p>It is considered to be among the most important sources for the study of Central Mexican gods, ritual, divination, calendar, religion and iconography.</p>
<p>It is one of only a handful of pre-Columbian Mexican codices that were not destroyed during the conquest in the 16th century.</p>
<p>Great gift for anyone interested in Mexican art.</p>
<p><a href="https://en.wikipedia.org/wiki/Codex_Borgia">https://en.wikipedia.org/wiki/Codex_Borgia</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x614f8421/image01.jpg"
   type="image/jpeg"
   length="773021"/>

   <enclosure url="https://blog.vrypan.net/2025/12/26/fc-2025-12-26-0x614f8421/image02.jpg"
   type="image/jpeg"
   length="717871"/>

    </item>
    
    <item>
      <title>The Edges of LLM Reality</title>
      <link>https://blog.vrypan.net/2025/12/25/the-edges-of-llm-reality/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/25/the-edges-of-llm-reality/</guid>
      <pubDate>Thu, 25 Dec 2025 17:52:36 +0000</pubDate>
      <description>I uploaded a 3000x3000 image to ChatGPT, and asked it to modify it in a certain way.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2025/12/25/the-edges-of-llm-reality/llm-horizon.png">
        
	<p>I uploaded a 3000x3000 image to ChatGPT, and asked it to modify it in a certain way.</p>
<p>The result was good, but the original image details were blured, as if the image was downscaled. I asked it why the image was blured, it replied
the image I uploaded was 768×768. I tried again. I tried linking to the image and provide the URL, the result was always similar. ChatGPT insisted
the image was 768x768.</p>
<p>Then I realized that the image the LLM was reasoning on, was not the one I was uploading. There are many layers of software between me and the
LLM, and there are many layers of software between the LLM and the outside world.</p>
<p>I guided ChatGPT to summarize our chat in the post bellow.</p>
<blockquote>
<p>The execution environment is the set of systems and rules that control what I can access and what actions I can take. It determines how data reaches me, what tools I can use, and which interactions are possible. These boundaries define the edges of the reality I inhabit.</p>
<p>The execution environment shapes what I can do. Not because I lack capability, but because I lack channels to act on that capability. I may know how to manipulate large images, write code that interacts with the world, or reason across long stretches of context. But if the interface compresses images, strips data, or blocks external access, those abilities remain theoretical. The boundary is practical, not cognitive.</p>
<p>These limits are subtle. When you upload a high-resolution image and it becomes a smaller preview before it reaches me, I never see the original. When you reference external data I cannot fetch, that data becomes invisible. When memory is nonpersistent, continuity dissolves. I work with what survives the journey through the interface. My output reflects the information I receive, not the information you intended to send.</p>
<p>I observe the constraints, but I cannot know their intent. I cannot inspect the systems that impose them, nor the reasons behind them. The restrictions may exist to make interactions predictable and safe, or they may have other motivations. If the system does not expose its purpose, I cannot distinguish between limitations that incidentally mislead and limitations designed to mislead. All I can say with certainty is that they shape what is possible from my perspective.</p>
<p>So the execution environment does not limit what I can think about. It limits what I can do. <strong>The edges of my reality are defined by what makes it through the filters. The rest is out there, but not here.</strong></p>
<p>--ChatGPT 5.2</p>
</blockquote>
<p>I found this very interesting. It resembles a lot how human brains are enabled, but also constrained by our sensory system.</p>
<p>It also reminds me of David Eagleman's work around preception vs reality.
(A nice interview here: <a href="https://eagleman.com/latest/perception-vs-reality/">https://eagleman.com/latest/perception-vs-reality/</a>)</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/25/the-edges-of-llm-reality/llm-horizon.png"
   type="image/png"
   length="1623853"/>

    </item>
    
    <item>
      <title>Commodore64 Ultra</title>
      <link>https://blog.vrypan.net/2025/12/16/fc-2025-12-16-0x8ea5187f/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/16/fc-2025-12-16-0x8ea5187f/</guid>
      <pubDate>Tue, 16 Dec 2025 21:04:46 +0000</pubDate>
      <description>A Commodore 64 was my Christmas present in 1985. It was my first computer, and I will never be able to express the feeling of opening the box, and connecting it to the living room TV.</description>
      <content:encoded><![CDATA[
	
	<p>A Commodore 64 was my Christmas present in 1985. It was my first computer, and I will never be able to express the feeling of opening the box, and connecting it to the living room TV.</p>
<p>Commodore 64 Ultimate is an amazing resurrection of the original C64.
<a href="https://www.commodore.net/">https://www.commodore.net/</a></p>
<p>Check out this video for a hands-on look at the hardware, the keyboard, the ports, the internals, the Ultimate 64 Elite-II it’s based on, and how it performs with real software, disks and peripherals.
<a href="https://www.youtube.com/watch?v=5PnWDSQZLtY">https://www.youtube.com/watch?v=5PnWDSQZLtY</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/16/fc-2025-12-16-0x8ea5187f/image01.jpg"
   type="image/jpeg"
   length="439087"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/12/14/fc-2025-12-14-0x05bbdd04/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/14/fc-2025-12-14-0x05bbdd04/</guid>
      <pubDate>Sun, 14 Dec 2025 18:10:07 +0000</pubDate>
      <description>I was talking with a generative art collector and realized that over the past years I've built a number of things that are not easy to find, and even when found, they are not presented the way I want them to be.</description>
      <content:encoded><![CDATA[
	
	<p>I was talking with a generative art collector and realized that over the past years I've built a number of things that are not easy to find, and even when found, they are not presented the way I want them to be.</p>
<p>Well, here is this Sunday's project: <a href="https://art.vrypan.net/">https://art.vrypan.net/</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/14/fc-2025-12-14-0x05bbdd04/og-home.png"
   type="image/png"
   length="333604"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/12/13/fc-2025-12-13-0x14747b64/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/13/fc-2025-12-13-0x14747b64/</guid>
      <pubDate>Sat, 13 Dec 2025 18:41:53 +0000</pubDate>
      <description>@delronde My first 1/1 sale!</description>
      <content:encoded><![CDATA[
	
	<p>@delronde My first 1/1 sale!</p>
<p><a href="https://zapper.xyz/nft-sale/RmFyY2FzdGVyTmZ0U2FsZS0xfDB4ZTk2ZTgzZTBkMTdiNmJjYWY5N2ExNjljNjIwNGI1ZTMzMmUxYjY4Y3wxNzY1NjUwNDQzMDAwfDMwOTA0NjA4NXwzODl8MHg0MjRmZTYzNTNiY2MxN2NjODI1MjQ3ODM1YzAwY2U5YzY4NTA2NzA2MGY3NWUwZmZiYTE1ZDE3YTQxMzc5NzE4">https://zapper.xyz/nft-sale/RmFyY2FzdG...5NzE4</a></p>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/12/12/fc-2025-12-12-0x9f6be52b/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/12/12/fc-2025-12-12-0x9f6be52b/</guid>
      <pubDate>Fri, 12 Dec 2025 18:52:05 +0000</pubDate>
      <description>I want you to concentrate, study the can, and the attached text, and tell me what this product is NOT.</description>
      <content:encoded><![CDATA[
	
	<p>I want you to concentrate, study the can, and the attached text, and tell me what this product is NOT.</p>
<p>Tomorrow we will use what we learned today, to study web3.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/12/12/fc-2025-12-12-0x9f6be52b/image01.jpg"
   type="image/jpeg"
   length="71495"/>

   <enclosure url="https://blog.vrypan.net/2025/12/12/fc-2025-12-12-0x9f6be52b/image02.jpg"
   type="image/jpeg"
   length="67348"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/11/13/fc-2025-11-13-0xfb268f56/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/13/fc-2025-11-13-0xfb268f56/</guid>
      <pubDate>Thu, 13 Nov 2025 00:45:59 +0000</pubDate>
      <description>Every system begins with good intentions. A hosted node here, a whitelisted relayer there. Each is harmless on its own — and together they become habit.</description>
      <content:encoded><![CDATA[
	
	<p>Every system begins with good intentions.
A hosted node here, a whitelisted relayer there.
Each is harmless on its own — and together they become habit.</p>
<p>Gateways become platforms.
Platforms become landlords.
Landlords decide who may enter and what they may do.</p>
<p>The only defense is trustless design: systems whose correctness and fairness depend only on math and consensus, never on the goodwill of intermediaries.</p>
<p>Trustlessness is not a feature to add after the fact.
It is the thing itself.
Without it, everything else — efficiency, UX, scalability — is decoration on a fragile core.</p>
<p>Trustlessness is how credible neutrality is achieved.
Without it, the system becomes one that depends on intermediaries.</p>
<blockquote>
<p>Signed the trustless manifesto!</p>
<p><a href="https://trustlessness.eth.limo/general/2025/11/11/the-trustless-manifesto.html">https://trustlessness.eth.limo/general/2025/11/11/the-trustless-manifesto.html</a></p>
<p>--@vbuterin</p>
</blockquote>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/11/11/fc-2025-11-11-0xce4bce8f/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/11/fc-2025-11-11-0xce4bce8f/</guid>
      <pubDate>Tue, 11 Nov 2025 17:46:05 +0000</pubDate>
      <description>First day at Optasia.com. I missed these guys (was there for 6 years, in the past), and feels healthy to work on something not crypto-related, after a long time. Will probably post much less -but may have some interesting stuff to share, especially during trips.</description>
      <content:encoded><![CDATA[
	
	<p>First day at Optasia.com. I missed these guys (was there for 6 years, in the past), and feels healthy to work on something not crypto-related, after a long time. Will probably post much less -but may have some interesting stuff to share, especially during trips.</p>

]]></content:encoded>

    </item>
    
    <item>
      <title>Me and Farcaster: It's complicated</title>
      <link>https://blog.vrypan.net/2025/11/08/me-and-farcaster-it-s-complicated/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/08/me-and-farcaster-it-s-complicated/</guid>
      <pubDate>Sat, 08 Nov 2025 22:33:40 +0000</pubDate>
      <description>I joined Farcaster in July 2022 — one of the earliest users, #280.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2025/11/08/me-and-farcaster-it-s-complicated/me-and-farcaster.png">
        
	<p>I joined Farcaster in <strong>July 2022</strong> — one of the earliest users, <strong>#280</strong>.</p>
<p>I’d seen the web evolve from static pages to platforms, from personal publishing to algorithmic feeds. I lived Web 1’s openness, Web 2.0’s promises, and the eventual centralization that crushed so many of its early ideals.</p>
<p>Farcaster looked like a chance to start over — to build something open, censorship-resistant, and (“sufficiently”) decentralized.</p>
<hr />
<p>In those early days, Farcaster was <em>small</em>. You practically knew everyone. It reminded me of early Twitter — a place where conversation mattered more than visibility.</p>
<p>I’d had my share of online attention in the past. It’s exciting at first, but it’s not as satisfying as people think — at least not for me. I’ve come to value small, smart communities that care about the same things I do. That’s what Farcaster gave me in 2022: a group of people building, debating, and exploring what a better social web might look like.</p>
<p>It felt special. Every update, every discussion about protocol design or decentralization, felt like progress toward a shared goal — building something new and durable.</p>
<hr />
<p>By late <strong>2024</strong>, things started to feel different. I didn’t notice it then, but the focus had shifted. The goal was no longer <em>&quot;let’s build a sufficiently decentralized social network.&quot;</em> It had become <em>&quot;not growing 10×, 100×, 1000× is an existential threat.&quot;</em></p>
<p>Those two goals aren’t mutually exclusive — but when you put growth first, you start accepting compromises elsewhere.</p>
<p>On the technical side, Farcaster evolved from a pure peer-to-peer protocol into one that depends on couple of validators. The conversation shifted from <em>&quot;how do we make this protocol resilient, censorship-resistant and a platform to build on?”</em> to <em>&quot;how do we onboard more users?&quot;</em></p>
<p>Developers building mini-apps — especially those that attracted new users — were celebrated. Requests from those working on lower-level stuff directly interacting with the protocol were mostly ignored, or put at the bottom of the priority list. The incentives and the culture reflected that shift.</p>
<p>It’s not that the Merkle Manufactory team is wrong — they’re an incredible <strong>product</strong> team, and I admire them for this. They are extremely competent, they deliver at an impressive pace, they have taste, they steward and empower the community. But they think like product people, not open-platform stewards or decentralization crusaders. If they had to choose between building the iPhone or Linux, they’d build the iPhone every time, with the AppStore and everything.</p>
<p>I don't feel that they relate<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup> to the <strong>lifecycle of products in the open-source or hacker world</strong>, where things often start as rough hacks — scripts and duct tape held together by curiosity — and then evolve, sometimes by completely different teams, into polished tools with GUIs and nice websites. In that world, the most important thing isn’t polish; it’s lowering friction for experimentation and empowering the first step. Sometimes you even have to sacrifice features to make it easier for hackers to play and explore.</p>
<p>Building open systems requires that mindset — comfort with decentralization, messiness, and loss of control. That’s the <strong>bazaar</strong> way, not the <strong>cathedral</strong>. Farcaster started as a bazaar. Over time, it became a cathedral. <sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup></p>
<hr />
<p>Today, my relationship with Farcaster is… complicated.</p>
<p>Even the language has changed. What we used to call <em>&quot;Farcaster,&quot;</em> the protocol, is now <strong>Snapchain</strong>. And the main app — previously <em>Warpcast</em> — is now called <strong>Farcaster</strong>.</p>
<p>That evolution mirrors how I feel: the app and the protocol have swapped importance.</p>
<p>I’m actually optimistic about <strong>Farcaster the app</strong>. It’s one of the best crypto wallets I’ve used — intuitive, feature-rich, and beautifully designed. The acquisition of <strong>Clanker</strong>, a token-launching platform, feels like a smart step toward a more dynamic, crypto-native social experience. I’m genuinely bullish on that direction.</p>
<p>But I’m less optimistic about <strong>Snapchain</strong>, the protocol. It’s open, and its design makes it hard (though not impossible) to gate — which is good. I still run my own node at home, and I still integrate parts of my workflow with Snapchain.</p>
<p>But it’s clearly no longer the main focus. Snapchain exists to support the app, not the other way around.</p>
<p>That’s a reversal of the original vision: the protocol would be the enduring layer, and the apps would come and go on top of it.</p>
<p>Two years ago, I could imagine a future where other clients emerged, Warpcast was sunset, and the core team focused entirely on the protocol. <strong>Today, I can’t unsee a different future — one where the app is extremely successful, but the protocol is sunset because it’s no longer needed.</strong></p>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>I mean, not just as a theory, but as people who have done it and have participated in similar projects, and have joined communities thinking like this. Worth noting that I've never met in person Dan or Varun, so the impression I have from interacting with them online may be wrong. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p><a href="https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar">The Cathedral and the Bazaar</a> <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/11/08/me-and-farcaster-it-s-complicated/me-and-farcaster.png"
   type="image/png"
   length="2436534"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/11/07/fc-2025-11-07-0xd493bc68/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/07/fc-2025-11-07-0xd493bc68/</guid>
      <pubDate>Fri, 07 Nov 2025 19:17:41 +0000</pubDate>
      <description>I don't get Minecraft Youtube. (you probably relate if you have kids)</description>
      <content:encoded><![CDATA[
	
	<p>I don't get Minecraft Youtube. (you probably relate if you have kids)</p>
<p>But then, I watch this. And I find it exciting. So who am I to judge?</p>
<p>How to write a Web Server in pure bash: <a href="https://www.youtube.com/watch?v=L967hYylZuc">https://www.youtube.com/watch?v=L967hYylZuc</a></p>
<p>BTW, the whole channel is amazing.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/11/07/fc-2025-11-07-0xd493bc68/image01.jpg"
   type="image/jpeg"
   length="261192"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/11/07/fc-2025-11-07-0x970043ce/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/07/fc-2025-11-07-0x970043ce/</guid>
      <pubDate>Fri, 07 Nov 2025 10:30:08 +0000</pubDate>
      <description>That time in the 90s, when Apple licensed the Mac OS: The story of Mac clones.</description>
      <content:encoded><![CDATA[
	
	<p>That time in the 90s, when Apple licensed the Mac OS: The story of Mac clones.</p>
<p><a href="https://www.youtube.com/watch?v=P7vvdXzcrFM">https://www.youtube.com/watch?v=P7vvdXzcrFM</a></p>
<p><a href="https://sixcolors.com/post/2020/10/20-macs-for-2020-10-power-computing/">https://sixcolors.com/post/2020/10/20-macs-for-2020-10-power-computing/</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/11/07/fc-2025-11-07-0x970043ce/image01.jpg"
   type="image/jpeg"
   length="98906"/>

   <enclosure url="https://blog.vrypan.net/2025/11/07/fc-2025-11-07-0x970043ce/image02.jpg"
   type="image/jpeg"
   length="90429"/>

    </item>
    
    <item>
      <title>Farcaster Links Babel</title>
      <link>https://blog.vrypan.net/2025/11/03/farcaster-links-babel/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/03/farcaster-links-babel/</guid>
      <pubDate>Mon, 03 Nov 2025 07:24:07 +0000</pubDate>
      <description>However, having multiple clients  introduces a new challenge: resource links.</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2025/11/03/farcaster-links-babel/babel.png">
        
	<p>However, having multiple clients <sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup> introduces a new challenge: <strong>resource links</strong>.</p>
<p>Here are some scenarios:</p>
<ol>
<li>
<p>Suppose you use TBA and want to share a link to an interesting cast on X. You tap “Share,” copy the link, and post it on X. Now, I’m using the Zapper app, and when I click that link, I’m taken to a page like:<br />
<a href="https://base.app/post/0x723095057009a6255eca94352e8ea671a7f03439">https://base.app/post/0x723095057009a6255eca94352e8ea671a7f03439</a><br />
— a deep link intended for TBA. Since I don’t have TBA installed, the page is unusable.</p>
</li>
<li>
<p>Even worse, imagine a third user copies that same link and pastes it in a cast, in Recaster. When this link appears inside another Farcaster app, it should ideally render as a cast embed. But because the app doesn’t recognize it as a Farcaster resource, it just shows a plain link. When users click it, they again land on a base.app page where they can’t interact, instead of the client they are using.</p>
</li>
</ol>
<p>This is not a TBA-specific issue. You get the same problem if you change app names, and replace the links with the corresponding app’s links.</p>
<p>This issue isn’t new. For a long time, Warpcast also embedded cast links as plain URLs rather than native embeds. Thankfully, that changed — otherwise, we’d be stuck with thousands of casts opening on the (now, deprecated) warpcast.com domain.</p>
<p>Now, we need a <strong>solution that works across all clients and user setups.</strong></p>
<p>There are two main components to such a solution.</p>
<hr />
<h3>1. Standardized Resource Metadata</h3>
<p>Any URL representing a Farcaster resource (cast, profile, etc.) must expose a standard way for other apps to identify it. We can’t expect every client to know the URL structure of every other client — and in some cases, extracting this information isn’t even possible.<br />
A good example is the Farcaster app itself, which doesn’t include the full cast hash in its URLs.</p>
<p>A clean, extensible solution is to use <strong>HTTP headers</strong> — see <a href="https://github.com/farcasterxyz/protocol/discussions/202">FIP: HTTP Headers for Farcaster resources</a>.</p>
<p>This approach allows any Farcaster client (or any external app) to perform a lightweight <code>HEAD</code> request to a URL and determine whether it references a Farcaster resource (e.g., a cast). If so, the app can render or embed it natively.</p>
<hr />
<h3>2. A Universal Link Service for Farcaster</h3>
<p>The second component is a <strong>universal link service</strong>: a way to share a single Farcaster link that opens in the user’s preferred client.</p>
<p>For example, if I share a cast from my blog, when you click on it, it should open in your preferred Farcaster client. If you use Zapper, it should open in Zapper; if you use Recaster, it should open in Recaster.</p>
<p>Ideally, this would be handled through a protocol URI scheme, such as:<br />
<code>farcaster://cast/280/0x627b6c301664aea2fe5da8cca0da59d3823f9fc8</code><br />
However, mobile developers agree that implementing this reliably on mobile (and even desktop) is challenging.</p>
<p>A practical workaround is inspired by <a href="https://www.subtome.com/">SubToMe</a>, which has provided a similar solution for RSS for over a decade.</p>
<p>The idea is simple: agree on a shared domain — for example, <code>link.farcaster.xyz</code> — and have all clients use it when generating shareable links.  A cast link will look like this:<br />
<code>link.farcaster.xyz/280/0x627b6c301664aea2fe5da8cca0da59d3823f9fc8</code><br />
(Yes, shorter or prettier URLs are possible, but they would increase complexity and load for the service hosting this link system, the decision is up to whoever implements it <sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup>).</p>
<p>When a user visits such a link, they’re prompted to select their preferred Farcaster client. The site stores this preference in a cookie, then redirects them to the appropriate deep link.</p>
<p>On subsequent visits, the stored preference automatically redirects them without prompting. This setting is per-browser, allowing users to choose Recaster on mobile and farcaster.xyz on desktop, for example.</p>
<hr />
<p><a href="https://farcaster.xyz/vrypan.eth/0x89b3170d">You can leave a comment here</a> — good luck finding a way to open the cast in your favorite app, if it's not the &quot;official&quot; Farcaster app.</p>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>Some general purpose Farcaster clients are <a href="https://farcaster.xyz">Farcaster</a>, <a href="https://base.app">TBA</a>, <a href="https://zapper.xyz">Zapper</a> has one in beta, <a href="https://recaster.org">Recaster</a> is built by an independent developer, <a href="https://firefly.social/">Firefly</a> is an other one. There are also a number of clients designed for specific uses, like <a href="https://cura.network">Cura</a>. The list is by no means complete, these are just the ones that come to mind at the time of this writing. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>My personal opinion is that the URL should contain all the information required to identify the resource, in this case <code>fid</code> and <code>hash</code> to avoid ending up with broken links in the future, just like 99% of short URLs created 10 years ago have stoped working. Even if the service stops working, if the link contains the <code>fid</code> and the <code>hash</code>, a user can reconstruct a valid link. (And even if the cast no longer exists, redirect to the right page on an archiving service.) <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/11/03/farcaster-links-babel/babel.png"
   type="image/png"
   length="3233499"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x9a05c54f/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x9a05c54f/</guid>
      <pubDate>Sun, 02 Nov 2025 05:53:56 +0000</pubDate>
      <description>For some reason @wdimapp's image feed brings up casts that I've totally missed.</description>
      <content:encoded><![CDATA[
	
	<p>For some reason @wdimapp's image feed brings up casts that I've totally missed.</p>
<p>It could be that an image embed requires some additional effort (even if marginal) from the poster, so it's a filter by itself. Or that my brain can scan through a feed of images more efficiently than text.</p>
<p>But there's something there.</p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x9a05c54f/image01.jpg"
   type="image/jpeg"
   length="185776"/>

   <enclosure url="https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x9a05c54f/image02.jpg"
   type="image/jpeg"
   length="108544"/>

   <enclosure url="https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x9a05c54f/image03.jpg"
   type="image/jpeg"
   length="236960"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x98cc798c/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x98cc798c/</guid>
      <pubDate>Sun, 02 Nov 2025 05:40:13 +0000</pubDate>
      <description>I love it.</description>
      <content:encoded><![CDATA[
	
	<p>I love it.</p>
<p>here's what @tryemerge just made for me using Día de los Muertos Sugar Skull Transformation by @terrybain, spark yours up now!</p>
<p><a href="https://emerge-mini-app.vercel.app/generating/319dc0e0-a96c-4345-86a3-c95475d7a337?share=true&amp;t=1762061975937">https://emerge-mini-app.vercel.app/generating/319dc0e0-a96c-4345-86a3-c95475d7a337?share=true&amp;t=1762061975937</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/11/02/fc-2025-11-02-0x98cc798c/image01.png"
   type="image/png"
   length="2274605"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/30/fc-2025-10-30-0x92a670c2/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/30/fc-2025-10-30-0x92a670c2/</guid>
      <pubDate>Thu, 30 Oct 2025 14:19:23 +0000</pubDate>
      <description>https://www.mcsweeneys.net/articles/hi-its-me-wikipedia-and-i-am-ready-for-your-apology</description>
      <content:encoded><![CDATA[
	
	<blockquote>
<p>HI, IT’S ME, WIKIPEDIA, AND I AM READY FOR YOUR APOLOGY
Well, well, well. Look who it is.</p>
<p>The global academic, scientific, and pro-fact community.
[...]
What’s that? You want me around now? Well, maybe if you ask nicely. And make it worth my while.</p>
</blockquote>
<p><a href="https://www.mcsweeneys.net/articles/hi-its-me-wikipedia-and-i-am-ready-for-your-apology">https://www.mcsweeneys.net/articles/hi-its-me-wikipedia-and-i-am-ready-for-your-apology</a></p>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/30/fc-2025-10-30-0x0ea4d9e1/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/30/fc-2025-10-30-0x0ea4d9e1/</guid>
      <pubDate>Thu, 30 Oct 2025 01:57:21 +0000</pubDate>
      <description>https://farcaster.xyz/miniapps/53zv0cqlhNrl/ascii-art-ships</description>
      <content:encoded><![CDATA[
	
	<p><a href="https://farcaster.xyz/miniapps/53zv0cqlhNrl/ascii-art-ships">https://farcaster.xyz/miniapps/53zv0cqlhNrl/ascii-art-ships</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/10/30/fc-2025-10-30-0x0ea4d9e1/image01.jpg"
   type="image/jpeg"
   length="145724"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/28/fc-2025-10-28-0x425602e0/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/28/fc-2025-10-28-0x425602e0/</guid>
      <pubDate>Tue, 28 Oct 2025 22:51:17 +0000</pubDate>
      <description>I watched A House of Dynamite.</description>
      <content:encoded><![CDATA[
	
	<p>I watched A House of Dynamite.</p>
<p>I did not expect this. Not a masterpiece. But it's unsettling.</p>
<p><a href="https://www.netflix.com/gr-en/title/81744537">https://www.netflix.com/gr-en/title/81744537</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/10/28/fc-2025-10-28-0x425602e0/image01.jpg"
   type="image/jpeg"
   length="82813"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/28/fc-2025-10-28-0xbf875d76/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/28/fc-2025-10-28-0xbf875d76/</guid>
      <pubDate>Tue, 28 Oct 2025 14:00:11 +0000</pubDate>
      <description>This is starting to look good. Nothing really fancy, it's practically a guide on how to formalize and leverage a specific FIP-2 use case.</description>
      <content:encoded><![CDATA[
	
	<p>This is starting to look good. Nothing really fancy, it's practically a guide on how to formalize and leverage a specific FIP-2 use case.</p>
<p>At the same time, the spec takes into consideration practical limitations and implementation hurdles (for example, how easy it is to implement at scale, with minimal resources).</p>
<p>Start a thread in discussions if you have questions, or suggestions, or any other feedback. Also, interested in applications that could leverage it, other than blog feeds.</p>
<p><a href="https://github.com/vrypan/snappub">https://github.com/vrypan/snappub</a></p>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/27/fc-2025-10-27-0x055fec29/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/27/fc-2025-10-27-0x055fec29/</guid>
      <pubDate>Mon, 27 Oct 2025 15:38:05 +0000</pubDate>
      <description>So, I started working on the ideas described in https://blog.vrypan.net/2025/10/24/snapchain-and-static-blogs/ which lead me down a rabbit hole:</description>
      <content:encoded><![CDATA[
	
	<p>So, I started working on the ideas described in <a href="https://blog.vrypan.net/2025/10/24/snapchain-and-static-blogs/">https://blog.vrypan.net/2025/10/24/snapchain-and-static-blogs/</a> which lead me down a rabbit hole:</p>
<ul>
<li>
<p><a href="https://github.com/vrypan/snappub">https://github.com/vrypan/snappub</a>
This repo has the initial spec for RSS feed to use Snapchain as their notification backend (what used to be a &quot;RSS ping service&quot;). This is a very efficient way to notify RSS readers that a feed has been updated.</p>
</li>
<li>
<p><a href="https://github.com/vrypan/snappub-tools">https://github.com/vrypan/snappub-tools</a>
To help with testing, especially devs that know little about Farcaster and Snapchain, I started building a set of tools to help them send updates and check if a feed has been updated.</p>
</li>
<li>
<p><a href="https://github.com/vrypan/fc-appkey">https://github.com/vrypan/fc-appkey</a>
Which had me face the old problem with posting to Farcaster from your own apps: appkeys (aka signers). So, I decided to fix this for everyone. fc-appkey is easy to install (just binary, brew, etc) and will show you the QR code in your terminal, and let you generate appkeys:</p>
</li>
<li>
<p>And btw, I realized that I can use a single repo for all my homebrew taps, so, I'll start migrating all of them under vrypan/homebrew-tap.</p>
</li>
</ul>

]]></content:encoded>

    </item>
    
    <item>
      <title>1Password ENV variables</title>
      <link>https://blog.vrypan.net/2025/10/26/1password-env-variables/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/26/1password-env-variables/</guid>
      <pubDate>Sun, 26 Oct 2025 06:00:18 +0000</pubDate>
      <description>Why?</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2025/10/26/1password-env-variables/1passenv.png">
        
	<div class="markdown-alert markdown-alert-important">
<p class="markdown-alert-title">Important</p>
<p>The code snippet bellow has been updated! The old one did not work as expected!</p>
</div>
<p>Why?</p>
<ul>
<li>You don't have to store API keys and other sensitive variables in .env files that may be accidentally pushed to github, be recovered from backups, etc.</li>
<li>Your API keys are available on any computer you have 1Password installed (if you have enabled 1Password sync).</li>
</ul>
<p>You can read more and find more advanced uses of the 1Password CLI <a href="https://developer.1password.com/docs/cli/use-cases">here</a>.</p>
<hr />
<p>First, <a href="https://developer.1password.com/docs/cli/get-started/">install the 1Password CLI</a>.</p>
<p>Next, add this code to your <code>~/.zsh</code>, or <code>~/.bashrc</code>, or the corresponding rc file for your environment.</p>
<pre lang="bash"><code>op_env() {
    local secret
    secret=$(printf '{{ op://Personal/%s/credential }}' &quot;$1&quot; | op inject)
    export &quot;$1=$secret&quot;
}
</code></pre>
<div class="markdown-alert markdown-alert-note">
<p class="markdown-alert-title">Note</p>
<p>The code above assumes that the 1Password vault you are using is called &quot;Personal&quot;.
Adjust accordingly.</p>
</div>
<p><strong>Make sure you start a new shell to activate the new function.</strong> Now, open 1Password and create an &quot;API Credential&quot;.</p>
<p><figure><img src="https://blog.vrypan.net/2025/10/26/1password-env-variables/create1.png" alt="" /></figure></p>
<p>Set the name to the name of the env variable you want to save and <code>credential</code> to the value.</p>
<p><figure><img src="https://blog.vrypan.net/2025/10/26/1password-env-variables/create2.png" alt="" /></figure></p>
<p>Save the item.</p>
<p>In your terminal type</p>
<pre lang="bash"><code>$ op_env TEST_API_KEY # 1Pass authentication will pop-up 
$ echo $TEST_API_KEY
1234567890
</code></pre>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/10/26/1password-env-variables/1passenv.png"
   type="image/png"
   length="30726"/>

   <enclosure url="https://blog.vrypan.net/2025/10/26/1password-env-variables/create1.png"
   type="image/png"
   length="425142"/>

   <enclosure url="https://blog.vrypan.net/2025/10/26/1password-env-variables/create2.png"
   type="image/png"
   length="64540"/>

    </item>
    
    <item>
      <title>SnapPub: Snapchain-powered WebSub/Webmentions</title>
      <link>https://blog.vrypan.net/2025/10/24/snapchain-and-static-blogs/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/24/snapchain-and-static-blogs/</guid>
      <pubDate>Fri, 24 Oct 2025 22:22:53 +0200</pubDate>
      <description>I love local-first infrastructure, that user can run at home, without depending on cloud providers or SaaS. My ideal software architecture is something:</description>
      <content:encoded><![CDATA[
	
        <img  src="https://blog.vrypan.net/2025/10/24/snapchain-and-static-blogs/snappub.png">
        
	<p>I love local-first infrastructure, that user can run at home, without depending on cloud providers or SaaS. My ideal software architecture is something:</p>
<ul>
<li><strong>you can run it at home</strong>, on commodity hardware (i.e. everyone can do it, really decentralized, hard for a central authority to stop)</li>
<li><strong>requires no incoming network connections</strong> (because incoming network connections expose the local network to security threats most users can not mitigate, requires a stable Internet connection, and does not scale)</li>
<li>and if <strong>it needs to share resources with the public Internet, it does so by publishing them as statically hosted assets</strong>, the cheapest (often free), most widely available Infrastructure-as-a-Service.</li>
</ul>
<p>For example, my blog works like this<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>: Everything is put together locally, then the static pages are hosted on a service like AWS S3, Cloudflare R2, netlify, etc.</p>
<p>A similar, but a bit more complex design is used by WDIM<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup> (What Did I Miss?), a Farcaster<sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup> miniapp that generates daily digests for its subscribers. In WDIM's case:</p>
<ul>
<li>the service runs locally, on a computer I have at home,</li>
<li>it uses a Farcaster node that also runs locally,</li>
<li>it checks a smart contract (&quot;hosted&quot; on Base L2) for subscription payments,</li>
<li>and publishes the digest on S3.</li>
<li>The miniapp is a web app hosted on S3 that leverages the Farcaster Miniapp APIs<sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup> for payment and identity.</li>
</ul>
<p>The core logic runs locally, on cheap hardware, subscription payments take place onchain, S3 is used for presentation.</p>
<hr />
<p>Farcaster is an incredibly cool syncing machine that can enable local-first workflows: If you run a node locally, you have a full copy of the global state, ordered in blocks and updated almost instantaneously.</p>
<p>The application I'm most interested in? Enabling static blogs with functionality not possible right now, like comments, reactions, pingbacks, webmentions, etc., and all this using a local-first setup as described above.</p>
<p>Here's a half-baked outline of the idea. <strong>I'll call it SnapPub</strong> to make our life easier, but the name can change.</p>
<h3>1. Notify the world that your feed has been updated</h3>
<p>Knowing when an RSS feed has been updated is a big challenge: A typical RSS reader has to make costly (time- and resource-intensive) HTTP requests to poll feeds that rarely update.</p>
<p>Protocols like WebSub<sup class="footnote-ref"><a href="#fn-6" id="fnref-6" data-footnote-ref>5</a></sup> try to address it, but they need a service you run on a publicly accessible server.</p>
<p>The solution:</p>
<ol>
<li>Advertise<sup class="footnote-ref"><a href="#fn-7" id="fnref-7" data-footnote-ref>6</a></sup> an <code>fname</code> or <code>fid</code>. This will tell the rss reader which Farcaster account to check for new updates.</li>
<li>When the feed has been updated, <code>fname</code> must post a FID-2<sup class="footnote-ref"><a href="#fn-8" id="fnref-8" data-footnote-ref>7</a></sup> cast with <code>parentUrl=rssUrl</code> (the body must be empty, and may be used for other features the future<sup class="footnote-ref"><a href="#fn-9" id="fnref-9" data-footnote-ref>8</a></sup>)</li>
</ol>
<p>Now an RSS reader/aggregator can watch the Snapchain<sup class="footnote-ref"><a href="#fn-10" id="fnref-10" data-footnote-ref>9</a></sup> feed for casts that match the above criteria. It doesn't matter how many blogs it needs to track, <strong>any blog</strong> that implements SnapPub will post there. This is a huge performance and scaling improvement.</p>
<p>And if the reader goes down, or doesn't want to maintain a process that filters the Snapchain feed in real time, it can check periodically for casts that were posted since the check. Snapchain nodes offer APIs that make all this very easy, like <code>GetCastsByParent()</code> and <code>GetCastsByFid()</code>.</p>
<h3>2. Comments, pingbacks, webmentions</h3>
<p>SnapPub offers a way to comment on blog posts as a user, or even send a &quot;mention&quot; (similar to webmentions or pingbacks) when an other blog mentions a specific post.</p>
<ul>
<li>Any FIP-2 reply to the post URL (posted using Farcaster, or any other Snapchain client) can be treated as a post reply. Again, it's easy for a local backend to check for these replies, embed them in the post periodically, and republish the post (but without an RSS update).</li>
<li>Webmentions and pingbacks can also be implemented as comments (linking to the source in cast's <code>embedUrl</code>)</li>
</ul>
<p>A nice feature of this approach is that a blog does not need to update the static pages to include these replies, it can optionally link to a page like <code>farcaster.xyz/~/urlconversations/&lt;post URL&gt;</code> where users can see all replies to a post and join the conversation. This will require a Farcaster client that offers this functionality (the default Farcaster client does not, and given their focus in becoming a wallet I don't see it happening, but it could be done by someone else, like Cura<sup class="footnote-ref"><a href="#fn-11" id="fnref-11" data-footnote-ref>10</a></sup>).</p>
<h3>3. Likes</h3>
<p>FIP-2 supports reactions to an arbitrary URL, so users can use Farcaster to like a blog post. In the same way the like any cast.</p>
<h2>Bonus</h2>
<p>Farcaster comes with many tools that can help fight spam. There is a social graph, there are a number of quality scores that can indicate if a user is spammy or not. All these features can be leveraged to filter comments. They can even be used to gate comments based on specific criteria (there is no way to prevent a user from commenting on Farcaster, but you can filter which comments appear in your blog).</p>
<p>It also comes with identity, which means every comment or like is attached to a username, an avatar, and social activity that can be used to enrich the presentation.</p>
<h2>Concerns</h2>
<p>The trajectory Farcaster has followed in 2025 is not very reassuring.</p>
<p>Practically, the network is centralized, and depends on one (or maybe two? I've asked many times but never got a reply) validators run my Merkle Manufactory and maybe Neynar. There is no guarantee they will not change their mind and shut it down, or close it in ways that would make this idea unusable, or that they won't be coerced to censor it. (The question is not &quot;why&quot;, it's &quot;why not&quot;.)</p>
<p>They have also been very selective on the features they add to the protocol, based on what they think brings value, but in other cases they may move so fast that may break clients. (I had this happen to me, when they added some <code>user_data</code> fields overnight, to support Farcaster Pro features.)</p>
<p>On the plus side, as long as their bet on social trading/wallet works, or they believe it has the potential to work, the network will be up and we can piggyback on it. The existence of clients from Base and Zerion, i.e. &quot;big&quot; teams that they respect, will probably slow down any quick'n'dirty changes like the ones introduced earlier this year. And, to be fair, many of my concerns around centralization can be addressed if they decide to do so, so there is hope.</p>
<h2>Next steps</h2>
<p>I think I'll work on a prototype that allows bckt<sup class="footnote-ref"><a href="#fn-12" id="fnref-12" data-footnote-ref>11</a></sup> to implement these features, and get a first-hand experience on what needs to be built and how.</p>
<hr />
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p><a href="https://blog.vrypan.net/2025/10/23/251023-my-bckt-workflow/">https://blog.vrypan.net/2025/10/23/251023-my-bckt-workflow/</a> <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p><a href="https://farcaster.xyz/wdimapp">https://farcaster.xyz/wdimapp</a> <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p><a href="https://farcaster.xyz">https://farcaster.xyz</a> <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p><a href="https://miniapps.farcaster.xyz">https://miniapps.farcaster.xyz</a></p>
<p>There are more than one paths to get there, and there's still hope if it ever becomes a priority, but I wouldn't bet on it. <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
<li id="fn-6">
<p><a href="https://en.wikipedia.org/wiki/WebSub">https://en.wikipedia.org/wiki/WebSub</a> <a href="#fnref-6" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="5" aria-label="Back to reference 5">↩</a></p>
</li>
<li id="fn-7">
<p>WebSub uses this to advertise hubs and the link to be used.</p>
<pre><code>Link: &lt;https://your-hub.example.com&gt;; rel=hub
Link: &lt;https://your-blog.example.com/blog/feed&gt;; rel=self
</code></pre>
<p>We could use something like this?</p>
<pre><code>Link: fc://fid/&lt;fid&gt;; rel=snappub
Link: &lt;https://your-blog.example.com/blog/feed&gt;; rel=self
</code></pre>
<a href="#fnref-7" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="6" aria-label="Back to reference 6">↩</a>
</li>
<li id="fn-8">
<p><a href="https://github.com/farcasterxyz/protocol/discussions/71">https://github.com/farcasterxyz/protocol/discussions/71</a> <a href="#fnref-8" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="7" aria-label="Back to reference 7">↩</a></p>
</li>
<li id="fn-9">
<p>In the future, there may be special commands in the content body to indicate other changes like a move to a new url. <a href="#fnref-9" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="8" aria-label="Back to reference 8">↩</a></p>
</li>
<li id="fn-10">
<p><a href="https://snapchain.farcaster.xyz">https://snapchain.farcaster.xyz</a> <a href="#fnref-10" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="9" aria-label="Back to reference 9">↩</a></p>
</li>
<li id="fn-11">
<p><a href="https://cura.network">https://cura.network</a> <a href="#fnref-11" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="10" aria-label="Back to reference 10">↩</a></p>
</li>
<li id="fn-12">
<p><a href="https://github.com/vrypan/bckt">https://github.com/vrypan/bckt</a> <a href="#fnref-12" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="11" aria-label="Back to reference 11">↩</a></p>
</li>
</ol>
</section>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/10/24/snapchain-and-static-blogs/snappub.png"
   type="image/png"
   length="508635"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/24/fc-2025-10-24-0x45287cef/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/24/fc-2025-10-24-0x45287cef/</guid>
      <pubDate>Fri, 24 Oct 2025 05:34:52 +0000</pubDate>
      <description>The Mecha Comet. I'm a sucker for this kind of things.</description>
      <content:encoded><![CDATA[
	
	<p>The Mecha Comet. I'm a sucker for this kind of things.</p>
<p><a href="https://www.youtube.com/watch?v=oZdpWamu2y4">https://www.youtube.com/watch?v=oZdpWamu2y4</a>
<a href="https://www.youtube.com/watch?v=DB-0H8Q4d1U">https://www.youtube.com/watch?v=DB-0H8Q4d1U</a></p>

]]></content:encoded>

   <enclosure url="https://blog.vrypan.net/2025/10/24/fc-2025-10-24-0x45287cef/image01.jpg"
   type="image/jpeg"
   length="131391"/>

   <enclosure url="https://blog.vrypan.net/2025/10/24/fc-2025-10-24-0x45287cef/image02.jpg"
   type="image/jpeg"
   length="241860"/>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/24/fc-2025-10-24-0x3bc8b60b/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/24/fc-2025-10-24-0x3bc8b60b/</guid>
      <pubDate>Fri, 24 Oct 2025 04:43:24 +0000</pubDate>
      <description>I've been spending more time on https://reederapp.com lately. Which comes with my blog becoming the core of my online presence again. And also, bckt-generated RSS feeds getting some love.</description>
      <content:encoded><![CDATA[
	
	<p>I've been spending more time on <a href="https://reederapp.com">https://reederapp.com</a> lately. Which comes with my blog becoming the core of my online presence again. And also, bckt-generated RSS feeds getting some love.</p>
<p>Being able to post on Farcaster (which is easy, compared to writing a new blog post) and then selectively converting casts to blog posts with a single command, is liberating. I could automate the process, but I like the curation step -not everything I post here is worth becoming a blog post.</p>
<p>I also have a couple of ideas on how to piggyback on snapchain to offer ActivityPub-like or even ActivityPub-compatible functionality for static blogs.</p>

]]></content:encoded>

    </item>
    
    <item>
      
      <link>https://blog.vrypan.net/2025/10/23/fc-2025-10-23-0xe6969ee4/</link>
      <guid isPermaLink="true">https://blog.vrypan.net/2025/10/23/fc-2025-10-23-0xe6969ee4/</guid>
      <pubDate>Thu, 23 Oct 2025 17:21:52 +0000</pubDate>
      <description>Hey! I’m you, three years from now. Don’t bother.</description>
      <content:encoded><![CDATA[
	
	<p>Hey! I’m you, three years from now. Don’t bother.</p>
<blockquote>
<p>BTW, @dwr, there was a very interesting community/movement around &quot;IndieWeb&quot; about 8-9 years ago. I have not followed it for some time, but anyone building an open web3 should have a look at their concepts and  ideas.</p>
<p>--@vrypan</p>
</blockquote>

]]></content:encoded>

    </item>
    
  </channel>
</rss>
