<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>VibeCode Sessions on locals.tf</title>
    <link>https://locals.tf/blog/vibecode/</link>
    <description>Recent content in VibeCode Sessions on locals.tf</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>© 2026 Max Severance</copyright>
    <lastBuildDate>Sat, 24 Oct 2026 00:00:00 +0300</lastBuildDate><atom:link href="https://locals.tf/blog/vibecode/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>A Transaction Is a Point in Time</title>
      <link>https://locals.tf/blog/vibecode/2026.10.24-a-transaction-is-a-point-in-time/</link>
      <pubDate>Sat, 24 Oct 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.10.24-a-transaction-is-a-point-in-time/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;A Transaction Is a Point in Time&#xA;    &lt;div id=&#34;a-transaction-is-a-point-in-time&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#a-transaction-is-a-point-in-time&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;The key-value store under the cluster had passed every functional test I had, and it had a bug that no functional test could have found: its transactions were not transactions. They were sequences. A reader who asked for a revision in the middle of one got half of it. This is the design of the repair — including the two places where my mental model of etcd turned out to be simply wrong until I measured it.&lt;/em&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Differential: Fourteen Ways a Key-Value Store Lied to Kubernetes</title>
      <link>https://locals.tf/blog/vibecode/2026.10.24-the-differential/</link>
      <pubDate>Sat, 24 Oct 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.10.24-the-differential/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;The Differential: Fourteen Ways a Key-Value Store Lied to Kubernetes&#xA;    &lt;div id=&#34;the-differential-fourteen-ways-a-key-value-store-lied-to-kubernetes&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#the-differential-fourteen-ways-a-key-value-store-lied-to-kubernetes&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;Over the last few days I replaced &amp;ldquo;does the store work?&amp;rdquo; with &amp;ldquo;does the store agree with etcd?&amp;rdquo;, operation by operation. The answer was no in fourteen places. One of them was a single request that aborted the control plane&amp;rsquo;s datastore. Several were invisible to every test the project had. Two were actively defended by tests that asserted the wrong behaviour. This is the method and the ledger.&lt;/em&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>A Point Is Not a Prefix: The Life and Times of a Four-Month-Old Bug</title>
      <link>https://locals.tf/blog/vibecode/2026.10.22-a-point-is-not-a-prefix/</link>
      <pubDate>Thu, 22 Oct 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.10.22-a-point-is-not-a-prefix/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;A Point Is Not a Prefix: The Life and Times of a Four-Month-Old Bug&#xA;    &lt;div id=&#34;a-point-is-not-a-prefix-the-life-and-times-of-a-four-month-old-bug&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#a-point-is-not-a-prefix-the-life-and-times-of-a-four-month-old-bug&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;In the previous post I chased a Kubernetes control plane that was burning a core in one-minute bursts. The proximate cause turned out to be an infinite retry loop, and the loop turned out to be caused by a store returning the wrong object for a lookup. This is the part of that story I had to dig for: which commit introduced the wrong object, why a regression test was written for exactly this and still didn&amp;rsquo;t catch it, and how a second test ended up asserting the bug as a feature.&lt;/em&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Two-Minute Loop: Hunting a Control Plane That Never Sleeps</title>
      <link>https://locals.tf/blog/vibecode/2026.10.22-the-two-minute-loop/</link>
      <pubDate>Thu, 22 Oct 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.10.22-the-two-minute-loop/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;The Two-Minute Loop: Hunting a Control Plane That Never Sleeps&#xA;    &lt;div id=&#34;the-two-minute-loop-hunting-a-control-plane-that-never-sleeps&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#the-two-minute-loop-hunting-a-control-plane-that-never-sleeps&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;A single-node Kubernetes control plane was showing up as the busiest process on an otherwise idle machine. The interesting part wasn&amp;rsquo;t the CPU number — it was that three independent metric families disagreed with each other by three orders of magnitude, the log line that looked like the cause meant the exact opposite of what it appeared to mean, and the reconciler responsible wasn&amp;rsquo;t even in the repository named on the container image.&lt;/em&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Turing Machine Is Not a CPU: OpenAI&#39;s n log n Multiplication on AVX2</title>
      <link>https://locals.tf/blog/vibecode/2026.10.11-turing-machine-is-not-a-cpu/</link>
      <pubDate>Sun, 11 Oct 2026 02:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.10.11-turing-machine-is-not-a-cpu/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;The Turing Machine Is Not a CPU: OpenAI&amp;rsquo;s n log n Multiplication on AVX2&#xA;    &lt;div id=&#34;the-turing-machine-is-not-a-cpu-openais-n-log-n-multiplication-on-avx2&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#the-turing-machine-is-not-a-cpu-openais-n-log-n-multiplication-on-avx2&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;The previous post mined the constants out of OpenAI&amp;rsquo;s &amp;ldquo;integer multiplication below n log n&amp;rdquo; proof. But that proof is a statement about a &lt;strong&gt;multitape Turing machine&lt;/strong&gt;. Real machines are out-of-order x64 cores with 256-bit SIMD, port-limited execution units, and a deep cache hierarchy. I took the paper&amp;rsquo;s primitives, built them on AVX2, and measured what actually survives the translation — and what doesn&amp;rsquo;t.&lt;/em&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Integer Multiplication Below n log n: Mining the Constants, and Why the Real Saving Is Cubic</title>
      <link>https://locals.tf/blog/vibecode/2026.10.11-integer-multiplication-below-nlogn/</link>
      <pubDate>Sun, 11 Oct 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.10.11-integer-multiplication-below-nlogn/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Integer Multiplication Below &lt;code&gt;n log n&lt;/code&gt;: Mining the Constants, and Why the Real Saving Is Cubic&#xA;    &lt;div id=&#34;integer-multiplication-below-n-log-n-mining-the-constants-and-why-the-real-saving-is-cubic&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#integer-multiplication-below-n-log-n-mining-the-constants-and-why-the-real-saving-is-cubic&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;OpenAI&amp;rsquo;s October 2026 mathematics release contains a proof that two n-bit integers can be multiplied below n log n on a fixed-tape Turing machine. The proof works, but its constants are so conservative that roughly 2^62 of the improvement is lying on the table for free. Pulling the paper apart, the interesting story is that the final exponent is a &lt;strong&gt;product&lt;/strong&gt; of three coupled slacks, and the one number that actually controls everything — the rank deficit of a finite linear network — is only ~1.5×10⁻¹¹. It gets cubed.&lt;/em&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Recovering a Tuya Local Key Without the Cloud (and Reimplementing the App API)</title>
      <link>https://locals.tf/blog/vibecode/2026.10.03-recovering-a-tuya-local-key-without-the-cloud/</link>
      <pubDate>Sat, 03 Oct 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.10.03-recovering-a-tuya-local-key-without-the-cloud/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Recovering a Tuya Local Key Without the Cloud (and Reimplementing the App API)&#xA;    &lt;div id=&#34;recovering-a-tuya-local-key-without-the-cloud-and-reimplementing-the-app-api&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#recovering-a-tuya-local-key-without-the-cloud-and-reimplementing-the-app-api&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;I run most of my smart-home gear locally. A Tuya-based &lt;strong&gt;garden watering controller&lt;/strong&gt; sits on my LAN, exposes the usual &lt;code&gt;6668/tcp&lt;/code&gt; local protocol, and is driven from Home Assistant through the &lt;code&gt;localtuya&lt;/code&gt; custom integration. It has been rock solid for months — until one day it wasn&amp;rsquo;t:&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Centre Held: From a Silent Boot to 9.9 Gbit/s and a Safer Jumbo Path</title>
      <link>https://locals.tf/blog/vibecode/2026.09.19-the-centre-held-rss-and-jumbo/</link>
      <pubDate>Sat, 19 Sep 2026 23:59:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.09.19-the-centre-held-rss-and-jumbo/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;The Centre Held: From a Silent Boot to 9.9 Gbit/s and a Safer Jumbo Path&#xA;    &lt;div id=&#34;the-centre-held-from-a-silent-boot-to-99-gbits-and-a-safer-jumbo-path&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#the-centre-held-from-a-silent-boot-to-99-gbits-and-a-safer-jumbo-path&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;Things fall apart; the centre cannot hold;&lt;/em&gt;&#xA;&lt;em&gt;Mere anarchy is loosed upon the world,&lt;/em&gt;&#xA;— W. B. Yeats, &lt;strong&gt;The Second Coming&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;Six days ago I published the story of a hand-ported RSS series that &lt;strong&gt;built clean and then refused to boot&lt;/strong&gt; — &lt;code&gt;init_module&lt;/code&gt; called, never returned, CPU pinned, five RCU stalls, watchdog reset. I ended it mid-investigation: the hang localised (by a wave of &lt;code&gt;pr_err&lt;/code&gt; markers) to a two-line window, a false suspect (the DIM rewrite) ruled out, the next boot ready to name its sentence.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Center Cannot Hold: Porting RSS to a Router That Hangs at Boot</title>
      <link>https://locals.tf/blog/vibecode/2026.09.13-the-center-cannot-hold-rss-router-hang/</link>
      <pubDate>Sun, 13 Sep 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.09.13-the-center-cannot-hold-rss-router-hang/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;The Center Cannot Hold: Porting RSS to a Router That Hangs at Boot&#xA;    &lt;div id=&#34;the-center-cannot-hold-porting-rss-to-a-router-that-hangs-at-boot&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#the-center-cannot-hold-porting-rss-to-a-router-that-hangs-at-boot&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;Things fall apart; the centre cannot hold;&lt;/em&gt;&#xA;&lt;em&gt;Mere anarchy is loosed upon the world,&lt;/em&gt;&#xA;— W. B. Yeats, &lt;strong&gt;The Second Coming&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;This is the story of a single kernel driver, ported by hand onto a stable tree, that builds perfectly and then refuses to boot. Not a compile error, not a link error — a &lt;strong&gt;hard hang&lt;/strong&gt;, forty seconds deep in module loading, with not a single line of driver output before the machine goes catatonic. And the fix wasn&amp;rsquo;t where I first looked.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Defeating AWS WAF Challenges in Pure Node.js (No Browser)</title>
      <link>https://locals.tf/blog/vibecode/2026.08.24-defeating-aws-waf-challenges-in-pure-node/</link>
      <pubDate>Mon, 24 Aug 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.08.24-defeating-aws-waf-challenges-in-pure-node/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Defeating AWS WAF Challenges in Pure Node.js (No Browser)&#xA;    &lt;div id=&#34;defeating-aws-waf-challenges-in-pure-nodejs-no-browser&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#defeating-aws-waf-challenges-in-pure-nodejs-no-browser&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;I have a small CLI called &lt;code&gt;goodread&lt;/code&gt; that tracks my reading progress on Goodreads: &lt;code&gt;./goodread set pendulum 81&lt;/code&gt; matches a currently-reading book by title fragment and POSTs a new percentage to one of Goodreads&amp;rsquo; private web endpoints, authenticated with a cookie string copied out of my browser. It worked for months.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>HA Not Supported: Rebuilding a Bitbucket DC Migration Export from REST Alone</title>
      <link>https://locals.tf/blog/vibecode/2026.08.20-hans-rebuilding-bitbucket-dc-export-from-rest-alone/</link>
      <pubDate>Thu, 20 Aug 2026 20:38:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.08.20-hans-rebuilding-bitbucket-dc-export-from-rest-alone/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;The admins on a production Bitbucket Data Center said &lt;strong&gt;&amp;ldquo;HA is not supported, so we can&amp;rsquo;t run the official migration export.&amp;rdquo;&lt;/strong&gt; That refusal was the entire motivation for &lt;code&gt;hans&lt;/code&gt;: a tool that reconstructs a &lt;strong&gt;valid&lt;/strong&gt; &lt;code&gt;Bitbucket_export_&amp;lt;jobId&amp;gt;.tar&lt;/code&gt; using &lt;strong&gt;only read-only REST API access and git mirror clones&lt;/strong&gt; — no admin privileges — such that GitHub Enterprise Importer (&lt;code&gt;gh bbs2gh migrate-repo --archive-path&lt;/code&gt;) accepts it. Correctness wasn&amp;rsquo;t assumed: every format claim was reverse-engineered from a &lt;strong&gt;real admin export&lt;/strong&gt; of a scripted &amp;ldquo;golden&amp;rdquo; repo, then gated four ways. Along the way we hit (and solved) a licensing hellscape, an activity-schema mismatch, a 35-minute git-object unpack, a 100x Rust rewrite, a &lt;code&gt;KeyError: &#39;commit&#39;&lt;/code&gt; crash on a real 10,031-PR repo caused by &lt;strong&gt;stacked PRs&lt;/strong&gt;. &lt;strong&gt;Final state: all gates PASS, git SHAs migrated byte-identical, and the tool produced a 30,105-entry archive for a real 10K-PR production repo.&lt;/strong&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>A Clock 4 Minutes Behind: Rolling NTP Time Sync Across the Home LAN</title>
      <link>https://locals.tf/blog/vibecode/2026.08.20-a-clock-4-minutes-behind-chrony-on-the-lan/</link>
      <pubDate>Thu, 20 Aug 2026 20:15:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.08.20-a-clock-4-minutes-behind-chrony-on-the-lan/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;A headless Debian box was &lt;strong&gt;~4 minutes behind real time&lt;/strong&gt;, and nothing on it was syncing — no NTP, no chrony, no &lt;code&gt;systemd-timesyncd&lt;/code&gt;. The obvious fix was just to turn one of them on, but that opened a bigger question: with a LAN full of Debian boxes, why not have &lt;em&gt;one&lt;/em&gt; accurate box serve time to the rest? I installed &lt;strong&gt;chrony&lt;/strong&gt; on the server (&lt;code&gt;changwang&lt;/code&gt;, 10.222.1.22), configured it to serve the &lt;code&gt;10.222.1.0/24&lt;/code&gt; LAN, then installed chrony as a &lt;strong&gt;client&lt;/strong&gt; on two other machines (precision and odroid at 10.222.1.40), pointing them at changwang and disabling their old &lt;code&gt;systemd-timesyncd&lt;/code&gt;. All three now sync from changwang, which itself syncs from the NTP pool. The clock is back to &lt;strong&gt;~1 ms of real time&lt;/strong&gt; instead of 4 minutes off.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The SSH Reset That Wasn&amp;#39;t the ISP: A Router Flowtable Ghost Story</title>
      <link>https://locals.tf/blog/vibecode/2026.08.17-the-ssh-reset-that-wasnt-the-isp/</link>
      <pubDate>Mon, 17 Aug 2026 21:20:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.08.17-the-ssh-reset-that-wasnt-the-isp/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Every SSH handshake from a LAN host through my OpenWrt router died the moment the key exchange began — GitHub, GitLab, legacy kex algorithms, even SSH-over-443. Plain TCP to port 22 connected fine and HTTPS worked perfectly. Packet captures initially screamed &amp;ldquo;ISP deep-packet-inspection is forging RSTs.&amp;rdquo; Adding &lt;strong&gt;MAC-address capture&lt;/strong&gt; flipped the diagnosis: the killer RST carried the router&amp;rsquo;s &lt;em&gt;own&lt;/em&gt; WAN MAC address, meaning &lt;strong&gt;the router generated it itself&lt;/strong&gt;. The culprit was the vendor&amp;rsquo;s &lt;strong&gt;software nftables flowtable&lt;/strong&gt; (&lt;code&gt;flow add @f&lt;/code&gt; in the &lt;code&gt;forward&lt;/code&gt; hook), which offloaded NAT&amp;rsquo;d SSH flows and then lost their state mid-KEX, causing the kernel to answer GitHub&amp;rsquo;s final key-exchange packet with an RFC-793 reset — as if nothing was listening on &lt;code&gt;:57700&lt;/code&gt;. The router&amp;rsquo;s &lt;em&gt;own&lt;/em&gt; SSH always worked because it never crosses the &lt;code&gt;forward&lt;/code&gt; path. Removing the flowtable offload fixed it instantly, 3-for-3.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Roswell, Majestic-12, and the Transistor: A Skeptic Deep Dive into Reverse Engineering Theory</title>
      <link>https://locals.tf/blog/vibecode/2026.08.16-roswell-and-the-transistor/</link>
      <pubDate>Sun, 16 Aug 2026 15:45:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.08.16-roswell-and-the-transistor/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;If a crashed UFO were genuinely recovered in July 1947 — per the Majestic-12 legend — and reverse-engineered, could its technology explain the transistor&amp;rsquo;s December 1947 breakthrough? The timeline &lt;em&gt;does&lt;/em&gt; overlap. But the transistor has a complete, continuous, and dated documentary lineage that independently explains its timing — and more importantly, the transistor is the &lt;em&gt;wrong kind of technology&lt;/em&gt; to trace to a crash. This post walks through the full timeline, the evidence, and the epistemological lessons.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Chasing a Laggy MX Master 3 on a Passively Cooled ODROID-H2</title>
      <link>https://locals.tf/blog/vibecode/2026.08.16-mx-master-3-lag-odroid-h2-diagnosis/</link>
      <pubDate>Sun, 16 Aug 2026 15:35:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.08.16-mx-master-3-lag-odroid-h2-diagnosis/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;My Logitech MX Master 3 felt laggy on a passively cooled ODROID-H2 running KDE Plasma on Wayland. A layer-by-layer diagnosis over SSH ruled out the mouse, the receiver, and the whole USB path; the input stream was rock solid at 125 Hz. The culprits turned out to be &lt;strong&gt;transient 2.4 GHz RF interference from a flaky Bluetooth radio&lt;/strong&gt; (fixed) and &lt;strong&gt;compositor latency on a very weak Intel UHD 600 iGPU&lt;/strong&gt; (mitigated). Then I went shopping for a Noctua fan and found that picking one for this board is an adventure in 5V headers and 1.25mm pitch connectors.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Progress Request That Never Arrived: Debugging a Ghost in the Kubernetes Watch Pipeline</title>
      <link>https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/</link>
      <pubDate>Mon, 06 Jul 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;The Progress Request That Never Arrived&#xA;    &lt;div id=&#34;the-progress-request-that-never-arrived&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#the-progress-request-that-never-arrived&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;How two silent bugs in a Rust etcd-compatible KV store caused thousands of errors per&#xA;minute in a near-idle k3s cluster — and the 14-hour investigation that found them.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Table of Contents&#xA;    &lt;div id=&#34;table-of-contents&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#table-of-contents&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#background-the-idle-cluster-that-wasnt&#34; &gt;Background: The Idle Cluster That Wasn&amp;rsquo;t&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#bug-0-the-zfs-eviction-spam&#34; &gt;Bug 0: The ZFS Eviction Spam&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#the-real-problem-error-getting-keys&#34; &gt;The Real Problem: &amp;ldquo;Error Getting Keys&amp;rdquo;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#bug-1-the-version-that-didnt-count&#34; &gt;Bug 1: The Version That Didn&amp;rsquo;t Count&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#bug-2-the-watch-id-that-went-nowhere&#34; &gt;Bug 2: The Watch ID That Went Nowhere&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#how-the-pipeline-actually-works&#34; &gt;How The Pipeline Actually Works&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#the-fix&#34; &gt;The Fix&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.07.06-the-progress-request-that-never-arrived/#key-lessons&#34; &gt;Key Lessons&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Background: The Idle Cluster That Wasn&amp;rsquo;t&#xA;    &lt;div id=&#34;background-the-idle-cluster-that-wasnt&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#background-the-idle-cluster-that-wasnt&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;A 30-pod k3s cluster running on Kudurru — a purpose-built etcd v3 gRPC server in Rust — was consuming &lt;strong&gt;~35% of a CPU core&lt;/strong&gt; on the control-plane node. For context, the previous kine+SQLite stack used 17% of a core, and Kudurru alone uses 0.10%. Something was very wrong.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Optimizing a Rust etcd KV Store: From 61% Overhead to 3% CPU in ~2 Weeks</title>
      <link>https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/</link>
      <pubDate>Thu, 25 Jun 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Optimizing a Rust etcd KV Store: From 61% Overhead to 3% CPU in ~2 Weeks&#xA;    &lt;div id=&#34;optimizing-a-rust-etcd-kv-store-from-61-overhead-to-3-cpu-in-2-weeks&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#optimizing-a-rust-etcd-kv-store-from-61-overhead-to-3-cpu-in-2-weeks&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;The full journey of replacing the k3s kine+SQLite storage stack with a purpose-built Rust etcd v3 gRPC server and systematically eliminating every category of waste until 83% overhead turned into 97% useful work.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Table of Contents&#xA;    &lt;div id=&#34;table-of-contents&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#table-of-contents&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#background-the-problem-with-kine&#34; &gt;Background: The Problem with kine&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#architecture-what-kudurru-is&#34; &gt;Architecture: What Kudurru Is&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#the-starting-point-61-infrastructure-overhead&#34; &gt;The Starting Point: 61% Infrastructure Overhead&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#phase-1-eliminate-the-sql-tax&#34; &gt;Phase 1: Eliminate the SQL Tax&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#phase-2-reduce-lock-contention&#34; &gt;Phase 2: Reduce Lock Contention&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#phase-3-eliminate-allocations&#34; &gt;Phase 3: Eliminate Allocations&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#phase-4-eliminate-polling&#34; &gt;Phase 4: Eliminate Polling&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#phase-5-reduce-serialization-zero-copy-grpc&#34; &gt;Phase 5: Reduce Serialization (Zero-Copy gRPC)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#phase-6-stop-doing-on-work&#34; &gt;Phase 6: Stop Doing O(n) Work&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#phase-7-production-learnings&#34; &gt;Phase 7: Production Learnings&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#final-results&#34; &gt;Final Results&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.06.25-optimizing-a-rust-etcd-kv-store/#key-lessons&#34; &gt;Key Lessons&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Background: The Problem with kine&#xA;    &lt;div id=&#34;background-the-problem-with-kine&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#background-the-problem-with-kine&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;k3s uses &lt;strong&gt;kine&lt;/strong&gt; as an etcd-to-SQL abstraction layer. By default, kine backs into SQLite — a full ACID SQL database — to store what is fundamentally an append-only key-value log. For a 30-pod cluster writing ~2.4 operations per second (mostly lease heartbeats), this stack consumes &lt;strong&gt;17% of a CPU core&lt;/strong&gt; on the control-plane node.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Fixing Kubelet Eviction Log Spam on ZFS: A Better Patch for containerfs.inodesFree</title>
      <link>https://locals.tf/blog/vibecode/2026.06.10-fixing-kubelet-eviction-log-spam-on-zfs/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.06.10-fixing-kubelet-eviction-log-spam-on-zfs/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Fixing Kubelet Eviction Log Spam on ZFS: A Better Patch for containerfs.inodesFree&#xA;    &lt;div id=&#34;fixing-kubelet-eviction-log-spam-on-zfs-a-better-patch-for-containerfsinodesfree&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#fixing-kubelet-eviction-log-spam-on-zfs-a-better-patch-for-containerfsinodesfree&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;Diagnosing a kubelet eviction manager that logs &amp;ldquo;no observation found for eviction signal containerfs.inodesFree&amp;rdquo; every 10 seconds on ZFS-backed container filesystems, finding upstream PRs that don&amp;rsquo;t fully solve it, designing a better two-part patch, and applying it to a live K3s cluster — cutting CPU from 35% to 11%.&lt;/em&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Optimizing a Java SIMD IPv6 Parser: From 7 M/s to 118 M/s in 17 Iterations</title>
      <link>https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Optimizing a Java SIMD IPv6 Parser: From 7 M/s to 118 M/s in 17 Iterations&#xA;    &lt;div id=&#34;optimizing-a-java-simd-ipv6-parser-from-7-ms-to-118-ms-in-17-iterations&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#optimizing-a-java-simd-ipv6-parser-from-7-ms-to-118-ms-in-17-iterations&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;em&gt;The full journey of porting Daniel Lemire&amp;rsquo;s hand-tuned C AVX-512 IPv6 parser to Java&amp;rsquo;s Vector API and systematically optimizing it through 17 iterations until it exceeded the C version&amp;rsquo;s throughput by 66%.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Table of Contents&#xA;    &lt;div id=&#34;table-of-contents&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#table-of-contents&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#background-what-were-parsing&#34; &gt;Background: What We&amp;rsquo;re Parsing&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#the-goal&#34; &gt;The Goal&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#the-starting-point-baseline-implementation&#34; &gt;The Starting Point: Baseline Implementation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#the-c-baseline-vs-javas-starting-performance&#34; &gt;The C Baseline vs Java&amp;rsquo;s Starting Performance&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-1-static-broadcast-constants--eliminate-arraycopy&#34; &gt;Iteration 1: Static Broadcast Constants + Eliminate arraycopy&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-2-eliminate-the-bit-scan-validation-loop&#34; &gt;Iteration 2: Eliminate the Bit-Scan Validation Loop&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-3-lut-based-hex-conversion-via-vpermb&#34; &gt;Iteration 3: LUT-Based Hex Conversion via vpermb&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-4-inline-long-extraction-for-hex-nibbles&#34; &gt;Iteration 4: Inline Long Extraction for Hex Nibbles&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-5-split-assembly-into-hotcold-paths&#34; &gt;Iteration 5: Split Assembly into Hot/Cold Paths&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-6-eliminate-segstartsegend-arrays&#34; &gt;Iteration 6: Eliminate segStart/segEnd Arrays&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-7-compresspair-vector-assembly&#34; &gt;Iteration 7: Compress+Pair Vector Assembly&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-8-three-quick-wins&#34; &gt;Iteration 8: Three Quick Wins&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-9-defer-colon-position-extraction&#34; &gt;Iteration 9: Defer Colon Position Extraction&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-10-vectorce-compresspair-fast-path&#34; &gt;Iteration 10: VectorCE Compress+Pair Fast Path&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-11-vectorce-intermediate-assembly-optimization&#34; &gt;Iteration 11: VectorCE Intermediate Assembly Optimization&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-12-reuse-the-validation-mask-for-compress&#34; &gt;Iteration 12: Reuse the Validation Mask for Compress&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-13-fix--pad-expansion-in-computeexpandmask&#34; &gt;Iteration 13: Fix :: Pad Expansion in computeExpandMask&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-14-port-5-bottleneck--short-vector-pairing&#34; &gt;Iteration 14: Port-5 Bottleneck — Short-Vector Pairing&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-15-the-breakthrough--merge--precompute--skip&#34; &gt;Iteration 15: The Breakthrough — Merge + Precompute + Skip&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-16-precomputed-compress-and-pair-masks&#34; &gt;Iteration 16: Precomputed Compress and Pair Masks&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#iteration-17-arithmetic-hex-conversion-no-vpermb&#34; &gt;Iteration 17: Arithmetic Hex Conversion (No vpermb)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#final-results&#34; &gt;Final Results&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://locals.tf/blog/vibecode/2026.05.31-optimizing-a-java-simd-ipv6-parser/#key-lessons&#34; &gt;Key Lessons&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Background: What We&amp;rsquo;re Parsing&#xA;    &lt;div id=&#34;background-what-were-parsing&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#background-what-were-parsing&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;An IPv6 address is a 128-bit number typically written as eight groups of four hexadecimal digits separated by colons:&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Debugging xrdp Session Sharing: Buffer Overflows, Double Frees, and State Machine Nightmares</title>
      <link>https://locals.tf/blog/vibecode/2026.04.03-xrdp.shadowing.fixes/</link>
      <pubDate>Fri, 03 Apr 2026 02:00:00 +0300</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.04.03-xrdp.shadowing.fixes/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Debugging xrdp Session Sharing: A Tale of Buffer Overflows, Double Frees, and State Machine Nightmares&#xA;    &lt;div id=&#34;debugging-xrdp-session-sharing-a-tale-of-buffer-overflows-double-frees-and-state-machine-nightmares&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#debugging-xrdp-session-sharing-a-tale-of-buffer-overflows-double-frees-and-state-machine-nightmares&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;We implemented session sharing (shadowing) in xrdp — allowing multiple RDP clients to connect to the same desktop session with independent cursors and input routing. The feature required fixes across &lt;strong&gt;three layers&lt;/strong&gt;: the xorgxrdp X driver (per-client MPX input dispatch), the sesman session manager (don&amp;rsquo;t kill existing clients when new ones join), and the xrdp window manager (non-terminal state to keep RDP connections alive). Along the way we fixed a 128-byte buffer overflow, a double-free from packed struct allocations, a state machine that re-processed its own state, and a UI that wouldn&amp;rsquo;t paint or respond to clicks. Core dumps and &lt;code&gt;gdb&lt;/code&gt; inside a privileged container were essential for cracking the hardest bugs.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Cracking irssi fish with SHA256-NI</title>
      <link>https://locals.tf/blog/vibecode/2026.03.28-cracking-irssi-fish-with-sha256-ni/</link>
      <pubDate>Sat, 28 Mar 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.28-cracking-irssi-fish-with-sha256-ni/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Debugging SHA256-NI: A Deep Dive into Endianness and Intel Hardware Acceleration&#xA;    &lt;div id=&#34;debugging-sha256-ni-a-deep-dive-into-endianness-and-intel-hardware-acceleration&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#debugging-sha256-ni-a-deep-dive-into-endianness-and-intel-hardware-acceleration&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;This blog post documents an intense debugging session to fix a SHA256-NI (Intel SHA Extensions) implementation in a FiSH encryption module for the Irssi IRC client. The goal was to create a high-performance password cracker for the FiSH encryption protocol used in Irssi, which requires 71,624 SHA256 iterations per password attempt. After discovering that OpenSSL was way too slow, we dove deep into Intel&amp;rsquo;s hardware-accelerated SHA256 intrinsics—only to hit a subtle endianness bug that took minutes to track down.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Building a Standalone Chart Fetching Script with Exchange Fallback</title>
      <link>https://locals.tf/blog/vibecode/2026.03.21-building-a-standalone-chart-fetching-script-with-exchange-fallback/</link>
      <pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.21-building-a-standalone-chart-fetching-script-with-exchange-fallback/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;TLDR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Extracted chart image fetching from the main trading-to-blog script into a standalone &lt;code&gt;fetch-charts.sh&lt;/code&gt; script&lt;/li&gt;&#xA;&lt;li&gt;The script reads chart requests from &lt;code&gt;debug.json&lt;/code&gt; (generated by the main script) and fetches chart images via the chart-img API&lt;/li&gt;&#xA;&lt;li&gt;Added intelligent exchange fallback: when an exchange returns 422 Invalid Symbol, the script tries alternative exchanges (NASDAQ → NYSE → AMEX for stocks, BINANCE → COINBASE → etc for crypto)&lt;/li&gt;&#xA;&lt;li&gt;chart-img provides API v3 endpoints (&lt;code&gt;/v3/tradingview/exchange/list&lt;/code&gt; and &lt;code&gt;/v3/tradingview/exchange/&amp;lt;EXCHANGE_ID&amp;gt;&lt;/code&gt;) to look up valid symbols&lt;/li&gt;&#xA;&lt;li&gt;The root cause was AI model hallucinations - the LLM sometimes outputs the wrong exchange (e.g., NASDAQ instead of NYSE) for common stocks&lt;/li&gt;&#xA;&lt;li&gt;Later eliminated duplication by invoking &lt;code&gt;fetch-charts.sh&lt;/code&gt; as a subprocess with a FIFO and fd 3 to separate chart markdown output from log output&lt;/li&gt;&#xA;&lt;li&gt;Added &lt;code&gt;--skip-image-processing&lt;/code&gt; and &lt;code&gt;--use-existing-post&lt;/code&gt; flags to the parent script to iterate on chart fetching without re-running expensive image processing or model calls&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;This post documents a VibeCode session where I built a standalone script to fetch TradingView charts from previously generated debug data. The journey involved extracting code from an existing script, handling API errors gracefully, and implementing intelligent exchange fallback for invalid symbols.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Thin Blue Lines</title>
      <link>https://locals.tf/blog/vibecode/2026.03.15-thin-blue-lines/</link>
      <pubDate>Sun, 15 Mar 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.15-thin-blue-lines/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;From VibeCode to Production: Building an LLM-Driven Trading Blog with Automated Chart Integration&#xA;    &lt;div id=&#34;from-vibecode-to-production-building-an-llm-driven-trading-blog-with-automated-chart-integration&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#from-vibecode-to-production-building-an-llm-driven-trading-blog-with-automated-chart-integration&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;In this comprehensive guide, I&amp;rsquo;ll walk you through how we transformed a basic trading blog automation script into a sophisticated system that uses Large Language Models to dynamically generate chart requests, fetch TradingView screenshots via the Chart-IMG API, and embed them directly into Hugo-compatible blog posts. This session represents a fascinating exploration of how AI can drive not just content generation but also the tool-calling patterns needed to fetch external resources in real-time.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>XRdp sound support</title>
      <link>https://locals.tf/blog/vibecode/2026.03.08-xrdp-sound-support/</link>
      <pubDate>Mon, 09 Mar 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.08-xrdp-sound-support/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Sound Support in xrdp Docker via PipeWire: A Comprehensive Implementation Guide&#xA;    &lt;div id=&#34;sound-support-in-xrdp-docker-via-pipewire-a-comprehensive-implementation-guide&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#sound-support-in-xrdp-docker-via-pipewire-a-comprehensive-implementation-guide&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;This blog post documents a complete implementation of audio sound support in an xrdp Docker container using PipeWire. The session covers everything from initial investigation through successful implementation, including troubleshooting, multiple iterations, and final refactoring for maintainability. Whether you&amp;rsquo;re running xrdp in Docker for remote desktop access or building a headless Linux desktop environment, this guide provides detailed instructions for enabling audio redirection to your RDP client.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>XRDP in k8s</title>
      <link>https://locals.tf/blog/vibecode/2026.03.08-xrdp-in-k8s/</link>
      <pubDate>Sun, 08 Mar 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.08-xrdp-in-k8s/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Running xrdp with GPU Acceleration in Kubernetes: A Complete Troubleshooting Guide&#xA;    &lt;div id=&#34;running-xrdp-with-gpu-acceleration-in-kubernetes-a-complete-troubleshooting-guide&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#running-xrdp-with-gpu-acceleration-in-kubernetes-a-complete-troubleshooting-guide&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;In this blog post, I&amp;rsquo;ll walk you through the complete journey of deploying xrdp (Remote Desktop Protocol server) in a Kubernetes environment with GPU acceleration. What seemed like a straightforward deployment turned into a multi-hour troubleshooting session covering storage classes, volume mounting issues, container security contexts, and resource allocation.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>From Virtual to Virtualized: Enabling GPU Hardware Acceleration in containerd/xrdp Containers</title>
      <link>https://locals.tf/blog/vibecode/2026.03.02-hardware-accelerating-xrdp-in-docker/</link>
      <pubDate>Mon, 02 Mar 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.02-hardware-accelerating-xrdp-in-docker/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;From Virtual to Virtualized: Enabling GPU Hardware Acceleration in containerd/xrdp Containers&#xA;    &lt;div id=&#34;from-virtual-to-virtualized-enabling-gpu-hardware-acceleration-in-containerdxrdp-containers&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#from-virtual-to-virtualized-enabling-gpu-hardware-acceleration-in-containerdxrdp-containers&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;In this comprehensive guide, I&amp;rsquo;ll walk you through the complete process of adding GPU passthrough to a containerd container using nerdctl while preserving state, configuring xrdp for hardware-accelerated graphics, and baking everything into a reproducible Dockerfile.&lt;/p&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Commit the container&lt;/strong&gt; to save state to an image, then recreate with GPU devices&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Pass both&lt;/strong&gt; &lt;code&gt;/dev/dri/card0&lt;/code&gt; and &lt;code&gt;/dev/dri/renderD128&lt;/code&gt; to the container&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Configure xorg.conf&lt;/strong&gt; with &lt;code&gt;DRMDevice&lt;/code&gt;, &lt;code&gt;DRI3&lt;/code&gt;, and &lt;code&gt;DRMAllowList&lt;/code&gt; options&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Add user to video and render groups&lt;/strong&gt; for device access&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Hardware acceleration confirmed&lt;/strong&gt;: ~12,000 FPS with glxgears (vs ~60 FPS with llvmpipe)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Understanding the Starting Point&#xA;    &lt;div id=&#34;understanding-the-starting-point&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#understanding-the-starting-point&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The user had a running containerd container (ID: &lt;code&gt;6d5b3c01f38a&lt;/code&gt;) built from &lt;code&gt;locals.tf/xrdp:latest&lt;/code&gt;. This container was running xrdp for remote desktop access and needed GPU passthrough for hardware acceleration.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Reverse Engineering the Fictional Product Licensing System: A Comprehensive Journey</title>
      <link>https://locals.tf/blog/vibecode/2026.03.01-fictional-product-licensing-system-reverse-engineering/</link>
      <pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.01-fictional-product-licensing-system-reverse-engineering/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Reverse Engineering the Fictional Product Licensing System: A Comprehensive Journey&#xA;    &lt;div id=&#34;reverse-engineering-the-fictional-product-licensing-system-a-comprehensive-journey&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#reverse-engineering-the-fictional-product-licensing-system-a-comprehensive-journey&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;In this comprehensive blog post, I document my extensive reverse engineering journey into the Fictional Product licensing system. What began as a curiosity about how commercial software licensing works evolved into a multi-week deep dive into cryptographic primitives, binary analysis, and the intricate architecture of modern license validation systems. This project ultimately resulted in a complete understanding of the license file format, cryptographic pipeline, and the successful generation of valid license files for all four Fictional Product components.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Investigating k3s CPU usage spikes in an idle K8S cluster</title>
      <link>https://locals.tf/blog/vibecode/2026.03.01-investigating-k3s-cpu-usage-spikes-in-an-idle-k8s-cluster/</link>
      <pubDate>Sun, 01 Mar 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.03.01-investigating-k3s-cpu-usage-spikes-in-an-idle-k8s-cluster/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Troubleshooting K3s CPU Spikes: A Deep Dive into Stuck Reflectors&#xA;    &lt;div id=&#34;troubleshooting-k3s-cpu-spikes-a-deep-dive-into-stuck-reflectors&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#troubleshooting-k3s-cpu-spikes-a-deep-dive-into-stuck-reflectors&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Root Cause:&lt;/strong&gt; Stuck Kubernetes reflector trying to watch a non-existent resource, causing ~160 failed watch attempts per hour&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Key Finding:&lt;/strong&gt; Fleet controller was the culprit, repeatedly retrying failed API watch requests&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Full k3s restart cleared the stuck reflectors&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Result:&lt;/strong&gt; CPU usage dropped from 10-25% to ~9% (with full restart achieving 0% idle)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Tools Used:&lt;/strong&gt; journalctl, kubectl, strace, curl with k3s certificates, tcpdump&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Kubernetes control plane performance issues can be notoriously difficult to diagnose, especially when the symptoms manifest as elevated CPU usage without clear error messages. In this article, I&amp;rsquo;ll walk through a comprehensive debugging session where we investigated a K3s cluster experiencing persistent CPU spikes. We&amp;rsquo;ll examine the investigation techniques, the root cause identification, and the ultimate resolution.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Extending GhidraMCP with Debugging Capabilities: A Developer&#39;s Journey</title>
      <link>https://locals.tf/blog/vibecode/2026.02.28.ghidra-mcp-server-development/</link>
      <pubDate>Sat, 28 Feb 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.02.28.ghidra-mcp-server-development/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Extending GhidraMCP with Debugging Capabilities: A Developer&amp;rsquo;s Journey&#xA;    &lt;div id=&#34;extending-ghidramcp-with-debugging-capabilities-a-developers-journey&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#extending-ghidramcp-with-debugging-capabilities-a-developers-journey&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The GhidraMCP project started as a tool to expose Ghidra&amp;rsquo;s static analysis capabilities—decompilation, function renaming, cross-references—via the Model Context Protocol (MCP). But reverse engineering often requires dynamic analysis, and we needed the MCP server to work seamlessly with Ghidra&amp;rsquo;s debugger as well.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Docker with xrdp &amp; lxqt</title>
      <link>https://locals.tf/blog/vibecode/2026.02.24-docker-with-xrdp--lxqt/</link>
      <pubDate>Tue, 24 Feb 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.02.24-docker-with-xrdp--lxqt/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Debugging and Enhancing a Docker-Based XRDP Desktop Environment: A VibeCode Session&#xA;    &lt;div id=&#34;debugging-and-enhancing-a-docker-based-xrdp-desktop-environment-a-vibecode-session&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#debugging-and-enhancing-a-docker-based-xrdp-desktop-environment-a-vibecode-session&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;In this blog post, I&amp;rsquo;m documenting a comprehensive troubleshooting and enhancement session with a Docker-based XRDP desktop environment running LXQt on Debian. The session covered fixing missing icons after login, configuring terminal applications with custom fonts, setting up the Fish shell, and optimizing the Docker build process for faster rebuilds. This was a &amp;ldquo;VibeCode&amp;rdquo; session—a real-time debugging and development workflow that demonstrates practical solutions to common Linux desktop containerization challenges.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>K8sizing homeassistant &amp; Zigbee2MQTT</title>
      <link>https://locals.tf/blog/vibecode/2026.02.23-k8sizing-homeassistant--zigbee2mqtt/</link>
      <pubDate>Mon, 23 Feb 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.02.23-k8sizing-homeassistant--zigbee2mqtt/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;From Containerd to Kubernetes: Migrating Home Assistant, Mosquitto, and Zigbee2MQTT&#xA;    &lt;div id=&#34;from-containerd-to-kubernetes-migrating-home-assistant-mosquitto-and-zigbee2mqtt&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#from-containerd-to-kubernetes-migrating-home-assistant-mosquitto-and-zigbee2mqtt&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;In this comprehensive guide, I&amp;rsquo;ll walk you through the process of migrating standalone containers running in containerd (managed via nerdctl) to Kubernetes. This session covers discovering non-Kubernetesized containers, creating Kubernetes manifests that preserve volumes and configurations, troubleshooting deployment issues, and successfully running IoT services in a Kubernetes cluster.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Blog Automation Setup with OpenCode</title>
      <link>https://locals.tf/blog/vibecode/2026.02.22-blog-automation/</link>
      <pubDate>Sun, 22 Feb 2026 01:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.02.22-blog-automation/</guid>
      <description>&lt;h2 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Built a self-hosted Hugo blog at &lt;code&gt;locals.tf/blog&lt;/code&gt; with automated workflows for:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Converting OpenCode session transcripts into polished blog posts using AI&lt;/li&gt;&#xA;&lt;li&gt;Parsing trading screenshots (IBKR/Binance) into weekly analysis posts&lt;/li&gt;&#xA;&lt;li&gt;Free API integration (Google Gemini or Groq) for AI processing&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;This OpenCode session focused on setting up a blog publishing system for two distinct content types: technical posts from our collaboration sessions and weekly trading analysis. The goal was to minimize ongoing maintenance while making post creation as effortless as possible.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Automating Blog Posts from VibeCode Sessions with OpenCode-s Free AI API</title>
      <link>https://locals.tf/blog/vibecode/2026.02.22-automated-blog-posts-from-opencode-sessions/</link>
      <pubDate>Sun, 22 Feb 2026 00:00:00 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.02.22-automated-blog-posts-from-opencode-sessions/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;Automating Blog Posts from VibeCode Sessions with OpenCode&amp;rsquo;s Free AI API&#xA;    &lt;div id=&#34;automating-blog-posts-from-vibecode-sessions-with-opencodes-free-ai-api&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#automating-blog-posts-from-vibecode-sessions-with-opencodes-free-ai-api&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;OpenCode&amp;rsquo;s Zen API at &lt;code&gt;opencode.ai/zen/v1/chat/completions&lt;/code&gt; provides free access to models like &lt;code&gt;big-pickle&lt;/code&gt; using the &amp;ldquo;public&amp;rdquo; API key&lt;/li&gt;&#xA;&lt;li&gt;The key discovery was that passing &lt;code&gt;max_tokens&lt;/code&gt; causes models to output to the &lt;code&gt;reasoning&lt;/code&gt; field instead of &lt;code&gt;content&lt;/code&gt; — removing this parameter fixes the issue&lt;/li&gt;&#xA;&lt;li&gt;Use &lt;code&gt;jq --rawfile&lt;/code&gt; for passing large files to the API (not &lt;code&gt;--slurpfile&lt;/code&gt; which expects JSON format)&lt;/li&gt;&#xA;&lt;li&gt;The opencode-cli works without an API key because it uses &lt;code&gt;apiKey: &amp;quot;public&amp;quot;&lt;/code&gt; which the server accepts for free models with &lt;code&gt;allowAnonymous: true&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;Introduction&#xA;    &lt;div id=&#34;introduction&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#introduction&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;In this session, I worked on automating the conversion of VibeCode session transcripts into blog posts using OpenCode&amp;rsquo;s free AI API. The journey involved discovering how the opencode-cli authenticates without requiring an API key, debugging API request format issues, and ultimately creating a working bash script that transforms raw transcripts into formatted markdown blog posts.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>DollHouse PostgreSQL Optimization</title>
      <link>https://locals.tf/blog/vibecode/2026.01.17-dollhouse-postgres-optimization/</link>
      <pubDate>Sat, 17 Jan 2026 18:34:37 +0200</pubDate>
      
      <guid>https://locals.tf/blog/vibecode/2026.01.17-dollhouse-postgres-optimization/</guid>
      <description>&lt;h1 class=&#34;relative group&#34;&gt;TL;DR&#xA;    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Moved application logic from Python loops to PostgreSQL functions/views, achieving &lt;strong&gt;50-80% runtime reduction&lt;/strong&gt; by eliminating the N+1 query pattern.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;The Problem&#xA;    &lt;div id=&#34;the-problem&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#the-problem&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The DollHouse application monitors torrent feeds and downloads TV releases matching a wishlist. The core &lt;code&gt;find_releases()&lt;/code&gt; method had a classic &lt;strong&gt;N+1 query problem&lt;/strong&gt;:&lt;/p&gt;</description>
      
    </item>
    
  </channel>
</rss>
