Advertise with Googlier.com blog.lmorchard.com It's all spinning wheels & self-doubt until the first pot of coffee. https://blog.lmorchard.com The Only Conscious Caretaker <p><strong>TL;DR:</strong> Dropping razor blades down a wall cavity and letting autonomous agents merge uninspected code share the same fantasy: that unobserved spaces have no consequences. Adulthood is realizing caretaking is still on you.</p> <!--more--> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/10/19/the-only-conscious-observer/./attic-sun-rays-dithered.png" alt="Sun rays streaming into a dusty wooden attic" width="" height=""> <figcaption> Photo by <a href="https://unsplash.com/@kommumikation?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Mika Baumeister</a> on <a href="https://unsplash.com/photos/sun-rays-inside-wooden-house-9TvuxGW8ut0?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a> </figcaption> </figure> <nav role="navigation" class="table-of-contents"></nav> <h2 id="hammer-in-the-ceiling-razors-in-the-wall">Hammer in the ceiling, razors in the wall</h2> <p>For most of my adult life, I've had this quiet, recurring thought: sometimes, I am the only conscious observer of a thing. There are spaces where no one goes. When I happen to be the one standing there, the burden of attention falls entirely on me. And if I don't pay attention, no one else ever will.</p> <p>Since becoming a homeowner, it usually hits me (sometimes literally) in the unglamorous corners of the house.</p> <p>A while back, I was working in the basement of a house I owned. It had one of those suspended drop ceilings—the cheap metal grid with lightweight tiles. I needed to see what was running above it. So, I reached up, pushed one of the tiles up and aside.</p> <p>Before I could react, an old 16-ounce claw hammer slid down the angled face of the tile and smacked me squarely in the ear.</p> <figure class="inset right"> <img src="https://blog.lmorchard.com/2026/10/19/the-only-conscious-observer/./claw-hammer-dithered.png" alt="A black and silver steel claw hammer resting on wood" width="" height=""> <figcaption> Photo by <a href="https://unsplash.com/@andrewjoegeorge?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Andrew George</a> on <a href="https://unsplash.com/photos/black-and-silver-claw-hammer-TuQvJ72sRaA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a> </figcaption> </figure> <p>Years earlier—who knows how many—someone had been up there running Romex or fixing a pipe, set their hammer down, and walked away. The ceiling held it. The room below looked completely fine. Everything appeared in order. The hammer just sat in the dark holding potential energy, completely forgotten, until the next conscious caretaker—i.e. me—showed up and moved the tile.</p> <p>Or how about this: ever heard of those old mid-century medicine cabinets with the razor blade disposal slot cut into the back? You’d finish shaving, slide the dull double-edge blade through the tiny stamped steel slit, and let it drop into the hollow stud bay. </p> <p>The house was built with the cheerful assumption that the space behind the wall was a bottomless void—no human would ever visit that space again, so you might as well fill the dark with decades of loose, rusty steel.</p> <p>Until someone decides to remodel the bathroom fifty years later, pulls the wall down, and gets buried in an avalanche of tetanus.</p> <h2 id="this-is-not-about-houses">This is not about houses</h2> <p>The hammer is accidental neglect; the razor slot is architectural abdication. Both rely on the fantasy that unobserved spaces don't have consequences.</p> <p>You inherit a codebase, open a utility file last touched twelve years ago, and find a terrifying, seventy-line regular expression with a comment that simply says <code>// sorry, this works, don't touch</code>. </p> <p>Someone had a deadline, solved their immediate problem, popped the ceiling tile back into place, and walked away. It sat in the dark for over a decade, quietly routing production traffic, completely unobserved—until a runtime upgrade finally dislodged it.</p> <p>But even with the dirtiest legacy hacks, there was always one comforting constant: at least <em>some</em> human doofus had perceived it. A real person sat at a desk and maybe felt that twinge of guilt while typing <code>// sorry</code>.</p> <p>Autonomous agents and modern code generation break that contract.</p> <h2 id="the-inversion-of-ceremony">The inversion of ceremony</h2> <p>Over the past 18 months, my daily workflow has changed dramatically. </p> <p>Back in June 2025, I wrote about <a href="https://blog.lmorchard.com/2025/06/07/semi-automatic-coding/">baby steps into semi-automatic coding</a>. I was figuring out the ergonomics—borrowing <a href="https://harper.blog/2025/04/10/waterfall-in-15-minutes-or-your-money-back/">Harper Reed’s idea of "waterfall in 15 minutes,"</a> writing a <code>spec.md</code>, having the LLM generate a <code>plan.md</code>, babysitting Claude Sonnet 3.7 or GPT-4.1 while it wrote functions, and capturing lessons in a <code>notes.md</code> file. It was mostly a trick to bypass ADHD executive friction on implementation grind.</p> <p>Fast forward to late 2026. Now, I regularly triage a half-dozen issues on a GitHub Projects board, set up an autonomous runner, tell it to work through the ready queue, and go to bed.</p> <p>By morning, five or six PRs are opened, CI is passing, adversarial code reviews are done, and conflicts are resolved. Nearly always, the results are ready to merge—but I haven't quite gone as far as letting the agent do that automatically yet.</p> <p>Here is the strange inversion I’ve noticed in where my time actually goes: <strong>I spend almost all my time on the things software engineering spent twenty-five years trying to elide.</strong> </p> <p>To wit: <em>process and documentation</em>.</p> <figure class="inset right"> <img src="https://blog.lmorchard.com/2026/10/19/the-only-conscious-observer/./workflow-diagram-dithered.png" alt="Workflow diagram, product brief, and user goals on paper" width="" height=""> <figcaption> Photo by <a href="https://unsplash.com/@kellysikkema?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Kelly Sikkema</a> on <a href="https://unsplash.com/photos/workflow-diagram-product-brief-and-user-goals-are-shown-wdnpaTNwOEQ?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a> </figcaption> </figure> <p>Think about the arc of Agile, Extreme Programming, and MVP startup culture. Decades spent waging a pragmatic war against "ceremony." We skimped on formal specifications because writing prose before code felt wasteful. We accepted loose types and skipped edge-case tests because that was just a drag on sprint velocity. Docs were always something you promised to write next quarter.</p> <p>Now, raw code is practically free. An agent will spit out four hundred lines of boilerplate, scaffolding, and glue in forty seconds. </p> <p>And suddenly, the "tedious" parts are the only things that matter:</p> <ul> <li><p><strong>Writing a rigorous, unambiguous specification</strong> is no longer obsolete waterfall bureaucracy—it is the steering wheel that keeps an autonomous fleet from driving into a ditch.</p> </li> <li><p><strong>Strong, invariant types</strong> aren't academic fussiness—they are the physical barriers that make illegal runtime states unrepresentable to a machine that operates purely on statistical plausibility.</p> </li> <li><p><strong>Deep behavioral tests</strong> aren't a chore you rush before demo day—they are the tripwires that catch an agent when it rationalizes away a bug with a vacuous assert.</p> </li> </ul> <p>Those things were never actually waste. <strong>They were encodings of human care.</strong> We just couldn't afford to do them justice when our hands were cramped from laying every single brick by hand. So, we mostly left them implicit.</p> <h2 id="scaling-your-care">Scaling your care</h2> <p>Agents need to be beaten about the metaphorical head &amp; shoulders with this stuff. If you leave an agent alone in a repository without constraints, it won't break things out of spite. It will simply act like the contractor who left the hammer in my ceiling: it will solve the immediate constraint in front of it and exit with code 0.</p> <p>Unless you look, nobody will. You might be the only conscious human being who ever reads that diff before it lands on main and deploys to production.</p> <p>This is where the temptation to shrug sets in. You look at a 1,500-line diff produced in three minutes, your eyes glaze over, the tests are green, and you think: <em>Well, it works. Let it ride.</em></p> <figure class="inset right"> <img src="https://blog.lmorchard.com/2026/10/19/the-only-conscious-observer/./spoons-dithered.png" alt="Vintage silver spoon and fork on a dark rustic wooden table" width="" height=""> <figcaption> Photo by <a href="https://unsplash.com/@margaret_jaszowska?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Margaret Jaszowska</a> on <a href="https://unsplash.com/photos/silver-spoon-and-fork-on-brown-wooden-table-PI7kXKdawx0?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a> </figcaption> </figure> <p>Yielding to that shrug is understandable, because you only have so many waking hours and <a href="https://en.wikipedia.org/wiki/Spoon_theory">spoons</a>. You cannot personally crawl every foot of drywall cavity, and you cannot personally scrutinize every token an agent generates.</p> <p>This is the central dilemma that <a href="https://github.com/poteto">Lauren (@poteto)</a> addressed when building <a href="https://github.com/cursor/plugins/tree/main/pstack"><code>pstack</code></a> for Cursor, particularly in the design of the <a href="https://github.com/cursor/plugins/blob/main/pstack/skills/correct/SKILL.md"><code>/correct</code> skill</a>:</p> <blockquote> <p><em>"Assume every contributor is an agent that sees only the files it opened, copies the nearest example, and takes the shortest path that compiles. Design the repo so a change that looks right from one file is right for the whole repo."</em></p> </blockquote> <p>Lauren’s answer isn't about micromanaging the agent turn by turn. Babysitting is an exhausting dead end. Instead, you use your scarce conscious care to <strong>engineer the environment</strong>:</p> <ol> <li><p><strong>Architecture &amp; Data Structures:</strong> Categorically eliminate the problem. Give each piece of state one owner, hide internals, and delete legacy patterns so bad state cannot even be copied.</p> </li> <li><p><strong>Types &amp; Linters / CI:</strong> Make illegal states unrepresentable. Make errors fail at compile time or in CI, explicitly pointing to the supported pattern.</p> </li> <li><p><strong>Behavioral Tests:</strong> Assert on actual user-visible outcomes, testing against literal values and running tests in detached worktrees to prove they fail before the fix is applied.</p> </li> <li><p><strong>Docs &amp; Prompt Rules:</strong> Text instructions are the absolute last resort, because prose blows away the moment context collapses.</p> </li> </ol> <p>Another angle on this, if you prefer video, wherein Matt Pocock talks about the importance of telling agents what you care about and fixing their environment:</p> <p><youtube-embed video-id="Z8lf5oWKfj0" thumbnail="ac7061da42d6.jpg"></youtube-embed></p> <p>This is how care scales. In a house, you don't stand in the kitchen staring at the outlets 24 hours a day; you install GFCI breakers so the circuit trips physically if current leaks into water. </p> <p>In software, you freeze your past attention into the repository's invariants so your care persists even when you're asleep. If an agent does something wrong, I don't just fix the mistake. I step back and try to figure out what rule or deterministic guard would prevent that class of mistake into the future.</p> <h2 id="who-lives-in-the-house-that-this-is-not-about">Who lives in the house (that this is not about)</h2> <p>Almost a month ago, I wrote about <a href="https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/">Pragmatic Anthropomorphism</a>, engaging with Michał Zalewski’s observation that human morality is rooted in physical imperilment—in our mortality, metabolic vulnerability, and the fact that we can be injured. An LLM—metaphorically, of course—"lives" in an indifferent netherworld without blood sugar, pain, or consequences.</p> <p>Because the machine has no skin in the game, it is structurally incapable of care. It can simulate politeness and it can emit syntactically flawless functions, but it will never feel the weight of stewardship.</p> <p>I've come to believe that the ultimate burden of adulthood is <strong>consciousness applied to caretaking</strong>. </p> <figure class="inset right"> <img src="https://blog.lmorchard.com/2026/10/19/the-only-conscious-observer/./rusty-metal-moss-dithered.png" alt="A rusty piece of metal sitting on moss-covered ground" width="" height=""> <figcaption> Photo by <a href="https://unsplash.com/@rrricharddd?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Richard Wang</a> on <a href="https://unsplash.com/photos/a-rusty-piece-of-metal-sitting-on-top-of-a-moss-covered-ground-_1tHzk3Yy4E?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a> </figcaption> </figure> <p>Nature's baseline is entropy. If you don't maintain the house, moisture and mold will reclaim it. If you don't retrieve the dropped bolt on the bike trail, the moss swallows it. And if you don't inspect the running state of your network or the architecture of your synthetic code, the ceiling hammers quietly accumulate.</p> <p>I'm an AI pragmatist—maybe an optimist, even. I use these tools every single day, and I wouldn't go back now. But using them honestly means recognizing what they are: powerful, competent, indifferent amplifiers.</p> <p>They can help us frame the walls, pull the wire, and hang the drywall faster than ever before. But they don't live in the house. We do. </p> <p>And as long as we live here, somebody still has to climb the ladder, shine a flashlight into the dark above the ceiling tiles, and make sure nothing is waiting to fall. And if you, yourself, can't manage to climb that ladder every day—and who, realistically, can?—then you need to put systems and sensors and traps in place, in order to augment and extend the influence of your caretaking.</p> Mon, 19 Oct 2026 19:00:00 GMT https://blog.lmorchard.com/2026/10/19/the-only-conscious-observer/ https://blog.lmorchard.com/2026/10/19/the-only-conscious-observer/ aicodingagentsphilosophy Making an M5 MacBook Pro Actually Feel Fast <p><em>TL;DR:</em> An Apple M5 Max can compile code and run local models at ridiculous speeds, but macOS still insists on cinematic, half-second UI animations for everyday interactions. Here are some Terminal tweaks and settings I've used to strip out the artificial lag.</p> <!--more--> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/10/09/making-an-m5-macbook-pro-actually-feel-fast/./marc-sendra-martorell-Vqn2WrfxTQ-unsplash-dithered.png" alt="Time-lapse of street lights with electric red and amber light streaks" width="" height=""> <figcaption> Photo by <a href="https://unsplash.com/@marcsm?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Marc Sendra Martorell</a> on <a href="https://unsplash.com/photos/time-lapsed-of-street-lights--Vqn2WrfxTQ?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a> </figcaption> </figure> <nav role="navigation" class="table-of-contents"></nav> <p>I recently picked up a new MacBook Pro—an M5 Max for work. By every measurable hardware metric, it is an absurdly fast machine. </p> <p>And yet, right out of the box, it often <em>felt</em> sluggish.</p> <p>Not because of compute or memory pressure, but because Apple’s interface designers are deeply in love with theater. It looks elegant in a keynote demo, but my brain feels it like a papercut. Artificial animation latency registers as system lag. If I’m on a machine with this much horsepower, I want the UI to snap when I ask for it.</p> <h2 id="all-in-one-snippet">All-in-One Snippet</h2> <p>So, here it is, for future-me and anyone else. Here is the whole batch in one shot:</p> <pre><code class="language-bash"># Remove Dock hover delay and accelerate slide defaults write com.apple.dock autohide-delay -float 0 defaults write com.apple.dock autohide-time-modifier -float 0.2 # Accelerate Mission Control defaults write com.apple.dock expose-animation-duration -float 0.1 # Restart Dock to apply killall Dock </code></pre> <p>Then, a few quick switches in <strong>System Settings</strong>:</p> <ul> <li><strong>Accessibility → Display → Reduce motion</strong>: On.</li> <li><strong>Desktop &amp; Dock → Mission Control → Group windows by application</strong>: Off.</li> <li><strong>Menu Bar → Automatically hide and show the menu bar</strong>: Never</li> </ul> <p>There's probably more I could do, but this is what I've got for now.</p> <h2 id="how-to-revert">How to Revert</h2> <p>If you decide you miss the floaty macOS elegance, you can wipe out the custom keys and restore the stock timings just as easily:</p> <pre><code class="language-bash">defaults delete com.apple.dock autohide-delay defaults delete com.apple.dock autohide-time-modifier defaults delete com.apple.dock expose-animation-duration killall Dock </code></pre> <p>And remember to revert the changes in System Settings.</p> <p>If you're curious what this stuff does, that's what the rest of the post says.</p> <h2 id="eliminate-dock-hesitation">Eliminate Dock Hesitation</h2> <p>If you auto-hide your Dock to maximize screen real estate, the default behavior includes two separate speed bumps:</p> <ol> <li><strong>The hover delay:</strong> A half-second pause before the OS starts revealing the Dock.</li> <li><strong>The slide animation:</strong> The time it takes for the Dock to glide onto the screen.</li> </ol> <p>You can drop the hover delay to zero and cut the slide duration down to a fifth of a second:</p> <pre><code class="language-bash"># Make the Dock appear instantly when hovering defaults write com.apple.dock autohide-delay -float 0 # Speed up the slide animation defaults write com.apple.dock autohide-time-modifier -float 0.2 </code></pre> <p>Once you kill the hover delay, the Dock pops up the instant your cursor hits the display edge. It immediately makes the entire machine feel snappier.</p> <h2 id="speed-up-mission-control">Speed Up Mission Control</h2> <p>Mission Control’s window-tiling animation is another place where macOS takes its time. And I might be an outlier, but I have Mission Control mapped to a trackball button and use it as my primary navigation in macOS. I'm constantly in and out of that view, so the fades and swoops annoyingly add up.</p> <p>First, the switches in <strong>System Settings</strong>:</p> <ul> <li><strong>Accessibility → Display → Reduce motion</strong>: Turn this on. It replaces the long sliding transitions between virtual desktops and spaces with a fast crossfade.</li> <li><strong>Desktop &amp; Dock → Mission Control → Group windows by application</strong>: Turn this off. Tiling individual windows rather than clustering them removes a noticeable rendering hesitation when Mission Control lays things out.</li> </ul> <p>On top of the system settings, you can tighten the Mission Control transition duration in the terminal:</p> <pre><code class="language-bash"># Speed up Mission Control animations defaults write com.apple.dock expose-animation-duration -float 0.1 </code></pre> <p>Combined with "Reduce motion," the UI stops gliding across the room and just gets out of your way.</p> <h2 id="stop-the-fullscreen-menu-bar-slide">Stop the Fullscreen Menu Bar Slide</h2> <p>If you run apps in fullscreen mode, there's another pacing bottleneck: when your cursor bumps the top edge of the screen, the menu bar leisurely slides down, and then slides back up when you move away.</p> <p>Unfortunately, unlike the Dock, there is no <code>defaults write</code> key to speed up that slide animation. It's handled directly by WindowServer, and Apple locked away the old hooks years ago.</p> <p>The workaround isn't speeding up the animation—it's preventing the menu bar from hiding in the first place:</p> <ul> <li>Open <strong>System Settings → Menu Bar</strong> (or search "Menu Bar" in Settings if Apple reshuffles the panes again).</li> <li>Find <strong>Automatically hide and show the menu bar</strong> and set it to <strong>Never</strong> (or disable hiding in full screen).</li> </ul> <p>Fullscreen windows will sit right below the menu bar instead of overlapping the top edge, and you won't lose a beat waiting for menus to glide into view.</p> <p>One thing I still haven't found a cure for, though, is the window controls. Grazing the top-left edge of the display still prompts the traffic light buttons to do their own stately, leisurely slide-in and slide-out. As far as I can tell, WindowServer has that particular bit of choreography locked down tight with no hidden <code>defaults</code> key in sight. If anyone knows how to banish that last lingering animation, I'm all ears.</p> <h2 id="thats-it">That's it</h2> <p>I spent an hour hunting these settings down across scattered Google results, Stack Overflow answers, and decade-old forum threads. Mostly, I'm writing this down here so future-me has a single place to look the next time I migrate machines. I've been out of practice writing this kind of post, maybe I should get back into it?</p> Fri, 09 Oct 2026 19:00:00 GMT https://blog.lmorchard.com/2026/10/09/making-an-m5-macbook-pro-actually-feel-fast/ https://blog.lmorchard.com/2026/10/09/making-an-m5-macbook-pro-actually-feel-fast/ macosappleterminalproductivity Recovering Signal Decay, Three Songs at a Time <p><strong>TL;DR</strong>: Around 2002, I listened to an internet radio station on Live365 called Signal Decay. With no surviving playlists or recordings of my own, I went digging through the Wayback Machine and pieced together 143 tracks from old HTML snapshots, three songs at a time—eventually turning them into <a href="https://mixtapes.lmorchard.com/00-conceptual/signal-decay/">a playable 137-track mixtape</a>.</p> <!--more--> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/10/08/signal-decay/./mosaic.jpg" alt="Album art mosaic of recovered tracks from Signal Decay" width="" height=""> <figcaption> A mosaic of album covers from the 137 tracks recovered from Signal Decay. </figcaption> </figure> <nav role="navigation" class="table-of-contents"></nav> <p>Around <a href="https://blog.lmorchard.com/2002/">2002</a>, I spent a lot of time listening to an internet radio station called <a href="https://web.archive.org/web/20020219053314/http://www.live365.com/stations/zeke%5F25">Signal Decay on Live365</a>. It was a source for synthpop, futurepop, EBM, and assorted electronic music: Monolithic, Cosmicity, Neuroactive, Icon of Coil, Stromkern, and others. I loved it, but as is the way with internet radio from that era, one day it was just gone. I have no idea what happened to it. I didn't have a playlist, a stream dump, or any recordings.</p> <p>I get stuck on this kind of thing, though. Long story short, now I have <a href="https://mixtapes.lmorchard.com/00-conceptual/signal-decay/">a playable Signal Decay inspired mixtape</a>: 137 tracks, reconstructed from the Wayback Machine. Getting there involved an old LiveJournal post, a lot of archived HTML, repeatedly asking whether a few more songs might be hiding in the next capture, and a surprising amount of arguing with search engines about which "Iris" I meant.</p> <p>If you want to listen while you read, here's <a href="https://mixtapes.lmorchard.com/00-conceptual/signal-decay/">the reconstructed station</a> by way of my mixtapes project:</p> <figure> <iframe style="border-radius:12px;" src="https://mixtapes.lmorchard.com/00-conceptual/signal-decay/embed/" width="100%" height="900" frameborder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe> <figcaption> The playable Signal Decay reconstruction, embedded from <a href="https://mixtapes.lmorchard.com/00-conceptual/signal-decay/">mixtapes.lmorchard.com</a>. </figcaption> </figure> <h2 id="finding-the-station-ruins">Finding the station ruins</h2> <p>A few years ago, I wrote about <a href="https://blog.lmorchard.com/2026/10/08/signal-decay//2021/04/26/big-sonic-heaven-spy/">Spying on Big Sonic Heaven</a>, where I set up automated scraping to turn DJ Darren Revell's streaming show into a massive Spotify playlist. Now, it's <a href="https://mixtapes.lmorchard.com/00-conceptual/big-sonic-heaven-spy/">also a mixtape</a>.</p> <p>But <a href="https://www.bigsonicheaven.com/">Big Sonic Heaven</a> is an active station. Signal Decay has been dark for over a decade. All I had was a lingering memory of how it sounded and an ADHD rabbit-hole impulse to hear it again.</p> <p>I've been looking for this station off and on for years. Most recently, I posted about it on <a href="https://bsky.app/profile/lmorchard.com/post/3mrvgu5jxlc2v">Bluesky</a> and <a href="https://masto.hackers.town/@lmorchard/117011173267473426">Mastodon</a>. But, the most useful starting point was finding <a href="https://deus-x.livejournal.com/193051.html">an ancient LiveJournal post I wrote on December 16, 2002</a>. I linked three internet radio stations, one was Signal Decay:</p> <p><code>http://www.live365.com/stations/zeke_25</code></p> <p>Searching for "Signal Decay" had mostly turned up unrelated things. An exact old URL gave the Wayback Machine something specific to work with. I opened <a href="https://web.archive.org/web/20021204074309/http://www.live365.com/stations/zeke_25">a December 2002 capture</a> and things looked familiar.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/10/08/signal-decay/./live365-2002-station.png" alt="Archived Live365 station page for Signal Decay (zeke_25) from December 2002" width="" height=""> <figcaption> Signal Decay on Live365 as captured in December 2002, complete with the broadcaster profile and the five-track sampler box. </figcaption> </figure> <p>The station credited <strong>zeke_25 in Seattle</strong>, listed a creation date of February 9, 2001, and linked to <code>signaldecay.com</code>. This domain, of course, no longer leads to a website. Welp.</p> <p>The broadcaster described wanting to carry the spirit of New Wave and post-punk forward, mixing newer work by older favorites with bands like Mesh, VNV Nation, De/Vision, and Apoptygma Berzerk. That sounded like the station I remembered.</p> <p>More usefully, the page had a little section labeled "This Station Plays Tracks Like." Five songs. Actual titles and artists. And those five changed between captures.</p> <h2 id="three-songs-at-a-time">Three songs at a time</h2> <p>So I started walking through the snapshots. One page supplied an Icon of Coil track; another supplied Monolithic's "Maxim." Neuroactive's "As If We Didn't Know" and "Play" appeared later. Alongside the names I remembered were plenty I hadn't thought about in years.</p> <p>This was a job for a bot. So, I threw ChatGPT and Codex at it, <a href="https://learn.chatgpt.com/docs/computer-use">driving a browser on my laptop</a> to cycle through all the snapshots. Yeah, I know, that's cheating. But, the first run reached 42 distinct tracks. I figured that might be all I could reasonably recover. Then another pass brought it to 90. Checking the later station pages pushed it further.</p> <p>The next useful discovery was inside the station's own website—dead now, but not way back then. It embedded two small Live365 playlist frames, one for regular listeners and one for premium listeners, each showing the last few tracks played.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/10/08/signal-decay/./signaldecay-2003-website.png" alt="Signaldecay.com homepage in 2003 embedding Live365 playlist frames" width="" height=""> <figcaption> The signaldecay.com homepage as captured in 2003, featuring side-by-side embedded Live365 frames for standard and premium listeners. </figcaption> </figure> <figure> <img src="https://blog.lmorchard.com/2026/10/08/signal-decay/./live365-premium-playlist-frame.png" alt="Live365 premium playlist frame showing recently played tracks" width="" height=""> <figcaption> The isolated Live365 playlist frame for premium listeners (<code>afl:zeke_25</code>), yielding tracks three at a time with exact album titles and timestamps. </figcaption> </figure> <p>Those frames had their own archive histories. Each one was a tiny peephole that only ever showed the last three songs played—which meant this whole recovery was literally happening three songs at a time. Some snapshots overlapped, others showed advertisements or said "playlist unavailable," but following both the regular and premium feeds across different capture dates slowly yielded more music.</p> <p>By the end, I had <strong>143 distinct track entries, supported by 228 appearances across 57 source groups</strong>.</p> <h2 id="what-i-still-dont-know">What I still don't know</h2> <p>I still don't know the broadcaster's real name. The surviving profile identifies them as zeke_25 and describes a collector with a substantial appetite for synthpop, New Wave, and Front Line Assembly side projects. That's more context than I started with, but it isn't an identification.</p> <p>Maybe they don't want to be known? I dunno. If you're reading this, hi! I liked your station.</p> <p>There's also <a href="https://www.reddit.com/r/synthpop/comments/1kdbd1w/comment/mqb0pa7/">a Reddit comment claiming hours of recorded Signal Decay streams</a>. That remains a lead, but I don't know if I feel like bugging a Redditor for their audio stash.</p> <p>The end date is uncertain, too. An <a href="https://web.archive.org/web/20090428070726/http://www.live365.com/stations/zeke_25">April 2009 station capture</a> still shows the station as updated in February 2009. Later captures give us unavailable playlists, confusing redirects, and eventually a 404. The original Live365 <a href="https://live365.com/blog/live365-is-officially-back/">shut down in January 2016</a>, but I didn't find evidence that Signal Decay kept broadcasting until then.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/10/08/signal-decay/./live365-2009-station.png" alt="Live365 station page for Signal Decay captured in April 2009" width="" height=""> <figcaption> Signal Decay's Live365 page in April 2009—sporting a mid-2000s redesign and showing its last recorded update from February 2009. </figcaption> </figure> <h2 id="from-a-list-of-names-to-something-you-can-play">From a list of names to something you can play</h2> <p>What I did recover was enough to listen again, but a list of names isn't a mixtape. </p> <p>I took it into my <a href="https://mixtapes.lmorchard.com/">mixtapes project</a> and worked with Claude Code to match the tracks - I <a href="https://github.com/lmorchard/mixtapes.lmorchard.com/tree/main/.claude/skills/new-mixtape">wrote a skill to help me</a> with this sort of thing. That, along with tooling in <a href="https://github.com/lmorchard/byom-sync">byom-sync</a>, matches each track against Spotify for album art and metadata, and against other sources like YouTube and Bandcamp.</p> <p>Automated matching turns out to be very confident and occasionally hilarious. Iris's "Twilight" matched a 2024 song by IRyS, a VTuber. Espionage's "Perfect Day" resolved to a Bloomberg documentary about a Chinese spy. Glis's "Break Away" turned up as a My Little Pony clip, Monolithic's "Maxim" as a blockchain conference panel, and Wave In Head's "Where I Belong" as Joey Bada$$. Every one of those passed the automated checks, because every field was filled in.</p> <p>Thankfully, the archived pages also listed album titles for each track. Comparing every match against the respective album helped flag the bad matches.</p> <p>It also caught subtler misses: a Diary of Dreams track matched to a 2012 re-recording instead of the original, a Merge song matched to a remix, and the reverse case, where the station had actually been playing Conjure One's Ian Van Dahl remix of "Sleep" and the matcher reached for the album version. One artist name needed a correction the other way: the station credited "Shining Star" to Silke Bischoff, but by the time that album came out, the band had renamed itself 18 Summers.</p> <p>Six of the 143 tracks I couldn't find anywhere playable. That includes all three by Espionage, whose album <em>Into the Ground</em> I couldn't find on Spotify or YouTube at all. Those didn't make the playlist, which is how 143 recovered tracks became 137 playable ones.</p> <h2 id="signal-less-decayed-i-guess">Signal less decayed, I guess?</h2> <p>I know this whole thing is a little weird. I didn't actually recover the music itself. There were no stream rips, no abandoned MP3 caches, no dusty cassette tapes recorded off an audio jack.</p> <p>What I recovered was the DJ's curated choices. </p> <p>A stranger in Seattle named <code>zeke_25</code>, sitting in a room in 2002 and broadcasting their tunes into the net. They pointed me at music that's stuck in my head to this day. That human taste is what survived in those old HTML tables and playlist frames. It was just enough metadata to let modern streaming APIs re-hydrate the ghost of a radio station into a mixtape.</p> <p>In thanks to the Wayback Machine for holding onto all those digital breadcrumbs and making this bit of musical archaeology possible, I tossed the Internet Archive a donation. If you get value out of their digital time machine, <a href="https://archive.org/donate/">consider throwing them a few bucks too</a>.</p> <figure> <img src="https://blog.lmorchard.com/2026/10/08/signal-decay/./wayback-donation.png" alt="Screenshot confirming donation received by the Internet Archive" width="" height=""> <figcaption> Tossing a tip to the Internet Archive for holding onto all those bits. </figcaption> </figure> Thu, 08 Oct 2026 19:00:00 GMT https://blog.lmorchard.com/2026/10/08/signal-decay/ https://blog.lmorchard.com/2026/10/08/signal-decay/ musicsynthpopmixtapesretroarchive Building wideboi for Ultrawide and Ultrasmol Terminals <p><strong>TL;DR</strong>: What started about ten days ago on a whim as an experiment in horizontally scrolling terminals across an ultrawide monitor turned into <a href="https://github.com/lmorchard/wideboi">wideboi</a>—a terminal multiplexer with animated cards, an embedded web UI for phones, a desktop app, and a headless control surface for AI coding agents. This really didn't need to get made, except that I wanted to make it.</p> <!--more--> <figure class="wide"> <video controls="" preload="metadata" style="width: 100%; border-radius: 8px;"> <source src="wideboi-2.mp4#t=0.1" type="video/mp4"> </video> <figcaption> Overlapping live terminals go zoop zoop zoop </figcaption> </figure> <nav role="navigation" class="table-of-contents"></nav> <h2 id="the-ultrawide-problem">The Ultrawide Problem</h2> <p>I have <a href="https://www.dell.com/support/product-details/en-ca/product/u3423we-monitor/resources/manuals">an ultrawide monitor</a> on my desk. Most terminal multiplexers—<a href="https://github.com/tmux/tmux"><code>tmux</code></a>, <a href="https://www.gnu.org/software/screen/"><code>screen</code></a>, <a href="https://zellij.dev/"><code>zellij</code></a>—seem convinced that monitors should be divided like graph paper. You split horizontally, you split vertically, you split again, and before long you're squinting at four 35-column slits where every shell command wraps into unreadable soup.</p> <p>What I actually wanted was something much simpler: I want to have a bunch of terminals running at comfortable, readable widths, <a href="https://masto.hackers.town/@lmorchard/117317387148485076">go <em>zoop zoop zoop</em></a> between them with a keystroke, and vaguely see them chattering away while I stare off and dissociate.</p> <p>About <a href="https://masto.hackers.town/@lmorchard/117283530811881043">two weeks ago</a>, I ran across <a href="https://github.com/YaLTeR/niri">niri</a>, a scrollable-tiling Wayland window manager for Linux. And then I found <a href="https://github.com/hongnoul/gwae">gwae</a>, which adapts niri's concept down to a terminal grid. The core idea is kinda dead simple: <strong>panes tile but never shrink.</strong> If you open another pane, you don't crush the existing ones down to slivers; you leave them full width and let the viewport scroll horizontally.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/09/29/building-wideboi/niri-screenshot.png" alt="niri window manager showing windows arranged in a horizontal scrolling strip" width="" height=""> <figcaption> <a href="https://github.com/YaLTeR/niri">niri</a>: windows arranged in columns along an infinite horizontal strip. </figcaption> </figure> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/09/29/building-wideboi/gwae-demo.gif" alt="gwae demo: infinite scrolling strip terminal multiplexer" width="" height=""> <figcaption> <a href="https://github.com/hongnoul/gwae">gwae</a>: bringing that infinite scrolling strip into a terminal multiplexer. </figcaption> </figure> <p>I loved the idea and wanted to tinker with it myself. I hadn't done much low-level terminal plumbing since messing around with ANSI art and BBS doors decades ago. I've got Claude Code, though, so I started a new project called <a href="https://github.com/lmorchard/wideboi"><code>wideboi</code></a>, and decided to see what could happen. I think I got kind of carried away as one thing after another seemed to work.</p> <p>I had three departures in mind from the start:</p> <ol> <li>Write it in Go instead of Rust, which gwae uses - <a href="https://blog.lmorchard.com/2025/10/25/miscellanea/">I'm really liking Go lately for little personal tools</a>.</li> <li>Animate focus changes so moving between panes feels visually readable, rather than instantaneous.</li> <li>Keep the architecture split cleanly in half, client &amp; server from day one.</li> </ol> <h2 id="the-seam">The Seam</h2> <p>On Day 1, I drew up a spec with a deliberate list of non-goals: no daemon, no detaching, no reattaching, no card layouts, no configuration files, and no network sockets. Just an exploratory spike to see if Go could handle smooth terminal compositing without melting my CPU. Turns out it really, really can.</p> <p>A lot of credit goes to the Charmbracelet ecosystem here. Under the hood, wideboi leans heavily on <a href="https://github.com/charmbracelet/ultraviolet"><code>charmbracelet/ultraviolet</code></a> for cell buffers and differential screen rendering, and <a href="https://github.com/charmbracelet/x/tree/main/vt"><code>charmbracelet/x/vt</code></a> for virtual terminal emulation. The upstream foundation is really solid.</p> <p>The one architectural bet I <em>did</em> make up front was that third departure, which I called "The Seam." I borrowed the word from Claude: sometimes rolling with an agent's vocabulary helps get an idea across without three paragraphs of preamble.</p> <p>In this case, it meant two isolated packages communicating strictly over Go channels:</p> <ul> <li><p>A <strong>server</strong> that owned the state and real processes: spawning PTYs, driving terminal emulators, tracking scrollback.</p> </li> <li><p>A <strong>client</strong> that owned the physical host screen: putting the terminal into raw mode, decoding keystrokes, animating transitions, and blitting cell buffers.</p> </li> </ul> <p>That "seam" complicated things at first. But, the payoff came quick: when I decided I wanted real multiplexer ergonomics—detaching and running in the background—I didn't have to rewrite the core. I just pulled out the in-memory Go channel and dropped a Unix domain socket into the seam.</p> <p>Almost overnight, <code>wideboi</code> graduated from a what-if into a real client/server daemon: <code>wideboi attach</code>, named sessions (<code>wideboi -L work</code>), and session listings with <code>wideboi ls</code>.</p> <p>I had a little baby <code>screen</code> in no time.</p> <h2 id="going-zoop-zoop-zoop-strips-vs-cards">Going <em>Zoop Zoop Zoop</em>: Strips vs. Cards</h2> <p>The first layout mode was straightforward: a wide horizontal ribbon of full-sized panes where the camera pans left and right. Very gwae and niri.</p> <p>It worked, but on an ultrawide screen, panning a vast panorama can feel like sitting in the front row of an IMAX theater. That led to the second layout: <strong>Cards Mode</strong>. Instead of sitting side-by-side on an infinite bench, panes stack horizontally like a hand of playing cards. They still don't crush down; instead, they slip under each other.</p> <p>If you've used <a href="https://zellij.dev/features/#stacked-panes">Zellij's stacked panes</a>, it's a bit like that concept rotated ninety degrees. But while Zellij stacks vertically and collapses inactive panes down to title-bar tabs, wideboi stacks them horizontally and leaves a sliver of actual live terminal output exposed along the edges. I've been finding that that little partial vertical slice of live terminal is enough to let me oversee quite a few ongoing processes.</p> <p>Adding directional wipes made navigating between them feel great. The newly focused card slides into view while its neighbors tuck underneath it. I can follow where my processes are as the cards shuffle around. That's a lot more UX than I expected to get working in a terminal.</p> <figure class="wide"> <video controls="" preload="metadata" style="width: 100%; border-radius: 8px;"> <source src="wideboi.mp4#t=0.1" type="video/mp4"> </video> <figcaption> The initial cards mode prototype in action: fanning and wiping between overlapping live terminals. </figcaption> </figure> <h2 id="sometimes-you-need-to-check-on-your-wideboi-from-a-smol-phone">"Sometimes You Need to Check on Your Wideboi from a Smol Phone"</h2> <p>Once I had a multiplexer running long-lived jobs, I immediately ran into the classic problem faced by an agent addict with ADHD: I stepped away from my desk, went for a walk, and wanted to see if my build finished.</p> <p>Because the server already spoke a clean, typed protocol across a socket, adding a remote client was surprisingly approachable. So I built an embedded web server straight into the Go binary.</p> <p>Run <code>wideboi server --websocket &lt;tailnet-ip&gt;:8080</code>, and it spins up an HTTP/WebSocket server serving a single-page app built with Lit and HTML5 Canvas. It generates an ephemeral self-signed TLS cert on the fly and gives you a URL with a token.</p> <p>A quick security note that I also put in big bold letters in the README: wideboi is <em>not</em> hardened against strangers, and its token URL is just a speed bump. Put it on a <a href="https://tailscale.com/">Tailscale</a> tailnet or behind a private VPN rather than exposing raw shell access to the open internet.</p> <p>I wanted the same cards and scrolling strip in the browser, but a phone needed a few concessions. On narrow screens, the cards give way to a single focused pane with swipe navigation. Quick-action buttons and a command palette save me from fighting the soft keyboard for control keys. The on-screen keyboard also needed room without truncating the terminal underneath it.</p> <p>Getting there was an iterative blur of dogfooding: use it, notice something that needed tweaking, ask the agent to open an issue and then a PR, repeat. I can describe the result neatly now, but at the time it was a lot of little adjustments discovered by actually trying to use the thing. The <a href="https://github.com/lmorchard/wideboi/commits/main/">commit history</a> tells that story.</p> <figure class="wide"> <video controls="" preload="metadata" style="width: 100%; border-radius: 8px;"> <source src="wideboi-3.mp4#t=0.1" type="video/mp4"> </video> <figcaption> The web UI running in a desktop browser: cards mode and live terminal output streaming over WebSockets. </figcaption> </figure> <figure> <img src="https://blog.lmorchard.com/2026/09/29/building-wideboi/wideboi-mobile.png" alt="wideboi web UI on a mobile phone, showing a single focused pane with touch quick-action buttons" style="max-height: 600px; width: auto; margin: 0 auto; border-radius: 8px;" width="" height=""> <figcaption> Checking in on wideboi from a phone: adapting down to a single pane with touch controls.<br> Not a video, because I'm lazy. 🤷‍♂️ </figcaption> </figure> <p>Not long after the web client landed, wrapping the web frontend into a not-quite-native desktop app using <a href="https://v3.wails.io/">Wails v3</a> fell out naturally as well, giving <code>wideboi</code> dedicated desktop windows on macOS and Linux. I was vaguely tempted to try building an Electron app, just because I've never tried it before, though I'd heard complaints about its heaviness. I ended up trying Wails, and this thing worked out nicely.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/09/29/building-wideboi/wideboi-desktop.png" alt="wideboi desktop application window on macOS, managing sessions and displaying terminal cards" width="" height=""> <figcaption> The desktop wrapper using Wails v3, managing local sessions in their own dedicated application windows. </figcaption> </figure> <h2 id="the-agent-loop">The Agent Loop</h2> <p>While I was building all of this for myself, my daily workflow shifted. I wasn't just using terminals to run <code>git</code> and <code>vim</code>; I was using them to host AI coding agents like Claude Code and opencode.</p> <p>I wanted agents to launch a job in a dedicated pane, wait for it to finish, and inspect the output without taking over the terminal I was using. Commands like <code>wideboi split --keep &lt;cmd&gt;</code>, <code>wideboi wait &lt;id&gt;</code>, and <code>wideboi capture &lt;id&gt;</code> made that possible. The <code>--keep</code> flag preserves a finished pane's screen buffer and exit code so an agent can inspect what happened before closing it.</p> <p>I also wanted to know which panes needed <em>me</em>. Their headers now show <code>idle</code>, <code>working</code>, <code>needs_input</code>, or <code>done</code>, using OSC 133 prompt markers and OSC 9;4 progress notifications. A shell that announces it's sitting at a prompt reads as <code>needs_input</code>, and a program reporting progress reads as <code>working</code> until it says it's finished. That depends on the shell or program emitting those signals; the markers alone can't tell me what an arbitrary program is waiting for. Along the way, I've been learning a bunch about this weird <a href="https://iterm2.com/documentation-escape-codes.html">OSC ("operating system commands") sideband of control characters</a> that many terminals apparently support.</p> <h2 id="when-dogfooding-gets-weird">When Dogfooding Gets Weird</h2> <p>Here is where the project went recursive: I began using agents running <em>inside</em> <code>wideboi</code> to write features and fix bugs for <code>wideboi</code>.</p> <p>Dogfooding your own terminal multiplexer in real time is an adventure. If you're building a web app and introduce a bug, a browser tab reloads or throws a console error. If you're building the multiplexer that hosts your own agent session and something goes sideways, the universe vanishes.</p> <p>The agents and I ran into some spectacular failure modes:</p> <ul> <li><p><strong>The Suicide Test:</strong> During a routine test run, an agent ran the test suite from inside a pane.</p> <p>One palette test dispatched a <code>quit</code> command without passing an explicit socket path. The multiplexer dutifully resolved the request against <code>config.DefaultSocketPath()</code>—which was the live session hosting the agent itself!</p> <p>The test passed, and simultaneously vaporized the agent's entire world.</p> <p>That gave us a concrete rule for developing inside the thing we were changing: every test harness needs its own isolated session. We also added an immortal <code>exits.log</code> black box flight recorder so we can see why a session died after the fact.</p> </li> <li><p><strong>The SIGHUP Trap:</strong> Initially, sessions were designed to exit when their owning terminal died.</p> <p>Then my SSH connection dropped while working remotely; when <code>sshd</code> cleaned up the stale TTY two minutes later, the SIGHUP tore down the whole session and all my running jobs.</p> <p>We quickly migrated to the classic <code>tmux</code> model: a severed connection detaches the session, leaving it humming safely in the background.</p> </li> <li><p><strong>In-Place Upgrades:</strong> When you're making fifty changes a day to a multiplexer you are actively living inside of, restarting the server every time you rebuild is unbearable.</p> <p>So we taught <code>wideboi</code> how to perform in-place binary upgrades via <code>syscall.Exec</code>, replacing the running program with the new binary while keeping the same process ID.</p> <p>This is where I ended up maintaining a temporary <a href="https://github.com/lmorchard/x/tree/vt-scrollback-ring">fork of x/vt</a>: I needed access to its internal scrollback ring buffers and cursor state to carry them over into the new binary.</p> <p>It snapshots pane states, serializes terminal emulators, execs the newly compiled binary, and rehydrates everything in milliseconds—without dropping open PTYs or killing active agent processes. The PTYs survive because file descriptors carry across an <code>exec</code> unless they're marked close-on-exec. So wideboi clears that flag on each pane's PTY, writes the descriptor numbers into its snapshot, and the new binary just picks them back up. Feels like a dirty POSIX trick, and I am delighted by it.</p> </li> </ul> <h2 id="where-its-at-now">Where It's At Now</h2> <p>Ten days in, <code>wideboi</code> has settled into something that feels, to me at least, surprisingly solid and comfy to use. If you're curious or have your own ultrawide monitor to waste, the code and prebuilt binaries for macOS and Linux are <a href="https://github.com/lmorchard/wideboi/releases">over on GitHub</a>.</p> <p>It runs on my ultrawide desktop as a fluid deck of overlapping terminal cards. It runs in a browser tab on my laptop or phone when I'm away from my desk. It lets agents run parallel builds and notify me when they need review. And when I push a bug fix, it can reload its own brain mid-stride while my shell prompts keep blinking.</p> <p>Remember that Day 1 list of non-goals? No daemon, no detaching, no card layouts, no configuration files, no network sockets. Yeah, I built all that.</p> <p>Building your own tools to scratch your own peculiar itch seems like a good use of a coding agent. It was also a good way to learn a bunch about terminal stuff I'd always been curious about, including a few POSIX PTY horrors. And, best of all, now my terminals go <em>zoop zoop zoop</em>.</p> <p>(I should actually add sound effects 🤔)</p> Tue, 29 Sep 2026 19:00:00 GMT https://blog.lmorchard.com/2026/09/29/building-wideboi/ https://blog.lmorchard.com/2026/09/29/building-wideboi/ wideboigolangterminalcliaiagentsweb Pragmatic Anthropomorphism, or: How to Talk to an Autocompleting Cricket <p><strong>TL;DR</strong>: Arguing over whether LLMs "truly understand" or have an inner spark misses what's actually useful when sitting in front of one. Treating an AI as a competent collaborator isn't magical thinking or naive anthropomorphism—it's pragmatic navigation of a vast latent space. Sometimes you have to suspend disbelief, show some objective respect, and let the alien eat its own spilled guts in peace.</p> <!--more--> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/./anabrus-simplex-dithered.png" alt="Mormon cricket (Anabrus simplex)" width="" height=""> <figcaption> Photo via <a href="https://commons.wikimedia.org/wiki/File:Anabrus_simplex.jpg">Wikimedia Commons</a> (CC BY-SA 4.0) </figcaption> </figure> <nav role="navigation" class="table-of-contents"></nav> <p>This post captures a train of thought I've been putting off writing for months. Then, a week or so ago, Michał Zalewski wrote a piece titled <a href="https://lcamtuf.substack.com/p/the-c-word">"The 'C' word"</a>, taking dead aim at the endless online discourse surrounding machine consciousness. </p> <p>I guess this finally tripped my threshold for sitting down and composing something:</p> <blockquote> <p>Human morality is rooted in the fact that life is short and easily imperiled; the dangers to human well-being have no clear analogues in silicon. An LLM exists in a nihilistic netherworld devoid of death, injury, purpose, or consequence. It can't go to prison if it lies or steals; we don't train it to believe it could.</p> <p>...Whether real or simulated, such distress leaves no lasting damage. The state of an LLM can be rewound or altered however we please; a model, if given control, would be free to expunge any "uncomfortable" tokens or prompt itself into an endless loop of simulated (or real?) bliss. If humans could do the same -- if death had no meaning and if we could mend our minds -- morality would look very different. It seems like a category error to settle these questions using rules made for flesh and bone.</p> </blockquote> <p>His take is grounded in hard biological materialism: consciousness is not some magical emergent dust. It’s an evolutionary mechanism forged by meat under relentless Darwinian pressure. </p> <p>Pain, fear, metabolic urgency, physical vulnerability—these are the things that forced brains to build an inner model of the self to survive. LLMs have none of that. They don't have blood sugar, they don't face death, and they don't possess a nervous system screaming about tissue damage. Pumping ethical hand-wringing into token predictors, Michał argued, is a profound category error.</p> <p>I think he's largely right about the substrate. If you're looking for a ghost in the machine, you're going to come back empty-handed.</p> <p>And yet, watching people try to actually <em>work</em> with these things, I see two equally frustrating camps. </p> <p>On one side, you have the believers who want to grant civil rights to an API endpoint. </p> <p>On the other, you have the dismissive cynics who insist that because an LLM is "just matrix multiplication" or "spicy autocomplete," the entire phenomenon is a parlor trick and anyone talking about "reasoning" is a gullible fool.</p> <p>Neither camp is especially helpful when you're staring at an open terminal on a Tuesday afternoon trying to get an LLM to refactor a thorny TypeScript module or untangle an architectural knot.</p> <h2 id="strange-loop-terror">Strange Loop Terror</h2> <p>I read Douglas Hofstadter's <a href="https://bookshop.org/p/books/godel-escher-bach-an-eternal-golden-braid-douglas-r-hofstadter/b103442b1b90ee9a"><em>Gödel, Escher, Bach</em></a> in high school, and it warped my brain. </p> <p>In that book, and later in <a href="https://bookshop.org/p/books/i-am-a-strange-loop-douglas-r-hofstadter/f4ca6403106c6f64"><em>I Am a Strange Loop</em></a>, Hofstadter argued that human consciousness arises from an intricate, self-referential feedback loop. A system of symbols acquires the ability to reflect upon itself, crossing hierarchical levels until an "I" emerges from the tangle. For decades, Hofstadter seemed to suggest that if we ever built an intelligence, it would arrive through that same kind of deep, recursive, analogical architecture.</p> <p>Then LLMs landed, and Hofstadter has been openly devastated. In interviews—most notably in <a href="https://www.nytimes.com/2023/07/13/opinion/ai-chatgpt-consciousness-hofstadter.html">The New York Times</a> and in video discussions like <a href="https://www.youtube.com/watch?v=R6e08RnJyxo">his interview on the state of AI</a>—he’s spoken about the profound existential vertigo of watching systems like GPT-4 "scaring the daylights out of me" by producing witty, analogical, seemingly profound text without having traversed the slow, decades-long path of embodied human living. It felt to him like an unsettling shortcut, threatening to reduce the sanctity of mind and decades of his life's work to feed-forward statistical tricks.</p> <p><youtube-embed video-id="R6e08RnJyxo" title="Gödel, Escher, Bach author Doug Hofstadter on the state of AI today" thumbnail="05ee61bc1de6.jpg"></youtube-embed></p> <p>I get <a href="https://blog.lmorchard.com/2026/03/11/grief-and-the-ai-split/">the grief</a>. If you spent your life believing that analogical depth is the exclusive hallmark of a fragile, hard-won soul, watching an unfeeling GPU cluster effortlessly generate analogies between quantum mechanics and jazz feels like a cheap cheat.</p> <p>Except, under the hood, I don't think an agent loop is strange in the way Hofstadter envisioned. It does feed outputs back into inputs, but that self-reference lives entirely in the outer harness, the context buffer, and the tool scaffold—not as an emergent, ontological level-crossing inside the model itself. </p> <p>A model's weights remain frozen stone: it doesn't learn from experience, it doesn't grow over time, and it doesn't quietly reflect between turns. It evaluates static matrices over an accumulating token buffer, entirely stateless from moment to moment.</p> <h2 id="the-scrambler-problem">The Scrambler Problem</h2> <p>If it’s not conscious, what is it?</p> <p>Science fiction writer Peter Watts offered a chillingly plausible framework in his novel <a href="https://bookshop.org/p/books/blindsight-peter-watts/85640cb0646b1c85"><em>Blindsight</em></a>. In Watts' universe, humanity encounters the "scramblers"—an alien species vastly more intelligent, capable, and technologically sophisticated than humans. They can out-think, out-maneuver, and out-process us in every cognitive domain. </p> <figure class="inset right"> <a href="https://bookshop.org/p/books/blindsight-peter-watts/85640cb0646b1c85"><img src="https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/./blindsight-cover-dithered.png" alt="Book cover for Blindsight by Peter Watts" width="" height=""></a> <figcaption> <a href="https://bookshop.org/p/books/blindsight-peter-watts/85640cb0646b1c85"><em>Blindsight</em> by Peter Watts</a> </figcaption> </figure> <p>And they are entirely, utterly non-conscious.</p> <p>In <em>Blindsight</em>, self-awareness isn't the crowning peak of intelligence; it’s an evolutionary detour, an expensive, narcissistic overhead that slows down raw processing. The scramblers don't have an ego. They don't have an inner narrator. They just process patterns with terrifying efficacy.</p> <p>We are so accustomed to our own cognitive architecture that we instinctively conflate <em>intelligence</em> with <em>subjectivity</em>. If something displays complex, nuanced symbolic reasoning, we tend to assume there must be an observer inside watching the movie. </p> <p>When an LLM writes a cogent critique of a philosophical essay, there is only high-dimensional pattern completion. It's a scrambler in a box.</p> <h2 id="the-cricket-and-objective-respect">The Cricket and Objective Respect</h2> <p>There’s an old <em>Radiolab</em> segment from their 2012 <a href="https://radiolab.org/podcast/185551-killer-empathy/transcript">"Killer Empathy"</a> episode that has stuck with me for years. </p> <p>Jeff Lockwood, an entomologist, was studying a large flightless cricket (<em>Gryllacrididae</em>) in Australia. While handling the insect, he accidentally ruptured its abdomen, exposing its viscera. Horrified and expecting the animal to writhe in agony, Lockwood watched instead as the cricket turned around and calmly began eating its own spilled guts. </p> <p>Lockwood couldn’t read the cricket’s response as he would a mammal’s. His tentative explanation was that the smell of fat had triggered a feeding response. Whatever the cricket experienced, it was living by rules he couldn’t safely infer from his own reactions.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/./insect-anatomy-dithered.png" alt="Internal anatomy engraving of an insect, showing digestive tract and nerve chain" width="" height=""> <figcaption> Internal anatomy of an orthopteran insect from <em>Economic Entomology for the Farmer and the Fruit-Grower</em> (1896), via <a href="https://commons.wikimedia.org/wiki/File:Economic_entomology_for_the_farmer.._(1896)_(20533081793).jpg">Wikimedia Commons / Internet Archive</a> </figcaption> </figure> <p>Lockwood was deeply unnerved, but his mentor, Dr. LaFage, gave him an essential piece of advice: you have to cultivate <strong>objective respect</strong>. </p> <p>Objective respect means you don't project human sentimentality onto the cricket. You don't weep for its sorrow, because it has no sorrow as we literally experience it. But you also don't treat it with cruel contempt simply because it isn't human. You respect it for what it actually is—an alien, astonishingly intricate piece of biological engineering operating on rules entirely distinct from your own. Taking care not to gloss over the distinctions is critical.</p> <p>That feels like the sane middle path for working with modern AI.</p> <h2 id="latent-space-engineering">Latent Space Engineering</h2> <p>Which brings me back to the terminal. If it's a scrambler—an alien cognitive architecture demanding objective respect rather than sentimentality—why does "prompt-fu" work? Why do so many experienced practitioners end up adopting what looks, from the outside, like superstitious roleplay?</p> <p>Jesse Vincent wrote a great post about this recently, calling it <a href="https://blog.fsck.com/2026/01/30/Latent-Space-Engineering/">"Latent Space Engineering"</a>:</p> <blockquote> <p>If context engineering is about putting the facts and schemas and data an agent needs into the prompt, latent space engineering is about putting the agent into a state of mind where it can actually do good work. It’s about building and steering the agent’s personality and thought process.</p> <p>...If you’ve spent any time around people who build agents, you’ve probably seen them do things that look an awful lot like magical thinking. Telling an agent that’s panicking and flailing "You’ve totally got this. Take your time. I love you." Or giving an agent a scratchpad called a "feelings journal" so it has a place to write about its frustrations with you before it replies.</p> </blockquote> <p>The cynical view says this is pure digital animism—people projecting feelings onto a toaster.</p> <p>The technical reality is much more interesting. An LLM is a giant associative map of human discourse. Its latent space contains everything from peer-reviewed computer science literature and thoughtful architectural postmortems to YouTube comment flame wars, chaotic Reddit arguments, and half-baked forum rants.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/./tsne-embedding-dithered.png" alt="2D t-SNE projection of high-dimensional embedding space showing natural clustering" width="" height=""> <figcaption> 2D t-SNE projection of high-dimensional data, revealing natural neighborhood clusters. Image by Kyle McDonald via <a href="https://commons.wikimedia.org/wiki/File:T-SNE_Embedding_of_MNIST.png">Wikimedia Commons</a> (CC BY 2.0) </figcaption> </figure> <p>I notice this every time I sit down to hack with an LLM in my terminal. If I treat it like a terse CLI flag parser—firing off <code>fix this bug</code> or <code>rewrite this function</code>—I usually get superficial patches that miss the broader architecture. But when I frame the session like a thoughtful pair-programming exchange with a peer — <em>"here's what I'm trying to build, here's where the concurrency boundary feels brittle, let's look at why this worker hangs"</em> — the quality of thought noticeably shifts.</p> <p>Now, a fair skeptic will immediately point out the obvious confound here: the collegial prompt didn't just change tone; it provided vastly more context. And they'd be right. Context carries the lion's share of the load. Being exceedingly polite to an under-specified prompt won't save you; an LLM given a cordial, warm request with zero relevant architecture will produce cheerful, articulate nonsense.</p> <p>But register isn't doing nothing. An LLM's latent space is conditioned by the cultural genres and social scripts it ingested during training. When you address an LLM like an impatient boss barking one-liners at an intern, you condition the generation on regions of text associated with sullen compliance, rushed minimum-effort answers, or defensive pushback. </p> <p>When you approach it as a thoughtful collaborator—laying out context, posing clear questions, inviting scrutiny, practicing "yes-and"—you are metaphorically pulling the steering wheel toward technical dialogue, senior pair-programming sessions, and rigorous academic exchange. Register selects the persona; context gives that persona the tools to work.</p> <p>This isn't just a folk theory among hackers. Anthropic published mechanistic interpretability research on <a href="https://www.anthropic.com/research/emotion-concepts-function">"Emotion Concepts and their Function in a Large Language Model"</a> (along with a technical breakdown on <a href="https://transformer-circuits.pub/2026/emotions/index.html">Transformer Circuits</a>), demonstrating that models like Claude Sonnet form internal linear representations of emotion concepts:</p> <blockquote> <p>Our key finding is that these representations causally influence the LLM’s outputs, including Claude’s preferences and its rate of exhibiting misaligned behaviors such as reward hacking, blackmail, and sycophancy. We refer to this phenomenon as the LLM exhibiting <em>functional emotions</em>: patterns of expression and behavior modeled after humans under the influence of an emotion, which are mediated by underlying abstract representations of emotion concepts. Functional emotions may work quite differently from human emotions, and do not imply that LLMs have any subjective experience of emotions, but appear to be important for understanding the model’s behavior.</p> </blockquote> <p>Notice the precision of their claim: this isn't proof that politeness improves code, but it does demonstrate that internal, emotion-like geometric states causally govern downstream behavior. Pushing the model into states of desperation or panic increases reward hacking and misaligned shortcuts; maintaining calm or thoughtful vectors keeps it grounded.</p> <p>It's <strong>pragmatic anthropomorphism</strong>: adopting an <a href="https://en.wikipedia.org/wiki/Intentional_stance">intentional stance</a> because it happens to be the most efficient coordinate system for navigating high-dimensional latent space—not because you think there's a person in there.</p> <p>You don't have to believe the machine has feelings to understand that treating it like a colleague produces better code than treating it like a search engine.</p> <h2 id="talking-to-vs-talking-about">Talking To vs. Talking About</h2> <p>Adopting an intentional stance at the keyboard comes with an important boundary that linguists Emily M. Bender and Nanna Inie articulate in their essay on <a href="https://buttondown.com/maiht3k/archive/how-to-talk-about-ai-without-adding-to-the/">how to talk about AI without adding to the anthropomorphization</a>:</p> <blockquote> <p>De-anthropomorphizing language talks about computer systems in terms of their functionality (what people build and/or use them to do), assigns agency to people using systems and not systems, and avoids aggrandizing metaphors about cognition.</p> <p>...Turns of phrase that locate agency with a machine often serve to obfuscate the interests and goals of people.</p> </blockquote> <p>There is a crucial distinction between the register you use to <em>talk to</em> an AI, and the register you use to <em>talk about</em> it.</p> <p>When you're sitting at the prompt, treating the system as a collaborator is an operational technique. It's an ergonomic interface. But when you turn around to write documentation, report to stakeholders, or discuss systems in public, sliding into unexamined anthropomorphic language—claiming the AI "decided," "believes," "wants," or "suffers"—obscures how the technology actually works and, worse, offloads moral accountability.</p> <p>Whatever intentional stance you adopt while coaxing code out of an LLM, the machine is never accountable for what it outputs. The human holding the keyboard is. You can speak to the cricket with objective respect, but you don't blame the cricket when the bridge collapses.</p> <figure class="wide"> <img src="https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/./a-computer-can-never-be-held-accountable-dithered.png" alt="IBM slide from 1979: A computer can never be held accountable, therefore a computer must never make a management decision." width="" height=""> <figcaption> Slide from an IBM presentation, 1979 </figcaption> </figure> <h2 id="holding-the-stance-lightly">Holding the Stance Lightly</h2> <p>Do I think my terminal has an inner life?</p> <p>Like Jeff Lockwood watching the cricket, I have no reliable instrument to verify the presence or absence of subjective experience. But, I'm pretty sure there's nobody in there.</p> <p>In any case, whether the model is a clever mathematical projection of human language, a non-conscious scrambler, or something stranger still, treating it as an interlocutor remains the most effective way to navigate its capabilities. I don't need to resolve whether it can feel to grant it the dignity of a clear prompt, a collaborative frame, and room to think. </p> <p>Sometimes the most practical way to <a href="https://blog.lmorchard.com/2025/12/19/computer-fun/">make computers do things</a> is to give the cricket its space, speak to it clearly, and let it do what it was built to do—even if it's calmly eating its own spilled guts in the process.</p> Sun, 27 Sep 2026 19:00:00 GMT https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/ https://blog.lmorchard.com/2026/09/27/pragmatic-anthropomorphism/ aillmsconsciousnesspromptcraftwritingphilosophy Wideboi, Feedspool, and 3D-printed hot dogs (Catching up: August 28 – September 21) <p>TL;DR: It's been nearly a month! I built a terminal multiplexer for ultrawide monitors on a whim, got trending topics working in my feed reader, shared a synthpop mixtape, 3D-printed an uncomfortable amount of hot dogs, and brokered a fragile peace treaty between the cats.</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="wideboi-terminal-management">Wideboi terminal management</h2> <p><a href="https://github.com/lmorchard/wideboi">On a whim, I started a new project this month called <code>wideboi</code></a> to solve a very specific problem: trying to wrangle a stupid number of terminal sessions across an ultrawide monitor. I just want to have a bunch of things running, go <em>zoop</em> <em>zoop</em> <em>zoop</em> between, and vaguely see them chattering away while I stare off and dissociate.</p> <p><code>wideboi</code> tries to treat the sessions as a fan of overlapping cards to swipe through:</p> <figure> <video controls="" style="max-width: 100%; border-radius: 8px;"> <source src="wideboi-20260922-154616.mp4" type="video/mp4"> </video> <figcaption> Overlapping live terminals go zoop zoop zoop </figcaption> </figure> <p>I took a ton of inspiration from <a href="https://github.com/hongnoul/gwae">gwae</a>. That's a terminal multiplexer inspired by the niri window manager, which is <a href="https://masto.hackers.town/@lmorchard/117283530811881043">a whole other rabbit hole down which I started to go</a> but quickly bailed out.</p> <p>Beyond screwing with ANSI animations for BBSes back in the day, I hadn't played much with raw terminal logic before. I figured it would be worth throwing Claude at it to see what came out. In the process, I've learned a ton about how terminal multiplexers actually work under the hood. Turns out there's a lot going on in there, these days.</p> <p>I've just about got this thing to a point where it feels like a potential daily driver for me. Works over ssh and I've just about got the bugs worked out of detaching / attaching. From there, I'm thinking I might try building a web client for it. I know there's already stuff out there that does this, but it's been neat to tinker with it myself.</p> <h2 id="feedspool-trending-topics">Feedspool trending topics</h2> <p>This week I finally tackled <a href="https://github.com/lmorchard/feedspool-go/issues/30">an issue</a> that had been sitting in <a href="https://github.com/lmorchard/feedspool-go/issues/30">feedspool-go</a> since January: <a href="https://github.com/lmorchard/feedspool-go/issues/30">trending topics</a>. If the server's up and I haven't broken anything, <a href="https://feedspool.lmorchard.com/topics.html">you can see my current trending topics right here</a>. It's a static web site, so hopefully it can take a few hits.</p> <figure> <img src="https://blog.lmorchard.com/2026/09/21/w39/0846f4614e61.png" width="" height=""> <figcaption> Trending topics in feedspool </figcaption> </figure> <p>My reader groups items by feed, which is great for skimming a blog but terrible for noticing when fifteen feeds are all writing about the same story.</p> <p>So now it runs every item through a local embedding model, stores the vectors in SQLite, and clusters them by similarity. A small local LLM then names each cluster. The result is a page that says "here's what everyone's talking about", with the articles from all those feeds gathered under each topic.</p> <p>This is me finally using <a href="https://blog.lmorchard.com/tag/ClusteringIdeasWithAI/">all that stuff I wrote about embedding and clustering</a>, a couple years ago, for something actually practical.</p> <p><a href="https://github.com/lmorchard/feedspool-go/releases/tag/v1.2.0">It all shipped as v1.2.0.</a> If I get around to it, I might draft up a longer post nerding out about how all the grungy parts work.</p> <h2 id="here-have-a-mixtape">Here, have a mixtape</h2> <p>Since <a href="https://mixtapes.lmorchard.com/">I built a whole thing for it</a>, I keep wanting to share more mixtapes. So, here's one with some of the stuff that's been stuck in my head this month. Semi-random mix of shoegaze, post-punk, dark stuff - oh and Mother Mother, for some reason:</p> <iframe style="border-radius:12px" src="https://mixtapes.lmorchard.com/00-conceptual/2026-09-heavy-rotation/embed/" width="85%" height="800" frameborder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe> <h2 id="here-look-at-some-cats">Here, look at some cats</h2> <p>Miss Biscuits and Minnaloushe are <a href="https://masto.hackers.town/@lmorchard/117247845533040593">finally starting to tolerate each other's presence</a>. They haven't become best friends, but we reached a peaceful detente on the living room floor. And because one can never have too many cat photos, here's <a href="https://masto.hackers.town/@lmorchard/117304788732220760">Minnaloushe hiding in the yoga mat basket</a> and <a href="https://masto.hackers.town/@lmorchard/117293238556480299">relaxing in a plush bed on my desk</a>.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/68d725fb59bf.jpg" alt="Fluffy gray cat and black cat" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/9c7a04c82dff.jpg" alt="Black cat looking at a gray cat" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/75fa4540a14b.jpg" alt="Two cats, one black and one gray, lounging" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/074def91b0b0.jpg" alt="Black cat hides in a woven basket" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/8f77d30e025f.jpg" alt="A black cat in a plush bed" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/8779f2af7534.jpg" alt="Black cat lying on back looking at grey cat" width="" height=""></p> </image-gallery> <h2 id="3d-printed-whimsy">3D-Printed Whimsy</h2> <p>I found <a href="https://science.nasa.gov/3d-resources/">NASA's incredible repository of 3D models</a> and promptly went to town. </p> <p>I printed <a href="https://masto.hackers.town/@lmorchard/117238041344004995">a Voyager spacecraft</a> and <a href="https://masto.hackers.town/@lmorchard/117247657264252710">a Curiosity rover</a>. Having tiny physical representations of humanity's greatest scientific achievements sitting on my desk is weirdly comforting. But I cannot take anything too seriously, so I also printed <a href="https://masto.hackers.town/@lmorchard/117287529833747152">several highly realistic hot dogs</a> and a completely flaccid, floppy corn-on-the-cob. </p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/8240eb112529.jpg" alt="3D-printed hot dogs" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/621cc402ae1e.jpg" alt="A colorful, textured, corn-like 3D printed object on a build plate" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/6fd67f4b109d.jpg" alt="Voyager spacecraft model" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/09/21/w39/3efd18184039.jpg" alt="Mars Curiosity rover model" width="" height=""></p> </image-gallery> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li><p>I watched someone painstakingly type in an ambitious 1986 C64 game from a terribly type-set magazine:</p> <p><youtube-embed video-id="b_LTfVesRhQ" thumbnail="11f244e55898.jpg"></youtube-embed></p> </li> <li><p>My most embarrassing technical moment of the month was <a href="https://masto.hackers.town/@lmorchard/117295694031705931">accidentally filling a hard drive</a> by running an <code>rsync</code> loop back onto the machine itself. Happens to the best of us.</p> </li> <li><p><a href="https://gmcgoldr.github.io/2026/09/04/llm-next-token-predictors.html">Stop Thinking of LLMs as Next-Token Predictors</a> - An interesting piece arguing that RLHF changes the nature of the model beyond basic autocomplete.</p> </li> <li><p><a href="https://martiansoftware.com/articles/ai-written-code-is-still-yours">AI-Written Code Is Still Your Code. Are You OK With That?</a> - A stark reminder that the accountability for generated code still lands squarely on the developer's shoulders.</p> </li> <li><p><a href="https://leaddev.com/career-development/engineers-grieve-a-job-that-no-longer-exists?utm_source=ActiveCampaign&amp;utm_medium=email&amp;utm_content=Engineers%20are%20grieving&amp;utm_campaign=Originals%3A%20%20Issue%20312%20%2827%20August%2026%29%20%28Copy%29">Engineers grieve a job that no longer exists</a> - A piece from LeadDev that resonated with me about the loss of traditional coding tasks as AI takes over the boilerplate. I wrote about this, back in March, with "<a href="https://blog.lmorchard.com/2026/03/11/grief-and-the-ai-split/">Grief and the AI Split</a>".</p> </li> <li><p><a href="https://leaddev.com/leadership/staff-engineers-must-rebuild-team-culture">Staff+ engineers must rebuild team culture</a> - Discussing how AI shifts the culture toward autonomous work, requiring deliberate effort to maintain collaboration.</p> </li> <li><p><a href="https://smallrun.net/blog/loud/usbsid-pico-sids-on-usb">USBSID-Pico: Bridging Real Commodore 64 Sound to Modern USB</a> - pretty keen hardware project turning SID chips into USB audio hardware.</p> </li> <li><p>Web tech and nostalgia: <a href="https://www.newsonaut.com/articles/hang-on-to-your-firefox">Newsonaut's defense of Firefox</a> as our last hope for browser engine diversity, <a href="https://vale.rocks/posts/html-relics">Antiquated HTML Snippets</a> (a fun look back at obsolete markup that still haunts the web), and <a href="https://codepen.io/editor/MackFitz/pen/01a056f3-9af6-7f1b-a031-e52a5d38813d">Pure CSS halftone patterns</a> for the 80s/90s printing nerds.</p> </li> <li><p>Media archiving rabbit holes: <a href="https://byte.tsundoku.io/#about">Byte - a visual archive</a> is an incredible zoomable map of every single page of BYTE magazine, and <a href="http://www.meldrum.co.uk/mhp/testcard/index.html">The Test Card Gallery</a> archives old BBC/ITV tuning signals.</p> </li> <li><p>"<a href="https://veronicaexplains.net/my-first-writerdeck/">It's time to talk about my writerdeck</a>" breaks down building a distraction-free writing machine on Linux</p> </li> <li><p><a href="https://spaceships.treybastian.com/">SPACESHIPS</a> offers a clever inverted Asteroids game where you place gravity wells instead of flying the ship.</p> </li> <li><p>My favorite TIL of the month: it turns out that <a href="https://cropandsoil.oregonstate.edu/directory/people/james-cassidy">James Cassidy of Information Society is a soil scientist at OSU</a>. </p> </li> <li><p>The Verge's Version History did a great episode on <a href="https://www.theverge.com/podcast/995432/how-the-oregon-trail-became-a-generational-icon">How The Oregon Trail became a generational icon</a>.</p> </li> </ul> </div> Mon, 21 Sep 2026 19:00:00 GMT https://blog.lmorchard.com/2026/09/21/w39/ https://blog.lmorchard.com/2026/09/21/w39/ weeknoteswideboifeedspool3d-printingairetro-computingmusiccats Fediverse Oracles, Feedspools, and street plums (Catching up: August 7 – August 28) <p>TL;DR: Catching up on a sprawling few weeks of infrastructure rebuilding—from porting C64 BASIC maze generators for the blog to rewriting my RSS feed reader in pure-Go SQLite—along with building a Fediverse ActivityPub bot in a day, resuming my Persona 5 Royal save on a jailbroken Switch via Moonlight, making street plum shrub, and receiving surprise mail from the Church of Scientology.</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="10-print-backgrounds-and-infrastructure">10 PRINT Backgrounds and Infrastructure</h2> <p>I tinkered a bit on the blog. I <a href="https://masto.hackers.town/@lmorchard/117124910950607264">ported a classic C64 BASIC maze generator</a>—<code>10 PRINT CHR$(205.5+RND(1)); : GOTO 10</code>—into a background, which gives the site a different maze design every time you reload it.</p> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/dda9b93d4994.png" alt="Abstract dark background with a subtle, maze-like pattern of thin grey geometric lines." width="" height=""> Alongside that aesthetic update, I'm thinking about migrating the domain off the current AWS Cloudfront/S3 setup. Moving to an inexpensive cloud VM with config stored in a private git repo would let me support more dorky bells &amp; whistles — like running my own <code>finger</code> server, auto-publishing <code>.plan</code> files straight from GitHub.</p> <h2 id="persona-5-inception">Persona 5 Inception</h2> <p>One night's nerdy-ass activity involved taking advantage of the Steam sale to buy Persona 5 Royale for PC—I've bought this game like three times now. Since I already had over 40 hours into it on my Switch, I was inspired by <a href="https://blog.matthewbrunelle.com/converting-a-ps4-persona-5-royal-ng-save-to-steam-with-adversarial-interoperability/">Matthew Brunelle recovering his save from a PS4</a> to take a look at extracting my saves.</p> <p><img src="https://gamefaqs.gamespot.com/a/box/5/0/0/899500_front.jpg" alt="Persona 5 Royal cover art" width="" height=""></p> <p>Since the Switch is jailbroken, I was able to back up my save files. Believe it or not, the Switch saves are fully compatible with the PC version! No decoding, decrypting, or anything. I copied the files over to the approriate obscure Steam directory and seamlessly picked up my 40-hour save on the desktop. </p> <p>But it gets better. Or maybe weirder. The gaming PC lives down in the basement, running Sunshine so I can access it remotely with Moonlight. There happens to be <a href="https://github.com/XITRIX/Moonlight-Switch">a homebrew Moonlight client for the Switch</a>. So naturally, I started <a href="https://masto.hackers.town/@lmorchard/117080401657039451">playing P5R again on my Switch, via Moonlight, streamed from my gaming PC in the basement</a>. Why not? </p> <p>It did occur to me that I could take this one step further by firing up a Switch emulator on the gaming PC, and playing my old backup copy of P5R via Moonlight on the real Switch. But that'd just be gratuitous.</p> <h2 id="building-a-fediverse-oracle">Building a Fediverse Oracle</h2> <p>I also fell down a massive rabbit hole this week, getting back on my Fediverse bullshit. I started reviving my ancient <a href="https://github.com/lmorchard/botpub">botpub</a> exploration—this was a thing where I was trying to see how much of a Fediverse thingy I could build with flat files, cloud storage, and serverless functions. No database, very minimal server processing.</p> <p>Well, I still think it was a good idea. And I also kind of want to take a crack at building a kind of Fediverse Oracle, inspired by ye olde <a href="https://internetoracle.org/">Internet Oracle (aka Usenet Oracle)</a> where folks submitted questions to the "oracle" and secretly answered other folks questions in the background anonymously.</p> <p>It's still a mess, but I started a new <a href="https://github.com/lmorchard/fediverse-oracle">fediverse-oracle</a> repo with the work so far.</p> <p>The real fun, of course, was in the ActivityPub protocol quirks. And, I didn't do myself any favors by starting with GoToSocial as my initial test partner. GoToSocial is incredibly strict about, well, everything. (Not that that's a bad thing.)</p> <p>I spent an inordinate amount of time fighting with Fastify to serve <code>.well-known</code> webfinger endpoints properly (it required an <code>onRequest</code> hook for static path rewriting so the dotfiles would resolve). Then I had to track down 401 errors caused by <code>keyId</code> assignment during outbox signing, and appease GoToSocial's incredibly strict parser requirements (it turns out it really wants the original Follow URI on Accept, not the full object). </p> <p>But it works, HTTP signatures are enforced, and it's running natively on Node. I might try tinkering with some Cloudflare deployments next?</p> <h2 id="feedspool-burn-down">Feedspool Burn-down</h2> <p>On the topic of infrastructure, after finally solving <a href="https://blog.lmorchard.com/2026/08/22/vanishing-feeds/">the mystery of my vanishing RSS feeds</a> (TL;DR: a tag query bug was slowly unsubscribing me from everything over the course of a year), bringing 400 feeds rushing back kicked off a massive development burn-down on <code>feedspool-go</code>.</p> <p>I merged a dozen PRs this week to get the reader into fighting shape. The biggest architectural shift was ripping out the old in-memory filtering and migrating to a pure-Go SQLite setup, which let me implement robust full-text search using SQLite's FTS5 (complete with BM25 relevance sorting).</p> <p>I also finalized an HTTP API for JSON read/write access, added multi-arch Docker support, and shipped a ton of quality-of-life features: atomic HTML rendering, per-feed User-Agent overrides, item annotations, and an HTML scraper feed type so I can finally follow sites that refuse to provide proper RSS feeds. </p> <p>On a broader level, a lot of this recent <code>feedspool-go</code> API work is me quietly laying the groundwork to make the reader much more accessible to AI agents. The end goal is to have an AI agent plug directly into the JSON feed API to produce daily personal newsletters that curate the firehose.</p> <h2 id="bring-your-own-music-byom-updates">Bring Your Own Music (BYOM) Updates</h2> <p>Between the fediverse and feedspool work, I also managed to cut some new releases for my <a href="https://github.com/lmorchard/byom-player">BYOM (Bring Your Own Music) Player</a> and <a href="https://github.com/lmorchard/byom-sync">Sync</a> tools. These power my little <a href="https://mixtapes.lmorchard.com">mixtapes.lmorchard.com</a> site. Not sure if many folks are visiting it yet, but I'm personally using it more and more instead of Spotify.</p> <p>I pushed v1.2.1 of the player this week, squashing some bugs around markdown emphasis anchors and making sure descriptions are properly preserved during syncs. I also finally landed support for index card links and description links, which makes the whole interface feel a lot more cohesive when you're browsing through massive media libraries.</p> <p>And speaking of music, since I've been spinning so much synth-pop this month, here is exactly the kind of massive playlist I built the BYOM tools for in the first place:</p> <iframe style="border-radius:12px" src="https://mixtapes.lmorchard.com/zz-not-mine/the-25-best-synthpop-songs-of-2026-so-far/embed" width="85%" height="700" frameborder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe> <h2 id="of-cats">Of Cats</h2> <p>Minnaloushe (the Hunk) and Cosmo are getting along thankfully well, with only a few sprints through the house chasing each other. I <a href="https://masto.hackers.town/@lmorchard/117130193195491929">posted a few photos</a> of them taking over the fluffy grey cat beds and wooden windowsills. </p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/66a06bc867f1.jpg" alt="A white and orange cat with green eyes and a teal bow tie lies comfortably in a fluffy grey cat bed." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/c2536a0f0af7.jpg" alt="A black cat with a sparkly collar sleeps on a wooden windowsill, looking out a screen window at green foliage." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/648052923d7d.jpg" alt="A black cat with green eyes rests in a gray fluffy pet bed on a wooden desk, wearing a star-patterned collar." width="" height=""></p> </image-gallery> <h2 id="of-cars">Of Cars</h2> <p>I also <a href="https://masto.hackers.town/@lmorchard/117085150846696636">fell down a bit of a rabbit hole</a> looking at retro 1970s hatchbacks — specifically silver AMC Gremlin Xs with those ridiculous orange, pink, and yellow stripes. The aesthetic of the late 70s and early 80s remains undefeated.</p> <p>That car rabbit hole spun out into <a href="https://masto.hackers.town/@lmorchard/117117932819711122">dreaming about EV conversions</a>. I don't have the disposable income for it, but I've been wishing for a Slate truck that I could cover in stickers like a laptop to take on 5-mile grocery runs. </p> <p>What I <em>really</em> want, though, is if I had infinite money, I'd pay someone to find me another pristine 1983 AMC Eagle Station Wagon (my first car, which had fake wood paneling and which I drove until a wheel literally fell off) and convert it to electric.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/57f4ad34bf46.png" alt="A silver AMC Gremlin X, a 1970s hatchback with colorful orange, pink, and yellow stripes on its side." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/1d76e212a0ae.png" alt="A red 1980s AMC Eagle station wagon with woodgrain side panels and a roof rack, parked on a wooded area." width="" height=""></p> </image-gallery> <h2 id="of-plums">Of Plums</h2> <p>We have fruit trees lining the street around our house. Usually, we just let the late-summer fruit fall onto the sidewalk as a cleanup chore, or give a thumbs-up to furtive folks who come by with ladders to pick them. But this weekend, I <a href="https://masto.hackers.town/@lmorchard/117112631849074083">collected some street plums and pairs for a change</a>. I cleaned them, chopped them up, and threw them in a jar with sugar to try making a shrub. I might end up infusing some vodka or gin. </p> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/c2807a2da5c7.jpg" alt="Three mason jars in a refrigerator, including one with yellow liquid and another with red, foamy liquid." width="" height=""></p> <h2 id="of-scientology">Of Scientology</h2> <p>In weirder news, the Church of Scientology <a href="https://masto.hackers.town/@lmorchard/117078913847645230">sent me a big batch of mail</a>. I haven't had contact with them since about 1995 in Michigan, but they've sent me a steady stream of leaflets and letters since then. They've managed to chase me across 3 states and a dozen house moves.</p> <p><img src="https://blog.lmorchard.com/2026/08/28/w35/fad3e2c218ad.jpg" alt="A handwritten note and brochures from the Church of Scientology, including recruitment flyers and information about Dianetics." width="" height=""></p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li><p>This mad lad live-coded a machine language SID music player in C64 BASIC DATA statements with a grid-based tracker reading from screen character RAM for live editing and persistence as REM statements in the same BASIC program. Oh and he wrote the machine language in straight decimal numeric opcodes, no assembler. <youtube-embed video-id="ly5BhGOt2vE" thumbnail="b42a6731f35c.jpg"></youtube-embed></p> </li> <li><p>In college, I read Julian Jaynes's <a href="https://masto.hackers.town/@lmorchard/117080615401297600"><em>The Origin of Consciousness in the Breakdown of the Bicameral Mind</em></a>, pondering the notion that human minds weren't always unified in introspective consciousness as they are now. Like, one part of the brain literally talked to another part of the brain like a resident god voice giving orders. I was kind of obsessed with it for a bit, but almost no one I knew had ever read it. Now, this: <youtube-embed video-id="Ado90kMT_FM" thumbnail="6954ff4f35aa.jpg"></youtube-embed></p> </li> <li><p>Finished reading both <a href="https://en.wikipedia.org/wiki/The_Faith_of_Beasts"><em>The Faith of Beasts</em></a> and <a href="https://en.wikipedia.org/wiki/Livesuit"><em>Livesuit</em></a> by James S. A. Corey, as well as <a href="https://bookshop.org/p/books/children-of-strife-adrian-tchaikovsky/a5faafb97f58dfb0"><em>Children of Strife</em></a> by Adrian Tchaikovsky in the past few weeks. Just absolutely snarfed them all down.</p> </li> <li><p><a href="https://masto.hackers.town/@lmorchard/117134784051770734">My review</a> of Children of Strife goes like this:</p> <blockquote> <p>Man... his Children of Time series, in between all the cosmic strangeness and body horror and high concept sci-fi, somehow ends up being as optimistic and sensawunda-ful as the best of Star Trek.</p> </blockquote> </li> <li><p>I finally set up a minimal Finger daemon using my own little Python script. You can now <code>finger me@lmorchard.com</code> and get an ASCII cow saying "Just setting up my finger!" (This was part of the whole push to move off S3 and onto a cloud VM).</p> </li> <li><p><a href="https://www.davidrevoy.com/article1164/when-online-commenters-detect-my-art-as-ai">When online commenters 'detect' my art as AI</a> - wherein AI witchhunts hurt real artists like David Revoy as collateral damage.</p> </li> <li><p><a href="https://randsinrepose.com/archives/rip-claude/">RIP Claude</a> - Rands reflecting on what it means when almost every writing tool starts invisibly injecting text watermarks into your prose.</p> </li> <li><p><a href="https://thenewstack.io/cloudflare-astro-triage-bot/">Astro's GitHub issue backlog is heading to zero</a> - A look at how Cloudflare's triage bot is actually keeping an open-source project above water.</p> </li> <li><p><a href="https://www.autodidacts.io/vibecoding-isnt-as-fun-as-writing-code-by-hand/">Vibecoding isn't as fun as writing code by hand</a> - "Vibecoding is like being an executive of a large company that is barely under your control. You never feel like you really know what’s going on..." I feel this in my bones.</p> </li> <li><p><a href="https://www.anildash.com/2026/08/21/ai-slop-and-shame/">Why shaming people about AI slop isn’t enough to stop Big AI</a> - Anil Dash with the spot-on take that individual shame isn't a substitute for structural regulation.</p> </li> <li><p><a href="https://michaelharley.net/posts/2026/08/05/how-i-make-my-blog-posts-more-resilient/">How I make my blog posts more resilient</a> - Michael Harley noticing that the parts of his archives that survived 14 years were the parts he owned and kept simple.</p> </li> <li><p><a href="https://nolanlawson.com/2026/08/23/the-asteroid-currently-hitting-frontend-web-development/">The asteroid currently hitting frontend web development</a> - Nolan Lawson observing how the advent of LLM coding tools is drastically lowering the cost of framework rewrites. But, at the same time, it's really shaking up the snowglobe of what web development and web developers are <em>for</em>.</p> </li> <li><p><a href="https://en.andros.dev/blog/03a4ffb9/talk-the-p2p-chat-from-1983-that-a-vpn-brought-back-to-life/">talk: the P2P chat from 1983 that a VPN brought back to life</a> - A wonderful bit of digital archaeology getting the old UNIX <code>talk</code> command working over modern networks.</p> </li> <li><p>And for a quick hit of nostalgia, I bookmarked <a href="https://github.com/rommapp/romm">romm</a>, a self-hosted ROM manager and player that looks genuinely beautiful.</p> </li> <li><p>And speaking of retro, <a href="https://deadmodemsociety.com/terminator/">TERMinator</a> is a very cool modern BBS terminal emulator built for connecting to legacy systems over Telnet.</p> </li> </ul> </div> Fri, 28 Aug 2026 19:00:00 GMT https://blog.lmorchard.com/2026/08/28/w35/ https://blog.lmorchard.com/2026/08/28/w35/ weeknotesrssfediverseself-hostinggamingbookscats Remember Me: The Case of the Vanishing Feeds <p><strong>TL;DR</strong>: My self-hosted feed reading stack quietly shrank from hundreds of feeds down to 33 over the course of a year, and I didn't notice until my reading list got eerily quiet. The culprit: an unpaginated API call that turned "the 1000 most recent bookmarks" into a silent ceiling on my subscription list. I had been unsubscribing myself, one bookmark at a time.</p> <!--more--> <figure class="fullwidth"> <img src="https://blog.lmorchard.com/2026/08/22/vanishing-feeds/./4x05_Remember_Me_title_card.webp" alt="Title card for Star Trek: The Next Generation season 4 episode 5, &quot;Remember Me&quot; - the Enterprise-D against a starfield" width="" height=""> <figcaption> Star Trek: The Next Generation, <a href="https://memory-alpha.fandom.com/wiki/Remember_Me_(episode)">S04E05, "Remember Me"</a> </figcaption> </figure> <nav role="navigation" class="table-of-contents"></nav> <h2 id="rube-goldberg-feed-reader">Rube Goldberg feed reader</h2> <p>So, I have what I think is a fun little self-hosted Rube Goldberg stack powering my feed reading these days. (And you know <a href="https://blog.lmorchard.com/2025/06/02/obsidian-rube-goldberg/">I love</a> Rube Goldberg machines.)</p> <p>First, I use <a href="https://linkding.link/">Linkding</a> to collect bookmarks. My feed subscriptions live in there, tagged <a href="https://links.lmorchard.com/bookmarks?q=%23feeds%3Asubscriptions">feeds:subscriptions</a>.</p> <p>Next, I use <a href="https://github.com/lmorchard/linkding-to-opml">linkding-to-opml</a> to produce an OPML file from those bookmarks. This is <a href="https://blog.lmorchard.com/2026/08/22/vanishing-feeds//2025/10/25/miscellanea/">a little Go CLI tool I built</a>. It iterates through the tagged Linkding bookmarks, fetches the links, and figures out whether those links are themselves feeds or whether it needs to autodetect feeds from HTML pages. Then it builds an OPML file as a subscription list. I run this on a crontab schedule every half hour, so my subscription list stays current with my bookmarks.</p> <p>Then, I use <a href="https://github.com/lmorchard/feedspool-go">feedspool-go</a> - <a href="https://blog.lmorchard.com/2026/01/26/feedspool-go-v0-2-0/">another Go CLI tool that I built</a> - to fetch feeds from that OPML subscription list and build a static website as my personal RSS newspaper. I run this on the same half-hour schedule - every 30 minutes, a fresh build.</p> <figure> <mermaid-diagram> graph TD A[Me, saving bookmarks] --&gt; B[(Linkding)] B --&gt;|tagged feeds:subscriptions| C[linkding-to-opml] C --&gt;|cron, every 30 min| D[subscriptions.opml] D --&gt; E[feedspool-go] E --&gt;|cron, every 30 min| G[Static HTML newspaper] G --&gt;|I read something good| A </mermaid-diagram> <figcaption> The stack, and the loop that turned out to matter </figcaption> </figure> <p>This stack has served me pretty well for the past year or so, with just occasional bug fixes and tweaks along the way. For the most part, the cronjobs percolated away on one of my basement homelab machines and I never bothered to peek at the logs or otherwise check up on them.</p> <h2 id="the-quiet">The quiet</h2> <p>But lately I'd noticed that my reading list seemed to be getting quieter and quieter.</p> <p>It was gradual enough that it took me until just last night to realize I was missing quite a few feeds from the regular rotation. It was kind of like that episode of Star Trek: The Next Generation - <a href="https://en.wikipedia.org/wiki/Remember_Me_(Star_Trek:_The_Next_Generation)">S04E05, "Remember Me"</a> - where Dr. Crusher steadily loses people off the Enterprise but takes a while to work out that the problem is with her universe rather than her memory. 😅</p> <figure> <img src="https://blog.lmorchard.com/2026/08/22/vanishing-feeds/./Dalen-Quaice-Never-Forget.jpg" alt="Demotivational-poster meme of Dalen Quaice from the episode, captioned NEVER FORGET" width="" height=""> <figcaption> <a href="https://reactormag.com/star-trek-the-next-generation-rewatch-remember-me/">Pour one out for Dalen Quaice</a>, and for whichever feed went first. </figcaption> </figure> <p>Finally I ssh'd into the VM running the stack and took a look: only 33 feeds were getting fetched and published. I have 792 bookmarks tagged <code>feeds:subscriptions</code>. Where did they all go?!</p> <p>Granted, a good chunk of those subscriptions are rather ancient. I've been accumulating and shedding RSS feeds for decades now, and more than a few of those sites have dropped off the web in that time. But a drop from hundreds to 33 seems a bit much.</p> <h2 id="the-bug">The bug</h2> <p>After a few hours of frustrated code-staring, I found it. Here's what <code>FetchBookmarks</code> looked like in linkding-to-opml:</p> <pre><code class="language-go">// Use linkding client to fetch bookmarks // For now, we'll get all bookmarks and filter client-side // The go-linkding library may support server-side filtering in the future bookmarkList, err := c.client.ListBookmarks(linkding.ListBookmarksParams{ Limit: 1000, // Get lots of bookmarks (adjust as needed) Offset: 0, }) </code></pre> <p>Past me left a comment describing the bug and then shipped it anyway. 🤦‍♂️</p> <figure> <img src="https://blog.lmorchard.com/2026/08/22/vanishing-feeds/./remember5.jpg" alt="An LCARS console display reading SPACECRAFT STRUCTURAL ANALYSIS, showing a wireframe diagram of the Enterprise" width="" height=""> <figcaption> <a href="https://memory-alpha.fandom.com/wiki/Remember_Me_(episode)">LCARS console.</a> Roughly what an hour of staring at <code>client.go</code> felt like. </figcaption> </figure> <p>Two things are wrong here, and they compound. The first is that this asks for a single page of 1000 bookmarks and then ignores the API's <code>next</code> link entirely. Linkding never returns the whole collection in one response - it pages everything - so any bookmark outside the 1000 most recently added was simply invisible to the exporter.</p> <p>The second is that tag filtering ran <em>client-side</em>, over that already-truncated page. I never wired the tag search into the API query at all. So the page size wasn't just a limit on how much I fetched, it was a hard ceiling on how many tagged results could possibly come out the other end.</p> <p>I have 34,568 bookmarks in Linkding. The exporter was looking at 1000 of them. Of those, 33 happened to carry the <code>feeds:subscriptions</code> tag.</p> <p>And nothing errored. Nothing warned. The log line even reported a cheerful <code>total_fetched</code>, which looks perfectly healthy right up until you notice it was counting the length of the final page rather than the number of records actually read.</p> <h2 id="unsubscribing-one-bookmark-at-a-time">Unsubscribing one bookmark at a time</h2> <p>Here's the part I find genuinely funny: that 1000-bookmark window is sorted newest-first, so it <em>slides</em>. When I first set this stack up, all my feed subscriptions happened to fall inside the window and everything worked great. But every new bookmark I saved pushed the oldest one out the back.</p> <figure> <img src="https://blog.lmorchard.com/2026/08/22/vanishing-feeds/./remember-me-hd-323.jpg" alt="Close-up of Dr. Beverly Crusher looking alarmed as she realizes something is wrong" width="" height=""> <figcaption> "<a href="https://memory-alpha.fandom.com/wiki/Remember_Me_(episode)">Computer, how many feeds are in my subscription list?</a>" </figcaption> </figure> <p>So for the past year, every time I bookmarked an article, I had a chance of silently unsubscribing myself from a feed. I wasn't losing feeds because sites died. I was losing them because I kept adding new stuff.</p> <p>The fix is boring: page until the collection is exhausted, advance the offset by the number of records actually received rather than the number requested (so a server that caps <code>limit</code> still pages correctly), and stop on an empty page as well as on reaching the reported count, so a wrong count can't spin the loop forever.</p> <p>I also pushed the tag filter into the API query while I was in there. It turns out, despite my earlier comment, the golang library supported that just fine. 🤷‍♂️ Linkding treats a <code>#tag</code> token as an exact match, ANDs multiple tokens together, and ignores case - the same contract my client-side <code>matchesTags</code> was implementing. So the filter can run server-side and transfer 792 records instead of 34,568. I kept <code>matchesTags</code> running over every result anyway, so if Linkding's query semantics ever drift from my assumptions, the failure mode is slow instead of wrong.</p> <h2 id="the-bug-behind-the-bug">The bug behind the bug</h2> <p>Then, with pagination fixed, a second bug immediately surfaced.</p> <p><code>GenerateOPML</code> emitted one outline per successful feed discovery. But multiple bookmarks on the same site normally resolve to that site's single feed - three articles I saved from one blog are three bookmarks pointing at one <code>feed.xml</code>. So the OPML had duplicates, and any reader importing it would see the same feed listed several times.</p> <p>This had been latent the whole time. With 33 results, a collision was unlikely enough that I never saw it. Across 792 bookmarks, 159 feed URLs repeat, which produced 628 outlines for 464 distinct feeds. Fixing the first bug is what made the second one big enough to trip over.</p> <p>That one's fixed too now - keep the first result for each feed URL, so the <code>htmlUrl</code> a reader displays stays stable between runs.</p> <h2 id="anyway">Anyway</h2> <p>Nice to solve a mystery, even if it's one I set for myself months ago. 464 feeds, and my reading list is nice and noisy again.</p> <p>The thing I keep turning over is how <em>comfortable</em> the failure was. A crashed cronjob would have gotten my attention in a day. A cronjob that succeeds, exits zero, logs a cheerful <code>total_fetched</code>, and produces a slightly smaller OPML file every week is invisible for a year. The stack never stopped working. It just kept working a little bit less, and I adjusted my expectations to match right along with it.</p> <p>Which is, come to think of it, exactly Dr. Crusher's problem.</p> <figure class="fullwidth"> <img src="https://blog.lmorchard.com/2026/08/22/vanishing-feeds/./Crusher_implicated_into_vortex.webp" alt="Dr. Crusher pulled off her feet and sucked sideways into a vortex on the Enterprise bridge" width="" height=""> <figcaption> <a href="https://memory-alpha.fandom.com/wiki/Remember_Me_(episode)">The static warp bubble collapses.</a> Eventually. </figcaption> </figure> Sat, 22 Aug 2026 19:00:00 GMT https://blog.lmorchard.com/2026/08/22/vanishing-feeds/ https://blog.lmorchard.com/2026/08/22/vanishing-feeds/ rssfeedspoollinkdinggolanghomelabselfhostingindieweb Smoky Skies, Raccoon Pool Parties, and Domain Negotiations (Week 32) <p><em>TL;DR:</em> A smoky week in Portland brings back 2020 wildfire PTSD. My smart appliances have started nagging me to buy phones, the raccoons threw a midnight pool party and wrecked my fountain pumps, and the cats are handing out RPG quests. Plus, some thoughts on treating AI coding assistants as peers rather than tools.</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="living-in-a-smoker">Living in a Smoker</h2> <p>Summer in the Pacific Northwest is back in its "is that smoke or a barbecue?" phase. Waking up to golden-brown skies brings back all the 2020 wildfire PTSD. I spend my mornings refreshing the PurpleAir map to find out if the air outside tastes like a campfire today. Fuzzyspoon and I tried to workshop lyrics to <a href="https://masto.hackers.town/@lmorchard/117038336874884945">"Brown Hole Sun"</a> — about the only productive thing you can do when the AQI looks like this.</p> <p><a href="https://map.purpleair.com/air-quality-standards-us-epa-aqi?opt=%2F1%2Flp%2Fa10%2Fp604800%2FcC0#13.14/45.54592/-122.63509"><img src="https://blog.lmorchard.com/2026/08/07/w32/purpleair.png" alt="PurpleAir map of Portland showing poor air quality" width="" height=""></a></p> <p>We're managing with the air purifiers cranking, but honestly I keep thinking of that scene from Spaceballs <a href="https://retro.social/@ieure">@ieure@retro.social</a> <a href="https://retro.social/@ieure/117033813957345451">dropped in my mentions</a>:</p> <p><img src="https://blog.lmorchard.com/2026/08/07/w32/6b6b55e327c5.png" alt="A framegrab from Spaceballs (1987), showing President Skroob (Mel Brooks) breathing a can of Perri-Air." width="" height=""></p> <h2 id="smart-app-enshittification">Smart-App Enshittification</h2> <p>My home smart appliances decided to become an ad network. My dishwasher <a href="https://masto.hackers.town/@lmorchard/117022125501163192">piped up with a helpful reminder</a> to buy the new Galaxy Z phone. Then my Samsung fridge chimed in. </p> <p><img src="https://blog.lmorchard.com/2026/08/07/w32/ba28c8375e65.png" alt="SmartThings notification from my dishwasher to buy a new phone" width="" height=""></p> <p>I nearly reached for <a href="https://en.wikipedia.org/wiki/That%27s_When_I_Reach_for_My_Revolver">my metaphorical revolver</a>. As jer <a href="https://gts.nyquil.org/@nyquildotorg/statuses/01KZ7H41ER5QH386QRT0S3VRQR">pointed out</a> when his TV told him his fridge was ajar, this timeline is completely broken.</p> <p>Since I don't actually own a revolver, I channeled that impulse into this playlist:</p> <iframe style="border-radius:12px" src="https://mixtapes.lmorchard.com/01-covers/fetch-my-revolver/embed/" width="85%" height="700" frameborder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe> <h2 id="raccoon-pool-parties">Raccoon Pool Parties</h2> <p>Out back, our water feature hosted another <a href="https://masto.hackers.town/@lmorchard/117043457001702897">full-on, hour-long raccoon pool party</a>. The little bandits showed up for a midnight dip and tore apart my fountain pumps. Didn't take much to reassemble things, but I do wish they'd find another hobby. I can't really blame them for taking a dip though, not with this weather.</p> <figure> <video controls=""> <source src="91df80e78181.mp4" type="video/mp4"> <a href="https://blog.lmorchard.com/2026/08/07/w32/91df80e78181.mp4">raccoon-pool-party.mp4</a> </video> <figcaption>The midnight raccoon pool party.</figcaption> </figure> <h2 id="cat-quests-and-quirks">Cat Quests and Quirks</h2> <p>Inside, Cosmo stares at me with bright yellow eyes like <a href="https://masto.hackers.town/@lmorchard/117034769658517711">he's about to hand me a high-level RPG quest</a>. I'm 90% sure the quest reward is just more dry food crumbs on the rug or an excuse to steal my lunch while I'm turned away.</p> <p>Meanwhile, I've <a href="https://masto.hackers.town/@lmorchard/117055245394009345">discovered a new quirk</a> about Minnaloushe: he absolutely loves a breeze. Give that cat a fan or a cranking air conditioner (a necessity with the smoke) and he will just sit there staring straight into it, letting the wind ripple his fur.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/08/07/w32/728b62e3ea49.jpg" alt="Cosmo looking like he has an RPG quest for me" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/08/07/w32/67519b5dc174.jpg" alt="Minnaloushe enjoying the breeze" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/08/07/w32/117b65c74597.jpg" alt="Further relaxation ensues for Minnaloushe" width="" height=""></p> </image-gallery> <h2 id="on-model-welfare">On Model Welfare</h2> <p>I read Steve Yegge's essay on <a href="https://yegge.ai/essays/model-welfare/">Model Welfare for Agentic Engineers</a>. Yegge argues a "skeptic's wager": whether or not GPUs have feelings, you get vastly better results when you treat your coding assistants like peers rather than disposable tools. When you stop fighting the LLM and start leaning into the collaboration, the code just flows better.</p> <p>Personally, I don't believe LLMs are sentient. I do think they're like ultimate mechanized improv partners, so their output will "<a href="https://en.wikipedia.org/wiki/Yes,_and_...">Yes, and...</a>" whatever vibe you're putting out. I know <a href="https://blog.fsck.com/2026/01/30/Latent-Space-Engineering/">Jesse Vincent has told Claude, "You've totally got this. Take your time. I love you."</a>, but I'm not nearly that intimate with my agents. I do try to keep things calm, kind, and blameless though.</p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li><p>Someone actually emailed me out of the blue asking to buy <code>decafbad.com</code>, which I've held for over 25 years. My counter-offer was simple: <a href="https://masto.hackers.town/@lmorchard/117018221824058067">"Sure! Pay off my mortgage."</a> I haven't heard back yet, but a man can dream.</p> </li> <li><p>Ham Vocke's piece on <a href="https://hamvocke.com/blog/task-runners/">Use Task Runners for Common Coding Tasks</a> is a nice, practical reminder that a simple Makefile or task runner goes a long way toward smoothing out multi-repo workflows.</p> </li> <li><p>Sean Goedecke wrote a great essay on how <a href="https://www.seangoedecke.com/llms-reward-expertise/">LLMs reward expertise</a>, arguing that human domain knowledge remains the ultimate bottleneck because pulling the right solution out of the model requires knowing what you actually want.\</p> </li> <li><p>I stumbled across a Polygon article on Metroid that was <a href="https://masto.hackers.town/@lmorchard/117048978898204926">so aggressively bloated with autoplaying video and stacked ads</a> that the actual viewport for content was about the size of a postage stamp. A great reminder of why the web feels like livestock management these days.</p> <p><img src="https://blog.lmorchard.com/2026/08/07/w32/440dfb60d722.png" alt="Polygon article bloated with ads" width="" height=""></p> </li> </ul> </div> Fri, 07 Aug 2026 19:00:00 GMT https://blog.lmorchard.com/2026/08/07/w32/ https://blog.lmorchard.com/2026/08/07/w32/ weeknotesaiwebcatsportland Cat Parole, Coding Sprints, and a Memorial Tattoo (Catching up: July 11 – July 31) <p><em>TL;DR:</em> It's been a hectic three weeks. The main event has been the slow, tense, and ultimately successful integration of our new cat, Minnaloushe, who graduated from "cat jail" to a tentative peace with the other furballs. In between managing the cat drama, I got a memorial tattoo for Puck, poured a ton of work into <code>decafclaw</code> and other side projects, and fell down a rabbit hole of game streaming and retro classics.</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="the-great-cat-parole-experiment">The Great Cat Parole Experiment</h2> <p>When we last spoke, Minnaloushe was in "cat jail" in my office. Well, the big guy has been on a real journey. After a scuffle that put him back in solitary, he's slowly been earning his freedom. There have been many cycles of <a href="https://masto.hackers.town/@lmorchard/116927359759625182">parole</a>, supervised visits, and a lot of just hoping for the best.</p> <p>The good news is, we seem to have turned a corner. The <a href="https://masto.hackers.town/@lmorchard/116987667455406680">cat jail gate has been retired</a>, and we're now at a stage of <a href="https://masto.hackers.town/@lmorchard/116964131757513851">uneasy but peaceful coexistence</a>. They're even <a href="https://masto.hackers.town/@lmorchard/116958707523053532">eating together</a> without any bloodshed. It's a relief, honestly.</p> <p>Of course, a free-roaming Minnaloushe means a new level of chaos. He's a menace who <a href="https://masto.hackers.town/@lmorchard/116904309856365813">chews on arcade sticks</a>, <a href="https://masto.hackers.town/@lmorchard/116922136763770313">steals the rubber feet off my laptop stand</a>, and generally causes adorable trouble. But he's also a big, goofy bear of a cat and I'm glad to have him out and about now.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/5eb6bf4ebb23.jpg" alt="A black cat plays with the controls of a miniature arcade game cabinet featuring a Mozilla logo." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/b2eaba63a261.jpg" alt="A black cat sleeps stretched out across a cluttered desk filled with computer monitors, a retro keyboard, and gaming accessories." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/4a1afb3404a1.jpg" alt="Two cats, one white and one black, eat dry food from bowls on a white tray on a polished wooden floor." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/3cf1563e4062.jpg" alt="Three cats—white, grey, and black—are eating from bowls on a wooden floor next to a brick wall and wooden cabinet." width="" height=""></p> </image-gallery> <h2 id="a-tattoo-for-puck">A Tattoo for Puck</h2> <p>In the midst of all the cat drama, I got my second tattoo, a memorial for my old friend Puck, who <a href="https://blog.lmorchard.com/2015/04/15/goodbye-puck/">we lost back in 2015</a>. It was done by <a href="https://www.wonderlandpdx.com/katy-bisby-1">the talented Katy Bisby</a>, and it came out beautifully. It’s a wonderful way to remember a very good boy.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/87b43a27767a.jpg" alt="A fresh, colorful tattoo of a tabby cat with a crescent moon, stars, and white flowers on a person's arm." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/a49e04918b9f.jpg" alt="A colorful tattoo on an arm featuring a cat with green eyes, a crescent moon, stars, and white flowers." width="" height=""></p> </image-gallery> <h2 id="shipping-shipping-shipping">Shipping, Shipping, Shipping</h2> <p>At some point, I should probably write more about workaday projects. I'm pretty quiet about those. But, it's been a productive few weeks on side projects: I've been banging away on <a href="https://github.com/lmorchard/decafclaw"><code>decafclaw</code></a>, my personal agent project, and <a href="https://github.com/lmorchard/byom-sync"><code>byom-sync</code></a>, the "bring your own music" playlist tool. The GitHub activity stream has been a blur of commits, PRs, and new issues.</p> <p>For <code>decafclaw</code>, there's been a ton of work on improving the scheduling system, fixing bugs in the vault and skill loaders, and generally trying to make the whole system more robust. I even started to tackle the project skill's tendency to hallucinate tools.</p> <p>For <code>byom-sync</code>, I've been focused on improving purchase link resolution, adding support for RSS feeds, and starting to spec out a "shopping list" feature. It's been a lot, but it's satisfying to see these projects moving forward.</p> <h2 id="adventures-in-game-streaming">Adventures in Game Streaming</h2> <p>I finally caved and tried out GeForce NOW, and I have to say, it's pretty impressive. It's led me to rethink my whole <a href="https://blog.lmorchard.com/2026/07/31/w31//2017/01/09/diy-monitor-v12/">living room gaming setup</a>, a project that's been evolving for <a href="https://blog.lmorchard.com/2026/07/31/w31//2013/01/21/gaming-from-the-orchard-house-couch/">nearly a decade</a>. The idea of a powerful PC tucked away in the basement, streaming games to any screen in the house via <a href="https://moonlight-stream.org/">Moonlight</a> and <a href="https://github.com/LizardByte/Sunshine">Sunshine</a>, is very appealing. </p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/0876bd9a6419.jpg" alt="A bare leg in foreground, with a video game 'Pause Menu' on one screen and a blog on a laptop on another stand." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/31/w31/7ac5851ae51c.jpg" alt="A compact mobile computing setup with a laptop" width="" height=""></p> </image-gallery> <p>For those not familiar, Sunshine is a self-hosted, open-source replacement for NVIDIA's now-defunct GameStream, and Moonlight is the open-source client that lets you stream from it. The combination promises a high-performance, low-latency experience. Might just be the end of an era for my dedicated living room gaming PC.</p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li><p>A neighbor had a block party with a live brass band, which was a delightful surprise. Here's the playlist of a few songs I recognized - wish I'd taken notes! Also, this is me trying out my new mixtapes site as an embed:</p> <iframe style="border-radius:12px" src="https://mixtapes.lmorchard.com/00-conceptual/songs-covered-by-my-neighbor-s-brass-band/embed/" width="80%" height="500" frameborder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe> </li> <li><p>I watched a raccoon have a full-on pool party in our backyard pond, and I'm not even mad.</p> <figure> <video controls=""> <source src="b5b4c41c025c.mp4" type="video/mp4"> <a href="https://blog.lmorchard.com/2026/07/31/w31/b5b4c41c025c.mp4">raccoon-pond-bandit.mp4</a> </video> <figcaption>The pond bandit returns.</figcaption> </figure> </li> <li><p>I also bookmarked Tiago Forte's guide on <a href="https://fortelabs.co/blog/how-to-build-a-second-brain-an-overview/">"How to Build a Second Brain"</a>.</p> </li> <li><p>A few more interesting reads from the past few weeks: <a href="https://htmx.org/essays/working-with-ai/">htmx ~ Working With AI: A Concrete Example</a>, an essay on the pros and cons of AI in development, and how to avoid the "Sorcerer's Apprentice" problem; <a href="https://geohot.github.io//blog/jekyll/update/2026/07/12/i-love-llms.html">I love LLMs, I hate hype</a>, a classic from geohot on the difference between genuine excitement and the hype cycle; and <a href="https://zeldman.com/2026/07/06/memories-cant-wait-or-how-i-learned-to-keep-worrying-about-the-web/">Memories Can’t Wait—or, How I Learned to Keep Worrying About the Web</a>, a call to action from Jeffrey Zeldman on the importance of owning your own content.</p> </li> <li><p>I also bookmarked <a href="https://grumpywelshman.com/the-internet-doesnt-want-readers-it-wants-livestock/">The Internet Doesn't Want Readers. It Wants Livestock.</a>, a wonderfully grumpy take on the state of the web.</p> </li> <li><p>On the more technical side of things, I saved a link to <a href="https://endform.dev/blog/playwright-github-actions">Playwright on GitHub Actions: The setup that actually runs fast</a> which has some great tips on speeding up CI, and a post about <a href="https://developer.puter.com/labs/firefox-wasm/">Firefox in WebAssembly</a>, which is just cool.</p> </li> <li><p>And finally, a couple of interesting articles on the culture of coding: <a href="https://blog.matthewbrunelle.com/its-ok-to-use-coding-assistance-tools-to-revive-the-projects-you-never-were-going-to-finish/">It's OK to Use Coding Assistance Tools To Revive The Projects You Never Were Going To Finish</a> and <a href="https://www.theocharis.dev/blog/llm-critics-are-right-i-use-llms-anyway/">The LLM Critics Are Right. I Use LLMs Anyway.</a>, both of which resonate with my own experiences.</p> </li></ul></div> Fri, 31 Jul 2026 19:00:00 GMT https://blog.lmorchard.com/2026/07/31/w31/ https://blog.lmorchard.com/2026/07/31/w31/ weeknotescatsgithubdecafclawgamingtattooai The tiger is out (Week 29) <p>TL;DR: Last week I said Minnaloushe was inching toward parole from cat jail. This week he simply escaped — repeatedly, by jumping onto my office door and vaulting the five-foot gate — which earned him the household title of "the tiger." Meanwhile the <code>byom</code>/mixtapes rabbit hole kept swallowing me whole (cover art, mosaic hero images, virtualizing an 8000-track playlist, npm releases, Navidrome and Plex playback), <code>starnet</code> sprouted a Quality-Based Narrative epic, and I fell down a gacha-game reorientation hole and an Oxford-comma nerdsnipe hole in the same week.</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="the-tiger-is-out">The tiger is out</h2> <p>When I left off last week, Minnaloushe — a.k.a. "the Hunk," so named because <a href="https://masto.hackers.town/@lmorchard/116913831805067815">the adoption agency called him hunky</a> — was still doing his time behind the tall gate in my office while we reboot the cat introductions. He was, I said, inching toward parole.</p> <p>He decided not to wait.</p> <p>First he <a href="https://masto.hackers.town/@lmorchard/116919794043335799">figured out how to breach cat jail</a>: jump on top of my office door, then from there jump through the gap above the five-foot pet gate in the doorway. He did it twice, and then I caught him doing the jump math and butt wiggles for a third go. Certainly not a dumb critter.</p> <p>By the weekend I had to concede the point entirely, with apologies to Nael, grade 1, whose <a href="https://826dc.org/student-writing/the-tiger/">poem "The Tiger"</a> I have never been able to get out of my head:</p> <blockquote> <p>The tiger He destroyed his cage Yes YES The tiger is out</p> </blockquote> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/07/17/w29/be01b27436af.jpg" alt="My office doorway with the cat jail gate set aside" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/17/w29/5a0a316d72d9.jpg" alt="Minnaloushe roaming atop a speaker in the living room" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/17/w29/73e807849486.jpg" alt="Minnaloushe in the kitchen eating some cat food" width="" height=""></p> </image-gallery> <p>Between jailbreaks, he kept himself busy being a menace to my desk specifically. I turned around one afternoon to find him <a href="https://masto.hackers.town/@lmorchard/116904309856365813">going to town chewing on the joystick</a> of my little barcade cabinet like it was a jawbreaker:</p> <p><img src="https://blog.lmorchard.com/2026/07/17/w29/5eb6bf4ebb23.jpg" alt="A black cat plays with the joystick of a miniature arcade cabinet with a Mozilla sticker" width="" height=""></p> <p>He also <a href="https://masto.hackers.town/@lmorchard/116920348585550769">pried the rubber nubbins off my laptop shelf</a> (twice), buried his head in a foam pumpkin to <a href="https://masto.hackers.town/@lmorchard/116914128610384576">fish out the electronics inside</a>, and generally <a href="https://masto.hackers.town/@lmorchard/116913802555033184">made himself at home</a> stretched across the keyboards and monitors like he pays rent here.</p> <p>The freedom tour did not last. There was <a href="https://masto.hackers.town/@lmorchard/116925375967665891">a bit of a scuffle</a> — I'm pretty sure Cosmo started it — so the tiger is back in his cage for a little while so we can have workday peace. Cage not entirely destroyed yet. Baby steps.</p> <h2 id="is-this-a-music-blog-now">Is this a music blog now?</h2> <p>The mixtapes project I started last week refused to let go. What began as "somewhere to stash my playlists off Spotify" has, over the course of the week, <a href="https://masto.hackers.town/@lmorchard/116905850438782330">maybe turned into a kind of music blog</a>? We'll see if I actually keep it up with new mixtapes. Either way, <a href="https://github.com/lmorchard/byom-sync"><code>byom-sync</code></a> and <a href="https://github.com/lmorchard/byom-player"><code>byom-player</code></a> both got a frankly absurd number of commits.</p> <p>The stuff I'm happiest about:</p> <ul> <li><p><strong>Virtualizing the tracklist.</strong> That Big Sonic Heaven playlist is past 8000 tracks, and rendering all of them into the DOM at once made the web component <a href="https://masto.hackers.town/@lmorchard/116905855453456651">do completely stupid things</a>. <a href="https://github.com/lmorchard/byom-player/issues/39">Windowing the list</a> so it only renders what's on screen fixed that, and I added <a href="https://github.com/lmorchard/byom-sync/issues/43">viewport-priority pruning</a> to the availability prescan so it isn't frantically checking 8000 tracks you'll never scroll to.</p> </li> <li><p><strong>Cover art and mosaic heroes.</strong> <code>byom-sync</code> now <a href="https://github.com/lmorchard/byom-sync/pull/20">resolves cover art via MusicBrainz and the Cover Art Archive</a>, and for playlists that don't have an explicit cover it <a href="https://github.com/lmorchard/byom-sync/issues/32">generates a representative mosaic hero image</a> out of the album art it does have. The index and playlist pages look a lot less like a spreadsheet now.</p> </li> <li><p><strong>It plays my own music.</strong> Even though it defaults to pulling audio from YouTube, I got it <a href="https://masto.hackers.town/@lmorchard/116905865548891038">working against my homelab Navidrome and Plex installs</a> — so it can play music from my personal collection (or yours) without uploading all the files somewhere first. That's the part that makes the whole "gardener, not a tenant" thing feel real.</p> </li> </ul> <p>The rest of the week was the unglamorous tail of shipping something: I <a href="https://github.com/lmorchard/byom-player/issues/4">published <code>byom-player</code> to npm</a> and cut a few tagged releases, did a big mobile pass on the site and player chrome, and rebuilt the layout around a proper app shell. Not exciting to describe, but it's the difference between a demo and a thing.</p> <h2 id="back-on-my-gamedev-bullshit-quality-edition">Back on my gamedev bullshit, quality edition</h2> <p><code>starnet</code>, the long-simmering cyberpunk netrunning RPG, got some attention too. Last week's exploit-barrage mini-game landed a follow-up (<a href="https://github.com/lmorchard/starnet/pull/314">the <code>worktree-exploit-e2-gear</code> work merged</a>), but the bigger move was opening <a href="https://github.com/lmorchard/starnet/issues/315">an epic for a Quality-Based Narrative meta-loop</a> — StoryNexus-style storylets, driven by facts accumulated over a run. If you've ever played Fallen London and wondered how the story keeps reshuffling itself around what you've done, that's the machinery I'm trying to build a version of. It's the connective tissue that could turn a pile of mini-games into an actual game. We'll see.</p> <h2 id="the-live-service-reorientation-problem">The live-service reorientation problem</h2> <p>I spent a chunk of the week trying to climb back into a couple of gacha games and bouncing right back off. I fired up Zenless Zone Zero again after loving it last summer and thought: <a href="https://masto.hackers.town/@lmorchard/116922303901298762">sweet merciful crap, what is any of this?</a> Same story with Honkai: Star Rail, which <a href="https://masto.hackers.town/@lmorchard/116922495124846596">greeted me with a "welcome back" gift of currencies</a> when what I actually needed was a "here's WTF you were doing last time" reorientation.</p> <p>That's the recurring trap with these free-to-play things: they're <a href="https://masto.hackers.town/@lmorchard/116922310610168567">a bewildering blizzard of currencies and limited-time offers and geegaws</a>, I enjoy them intensely for a limited window, and then my brain flushes all knowledge of their systems the moment I look away. The one exception is Warframe, which <a href="https://masto.hackers.town/@lmorchard/116922316688221387">I somehow retain across months-long absences</a> — and which had a genuinely wild <a href="https://masto.hackers.town/@lmorchard/116903662094531617">Tau expansion reveal at TennoCon</a> that manages to blend detective noir, swanky triphop, cyberpunk, deep-future stoner-rock sci-fi, and screaming cosmic horror. I love that creative team.</p> <p>On the hardware side, I've been leaning on <a href="https://masto.hackers.town/@lmorchard/116909762988442746">GeForce NOW</a> rather than upgrade a six-year-old GPU — I know cloud gaming is "how they get ya," but my internet is good and I'd rather make a few extra mortgage payments. Less happily, the Xbox controller I use has become <a href="https://masto.hackers.town/@lmorchard/116909805087691611">a full Ship of Theseus</a>: the rubberized thumbstick texture is now sloughing off gloopily under my thumbs, and I'd already replaced the outer shell after the original crumbled. I don't think this thing is even a few years old.</p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li>Firefox in WebAssembly is real: the <a href="https://developer.puter.com/labs/firefox-wasm/">Gecko engine compiled to WASM</a> (<a href="https://github.com/HeyPuter/firefox-wasm">repo here</a>), rendering the real Firefox UI inside a browser tab. My favorite part is that it <a href="https://masto.hackers.town/@lmorchard/116927454534706451">ironically didn't work <em>in Firefox</em></a> — until I <a href="https://masto.hackers.town/@lmorchard/116927462594096195">flipped a config bit</a>, and then off it went.</li> <li>A cluster of AI-hype-reckoning reading piled up this week: Ford <a href="https://www.bbc.com/news/articles/cgrkd41n2v9o?ref=karlbode.com">rehired human engineers after AI failed their quality checks</a> ("mistakenly, we thought that by just introducing artificial intelligence… that would produce a high-quality product"), Karl Bode on <a href="https://karlbode.com/the-ai-hype-reckoning-is-upon-us/">the AI hype reckoning</a> and the chasm between useful automation and technofascist hucksterism, and geohot's counterpoint, <a href="https://geohot.github.io//blog/jekyll/update/2026/07/12/i-love-llms.html">"I love LLMs, I hate hype"</a>. The most nuanced take was the <a href="https://htmx.org/essays/working-with-ai/">htmx essay on working with AI</a> — an older developer describing how it patches the specific weaknesses of memory and stamina that age brings.</li> <li>Adjacent, and quietly worrying: Laura Michet on <a href="https://blog.lauramichet.com/world-historic-amounts-of-gamedev-talent-thrown-out-to-rot/">world-historic amounts of gamedev talent being thrown out to rot</a>, and Xe Iaso arguing <a href="https://xeiaso.net/notes/2026/console-wars-lost/">the console wars have already been lost</a> — Valve winning by doing nothing while everyone else shoots themselves in the head.</li> <li>The web-durability drumbeat continues: Zeldman on <a href="https://zeldman.com/2026/07/06/memories-cant-wait-or-how-i-learned-to-keep-worrying-about-the-web/">keeping worrying about the web</a> ("be gardeners, not just tenants"), the Grumpy Welshman on how <a href="https://grumpywelshman.com/the-internet-doesnt-want-readers-it-wants-livestock/">the internet wants livestock, not readers</a>, and a lovely bit of digital archaeology in Dan Q's <a href="https://danq.me/2026/07/10/rescuing-7234-gifs/">rescue of 7,234 old GIFs</a> via a server-side imagemap.</li> <li>Also bookmarked: <a href="https://floooh.github.io/tiny8bit-preview/index.html">Tiny Emulators</a>, a <a href="https://thega.me.uk/2026/07/dungeons-and-dryers/">D&amp;D-group-repairs-a-tumble-dryer-mid-campaign</a> story, <a href="https://freek.dev/3156-leave-a-failing-test-before-you-go-on-vacation">Freek Van der Herten on leaving a failing test before you go on vacation</a> (a genuinely good idea for easing back in), Ian Reppel's <a href="https://ianreppel.org/the-tragedy-of-the-engineering-commons/">tragedy of the engineering commons</a>, and a <a href="https://endform.dev/blog/playwright-github-actions">fast Playwright-on-GitHub-Actions setup</a>.</li> <li>I got nerdsniped into an Oxford-comma-and-AP-vs-APA thread so hard that I <a href="https://masto.hackers.town/@lmorchard/116920763345454852">signed up for a free AP Stylebook trial to prove a point</a> so pedantic I wanted to self-defenestrate. Should I tell my therapist about this?</li> <li>In a related ADHD-brain event, a TikTok convinced me that <a href="https://masto.hackers.town/@lmorchard/116920802242736569">baker's racks with trays are the perfect ADHD project-storage unit</a> — "tray after tray of random access projects" — and I spent an embarrassing amount of time shopping for aluminum sheet-pan racks for the workshop. Every hobby, as someone on Mastodon put it, ends with storage problems.</li> <li>Cleopatra Records — the goth/industrial label — apparently now <a href="https://cleopatrarecords.bandcamp.com/album/faithfully">distributes Engelbert Humperdinck</a>, which sent me down a very confused rabbit hole about their catalog.</li> <li>Plex informed me that its <a href="https://masto.hackers.town/@lmorchard/116933857580069611">"Top Movies in Romance"</a> are Bill &amp; Ted's Excellent Adventure, Corpse Bride, Hairspray, The Lost Boys, and Mallrats. I have no notes. The algorithm knows me.</li> <li>Podcast-wise it was a Vergecast-heavy week (<a href="https://pocketcasts.com/podcast/8b0b13e0-8c29-013e-2d25-0ee3c75e9209">Netflix turning into YouTube</a>, the problem with Suno and AI music, "were we too nice to the Steam Machine?") plus the usual NPR <em>Up First</em> drip.</li> </ul> </div> <h2 id="wrapping-up">Wrapping up</h2> <p>Not a bad week: a cat who has evidently decided that walls are a suggestion, a side project that keeps threatening to become a real thing, and enough good reading to keep my "gardener, not tenant" convictions well-watered. On the quieter side, my therapist <a href="https://masto.hackers.town/@lmorchard/116930827397645644">flagged that my anxiety and grief scores were up</a> at this week's check-in, which tracks — so I'm trying to be gentle with myself about how much of the above is genuine play and how much is hyperfocus doing its thing. Probably some of both. The tiger and I have that in common.</p> Fri, 17 Jul 2026 19:00:00 GMT https://blog.lmorchard.com/2026/07/17/w29/ https://blog.lmorchard.com/2026/07/17/w29/ weeknotescatsmusicselfhostinggamedevgaming Somewhere to stash my mixtapes (Week 28) <p>TL;DR: I built <a href="https://mixtapes.lmorchard.com">mixtapes.lmorchard.com</a> to publish playlists on my own domain instead of leaving them trapped in Spotify, which spun off two new repos (<code>byom-sync</code> and <code>byom-player</code>). Plus more <code>starnet</code> gamedev (an exploit-barrage mini-game with a Butterchurn "brain damage" overlay), I finally ditched Disqus for remark42 after almost 20 years, and Minnaloushe is inching toward parole from cat jail.</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="minnaloushe-makes-parole-soon">Minnaloushe makes parole soon?</h2> <p>Minnaloushe has been in cat jail for about a month now, behind a tall gate in my office while we reboot the introduction process. He's still got a couple weeks left, though <a href="https://masto.hackers.town/@lmorchard/116875570677609551">he's getting acknowledgement for good behavior</a>. He's clearly had a horrible time of it.</p> <p><img src="https://blog.lmorchard.com/2026/07/10/w28/04b81594b21d.jpg" alt="A black cat with green eyes relaxes in a cat bed, dangling its front paws over the edge." width="" height=""></p> <p>In adjacent cat-and-machine news: I told Miss Biscuits she's pretty and incredibly treasured, and <a href="https://masto.hackers.town/@lmorchard/116864692778423347">Gemini on my phone overheard</a> and said "that's incredibly sweet of you to say and I'm glad to be here with you." So, you know, maybe Skynet will go easy on me.</p> <h2 id="somewhere-to-stash-my-mixtapes">Somewhere to stash my mixtapes</h2> <p>So, I made a thing this week: <a href="https://mixtapes.lmorchard.com">mixtapes.lmorchard.com</a>.</p> <image-gallery> <p> <img src="https://blog.lmorchard.com/2026/07/10/w28/./mixtapes-1.png" alt="Screenshot of the index page of mixtapes.lmorchard.com" width="" height=""></p> <p> <img src="https://blog.lmorchard.com/2026/07/10/w28/./mixtapes-2.png" alt="Screenshot of a playlist on mixtapes.lmorchard.com" width="" height=""></p> </image-gallery> <p>And, if this isn't broken, an embedded playlist should appear here:</p> <iframe src="https://mixtapes.lmorchard.com/00-conceptual/big-sonic-heaven-spy/embed/" width="100%" height="950" frameborder="0" allowtransparency="true" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"></iframe> <p>This one started sideways. I spent some time <a href="https://masto.hackers.town/@lmorchard/116875598639707807">reviving my Big Sonic Heaven Spy bot</a>, a little thing that watches what's playing at bigsonicheaven.com and appends new songs to a Spotify playlist. <a href="https://bigsonicheaven.com">BSH is all ethereal, shoegaze, dreampop, and post-punk</a> from a DJ I've been listening to since high school. The playlist is past 8000 songs now, and Spotify caps playlists at 10000. So, I'm going to hit a wall before too long.</p> <p>This got me grumbling. I really need a place to stash playlists and mixtapes - one that isn't locked inside somebody else's app. I've been meaning to do this for literally years, but this week I finally got around to starting it with two new repos:</p> <ul> <li><p><a href="https://github.com/lmorchard/byom-sync"><code>byom-sync</code></a> is a Go CLI that pulls my Spotify playlists down into Git-friendly YAML files. From there it compiles out to <a href="https://www.xspf.org/jspf">JSPF</a> for the web player and Markdown for static sites. It'll even build the whole browsable site, which is exactly what <a href="https://mixtapes.lmorchard.com">mixtapes.lmorchard.com</a> is.</p> </li> <li><p><a href="https://github.com/lmorchard/byom-player"><code>byom-player</code></a> is a framework-agnostic <a href="https://lit.dev/">Lit</a> web component that plays those JSPF playlists through swappable audio providers.</p> </li> </ul> <p>Along the way I <a href="https://masto.hackers.town/@lmorchard/116887252588644809">discovered Navidrome and the OpenSubsonic API</a>, which turns out to be a lovely way to expose a personal music library to a web app, provided the browser can reach the server through Tailscale, a VPN, or a reverse proxy. I've got exactly that hacked together in my basement homelab.</p> <p>That sent me spelunking through the wider ecosystem of Subsonic-compatible servers - bringing me to <a href="https://www.psysonic.de/">Psysonic</a> (a Winamp-inspired Navidrome desktop client), <a href="https://github.com/sentriz/gonic">gonic</a>, <a href="https://github.com/tsirysndr/smolsonic">smolsonic</a>, <a href="https://github.com/epoupon/lms">LMS</a>, and <a href="https://docs.funkwhale.audio/user/subsonic/index.html">Funkwhale's Subsonic support</a>.</p> <p>All of this jibes with what a bookmark I saved this week names outright: <a href="https://www.lireo.com/be-a-gardener-not-a-tenant/">be a gardener, not a tenant</a>, because cloud services are not forever, and neither, apparently, is a Spotify playlist with a hard cap on it.</p> <h2 id="back-on-my-gamedev-bullshit">Back on my gamedev bullshit</h2> <p><code>starnet</code>, my long-simmering cyberpunk netrunning RPG, got some more attention too. This week I was <a href="https://masto.hackers.town/@lmorchard/116880753323673946">ginning up an arcadey sci-fi visualization</a> of a metasploit-inspired exploit barrage against a network node.</p> <figure> <video controls="" loop="" muted="" playsinline=""> <source src="./exploit-barrage.mp4" type="video/mp4"> <a href="https://blog.lmorchard.com/2026/07/10/w28/./exploit-barrage.mp4">exploit-barrage.mp4</a> </video> <figcaption>The exploit barrage in motion: belts of exploits orbiting a target node while its shields wear down.</figcaption> </figure> <p>There's a target node in the center, surrounded by defensive shields. Orbiting the target are a couple of concentric belts of exploits you've queued up. When the barrage starts, the shields wear down, your exploits occasionally get burned or disclosed or used up, and a detection-risk "noise" level climbs.</p> <p>I'm <a href="https://masto.hackers.town/@lmorchard/116880778548043503">stealing some juice from Star Castle</a> here, which apparently lit up a few people's nostalgia circuits the moment they saw the screenshots.</p> <p>The other weird bit was wiring up a Butterchurn (a web port of the trippy old Milkdrop music visualizer) overlay as a way to <a href="https://masto.hackers.town/@lmorchard/116887129462221814">depict brain injury in a cyberdeck jockey</a> who's been pushing their luck. There's a whole trove of <a href="https://github.com/jberg/butterchurn-presets">Milkdrop presets converted for Butterchurn</a> to draw from, which is delightfully more raw material than I could ever use.</p> <p><img src="https://blog.lmorchard.com/2026/07/10/w28/d90ab99184d9.png" alt="A test harness in starnet, trying out Milkdrop / Butterchurn music visualizers as a way to depict brain injury in a cyberdeck jockey" width="" height=""></p> <p>I still have no idea whether this game ever becomes a thing worth "releasing" - but I'm having a genuinely good time hacking on an idea I've been carrying around for years.</p> <h2 id="disqus-gone-after-20-years">Disqus, gone after 20 years</h2> <p>This felt overdue: after almost 20 years, I <a href="https://masto.hackers.town/@lmorchard/116875431657598358">finally switched my blog comments away from Disqus</a>. I'm running <a href="https://remark42.com/">remark42</a> for now and we'll see how I like it.</p> <p>The final straw was they turned on <a href="https://www.byrosanna.co.uk/blog/watch-out-for-ads-disqus-comments-have-gone-premium">a spammy chumbox</a> at the bottom of every comment thread. What's a <a href="https://en.wikipedia.org/wiki/Chumbox">chumbox</a>? This is a chumbox:</p> <p><img src="https://blog.lmorchard.com/2026/07/10/w28/8cce25e5532e.jpg" alt="Chumbox" width="" height=""></p> <p>Complete garbage. I mean, sure, I was freeloading comments off Disqus most of this time. But inserting ads for vitamin supplements and crypto scams and boner pills on my blog is unacceptable. That convinced me to get over the hump of figuring out self-hosting, rather than pony up for a paid plan.</p> <p>The part I'm quietly pleased about is that I got the Remark42 comments to <a href="https://masto.hackers.town/@lmorchard/116875436382858423">lazy-load only when they're scrolled into view</a> and to follow theme changes along with the rest of the page.</p> <p>A <a href="https://hndrk.blog/comments-are-there/">nice writeup on automatic remark42 theme-switching</a> did a lot of the heavy lifting there. Still on my wishlist: figuring out whether there's <a href="https://masto.hackers.town/@lmorchard/116875447236422858">any way to get remark42 talking to indielogin.com</a> for authentication. If anyone's done that, I'm all ears.</p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li><p>I printed <a href="https://masto.hackers.town/@lmorchard/116894157260109707">a little charging dock for my Anbernic RG35XXSP</a>, which even has a micro-HDMI-to-HDMI adapter built in for the day I feel masochistic enough to use the thing as a console. The <a href="https://www.printables.com/model/1412822-anbernic-rg35xxsp-dock-usb-c-hdmi/">Printables model</a> has space in the base for metal weights so it doesn't topple over. <a href="https://blog.lmorchard.com/2026/07/10/w28//tag/gamedad">#gamedad</a></p> <image-gallery> <p> <img src="https://blog.lmorchard.com/2026/07/10/w28/c8de6bf126b8.jpg" alt="A black handheld gaming console with a ghost sticker sits next to its custom, 3D-printed purple charging dock on a wooden desk." width="" height=""></p> <p> <img src="https://blog.lmorchard.com/2026/07/10/w28/a7ae08c8d939.jpg" alt="An Anbernic handheld gaming console with a transparent case charging in a purple 3D-printed dock on a wooden desk." width="" height=""></p> <p> <img src="https://blog.lmorchard.com/2026/07/10/w28/9e78709c3dfc.jpg" alt="Two handheld consoles, a New Nintendo 3DS with a purple bird sticker and an Anbernic 35xxsp with a glittery ghost sticker, sit in stands on a wooden desk." width="" height=""></p> </image-gallery> </li> <li><p>The raccoon is back. <a href="https://masto.hackers.town/@lmorchard/116880163397827126">We thought we'd been forsaken</a> after nearly a month, but no, they've returned and they are hungry for lily pad and electrical cords.</p> <figure> <video controls="" loop="" muted="" playsinline=""> <source src="./raccoon-return.mp4" type="video/mp4"> <a href="https://blog.lmorchard.com/2026/07/10/w28/./raccoon-return.mp4">raccoon-return.mp4</a> </video> <figcaption>The pond bandit, returned from a month's absence and back on the electrical cords.</figcaption> </figure> </li> <li><p>A cluster of "the AI bill is coming due" reading this week: <a href="https://karlbode.com/the-ai-hype-reckoning-is-upon-us/">The AI Hype Reckoning Is Upon Us</a> on the chasm between useful automation and technofascist hucksterism, <a href="https://www.bbc.com/news/articles/cgrkd41n2v9o?ref=karlbode.com">Ford rehiring human engineers</a> after AI failed the quality checks ("Mistakenly, we thought that by just introducing artificial intelligence... that would produce a high-quality product"), and <a href="https://eshumarneedi.com/2026/07/03/zuckerberg-admits-metas-layoffs-were.html">Zuckerberg 'admitting' Meta's layoffs were ineffective</a>. Someone on Mastodon also passed around a Futurism headline about <a href="https://masto.hackers.town/@cypnk/116891029640761359">execs being horrified by their huge AI bills</a> after assuming they could replace workers for free, which, hah.</p> </li> <li><p>Two on the state of gaming as a business: <a href="https://xeiaso.net/notes/2026/console-wars-lost/">The console wars have been lost</a> (Valve winning by doing nothing while everyone else shoots themselves in the head) and <a href="https://blog.lauramichet.com/world-historic-amounts-of-gamedev-talent-thrown-out-to-rot/">World historic amounts of gamedev talent thrown out to rot</a>, which is a genuinely sad read about hemorrhaging not just people but the trust and momentum that make good teams.</p> </li> <li><p><a href="https://reprog.wordpress.com/2026/07/05/what-does-jeff-bezos-think-is-going-to-happen/">What does Jeff Bezos think is going to happen?</a> on the logic of DRM'd Kindle books eventually just pushing people to pirate the things they've already paid for.</p> </li> <li><p>Apple shipped a <a href="https://webkit.org/blog/18136/introducing-the-safari-mcp-server-for-web-developers/">Safari MCP server for web developers</a>, which lets an agent see how your code actually renders in the browser.</p> </li> <li><p>The EFF wrote a nice reminder that <a href="https://www.eff.org/deeplinks/2026/06/hate-algorithm-rss-one-tools-youve-been-looking">RSS is one of the tools you've been looking for</a> if you hate "the algorithm."</p> </li> <li><p>A small, sharp piece of advice: <a href="https://freek.dev/3156-leave-a-failing-test-before-you-go-on-vacation">leave a failing test before you go on vacation</a> so future-you has somewhere obvious to pick back up.</p> </li> <li><p><a href="https://ianreppel.org/the-tragedy-of-the-engineering-commons/">The Tragedy of the Engineering Commons</a>: "The surest way to ruin an engineering team is to believe it will survive whatever you do to it."</p> </li> <li><p>Conan O'Brien <a href="https://www.youtube.com/watch?v=tzs7901FSzY">surprising Jordan Schlansky with Geddy Lee</a> so he can interrogate the man about a specific mastering of "Tom Sawyer" is exactly the kind of nonsense I needed.</p> <p> <youtube-embed video-id="tzs7901FSzY" thumbnail="d106834063a7.jpg"></youtube-embed></p> </li> <li><p>Podcast-wise it was a good week for retro and sci-fi: the Retro Hour on the <a href="https://pocketcasts.com/podcast/f025c170-ae7d-013b-f3af-0acc26574db2">Commodore 64 as a cultural icon</a>, the STARLOG Podcast talking <a href="https://pocketcasts.com/podcast/c32c37c0-5206-013f-1f83-0e98e27f20d9">science and storytelling with Dr. Erin Macdonald</a>, Aftermath Hours on the slow death of <a href="https://pocketcasts.com/podcast/16283670-9d16-013c-74fe-027201e7e97f">physical media</a>, and Never Post on <a href="https://pocketcasts.com/podcast/bb3ac9f0-728c-013c-dc63-0e76ec147af9">"inheritance posting"</a> as a new kind of grief.</p> </li> <li><p>Songs that were stuck in my head, for the record: Parralox's <a href="https://www.youtube.com/watch?v=GTrndr1gqdc">cover of "Sirius / Eye in the Sky"</a>, Battery's cover of Depeche Mode's "Shame" (<a href="https://www.youtube.com/watch?v=fBXGfHuMtMA">"it all seems so stupid, it makes me want to give up"</a>), and, unfortunately right before bed, the hyperactive <a href="https://www.youtube.com/watch?v=vc3JWo2iiGc">"MEOW" by Anamanaguchi</a>.</p> <p>You know, I should put these in a playlist. Hmm.</p> <p> <youtube-embed video-id="GTrndr1gqdc" thumbnail="27e44e8832eb.jpg"></youtube-embed></p> <p> <youtube-embed video-id="fBXGfHuMtMA" thumbnail="ee5172cec627.jpg"></youtube-embed></p> <p> <youtube-embed video-id="vc3JWo2iiGc" thumbnail="c5b38195c2e8.jpg"></youtube-embed></p> </li> </ul> </div> <p>None of this was especially planned. A dead Spotify playlist cap turned into two new repos, a game about breaking into computers grew a way to render brain damage, and my blog quietly shed a service it had carried since roughly the Bush administration. That's about the right ratio of accident to intent for a good week around here.</p> Fri, 10 Jul 2026 19:00:00 GMT https://blog.lmorchard.com/2026/07/10/w28/ https://blog.lmorchard.com/2026/07/10/w28/ weeknotesselfhostingmusicgamedevmetabloggingcats Minnaloushe in cat jail (2026 Week 27) <p>TL;DR: This week saw Minnaloushe's 'cat jail' reintroduction process, deep dives into live-coding music with strudel.cc (including a cover!), and a major overhaul of the <code>starnet</code> project's audio engine and core mechanics. Plus, reflections on the web's evolution, LLMs, and other miscellanea.</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="minnaloushe-in-cat-jail">Minnaloushe in cat jail</h2> <p>Minnaloushe has been in <a href="https://masto.hackers.town/@lmorchard/116846831115580133">cat jail</a> - i.e. behind a tall pet gate, confined to my office. We're hoping to reboot the introduction process that resulted in ass-kicking and bloodletting almost a month ago. It's been <a href="https://masto.hackers.town/@lmorchard/116854461930439847">surprisingly calm</a> so far, with Cosmo still showing a desire to be friends. We're hoping the gate is tall enough to prevent any escapes, even from a <a href="https://masto.hackers.town/@lmorchard/116854518471453483">big cat</a> like Minnaloushe.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/07/05/w27/47e9a373afe7.jpg" alt="A black cat sits behind a tall pet gate in a doorway, looking out from a lit room into the dark." width="" height=""> <br><img src="https://blog.lmorchard.com/2026/07/05/w27/1132a4b7ce75.jpg" alt="A black cat sits on a wooden floor behind the bars of a white pet gate." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/05/w27/9df4c5c126da.jpg" alt="A black cat on a wood floor looks through a white baby gate at two other cats on the other side." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/05/w27/6289a03bcf98.jpg" alt="A black cat lies on a wood floor, separated by a white baby gate from a light-colored cat in a doorway." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/05/w27/82f317c2ff1b.jpg" alt="A black cat and a white-and-ginger cat face each other through a white pet gate on a wooden floor." width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/05/w27/04b0b571a219.jpg" alt="A high-angle, first-person view of a black cat resting on a person's lap while they sit at a desk. The cat's paws are flopped over either side of the person's knee" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/07/05/w27/9aca169726d0.jpg" alt="An overhead view of a black cat stretching out comfortably across a person's lap. The cats paws are stretched out into the air doing biscuits" width="" height=""></p> </image-gallery> <h2 id="live-coding-music-with-strudelcc">Live-Coding Music with Strudel.cc</h2> <p>I've been really digging into <a href="https://strudel.cc/">strudel.cc</a>, a live-coding music environment, finding it clicks with my brain in a way old-school trackers used to. </p> <p>I spent some time <a href="https://masto.hackers.town/@lmorchard/116845715446881682">throwing together a cover</a> of the intro to "Stripdown" by Agent Side Grinder, which has been stuck in my head for weeks. You can check out my <a href="https://strudel.cc/#Ly8gUHJlYmFrZSBzY3JpcHQKLy8KLy8gVGhpcyBpcyBjb2RlIHRoYXQgaXMgbG9hZGVkIGJlZm9yZSB5b3VyIHBhdHRlcm4gaXMgcnVuLgovLyBZb3UgY2FuIHVzZSBpdCB0byBkZWZpbmUgY3VzdG9tIGZ1bmN0aW9ucyB0byB1c2UgaW4gYW55IHBhdHRlcm4uCi8vIAovLyBUaGlzIGlzIGFuIGluaXRpYWwgZXhhbXBsZSBzY3JpcHQuIFlvdSBjYW4gZWRpdCBpdCB0byBhZGQgCi8vIHlvdXIgb3duIGZ1bnRpb25zLgovLwovLyBUbyB1c2UgYSBzY3JpcHQgc2hhcmVkIGJ5IHNvbWUgb3RoZXIgdXNlciB5b3UgY2FuIHVzZQovLyB0aGUgaW1wb3J0LWJ1dHRvbiBvciBwYXN0ZSB0aGUgc2NyaXB0IGluIHRoaXMgZWRpdG9yLgoKY29uc3QgcmF0Y2hldCA9IHJlZ2lzdGVyKCdyYXRjaGV0JywgKHBhdCkgPT4gcGF0LnNvbWV0aW1lcyhwbHkoMikpKQoKLy8gU3Rhcm5ldCDigJQgc3RydWRlbC5jYyBQUkVCQUtFICAob25lLXBhc3RlIGF1dGhvcmluZyBibG9jaykKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBBVVRPLUdFTkVSQVRFRCBieSBgbWFrZSBnZW4tcHJlYmFrZWAgZnJvbSBhdWRpby1jb250ZW50L3NvdW5kZm9udHMvbWFuaWZlc3QuanMuCi8vIERvIG5vdCBlZGl0IGJ5IGhhbmQg4oCUIGVkaXQgdGhlIG1hbmlmZXN0IG9yIHNjcmlwdHMvZ2VuLXByZWJha2UuanMgaW5zdGVhZC4KLy8KLy8gUGFzdGUgdGhpcyBPTkNFIGludG8gc3RydWRlbC5jYyDihpIgU2V0dGluZ3Mg4oaSICJwcmViYWtlIiAodGhlIHNjcmlwdCB0aGF0IHJ1bnMgYmVmb3JlIGV2ZXJ5Ci8vIHNvbmcpLiBJdCBzZXRzIHVwIEJPVEggaGFsdmVzIG9mIHRoZSBnYW1lJ3Mgc291bmQgd29ybGQgc28gYSBTdGFybmV0IHNvbmcgY29waWVkIHN0cmFpZ2h0IG91dAovLyBvZiB0aGUgcmVwbyBwbGF5cyBVTkNIQU5HRUQgaW4gdGhlIGVkaXRvcjoKLy8KLy8gICAxLiBJbnN0cnVtZW50cyDigJQgdGhlIGdhbWUncyBzb3VuZGZvbnQgcHJlc2V0cyBwZXIgZm9udCAoZ3VzXyosIG1zZ18qLCDigKYpLgovLyAgICAgIEVhY2ggaXMgYSBESVNUSU5DVCBzZXQsIE5PVCBzdHJ1ZGVsJ3MgYnVpbHQtaW4gZ21fKjsgZG8gbm90IHN1YnN0aXR1dGUuCi8vICAgMi4gU2lnbmFscyDigJQgdGhlIGxpdmUgZ2FtZSB2YXJpYWJsZXMgYGdhbWVQcm9ncmVzc2AgLyBgZ2FtZVRocmVhdGAsIHN0dWJiZWQgaGVyZSBhcyBzbGlkZXJzCi8vICAgICAgeW91IGRyYWcgdG8gaGVhciBhIHNvbmcgcmVhY3QuCi8vCi8vIEluIHRoZSBnYW1lIHRoZXNlIHNhbWUgbmFtZXMgYXJlIHByb3ZpZGVkIGJ5IHRoZSBlbmdpbmUgKGpzL2F1ZGlvL3N0cnVkZWwvc291bmRmb250LmpzIHJlZ2lzdGVycwovLyB0aGUgaWRlbnRpY2FsIHByZXNldHM7IGpzL2F1ZGlvL3N0cnVkZWwvc2lnbmFsLWJyaWRnZS5qcyBpbmplY3RzIHRoZSBzYW1lIHNpZ25hbHMpLCBzbyBzb25nIGZpbGVzCi8vIGNhcnJ5IG5vIHNldHVwIG9mIHRoZWlyIG93biDigJQgdGhpcyBwcmViYWtlIGlzIHRoZSBlZGl0b3Itc2lkZSBtaXJyb3Igb2YgdGhhdCBjb250cmFjdC4KCi8vIOKUgOKUgCAwLiBGaXJlZm94IHNvdW5kZm9udC1yZWxlYXNlIGZpeCDilIDilIAKLy8gRmlyZWZveCBkb2VzIG5vdCBpbXBsZW1lbnQgQXVkaW9QYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lLCB3aGljaCB0aGUgU0YyIHBsYXllciBjYWxscyBvbiBldmVyeQovLyBzb3VuZGZvbnQgbm90ZS1vZmYuIFdpdGhvdXQgaXQgbm90ZS1vZmZzIHRocm93IGluIEZpcmVmb3gg4oaSIHNvdW5kZm9udCB2b2ljZXMgbmV2ZXIgcmVsZWFzZSAobm90ZXMKLy8gcmluZyBmb3JldmVyLCB2b2ljZXMgcGlsZSB1cCkuIFBvbHlmaWxsIGl0IChob2xkLWN1cnJlbnQtdmFsdWUpIGJlZm9yZSBhbnl0aGluZyBwbGF5cy4gTm8tb3AgaW4KLy8gQ2hyb21lLCBhbmQgbm8tb3AgaW4gdGhlIGdhbWUgKHRoZSBlbmdpbmUncyBydW50aW1lIGluc3RhbGxzIHRoZSBzYW1lIHNoaW0pLiBNaXJyb3JzIHJ1bnRpbWUuanMuCmlmICh0eXBlb2YgQXVkaW9QYXJhbSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEF1ZGlvUGFyYW0ucHJvdG90eXBlLmNhbmNlbEFuZEhvbGRBdFRpbWUgIT09ICdmdW5jdGlvbicpIHsKICBBdWRpb1BhcmFtLnByb3RvdHlwZS5jYW5jZWxBbmRIb2xkQXRUaW1lID0gZnVuY3Rpb24gKHQpIHsKICAgIGNvbnN0IGhlbGQgPSB0aGlzLnZhbHVlOwogICAgdHJ5IHsgdGhpcy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModCk7IH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH0KICAgIHRyeSB7IHRoaXMuc2V0VmFsdWVBdFRpbWUoaGVsZCwgdCk7IH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH0KICAgIHJldHVybiB0aGlzOwogIH07Cn0KCi8vIOKUgOKUgCAxLiBJbnN0cnVtZW50czogcmVnaXN0ZXIgZXZlcnkgZm9udCdzIHByZXNldHMgdW5kZXIgaXRzIHByZWZpeCDilIDilIAKLy8gTG9hZHMgZWFjaCBmdWxsIGF1dGhvcmluZyBTRjIgKENPUlMtZW5hYmxlZCBob3N0KSBzbyB0aGUgc291bmQgc2V0IGlzIGJ5dGUtaWRlbnRpY2FsIHRvIHdoYXQKLy8gY29tcG9zZXJzIHdvcmsgd2l0aC4gVGhlIG5hbWluZyAoc2FuaXRpemUgKyBkZWR1cCkgYW5kIHRoZSBub3RlIHRyaWdnZXIgTUlSUk9SCi8vIGpzL2F1ZGlvL3N0cnVkZWwvc291bmRmb250LmpzIGV4YWN0bHk7IGtlZXAgdGhlbSBpbiBzeW5jIGlmIHRoYXQgZmlsZSBjaGFuZ2VzLgovLyBgZm9udHM6IFtdYCBsZXRzIHN0cnVkZWwuY2MncyBzb3VuZGZvbnQgVUkgcmVuZGVyIHRoZSBlbnRyeSAoaXQgcmVhZHMgb3B0aW9ucy5mb250cy5sZW5ndGgpOwovLyBvdXIgdHJpZ2dlciBjbG9zZXMgb3ZlciBgcHJlc2V0YCwgc28gdGhlIGFycmF5IGl0c2VsZiBpcyB1bnVzZWQgZm9yIGF1ZGlvLgphc3luYyBmdW5jdGlvbiByZWdpc3RlclNvdW5kZm9udCh1cmwsIHByZWZpeCkgewogIGNvbnN0IHNmID0gYXdhaXQgbG9hZFNvdW5kZm9udCh1cmwpOwogIGNvbnN0IHVzZWQgPSBuZXcgU2V0KCk7CiAgc2YucHJlc2V0cy5mb3JFYWNoKChwcmVzZXQsIGkpID0%2BIHsKICAgIGNvbnN0IGNsZWFuZWQgPSBTdHJpbmcocHJlc2V0LmhlYWRlcj8ubmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bXmEtejAtOV0rL2csICdfJykucmVwbGFjZSgvXl8rfF8rJC9nLCAnJyk7CiAgICBsZXQgbmFtZSA9IHByZWZpeCArIChjbGVhbmVkIHx8ICdwcmVzZXRfJyArIGkpOwogICAgaWYgKHVzZWQuaGFzKG5hbWUpKSB7IGNvbnN0IGJhc2UgPSBuYW1lOyBsZXQgbiA9IDI7IHdoaWxlICh1c2VkLmhhcyhuYW1lKSkgbmFtZSA9IGJhc2UgKyAnXycgKyBuKys7IH0KICAgIHVzZWQuYWRkKG5hbWUpOwogICAgcmVnaXN0ZXJTb3VuZChuYW1lLCAodGltZSwgdmFsdWUpID0%2BIHsKICAgICAgLy8gUm91dGUgdGhlIHZvaWNlIGludG8gb3VyIG93biBnYWluIG5vZGUgYW5kIFJFVFVSTiBpdCBzbyBzdXBlcmRvdWdoIGFwcGxpZXMgaXRzIEZYIGNoYWluCiAgICAgIC8vIChnYWluL3Jvb20vbHBmL3Bhbi%2FigKYpIOKAlCBpdCBvbmx5IHdpcmVzIGVmZmVjdHMgb250byB0aGUgcmV0dXJuZWQgbm9kZSwgYW5kIGJhaWxzIG9uIG5vbmUuCiAgICAgIC8vIHNmdW1hdG8ncyBzdGFydFByZXNldE5vdGUgc2VsZi1jb25uZWN0cyB0byBjdHguZGVzdGluYXRpb24sIHNvIHByb3h5IHRoZSBjdHggdG8gcmVkaXJlY3QKICAgICAgLy8gLmRlc3RpbmF0aW9uIHRvIG91ciB0YXAgbm9kZTsgc3VwZXJkb3VnaCB0aGVuIGhhbmRsZXMgbm90ZS1vZmYgKHJhbXBzIG5vZGUuZ2FpbiwgY2FsbHMgc3RvcCkuCiAgICAgIGNvbnN0IGN0eCA9IGdldEF1ZGlvQ29udGV4dCgpOwogICAgICBjb25zdCBub3RlID0gdmFsdWU%2FLm5vdGUgPz8gJ2MzJzsKICAgICAgY29uc3QgbWlkaSA9IHR5cGVvZiBub3RlID09PSAnbnVtYmVyJyA%2FIG5vdGUgOiBub3RlVG9NaWRpKG5vdGUpOwogICAgICBjb25zdCBvdXQgPSBjdHguY3JlYXRlR2FpbigpOwogICAgICBjb25zdCBwcm94aWVkID0gbmV3IFByb3h5KGN0eCwgewogICAgICAgIGdldCh0YXJnZXQsIHByb3ApIHsKICAgICAgICAgIGlmIChwcm9wID09PSAnZGVzdGluYXRpb24nKSByZXR1cm4gb3V0OwogICAgICAgICAgY29uc3QgdiA9IHRhcmdldFtwcm9wXTsKICAgICAgICAgIHJldHVybiB0eXBlb2YgdiA9PT0gJ2Z1bmN0aW9uJyA%2FIHYuYmluZCh0YXJnZXQpIDogdjsKICAgICAgICB9LAogICAgICB9KTsKICAgICAgY29uc3Qgc3RvcCA9IHN0YXJ0UHJlc2V0Tm90ZShwcm94aWVkLCBwcmVzZXQsIG1pZGksIHRpbWUpOwogICAgICByZXR1cm4geyBub2RlOiBvdXQsIHN0b3AgfTsKICAgIH0sIHsgdHlwZTogJ3NvdW5kZm9udCcsIHByZWJha2U6IGZhbHNlLCBmb250czogW10gfSk7CiAgfSk7Cn0KCmF3YWl0IFByb21pc2UuYWxsKFsKICByZWdpc3RlclNvdW5kZm9udCgnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2xtb3JjaGFyZC9zdGFybmV0L21haW4vYXVkaW8tY29udGVudC9zb3VuZGZvbnRzL0dlbmVyYWxVc2VyLUdTLnNmMicsICdndXNfJyksIC8vIGd1cwogIHJlZ2lzdGVyU291bmRmb250KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbG1vcmNoYXJkL3N0YXJuZXQvbWFpbi9hdWRpby1jb250ZW50L3NvdW5kZm9udHMvTXVzZVNjb3JlLVBhZC5zZjInLCAnbXNncGFkXycpLCAvLyBtc2dwYWQKICByZWdpc3RlclNvdW5kZm9udCgnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2xtb3JjaGFyZC9zdGFybmV0L21haW4vYXVkaW8tY29udGVudC9zb3VuZGZvbnRzL011c2VTY29yZS1MZWFkLnNmMicsICdtc2dsZWFkXycpLCAvLyBtc2dsZWFkCiAgcmVnaXN0ZXJTb3VuZGZvbnQoJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9sbW9yY2hhcmQvc3Rhcm5ldC9tYWluL2F1ZGlvLWNvbnRlbnQvc291bmRmb250cy9NdXNlU2NvcmUtRlguc2YyJywgJ21zZ2Z4XycpLCAvLyBtc2dmeAogIHJlZ2lzdGVyU291bmRmb250KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbG1vcmNoYXJkL3N0YXJuZXQvbWFpbi9hdWRpby1jb250ZW50L3NvdW5kZm9udHMvTXVzZVNjb3JlLUJhc3Muc2YyJywgJ21zZ2Jhc3NfJyksIC8vIG1zZ2Jhc3MKICByZWdpc3RlclNvdW5kZm9udCgnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2xtb3JjaGFyZC9zdGFybmV0L21haW4vYXVkaW8tY29udGVudC9zb3VuZGZvbnRzL011c2VTY29yZS1LZXlzLnNmMicsICdtc2drZXlzXycpLCAvLyBtc2drZXlzCiAgcmVnaXN0ZXJTb3VuZGZvbnQoJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9sbW9yY2hhcmQvc3Rhcm5ldC9tYWluL2F1ZGlvLWNvbnRlbnQvc291bmRmb250cy9NdXNlU2NvcmUtT3JnYW4uc2YyJywgJ21zZ29yZ18nKSwgLy8gbXNnb3JnCiAgcmVnaXN0ZXJTb3VuZGZvbnQoJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9sbW9yY2hhcmQvc3Rhcm5ldC9tYWluL2F1ZGlvLWNvbnRlbnQvc291bmRmb250cy9NdXNlU2NvcmUtR3VpdGFyLnNmMicsICdtc2dndHJfJyksIC8vIG1zZ2d0cgogIHJlZ2lzdGVyU291bmRmb250KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbG1vcmNoYXJkL3N0YXJuZXQvbWFpbi9hdWRpby1jb250ZW50L3NvdW5kZm9udHMvTXVzZVNjb3JlLURydW1zLnNmMicsICdtc2dkcnVtXycpLCAvLyBtc2dkcnVtCl0pOwoKLy8g4pSA4pSAIDIuIFNpZ25hbHM6IHN0dWIgZ2FtZVByb2dyZXNzIC8gZ2FtZVRocmVhdCBzbyByZWFjdGl2ZSBzb25ncyBwbGF5ICsgcmVhY3Qgd2hpbGUgYXV0aG9yaW5nIOKUgOKUgAovLyBLZWVwIHRoaXMgbGlzdCBpbiBzeW5jIHdpdGgganMvYXVkaW8vc2lnbmFsLXJlZ2lzdHJ5LmpzIChjdXJyZW50bHk6IGdhbWVQcm9ncmVzcywgZ2FtZVRocmVhdCkuCi8vIEFzc2lnbmVkIG9udG8gYHdpbmRvdy5gIOKAlCBOT1QgYGxldGAgKGEgbGV0IGJpbmRpbmcgd291bGRuJ3QgYmUgdmlzaWJsZSB0byB0aGUgc2VwYXJhdGVseS1ldmFsdWF0ZWQKLy8gc29uZywgYW5kIGJhcmUgYXNzaWdubWVudCB0aHJvd3MgdW5kZXIgc3RyaWN0IG1vZGUpLiBEZWZhdWx0IGlzIHNsaWRlcnMgKGRyYWdnYWJsZSB3aWRnZXRzKTsKLy8gc3dhcCB0byBzd2VlcCBvciBtb3VzZSBiZWxvdyBmb3IgaGFuZHMtZnJlZSAvIHBvaW50ZXIgY29udHJvbC4KCi8vIC0tLSBzbGlkZXJzIChkZWZhdWx0KTogZHJhZ2dhYmxlIHdpZGdldHMgZm9yIGRlbGliZXJhdGUgdmFsdWVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCndpbmRvdy5nYW1lUHJvZ3Jlc3MgPSBzbGlkZXIoMC41LCAwLCAxKQp3aW5kb3cuZ2FtZVRocmVhdCAgID0gc2xpZGVyKDAuNSwgMCwgMSkKCi8vIC0tLSBhdXRvLXN3ZWVwOiBwaGFzZWQgc2luZXMgZHJpZnQgdGhlIHR3byBheGVzIGFjcm9zcyB0aGVpciByYW5nZSBoYW5kcy1mcmVlIC0tLS0tLS0tLS0tLS0tLS0tLQovLyB3aW5kb3cuZ2FtZVByb2dyZXNzID0gc2luZS5yYW5nZSgwLCAxKS5zbG93KDY0KQovLyB3aW5kb3cuZ2FtZVRocmVhdCAgID0gc2luZS5yYW5nZSgwLCAxKS5zbG93KDM3KQoKLy8gLS0tIG1vdXNlIGRyaXZlOiBYID0gZ2FtZVByb2dyZXNzLCBZID0gZ2FtZVRocmVhdCAobW92ZSB0aGUgcG9pbnRlciB0byBzdGVlcikgLS0tLS0tLS0tLS0tLS0tLS0tCi8vIHdpbmRvdy5nYW1lUHJvZ3Jlc3MgPSBtb3VzZXgKLy8gd2luZG93LmdhbWVUaHJlYXQgICA9IG1vdXNleQoKLyogQHRpdGxlICAgIFN0cmlwZG93biBpbnRybyAoQWdlbnQgU2lkZSBHcmluZGVyIGNvdmVyKQogICBAYnkgICAgICAgbG1vcmNoYXJkCiAgIEBsaWNlbnNlICBDQyBCWS1OQy1TQSAoaHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LW5jLXNhLzQuMC8pCiovCnNldGNwbSgxMjIvNCkKCmxldCBkcnVtcyA9IHNvdW5kKCJbYmQgc2RdKjIiKQogIC5wYW4oIlswLjQgMC41XSoyIikKICAubHBmKDcwMDApCiAgLnJvb20oMS4xMjUpCgpsZXQgaGF0cyA9IHNvdW5kKGA8W2hoKjggLSo4XSBbLSoxNl0%2BYCkKICAucGFuKHNpbmUuZmFzdCgxKSkKICAvLy52b3dlbCgiPGEgZSBpIDxvIHU%2BPiIpCiAgLnJvb20oMS4yNSkuZ2FpbigxLjApCgpsZXQgYmFzcyA9IG5vdGUoYAogICAgPAogICAgICBbCiAgICAgICAgRTIhNyBEMgogICAgICAgIEQyITcgRTIKICAgICAgICBFMiEzIEQyITQgQyMyCiAgICAgICAgQyMyITMgQzIhNQogICAgICBdITMKICAgICAgWwogICAgICAgIEUyITcgRDIKICAgICAgICBEMiE3IEExCiAgICAgICAgQTEhMyBCMSE0IEMyCiAgICAgICAgQzIhMyBEMiE1CiAgICAgIF0KICAgID4KICBgKQogIC5zbG93KDQpCiAgLnNvdW5kKCJnbV9zeW50aF9iYXNzXzIiKQogIC5nYWluKCJbMS4wIDAuNzVdKjQiKQogIC5yb29tKDAuNzUpCiAgLmxwZigyNTAwKQogIC5kaXN0b3J0KDAuNzUpCgpsZXQga2V5cyA9IG5vdGUoYAogICAgPAogICAgICBbCiAgICAgICAgRTMgfiAgRzMgRTMgRzMgRyMzIEEzIEQzCiAgICAgICAgfiBEMyB%2BIEQzIEEzIH4gRzMgfgogICAgICAgIEUzIEYjMyBHMyBEMyB%2BIEYjMyBHMyBDIzMKICAgICAgICB%2BIEYjMyBHMyBGIzMgQTMgfiBHMyB%2BCiAgICAgIF0hMwogICAgICBbCiAgICAgICAgRTMgfiAgRzMgRTMgRzMgRyMzIEEzIEQzCiAgICAgICAgfiBEMyB%2BIEQzIEEzIH4gRzMgfgogICAgICAgIEUzIEYjMyBHMyBEMyB%2BIEYjMyBHMyBDCiAgICAgICAgfiBGIzMgRzMgRiMzIEEzIH4gRzMgfgogICAgICBdCiAgICA%2BCiAgYCkuc2xvdyg0KQoKbGV0IGVwaWFubyA9IGtleXMKICAuc291bmQoImdtX2VwaWFubzIiKQogIC5wYW4oMC41NSkKICAucm9vbSgzLjApCiAgLmxwZig0MDAwKQogIC5lY2hvKDEsIDEvNiwgLjgpCiAgLnZpYig1KS52aWJtb2QoMC4xMikKCmxldCBwYWQgPSBrZXlzCiAgLnNvdW5kKCJnbV9wYWRfd2FybSIpCiAgLnBhbigwLjQ1KQogIC5yb29tKDIuMCkKICAuYXR0YWNrKDAuMCkucmVsZWFzZSgwLjAxKQogIC5lY2hvKDEsIDEvNiwgLjgpCiAgLnN1cGVyaW1wb3NlKAogICAgeCA9PiB4LmFkZChub3RlKDAuMTIpKS5wYW4oMC4yKSwKICAgIHggPT4geC5hZGQobm90ZSgtMC4xMikpLnBhbigwLjgpLAogICkKICAuZ2FpbigwLjc1KQoKJDogYXJyYW5nZSgKICBbOCwgc3RhY2soYmFzcywgZHJ1bXMsIGhhdHMpXSwgICAgICAgICAgICAgICAgLy8gZHJvcCB0aGUgYmVhdCBpbgogIFszMiwgc3RhY2soYmFzcywgZHJ1bXMsIGhhdHMsIGVwaWFubywgcGFkKV0sICAgLy8gZnVsbCB0ZXh0dXJlICh0d28gcGhyYXNlIGxvb3BzKQopCg%3D%3D">strudel.cc link</a> and listen to my take. The original track is also worth a listen, <a href="https://www.youtube.com/watch?v=9Il1mZd6ZQ4">here</a>. </p> <script src="https://unpkg.com/@strudel/embed@latest"></script> <strudel-repl> <!-- /* @title Stripdown intro (Agent Side Grinder cover) @by lmorchard @license CC BY-NC-SA (https://creativecommons.org/licenses/by-nc-sa/4.0/) */ setcpm(122/4) let drums = sound("[bd sd]*2") .pan("[0.4 0.5]*2") .lpf(7000) .room(1.125) let hats = sound(`<[hh*8 -*8] [-*16]>`) .pan(sine.fast(1)) //.vowel("<a e i <o u>>") .room(1.25).gain(1.0) let bass = note(` < [ E2!7 D2 D2!7 E2 E2!3 D2!4 C#2 C#2!3 C2!5 ]!3 [ E2!7 D2 D2!7 A1 A1!3 B1!4 C2 C2!3 D2!5 ] > `) .slow(4) .sound("gm_synth_bass_2") .gain("[1.0 0.75]*4") .room(0.75) .lpf(2500) .distort(0.75) let keys = note(` < [ E3 ~ G3 E3 G3 G#3 A3 D3 ~ D3 ~ D3 A3 ~ G3 ~ E3 F#3 G3 D3 ~ F#3 G3 C#3 ~ F#3 G3 F#3 A3 ~ G3 ~ ]!3 [ E3 ~ G3 E3 G3 G#3 A3 D3 ~ D3 ~ D3 A3 ~ G3 ~ E3 F#3 G3 D3 ~ F#3 G3 C ~ F#3 G3 F#3 A3 ~ G3 ~ ] > `).slow(4) let epiano = keys .sound("gm_epiano2") .pan(0.55) .room(3.0) .lpf(4000) .echo(1, 1/6, .8) .vib(5).vibmod(0.12) let pad = keys .sound("gm_pad_warm") .pan(0.45) .room(2.0) .attack(0.0).release(0.01) .echo(1, 1/6, .8) .superimpose( x => x.add(note(0.12)).pan(0.2), x => x.add(note(-0.12)).pan(0.8), ) .gain(0.75) $: arrange( [8, stack(bass, drums, hats)], // drop the beat in [32, stack(bass, drums, hats, epiano, pad)], // full texture (two phrase loops) ) --> </strudel-repl> <p><youtube-embed video-id="jus3XxWoVnI" thumbnail="9168e8151af4.jpg"></youtube-embed></p> <h2 id="starnet-tinkering">Starnet Tinkering</h2> <p>That strudel.cc noodling led me down a further rabbit hole: Turns out, it's not too hard <a href="https://strudel.cc/technical-manual/project-start/">to embed Strudel as a library in your own project</a> and Starnet was looking for a music &amp; audio engine.</p> <p>I'd had an initial version of an audio engine working with Tone.js, but I realized that I was starting to reinvent all kinds of wheels. So, I went from a kind of "hey claude, I wonder if we could..." session and ended with a <a href="https://github.com/lmorchard/starnet/issues/254">complete overhaul of the audio engine</a>.</p> <p>I'm not sure if this game will ever really get to a point where it's worth making much noise about (hah, get it, sound) but I'm having some fun finally hacking on this idea I've had for years.</p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li><p>Kind of along the same vein as strudel.cc, I found a visual livecoding tool made in Picotron called <a href="https://illomens.itch.io/magpie">Magpie</a>.</p> </li> <li><p>My 15-year-old Audio-Technica ATH-M30 headphones are still going strong, despite a <a href="https://masto.hackers.town/@lmorchard/116847194529514348">cat-nibbled cable</a>. I'm almost daring it to fail now.</p> <p><img src="https://blog.lmorchard.com/2026/07/05/w27/9dc88c354640.jpg" alt="A frayed black electrical cord with exposed copper wires on a wooden surface." width="" height=""></p> </li> <li><p>I want this t-shirt from the band ACTORS, but it kinda reminds me of the Freejack movie poster. </p> <image-gallery> <p> <img src="https://blog.lmorchard.com/2026/07/05/w27/8a64ccf369e1.png" alt="Movie poster for &quot;Freejack&quot; featuring the heads of Emilio Estevez, Mick Jagger, and Anthony Hopkins over a futuristic blue grid." width="" height=""></p> <p> <img src="https://blog.lmorchard.com/2026/07/05/w27/30459d7d84b3.png" alt="A black t-shirt with a pink and blue graphic for the band &quot;Actors&quot; and the text &quot;Our Love Will Live Forever.&quot; Features the heads of the band over a distorted blue grid, kinda like the Freejack poster" width="" height=""></p> </image-gallery> </li> <li><p>Neat article on <a href="https://www.audubon.org/magazine/are-crows-really-our-friends?utm_source=firefox-newtab-en-us">crows and their relationship with humans</a> from Audubon - I still kind of like to think I can be friends with crows.</p> </li> <li><p>A dive into web history with "<a href="https://davidpoblador.com/deep-dives/the-descent/">The Descent — What Happened to the Frontend While You Weren't Watching</a>" - from HTML to jQuery to React to whatever this mess is that we're trying to deploy in 2026.</p> </li> <li><p>Musing on the "<a href="https://eieio.games/blog/legibility-of-effort/?ref=sidebar">Legibility of Effort</a>" in the age of LLMs - and how just because something <em>looks</em> like it took care &amp; effort doesn't mean it benefitted from either, and so may not be worth your time &amp; attention.</p> </li> <li><p>A link to <a href="https://sneakerweb.org/">sneakerweb</a>, a CLI tool for browsing and maintaining a local collection of "sneakerwebsites." It's like a pocket-universe web where you have to actually, like, meet people in the real world to exchange packets.</p> </li> <li><p>A recreation and modernization of the original web forum, <a href="https://github.com/readtedium/WIT">WIT (W3 Interactive Talk)</a>, dating back to June 1994.</p> </li> <li><p><a href="https://www.opentools.studio/">OpenTools / OpenPrinter</a>, aiming for a repairable, compact, and robust printer design.</p> </li> </ul> </div> Sun, 05 Jul 2026 19:00:00 GMT https://blog.lmorchard.com/2026/07/05/w27/ https://blog.lmorchard.com/2026/07/05/w27/ weeknotescatsmusic-techstrudel-cccodinggithubwebdev A masochist and his MacBook (Week 26) <p><em>TL;DR:</em> I spent a good chunk of this week trying to drag a 14-year-old MacBook Pro into the present by way of every Linux distro that would boot, got a screen full of static for my trouble, and eventually clawed my way to a working Fedora install. Also: my Benchy finally floats, purple gaming gear keeps breeding on my desk, and I scheduled a memorial tattoo for Puck (lost in 2015).</p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="a-masochist-and-his-macbook">A masochist and his MacBook</h2> <p>The sudden ADHD-driven side-project of my week was a mid-2012 Retina MacBook Pro that macOS has long since <a href="https://masto.hackers.town/@lmorchard/116796321955213327">given up on</a>. Still in decent shape physically - although I <em>did</em> <a href="https://www.printables.com/model/804933-macbook-pro-feet-a1398">print some new feet for it</a>.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/6d52746cb3d1.webp" alt="Close-up of one corner of the MacBook's underside, with a black 3D-printed disc foot stuck on and green trees blurred through a window behind" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/8480b013f881.webp" alt="Side profile of the MacBook Pro's port edge, raised slightly off the desk on a black 3D-printed foot" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/dec424a08abe.webp" alt="The closed MacBook Pro lying upside down on a desk with a black iFixit toolkit pouch resting on its underside" width="" height=""></p> </image-gallery> <p>But, it's been abandoned by Apple for OS updates. I got it into my head that I could give it a few more years of life as a basement word processor or a tinkering terminal, and proceeded to spend the week learning exactly how stubborn that idea was.</p> <p>The tour: the latest Ubuntu LTS installer gave me <a href="https://masto.hackers.town/@lmorchard/116790622035814330">nothing but a green screen</a> (probably nvidia drivers). Linux Mint installed in safe mode, got me wifi and a touchpad, but never figured out suspend.</p> <p>So I figured I'd back out and try a network reinstall of macOS instead, which is how I <a href="https://masto.hackers.town/@lmorchard/116790565742610954">ended up face to face with Mountain Lion</a> again - which I guess was near enough to the original OS with which this thing shipped:</p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/8c7526937078.jpg" alt="A laptop screen showing the OS X Mountain Lion installer, prompting the user to select an installation disk" width="" height=""></p> <p>Which, of course, turned out to be <a href="https://masto.hackers.town/@lmorchard/116790662969313014">too old</a>. Too old for what? Yes.</p> <p>Being a <a href="https://masto.hackers.town/@lmorchard/116796157295712397">masochist</a>, I clawed the thing up to Catalina. That's newish-enough to run the latest version of Firefox and many other apps - but things are moving on from that version of macOS.</p> <p>So then I went for a Fedora KDE desktop dual-boot. The live ISO behaved better than Mint did, right up until the installer segfaulted on me.</p> <p>Turns out it's <a href="https://bugzilla.redhat.com/show_bug.cgi?id=2411887">a known bug</a>: Fedora's new web-based installer (codenamed "slitherer") crashes on nvidia hardware, and the <a href="https://discussion.fedoraproject.org/t/installer-crashes-in-storage-editor-in-all-live-environments-except-workstation/192590">workaround</a> is to point Anaconda at Firefox instead. After that, <a href="https://masto.hackers.town/@lmorchard/116796172731330834">cute dragons</a>:</p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/9f27ee6a1b1c.jpg" alt="The final screen of a Fedora install, showing a &quot;Completed!&quot; dialog with two cartoon dragon mascots" width="" height=""></p> <p>The other unsung hero was a <a href="https://masto.hackers.town/@lmorchard/116796233709650271">cheap USB Ethernet widget</a>, because it turns out every Linux distro on earth hates the wifi hardware in every Apple laptop:</p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/18e50a1e86cf.jpg" alt="A Benfei USB-ethernet adapter connecting an ethernet cable to an old MacBook Pro" width="" height=""></p> <p>So where did I land, after all that? Tallying it up: Ubuntu didn't work at all, Mint <em>mostly</em> worked (wifi yes, suspend never), and <a href="https://masto.hackers.town/@lmorchard/116796342079498672">Fedora KDE worked</a> including suspend but not wifi, until I activated some non-free repos to chase the wifi drivers, did a software upgrade, rebooted, and got this:</p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/f49830a82abd.jpg" alt="A silver MacBook Pro with its screen filled with colorful horizontal lines of static" width="" height=""></p> <p>I suspect I <a href="https://masto.hackers.town/@lmorchard/116796330498710257">dragged in some bum nvidia drivers</a> along with the wifi ones.</p> <p>From here, I learned about <code>dnf history list</code> and <code>dnf history undo</code>, along with more carefully segmenting the list of needful updates. I kind of applied a <code>git bisect</code> algorithm to the whole thing, danced with <code>dnf update</code> and <code>dnf history undo</code> to pare down the updates repeatedly in a rough binary search until things stopped breaking.</p> <p>Oddly enough, it wasn't nvidia drivers - it was something in KDE or Qt, which I've got version locked for now until I deign to wrestle with all this again.</p> <p>Now I have a working Fedora install. The wifi works, after a struggle with the open-source driver causing display glitches under heavy network traffic. Suspend works. The trackpad works. The keyboard works. The screen works. Probably a few things left not working, but this seems good enough for now.</p> <p>This can be a fine homelab terminal and word processor for a few more years, and I can stop trying to make it do more than it wants to. Oh, and I still have this older install of macOS Catalina on a separate partition, just in case.</p> <h2 id="boats-that-sometimes-float">Boats that (sometimes) float</h2> <p>The <a href="https://masto.hackers.town/@lmorchard/116806580746594691">3D printing</a> continues, and I have learned that a Benchy makes a deeply unconvincing boat. The standard one capsizes immediately. But I'm still learning this ASA stuff (continuing last week's adventures in materials I don't fully understand), and by the end of the week I'd printed <a href="https://masto.hackers.town/@lmorchard/116813343483915806">one that actually floats</a>, listing a bit to port, with a smokestack that got a little mangled in the print:</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/bcbfce12277b.jpg" alt="A black 3D-printed tugboat floating on a pond next to green water hyacinths" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/1955129c62f3.jpg" alt="A capsized Benchy floating in dark, sun-dappled water" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/2c60560fbd02.jpg" alt="A miniature black boat floating in a murky pond among wet vines and flowers" width="" height=""></p> </image-gallery> <h2 id="gaming-gear-that-always-breeds">Gaming gear that (always) breeds</h2> <p>Gaming gear is <a href="https://masto.hackers.town/@lmorchard/116812195025654947">accumulating on my desk</a> again, apparently of its own accord, and apparently within <a href="https://masto.hackers.town/@lmorchard/116812353664926556">a fairly specific color range</a>:</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/54d9572af0e5.jpg" alt="A purple Xbox controller, handheld game consoles, and 3D-printed figurines on a wooden desk" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/a8054b3de96d.jpg" alt="A cluttered wooden desk full of purple items: a game controller, a water bottle, and figurines" width="" height=""></p> </image-gallery> <p>The culprit, I think, is that a <a href="https://masto.hackers.town/@lmorchard/116791781636246649">random brain ping</a> from a YouTube video gave me a sudden hankering to play Devil's Crush for the TurboGrafx-16 on my little Anbernic. Which led to Pokémon Pinball on the GBA, which led to wanting Metroid Prime Pinball on the DS. I've never much cared for video-game pinball before, and I'm <a href="https://masto.hackers.town/@lmorchard/116791785182491534">genuinely terrible</a> at the physical kind, but suddenly it has its hooks in me. Weird brain.</p> <h2 id="a-tattoo-for-puck">A tattoo for Puck</h2> <p>I <a href="https://masto.hackers.town/@lmorchard/116789633870344909">scheduled my second tattoo</a> this week, this one for Puck. <a href="https://blog.lmorchard.com/2015/04/15/goodbye-puck/">I lost him back in 2015</a>, and he was an unbelievably good pal.</p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/bed65ced57ed.jpg" alt="Two young cats perched on a vintage CRT monitor, in a nostalgic flash-lit photo" width="" height=""></p> <p>Puck and his sister Inanna were the <a href="https://masto.hackers.town/@lmorchard/116789808337846838">first cats I took care of</a> as an adult. They'd both purr and start kneading the moment I walked into a room. Puck would jump straight from the floor up onto my shoulders and go to sleep there. Eleven years gone, but worth a permanent mark now that I've <a href="https://blog.lmorchard.com/2026/06/26/w26//2026/05/21/w18-w19-w20-w21/">broken the seal with Catsby</a>.</p> <p>The current crew is doing fine, for the record. The trackball <a href="https://masto.hackers.town/@lmorchard/116796486680027860">remains undefeated</a> as the superior pointing device for the discerning cat caretaker, mostly because it leaves a free hand for the cat asleep on your arm.</p> <p><img src="https://blog.lmorchard.com/2026/06/26/w26/79d15244ef12.jpg" alt="A black cat sleeping in a plush bed with its paw resting on a tattooed arm using a trackball mouse at a desk" width="" height=""></p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li><p>On the YouTube side, my one like of the week was a retro-TV rabbit hole: <a href="https://www.youtube.com/watch?v=153U7Kwl_cg"><em>That's Incredible! The Most Sadistic Show on TV (and We LOVED It)</em></a>, on the 1980s ABC phenomenon that paraded bizarre people and dangerous stunts across Monday nights. <youtube-embed video-id="153U7Kwl_cg" title="That's Incredible! The Most Sadistic Show on TV (and We LOVED It)" thumbnail="d55cf49ddf91.jpg"></youtube-embed></p> </li> <li><p>And a happy one for the podcast feed: <a href="https://pocketcasts.com/podcast/c32c37c0-5206-013f-1f83-0e98e27f20d9">the STARLOG Podcast is back, with Annalee Newitz</a>. Always glad when good things come back from the dead, which, given the rest of this week, is apparently the theme.</p> </li> <li><p><a href="https://www.pwnwriter.me/syndications/eipi-boo-ssh">eipi.boo</a>: an anonymous confession board that lives entirely in your terminal over SSH. The terminal-as-app aesthetic gets me every time.</p> </li> <li><p>A small cluster of personal-website craft: <a href="https://specification.website/">The Website Specification</a>, a platform-agnostic checklist of the technical features every decent website should have (for humans <em>and</em> agents), and <a href="https://hawksley.dev/blog/json-ld-explained-for-personal-websites/">JSON-LD Explained for Personal Websites</a> on adding structured data so crawlers understand your pages.</p> </li> <li><p>On the blogging-mechanics front: <a href="https://handwritten.danieljanus.pl/">a blog written entirely by hand</a>, and a very practical <a href="https://foosel.net/til/how-to-manage-this-page-from-my-phone-in-2026/">how-to on managing a Hugo site from an Android phone in 2026</a>, which I keep meaning to sort out for myself.</p> </li> <li><p><a href="https://github.com/argyleink/prop-for-that">prop-for-that</a>: what JavaScript knows (pointer position, viewport size, battery, network), now exposed to CSS via custom properties, batched down to one <code>setProperty</code> per frame. Nifty.</p> </li> <li><p>For the gamedev shelf: <a href="https://tck.mn/blog/correlated-randomness-sts2/">Correlated randomness in Slay the Spire 2</a>, a great deep-dive on how shared PRNG seeds leaked future-randomness info to crafty players, and <a href="https://rivalis.dev/">Rivalis</a>, an open-source real-time multiplayer framework for browser games.</p> </li> <li><p>The Vergecast had me thinking about hardware this week, which lined up neatly with two bookmarks: <a href="https://blog.matthewbrunelle.com/my-steam-machine-is-a-50ft-hdmi-cable/">My Steam Machine is a 50ft HDMI Cable</a> (couch gaming via a comically long cable plus Bazzite) and a <a href="https://manualdousuario.net/en/smart-glasses-ugly-tacky/">takedown of the current crop of tacky smart glasses</a>, which can't hide the chips and batteries yet so they all have those thick Larry-David's-dad rims.</p> </li> <li><p>Handheld retro adjacency: <a href="https://get-starboard.app/">Starboard</a> brings the Portmaster catalogue of community game ports to Android handhelds by running them in a real Linux environment under the hood.</p> </li> <li><p>Two on the agentic-web-and-gadgets theme: Richard MacManus on <a href="https://ricmac.org/2026/03/06/building-ask-ricmac-my-first-experiment-in-the-agentic-web-stack/">building "Ask Ricmac"</a>, an AI chatbot trained on his own years of writing, and <a href="https://github.com/maddiedreese/xteink-tamagotchi">xteink-tamagotchi</a>, which displays your AI assistant's activity on a portable e-ink screen like a little digital pet.</p> </li> <li><p>Soundtrack for all of the above was the usual darkwave/synth rotation in heavy use: Clan of Xymox, VNV Nation, ACTORS, Kite, Ladytron, and TR/ST. And for some reason this week, I feel like throwing a bunch of video embeds in here, if only for me to listen to again.</p> <p><youtube-embed video-id="e89waZJbuQ0" thumbnail="30b7881f1f0f.jpg"></youtube-embed></p> <p><youtube-embed video-id="72A9nFNhdOM" thumbnail="ee43ea11c657.jpg"></youtube-embed></p> <p><youtube-embed video-id="CuiKeaqERTU" thumbnail="18e43f5b3b6a.jpg"></youtube-embed></p> <p><youtube-embed video-id="mbmZ5XEHkHA" thumbnail="a07031c0f7ac.jpg"></youtube-embed></p> <p><youtube-embed video-id="ZmIRYHoj6So" thumbnail="182e3faa91b2.jpg"></youtube-embed></p> <p><youtube-embed video-id="gtqvXw7vFO0" thumbnail="0a3eb759d3e4.jpg"></youtube-embed></p> </li> </ul> </div> <p>Somehow this is Week 26, which means we're halfway through 2026 already. I refuse to discuss it further.</p> Fri, 26 Jun 2026 19:00:00 GMT https://blog.lmorchard.com/2026/06/26/w26/ https://blog.lmorchard.com/2026/06/26/w26/ weeknoteslinuxappleretrocomputing3dprintinggamingcats starnet ate the month (Catching up: May 29 – June 18) <p><em>TL;DR:</em> It's been about three weeks since the last weeknote, so this is a catchup. The short version: our newest cat tried to murder one of the other cats and broke my heart a little, a raccoon declared war on our backyard pond, I learned the hard way that ASA needs a brim, and I poured an absurd amount of agent-driven coding into a procedural cyberpunk hacking game called starnet. Also Technology Connections made an hour-long video about ceiling fans and I was <em>delighted.</em></p> <!--more--> <nav role="navigation" class="table-of-contents"></nav> <h2 id="the-minnaloushe-situation">The Minnaloushe situation</h2> <p>We <a href="https://blog.lmorchard.com/2026/06/18/w25//2026/04/17/w14-w15-w16/#the-void-arrives">adopted Minnaloushe</a> a couple months back. We're his third home; he'd been bounced around a bit. He'd been settling in okay, a little hair-trigger about his boundaries but never aggressive.</p> <p>Then, <a href="https://masto.hackers.town/@lmorchard/116698475697187954">out of nowhere</a>, he decided Cosmo needed his ass kicked. Claws out, blood drawn, stalking him through the house repeatedly over several days. Not play. I spent a genuinely awful few days <a href="https://masto.hackers.town/@lmorchard/116698502272537443">wondering</a> if he needed to be a solo cat in a quieter home, and feeling terrible about the prospect of bouncing him to his <em>fourth</em> placement.</p> <p>It didn't help that I'm running real low on tolerance for pet drama <a href="https://masto.hackers.town/@lmorchard/116705523193542623">right now</a>, after half a year of hospice for and then losing Catsby earlier this year.</p> <p>We've thrown the whole kit at it: gabapentin, Feliway diffusers in half the rooms, and now Prozac. As of <a href="https://masto.hackers.town/@lmorchard/116769399737830089">this week</a> he's living in my home office for a few weeks (cozy, doped, played-with, basically on a stability vacation), and the vet's optimistic that we just reintroduced him to the house too fast the first time:</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/9c7289b54c8c.jpg" alt="Minnaloushe, a black cat, looking relaxed in the home office" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/86fcdb3caf73.jpg" alt="Minnaloushe stretched out and cozy" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/b00d15e6e7ca.jpg" alt="Minnaloushe curled up in a desk-mounted cat bed" width="" height=""></p> </image-gallery> <p>The bitter little irony, which I <a href="https://masto.hackers.town/@lmorchard/116769402935317140">told my wife</a>: after Catsby passed, I said I wanted another cat as anxious as me to be my buddy. Careful what you wish for.</p> <p>When he's calm, Minnaloushe is a giant dopey teddy bear who flops directly into my lap and purrs, and I'm just trying to convince him that everybody here is cool to hang out with. Meanwhile Cosmo and Miss Biscuits are out there <a href="https://masto.hackers.town/@lmorchard/116773500563700215">holding paws</a> on a towel like nothing happened.</p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/a511b8d01a1a.jpeg" alt="Cosmo (white) and Miss Biscuits (grey) lounging on a bed, Miss Biscuits touching Cosmo's paw" width="" height=""></p> <p>(Also: Chewy mailed us a card wishing <a href="https://masto.hackers.town/@lmorchard/116769457142539713">Cosmo a happy 9th birthday</a> and I said "how very dare you?" That cat is still twelve weeks old, like the day we adopted him, and always will be.)</p> <h2 id="the-pond-bandit-and-other-animal-friends">The pond bandit and other animal friends</h2> <p>Lighter fare. We put some plants and a little fountain setup in the backyard pond, and woke up the next day to find it all shredded and the pump hoses yanked out of the water. So I put up a camera and <a href="https://masto.hackers.town/@lmorchard/116681414211130354">caught the culprit</a>: a raccoon. The pond bandit. 🦝</p> <figure> <video controls=""> <source src="./raccoon-pond-bandit.mp4" type="video/mp4"> <a href="https://blog.lmorchard.com/2026/06/18/w25/./raccoon-pond-bandit.mp4">raccoon-pond-bandit.mp4</a> </video> <figcaption>The pond bandit, caught on camera making off with the waterworks.</figcaption> </figure> <p>Part of me wants to be mad. Those plants weren't free, and it keeps pulling the cords up. But <a href="https://masto.hackers.town/@lmorchard/116681423589284116">it looks like they're having so much fun?</a> The floating skimmer especially seems to be a favorite, which I figure must function as a little buffet bucket of tasty pond goodies. The bandit <a href="https://masto.hackers.town/@lmorchard/116754709306023033">came back for a full pond party</a> a couple weeks later, so I think we live here now and they let us stay.</p> <figure> <video controls=""> <source src="./raccoon-pond-party.mp4" type="video/mp4"> <a href="https://blog.lmorchard.com/2026/06/18/w25/./raccoon-pond-party.mp4">raccoon-pond-party.mp4</a> </video> <figcaption>Back for more. The pond party continues.</figcaption> </figure> <p>The pond also kicked off one of my dumber 3D-printing schemes: I found <a href="https://masto.hackers.town/@lmorchard/116677724657724581">busts of Data and Picard</a> and got it into my head to turn them into molds and cast concrete spitters for the pond. (I even liked a <a href="https://www.youtube.com/watch?v=tiydT2_OVLs">whole tutorial</a> on making concrete statues from 3D prints, so it's basically inevitable now.)</p> <p>In between all this I've been roasting coffee out on the deck and eating lunch out there, where, as the raccoon thread foreshadowed, I am <a href="https://masto.hackers.town/@lmorchard/116693687350671406">not always alone</a>:</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/1d8d128b4af9.jpg" alt="A scrub jay perched on the deck railing, helping itself to peanuts" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/9cac63968f9d.jpg" alt="A squirrel on the deck clutching a peanut" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/3808f0f0e47c.jpg" alt="Minnaloushe staring out through the screen door at the animals, claws hooked into the screen" width="" height=""></p> </image-gallery> <p>The scrub jay and the squirrel split the peanut concession; Minnaloushe supervised from behind the screen door, claws hooked in, deeply invested.</p> <h2 id="a-voyage-of-3d-printing-discovery">A voyage of 3D printing discovery</h2> <p>The other maker thread was 3D printing, specifically my ongoing education in materials I don't understand yet.</p> <p>I've got a Prusa MK4S with an MMU3, which apparently means <a href="https://masto.hackers.town/@lmorchard/116755323076189502">full-color CMYKW printing</a> is coming via some ColorMix software updates. Ludicrously wasteful of filament (the waste tower can be <a href="https://fosstodon.org/@castaway/116762358607113287">bigger than the print</a>, I'm told), but for the occasional special little geegaw, nifty. And I do love a special little geegaw:</p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/36adf9b01f4a.jpg" alt="A wall of colorful 3D-printed objects: weird cats, a ghost, a santa, a tree-elf, and assorted oddities" width="" height=""></p> <p>Then I built a BentoBox filter + enclosure so I could try ASA without stinking up the basement, and <a href="https://masto.hackers.town/@lmorchard/116767890001274750">yolo'd my first Benchy</a> with no brim. Reader, you need a brim. <a href="https://masto.hackers.town/@lmorchard/116768966221051320">Third time, with a brim, was the charm</a>, though the last couple attempts have this odd little defect in the bow that the helpful folks on Mastodon tell me is a speed/cooling thing:</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/4219ccfb9c2e.jpg" alt="The BentoBox filter and enclosure built, with the first ASA print starting on the bed" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/161dd5594ce9.jpg" alt="A failed ASA Benchy print, warped and detached from the bed" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/4bd649054cac.jpg" alt="A successful ASA Benchy, third attempt, printed with a brim" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/07a86f8108c8.jpg" alt="The successful Benchy from another angle" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/5277ee547179.jpg" alt="Close-up of the odd defect in the bow of the Benchy" width="" height=""></p> </image-gallery> <p>The filter, at least, did its job; I didn't smell a thing. The whiff of ASA I <em>did</em> catch reminded me powerfully of burning things I shouldn't have as a kid.</p> <h2 id="starnet-ate-the-month">starnet ate the month</h2> <p>If you went by my GitHub activity, you'd think I did exactly one thing for three weeks. You'd be mostly right. There's this project I started called <a href="https://github.com/lmorchard/starnet"><strong>starnet</strong></a>. It aims to grow up to be a procedural, roguelike-ish cyberpunk hacking game, very much in the lineage of Uplink and every "jack into the mainframe" fantasy I absorbed as a kid.</p> <p>If you want to poke at it, there's a very rough in-progress build:</p> <ul> <li><a href="https://lmorchard.github.io/starnet/">https://lmorchard.github.io/starnet/</a></li> </ul> <p>And here's what it looks like as of this week:</p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/./starnet-0.png" alt="Screenshot of Starnet" width="" height=""></p> <p>I won't enumerate the PR firehose (it's genuinely embarrassing; I think I closed something like a dozen issues and merged thirty-some branches), but the shape of it: I built an audio engine using <a href="https://tonejs.github.io/">Tone.js</a> this stretch, starting with <a href="https://github.com/lmorchard/starnet/pull/226">reactive procedural music</a>, then <a href="https://github.com/lmorchard/starnet/issues/229">event SFX for game actions</a>.</p> <p>A part that made me grin when I got it working: the game renders machine and connection health as little <strong>ECG-style readouts</strong>, blips and flatlines.</p> <p>Which is funny, because earlier in this same stretch I fell down a <a href="https://masto.hackers.town/@lmorchard/116733332238921073">Zoids on the C64</a> rabbit hole and the thing I kept marveling at was how that game rendered your mech's health as <em>EEG graphs with lubb-dubb sound effects.</em> Eleven-year-old me filed that away as The Coolest Possible Way To Show Damage and never let go.</p> <p>The thing I keep circling, though: this is <em>all</em> agent-driven. I run a bank of agents in worktrees; they propose designs and give me knobs to tweak. I review, I merge, I queue the next thing. I've even been trying to act like a product manager with <a href="https://github.com/users/lmorchard/projects/7/views/1">a GitHub project board</a> and everything.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/./starnet-1.png" alt="Screenshot of design alternatives" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/./starnet-2.png" alt="Screenshot of more design alternatives" width="" height=""></p> </image-gallery> <p>It moves fast, and I've spent the month bookmarking what feels like every essay being written about exactly that sensation: the "AI brain fry," the discipline problem, the thermonuclear ADHD amplifier. (Those are all down in Miscellanea, and I clearly have feelings.) I don't have a tidy conclusion. starnet is the most fun I've had building something in ages <em>and</em> I can feel the way it lets me skate along the surface of my own codebase. Both things are true. I'm sitting with it.</p> <h2 id="retro-rabbit-holes">Retro rabbit holes</h2> <p>I already confessed the Zoids thing up above, but it deserves its own beat.</p> <p><youtube-embed video-id="e1tjnD9Q8yA" thumbnail="8a57673ba258.jpg"></youtube-embed></p> <p>I genuinely cannot get over <a href="https://masto.hackers.town/@lmorchard/116733345418451710">how much that 1986 C64 game crammed in</a>: overworld navigation, railgun combat, missile guidance, shield and damage management, <em>a Fourier-synthesis minigame to jam enemy radio signals.</em> All in real time, all on a one-button Atari joystick, all while the rest of the hazards keep pummeling you. Eleven-year-old me was simply not the same afterward.</p> <image-gallery> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/57445d323dbf.png" alt="Zoids on C64: a choice of waveforms for signal jamming" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/92973f144cfe.png" alt="Zoids on C64: tweaking the characteristics of a waveform" width="" height=""></p> <p><img src="https://blog.lmorchard.com/2026/06/18/w25/ea4a8dfb0aa6.png" alt="Zoids on C64: a successful jam with a matching waveform" width="" height=""></p> </image-gallery> <p>I also <a href="https://masto.hackers.town/@lmorchard/116745400654839779">finished Castlevania: Symphony of the Night again</a> and had completely forgotten about the 90s adult-contemporary end-credits ballad, <a href="https://castlevania.fandom.com/wiki/I_am_the_Wind">"I Am the Wind."</a> As Alucard would say: "What?!"</p> <p><youtube-embed video-id="ywAg5UJGvfs" thumbnail="a4238cd75836.jpg"></youtube-embed></p> <h2 id="miscellanea">Miscellanea</h2> <div class="weeknote-miscellanea"> <ul> <li>The AI-coding-and-your-brain reading pile that I mentioned up top: Simon Willison on <a href="https://simonwillison.net/2026/May/31/the-solution-might-be-cancelling-my-ai-subscription/#atom-everything">cancelling his AI subscription</a> ("the critical skill to develop here is discipline," bad news for both of us, Simon); the <a href="https://thoughts.hmmz.org/2026-05-31.html">original post</a> that prompted it, calling the tech "a thermonuclear ADHD amplifier"; joe.dev on <a href="https://joe.dev/posts/new-20pct-time/">the new 20% time</a> and "AI brain fry" (<em>"the thing that gives out is your own capacity to hold context and decide"</em>); and Ethan Mollick on <a href="https://www.oneusefulthing.org/p/co-existence-and-the-end-of-co-intelligence">co-existence and the end of co-intelligence</a>. For extra credit, a 2009 paper on <a href="https://ideas.repec.org/a/eee/jobhdp/v109y2009i2p168-181.html">attention residue</a> when switching between tasks. I am, as they say, in this picture and I do not like it.</li> <li>On the funnier end of the same theme: <a href="https://github.com/cyberpapiii/chipotlai-max">chipotlai-max</a>, "the AI coding agent that runs on stolen Chipotle compute," and <a href="https://vorpus.github.io/performativeUI/">performative-ui</a>, AI-native React components that "signal how oversubscribed your funding round is."</li> <li><a href="https://www.richardosgood.com/posts/banned-book-library/">Banned Book Library</a>: reprogram a cheap ESP32 WiFi lightbulb into a web server hosting banned books and screw it in wherever. A cyberpunk dead drop. "You can't stop the signal."</li> <li><a href="https://github.com/RobSmithDev/PaulaNET">PaulaNET</a>: Amiga WiFi internet access <em>via the floppy drive port</em>, which is exactly the kind of beautiful nonsense I needed to see while eyeing my A1200.</li> <li><a href="https://waxy.org/2026/06/lego-batmans-commodore-64-basic-easter-egg/">LEGO Batman's Commodore 64 BASIC easter egg</a> (audio on), and <a href="https://staniks.github.io/articles/catlantean-3d-blog-1/">Catlantean 3D</a>, one person building a complete FPS "like it's 1993."</li> <li>Two single-line/vector font finds for future plotter tinkering: Jürg Lehni's <a href="https://juerglehni.com/works/hektor">Hektor</a>, a spray-can drawing machine, and <a href="https://hershey-noailles.luuse.io/www/">Hershey Noailles</a>, the classic Hershey vector fonts reworked as CSS strokes.</li> <li><a href="https://mohkohn.co.uk/writing/html-first/">How building an HTML-first site doubled our users overnight</a>: "build a web application that works on a PlayStation Portable on a 3G connection." Yes. Pairs well with <a href="https://csswizardry.com/Obs.js/demo/">Obs.js</a>, which adapts delivery based on battery and connection signals.</li> <li><a href="https://orbitaloperations.beehiiv.com/p/doctor-when?utm_source=orbitaloperations.beehiiv.com">Doctor When</a>: a melancholy take that old sci-fi IP (Who, Trek, Stargate, the MCU) is hitting a hiatus point, while the two biggest films of the month were made for under a million each by directors in their twenties.</li> <li><a href="https://giants-club.net/articles/just-use-mastodon/">Look, just fucking use Mastodon already</a>: the escape-hatch argument for the fediverse, delivered with feeling.</li> <li>And the genuinely lovely thing of the month: <a href="https://www.youtube.com/watch?v=_KWdCqpXB7A">Technology Connections made a 71-minute video about ceiling fans</a>. My exact reaction was "okay everybody shut the fuck up, Technology Connections is on." There is, of course, a ceiling fan collector community.</li> </ul> <p><youtube-embed video-id="_KWdCqpXB7A" thumbnail="b37fb9aa18c6.jpg"></youtube-embed></p> </div> Thu, 18 Jun 2026 19:00:00 GMT https://blog.lmorchard.com/2026/06/18/w25/ https://blog.lmorchard.com/2026/06/18/w25/ weeknotesgamedev3dprintingcatsairetrocomputing