<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Geir&apos;s Everything</title>
    <description>Philosophy - Sciences - Geekery - Art - Life - Coaching - Fun &lt; Simplify Everything</description>
    <link>https://isene.org/</link>
    <atom:link href="nathanrooy.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Wed, 06 May 2026 12:22:48 +0000</pubDate>
    <lastBuildDate>Wed, 06 May 2026 12:22:48 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
      
    
    <item>
        <title>Fan! Can you please shut up?</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/posts/fan.png&quot; alt=&quot;The fan trip&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;why-is-the-fan-so-noisy&quot;&gt;Why is the fan so noisy?&lt;/h2&gt;

&lt;p&gt;It’s my brand new Dell XPS 14, and the fan is noticeably, annoyingly, incessantly… there. Not really loud by anyone’s measure. But it’s there.&lt;/p&gt;

&lt;p&gt;And thus it started. Tweaking the power profile, downloading the latest firmware, tweaking the power profile some more, waiting for new firmware… nope. Still there.&lt;/p&gt;

&lt;p&gt;What is making it noisy? CPU is heating up. Clocked the CPU down. Still noisy. What is making the CPU busy? Lots of unnecessary processes. Shaving them off one by one. Still there.&lt;/p&gt;

&lt;p&gt;It’s the desktop. All my Ruby scripts, the conky bar, the Ruby file manager, mutt with all my extensions, vim with my hyperlist plugin, etc. Bits here and there constantly polling, checking, fetching.&lt;/p&gt;

&lt;p&gt;Can I fix this once and for all? Can I get the fan to shut up?&lt;/p&gt;

&lt;h2 id=&quot;the-scratch&quot;&gt;The scratch&lt;/h2&gt;

&lt;p&gt;This was the birth of &lt;a href=&quot;https://isene.org/chasm/&quot;&gt;CHasm&lt;/a&gt; and &lt;a href=&quot;https://isene.org/fe2o3/&quot;&gt;Fe₂O₃&lt;/a&gt;. A desktop in pure assembly, with the major applications written in Rust. The itch that needed scratching. And with &lt;a href=&quot;https://claude.com/claude-code&quot;&gt;Claude Code&lt;/a&gt;, it was actually doable.&lt;/p&gt;

&lt;p&gt;As I write this in my vim replacement &lt;a href=&quot;https://github.com/isene/scribe&quot;&gt;scribe&lt;/a&gt;, the fan is silent, the CPU sits at 36 °C, and the battery drain is around 3.5 W with screen brightness at 80 %. Two sessions of Claude Code are working away on Workspace 1 and 2 while I type this in WS6.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/silent-fan-desktop.png&quot; alt=&quot;Silent desktop&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;nerdvana&quot;&gt;Nerdvana&lt;/h2&gt;

&lt;p&gt;I have never experienced a desktop this snappy and this tailored to my needs. Not only a silent fan, but keybindings that feel natural and consistent, and programs that do exactly what I need them to do.&lt;/p&gt;

&lt;p&gt;It’s pure nerdvana.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Link to this post: https://isene.org/2026/05/Fan.html&lt;/p&gt;
</description>
        <pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/05/Fan.html</link>
          
        
            <category>Geekery</category>
        
            <category>Technology</category>
        
          
        
          
      </item>
    
    <item>
        <title>The agency stack</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/posts/agency-stack.png&quot; alt=&quot;The agency stack&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s been an interesting few days with insightful comments related to my latest developments.&lt;/p&gt;

&lt;p&gt;The sharpest pushback on &lt;a href=&quot;/2026/05/Audience-of-One.html&quot;&gt;my desktop post&lt;/a&gt; — the one about replacing my desktop with software I’d built — was a single line in the lobste.rs thread:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;How is this OSS/FS promise if you have just hard locked yourself into using an insanely big subscription-based closed source software (claude)? You sure that it’s liberating?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s a fair charge and I want to answer it properly, because the off-the-cuff response I gave in the thread was true but incomplete.&lt;/p&gt;

&lt;h2 id=&quot;the-argument-in-full&quot;&gt;The argument, in full&lt;/h2&gt;

&lt;p&gt;The Free and Open Source Software movement has always been about &lt;strong&gt;agency over the artifacts I depend on&lt;/strong&gt;… the right to read, modify, share, and replace any program in my life. I’ve been an &lt;a href=&quot;/2026/04/MyTools.html&quot;&gt;OSS/FS advocate since 1999&lt;/a&gt;, board member of EFN (FSF’s sister org in Norway) for 10 years, one of those people who organised the nerd protest march against OOXML.&lt;/p&gt;

&lt;p&gt;So here I am, having spent the last five weeks building my desktop with &lt;a href=&quot;https://claude.com/claude-code&quot;&gt;Claude Code&lt;/a&gt;, a proprietary product from a single American company on a subscription that could change price or terms tomorrow. Have I just bought my agency back from one set of vendors and rented it from another?&lt;/p&gt;

&lt;p&gt;I want to grant the critic their point. &lt;strong&gt;Yes&lt;/strong&gt;, I have a new dependency. &lt;strong&gt;Yes&lt;/strong&gt;, it’s closed. &lt;strong&gt;Yes&lt;/strong&gt;, if Anthropic disappears or goes hostile or just gets boring, my flow of new tools stops. That’s a real cost.&lt;/p&gt;

&lt;p&gt;But I think the framing of “agency or no agency” misses how agency actually stacks.&lt;/p&gt;

&lt;h2 id=&quot;the-stack-was-never-clean&quot;&gt;The stack was never clean&lt;/h2&gt;

&lt;p&gt;Pull on any thread of “I’m using free software” and you find proprietary fibres a few layers down. The Linux kernel runs on a CPU whose microcode is not free. The keyboard firmware in your laptop is not free. The display panel’s scaler is not free. The fab process that made the silicon is locked behind a forest of trade secrets. Even Stallman’s GCC was, for years, bootstrapped with whatever compiler was at hand on the host system — sometimes proprietary.&lt;/p&gt;

&lt;p&gt;OSS/FS has never delivered a fully free stack. What it has delivered, consistently, is &lt;strong&gt;more agency than you had before&lt;/strong&gt;, in the layers where agency was reachable. The question was never “is this entirely free?” — it was “is this freer than the alternative?”&lt;/p&gt;

&lt;p&gt;By that test, my desktop today has &lt;em&gt;more&lt;/em&gt; of my agency in it than it did six months ago, not less. The window manager, terminal, editor, file manager, mail client, calendar, RSS reader, music tool — every one of them is something I can read end to end, modify in an afternoon, and redistribute under the Unlicense if anyone wants. They live in two sister suites: &lt;a href=&quot;https://isene.org/fe2o3/&quot;&gt;Fe₂O₃&lt;/a&gt; (the Rust half: editor, file manager, browser, mail, calendar, astronomy, and so on) and &lt;a href=&quot;https://isene.org/chasm/&quot;&gt;CHasm&lt;/a&gt; (the x86_64 assembly half: shell, terminal, window manager, status bar, screen locker, font rasterizer). Claude is a single new layer in the stack, and it’s the layer &lt;strong&gt;furthest from my final artifact&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If Anthropic vanishes tomorrow, I lose the ability to &lt;strong&gt;generate new&lt;/strong&gt; code as fast as I’m generating it now. I do not lose:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The code itself, all of which is mine.&lt;/li&gt;
  &lt;li&gt;The right to modify it by hand, the way I would have anyway in a pre-LLM world.&lt;/li&gt;
  &lt;li&gt;The patterns I’ve learned by walking through these designs.&lt;/li&gt;
  &lt;li&gt;The ability to switch to whatever LLM tooling comes next — open-weight or otherwise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The artifact is the thing. The artifact is mine. The toolchain that produced it is rentable, and I’m renting it.&lt;/p&gt;

&lt;h2 id=&quot;the-compiler-argument&quot;&gt;The compiler argument&lt;/h2&gt;

&lt;p&gt;I frame it like this: &lt;strong&gt;an LLM is a compiler&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When I write Rust, I don’t write the machine code. I write Rust, and a compiler turns it into instructions the CPU can run. The compiler is a trust layer — I trust it to translate my intent faithfully. Most of human software development has lived inside this trust assumption, and most programmers do not write their own compilers.&lt;/p&gt;

&lt;p&gt;When I write a prompt to Claude Code, I trust it to translate my intent into Rust. It’s a higher-level compiler. The trust surface is bigger, the failure modes are weirder, and the licence is proprietary. But the &lt;em&gt;shape&lt;/em&gt; of the dependency (“I trust this tool to translate”) is one we’ve always had with our toolchains.&lt;/p&gt;

&lt;p&gt;If LLMs were on a public-domain compute substrate tomorrow, I’d switch. Until then, the same calculation that lets us run gcc-on-Intel applies: use the freest tool that gets the job done, and don’t pretend the stack is purer than it is.&lt;/p&gt;

&lt;h2 id=&quot;whats-actually-at-risk&quot;&gt;What’s actually at risk&lt;/h2&gt;

&lt;p&gt;The honest answer to “what do I lose if this goes wrong?” is this: I lose &lt;strong&gt;velocity&lt;/strong&gt;, not &lt;strong&gt;possession&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If Anthropic decides scribe should not exist, they cannot un-publish the source from my disk. They cannot make my running editor stop running. They cannot revoke my understanding of how the code works. What they &lt;em&gt;can&lt;/em&gt; do is stop being a useful collaborator, at which point I revert to writing code at human speed, the way I did from 1978 to 2025.&lt;/p&gt;

&lt;p&gt;Velocity is real. Five weeks of LLM-paired work is years at solo human speed (my speed). If the rate goes back to solo-human, I will ship less new stuff per unit time. But the &lt;em&gt;existing&lt;/em&gt; stuff doesn’t move; my tools keep working; my muscle memory keeps applying.&lt;/p&gt;

&lt;p&gt;This is a different trade than, say, depending on a closed cloud service whose servers hold the only copy of my data, or a SaaS app whose contents disappear when the subscription lapses. The proprietary tool is &lt;em&gt;upstream&lt;/em&gt; of my work, not &lt;em&gt;containing&lt;/em&gt; it.&lt;/p&gt;

&lt;h2 id=&quot;why-im-ok-with-the-trade&quot;&gt;Why I’m OK with the trade&lt;/h2&gt;

&lt;p&gt;A purist position is available: refuse to use any closed tool, build everything on free-software foundations, accept the slower pace as the price of consistency. I respect that position. I’ve taken something like it for most of my life.&lt;/p&gt;

&lt;p&gt;I think it’s the wrong choice for &lt;em&gt;me, today&lt;/em&gt;, because:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The agency I gain at the artifact layer is enormous and immediate.&lt;/li&gt;
  &lt;li&gt;The agency I cede at the toolchain layer is bounded — I keep what I produce, and the worst case is “develop slower again”, not “lose my desktop”.&lt;/li&gt;
  &lt;li&gt;Open-weight LLMs are improving fast; if Anthropic gets unbearable, the alternatives will likely be ready.&lt;/li&gt;
  &lt;li&gt;The asymmetry is in my favour: a few weeks of subscribed compute bought me decades of compounding personal-fit improvements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The alternative — wait for the perfect free-software stack before using anything imperfect — is the same logic that kept Linux desktops perpetually “almost ready” for thirty years. At some point you have to build with what’s in the room.&lt;/p&gt;

&lt;h2 id=&quot;the-bigger-point&quot;&gt;The bigger point&lt;/h2&gt;

&lt;p&gt;OSS/FS was never a destination. It’s a direction. &lt;strong&gt;More agency, more often, in more layers than yesterday.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By that measure, my desktop has more freedom in it now than it did before I started talking to a closed model. While the model is closed, the the result is. And the result is what I live inside.&lt;/p&gt;

&lt;p&gt;If the model becomes free too, even better. If it doesn’t, I still own the desktop.&lt;/p&gt;

&lt;p&gt;I think that’s the right way to keep score.&lt;/p&gt;
</description>
        <pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/05/The-Agency-Stack.html</link>
          
        
            <category>Geekery</category>
        
            <category>Philosophy</category>
        
            <category>Technology</category>
        
          
        
          
      </item>
    
    <item>
        <title>An audience of one - by the numbers</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/posts/audience-of-one-numbers.png&quot; alt=&quot;An audience of one - by the numbers&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;/2026/05/Audience-of-One.html&quot;&gt;previous post&lt;/a&gt; made a case for building your own desktop. The argument was philosophical: removing multi-user accommodation eliminates substantial complexity. This post is the tally.&lt;/p&gt;

&lt;p&gt;The bottom line, before the details: &lt;strong&gt;+3.5 hours of battery time&lt;/strong&gt; on my Dell XPS 14, a fan that is mostly silent, and a terminal stack that fits in 691 KB instead of 109 MB.&lt;/p&gt;

&lt;p&gt;All numbers below come from the actual binaries on my XPS 14 today, measured against the upstream tools they replaced. Every CHasm binary is pure x86_64 NASM with zero shared libraries and every Fe₂O₃ binary is Rust on top of a small shared library called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crust&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;binary-size&quot;&gt;Binary size&lt;/h2&gt;

&lt;p&gt;The terminal stack — shell, terminal emulator, window manager, status bar, pager — is the part of the desktop that runs all the time. Here is what that costs in CHasm versus what it cost before.&lt;/p&gt;

&lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 1em 0;&quot;&gt;
  &lt;tr&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;Layer&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;Before&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;Bytes&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;After (CHasm)&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;Bytes&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Shell&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bash&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;1,540,520&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bare&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;168,232&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Terminal&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;kitty (binary)&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;207,496&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;glass&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;191,208&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Terminal (full)&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;kitty.app bundle&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;109,270,888&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;glass&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;191,208&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Window manager&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;i3&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;580,800&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;tile&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;82,616&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Status bar&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;i3bar&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;122,160&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;strip&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;34,744&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Bar content&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;conky&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;1,019,056&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;asmites (×16)&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;159,488&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Screen locker&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;i3lock&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;59,864&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bolt&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;30,528&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Pager&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;less&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;245,256&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;show&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;41,144&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;CHasm core total (bare + glass + tile + strip + asmites + bolt + show): &lt;strong&gt;707,960 bytes = 691 KB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The kitty comparison is the headline number. The kitty &lt;em&gt;binary&lt;/em&gt; is small because it is a launcher; the real workhorse is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.local/kitty.app&lt;/code&gt;, which contains a bundled Python 3.14 runtime, HarfBuzz, pixman, GLib, SQLite, and 107 shared objects. &lt;strong&gt;109 MB total.&lt;/strong&gt; glass replaces it at 191 KB with zero shared objects, including a TrueType / OpenType rasterizer (glyph), color emoji via CBDT, variable fonts, synthetic italic/bold, and full Unicode beyond the BMP.&lt;/p&gt;

&lt;p&gt;That is a factor of 571× smaller for the user-visible terminal feature set I actually use.&lt;/p&gt;

&lt;h2 id=&quot;dynamic-linking&quot;&gt;Dynamic linking&lt;/h2&gt;

&lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 1em 0;&quot;&gt;
  &lt;tr&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;Tool&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;code&gt;.so&lt;/code&gt; dependencies&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bare&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;glass&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;tile&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;strip&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bolt&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;show&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;chasm-bits (each)&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; background: #2a2a2a;&quot; colspan=&quot;2&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bash&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;2&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;kitty (launcher)&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;6&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;kitty (bundle)&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;107&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;i3&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;55&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;i3bar&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;46&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;i3lock&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;32&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;conky&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;51&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;urxvt&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;43&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;gnome-terminal&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;80&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;vim&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;86&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Every CHasm binary is statically linked. Nothing in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/lib&lt;/code&gt; can break my terminal at boot. Distribution upgrade churn no longer reaches the desktop.&lt;/p&gt;

&lt;h2 id=&quot;the-feo-side&quot;&gt;The Fe₂O₃ side&lt;/h2&gt;

&lt;p&gt;The Rust tools are not micro-optimised for size in the same way. They opt into a shared &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crust&lt;/code&gt; TUI library and link &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc&lt;/code&gt; like any normal Linux program. They are still small.&lt;/p&gt;

&lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 1em 0;&quot;&gt;
  &lt;tr&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;Fe₂O₃ tool&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;Bytes&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;Replaces&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;Predecessor bytes&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;scribe&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;2,939,560&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;vim&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;5,609,800&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;pointer&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;4,240,680&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;ranger&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;4,866,877&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;scribe replaces vim at half the size and pointer replaces ranger with a lot more functionality, both on top of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crust&lt;/code&gt; runtime that several of these tools share.
scribe is much, much faster in handling &lt;a href=&quot;https://isene.org/hyperlist/&quot;&gt;HyperLists&lt;/a&gt; than vim+&lt;a href=&quot;https://www.vim.org/scripts/script.php?script_id=4006&quot;&gt;hyperlist.vim&lt;/a&gt; could ever be.&lt;/p&gt;

&lt;h2 id=&quot;startup&quot;&gt;Startup&lt;/h2&gt;

&lt;p&gt;“Shell startup” can mean two different things and the smaller number tells you nothing about the bigger one. Quoting both, from the bare README, both shells on the same machine:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interactive prologue&lt;/strong&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execve&lt;/code&gt; to “ready for the first keystroke”, with history, tab completion, and syntax-highlighted prompt initialised:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./bare --bench
bare startup: 9 microseconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Non-interactive whole-process&lt;/strong&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo cmd | shell &amp;gt; /dev/null&lt;/code&gt;, i.e. spawn shell, parse one line, fork-exec the command, wait, exit. This is the right number for using a shell as a pipe target or script interpreter. 1000 iterations each:&lt;/p&gt;

&lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 1em 0;&quot;&gt;
  &lt;tr&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;shell&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;code&gt;echo true | shell&lt;/code&gt;&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;code&gt;echo ls | shell&lt;/code&gt;&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;syscalls/invocation&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bash&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;2.5 s&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;4.5 s&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;26&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bare&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;2.1 s&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;4.5 s&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;&lt;strong&gt;14&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;bare wins the minimal benchmark (~17% faster) and ties on the realistic one where the spawned command’s own work dominates. Half the syscalls per invocation, no dynamic linker, no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt; parse. Same binary in both rows; bare detects &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isatty(0)&lt;/code&gt; at startup and gates history, PATH exec-cache, and prompt-state init behind it.&lt;/p&gt;

&lt;p&gt;None of that matters if you only ever start a shell once a day; all of it matters if you fork shells from inside a status bar refreshing every 4 seconds, because that is &lt;strong&gt;86,400 forks/day per segment&lt;/strong&gt; at 1 Hz, the reason CHasm’s status bar segments are tiny static asm binaries (“asmites”) rather than shell helpers.&lt;/p&gt;

&lt;h2 id=&quot;resident-memory&quot;&gt;Resident memory&lt;/h2&gt;

&lt;p&gt;Captured from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/bin/time -v&lt;/code&gt; on cold runs of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;shell&amp;gt; -c exit&lt;/code&gt;:&lt;/p&gt;

&lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 1em 0;&quot;&gt;
  &lt;tr&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;Shell&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;RSS&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bare&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;392 KB&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;bash&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;3,700 KB&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;zsh&lt;/td&gt;&lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: right;&quot;&gt;4,200 KB&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;bash and zsh sit at roughly ten times the resident-set size of bare on a no-op invocation. Again: irrelevant for one shell, decisive for hundreds of helper invocations per minute.&lt;/p&gt;

&lt;h2 id=&quot;what-this-buys&quot;&gt;What this buys&lt;/h2&gt;

&lt;p&gt;I did not set out to make small binaries. I set out to make a desktop that fits the way I work. Small binaries are what falls out of the process when the design rules are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;No wasted CPU cycles.&lt;/strong&gt; Every feature has a config flag and an early-return fast path. A “for some users” feature that runs unconditionally for everyone is waste.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Lightning fast.&lt;/strong&gt; No interpreters in the hot path. No &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awk&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perl&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; in shell helpers, just builtins or asm.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;More battery life.&lt;/strong&gt; Anything that polls, wakes, or spawns a subprocess on a timer is suspect. Prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inotify&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sleep 1; check&lt;/code&gt;. Prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stat()&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A stack that is &lt;strong&gt;691 KB total&lt;/strong&gt; with &lt;strong&gt;zero shared libraries&lt;/strong&gt; is what those rules look like applied to the terminal layer. A 109 MB Python-bundling terminal is what they look like ignored.&lt;/p&gt;

&lt;h2 id=&quot;why-assembly-then&quot;&gt;Why assembly, then?&lt;/h2&gt;

&lt;p&gt;A fair reader question after seeing the previous post on Hacker News. Assembly is not chosen for purity or for the romance. The romance came after. Assembly fell out of the rules above the same way the small numbers did. There is no library tax. There is no runtime to warm up. Each instruction has a cost I can see and a behaviour I can predict. When the rule is &lt;em&gt;no wasted CPU cycles&lt;/em&gt;, working at the level where every cycle is visible turns out to be the lowest-friction place to enforce that rule. Rust would also have worked for most of the stack. It is what powers the Fe₂O₃ side. Assembly was the right tool for the layer that runs all the time.&lt;/p&gt;

&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Feature parity is not 1:1. kitty has graphics protocol, ligatures via HarfBuzz, and a configuration language. glass has none of those. glass has variable fonts, CBDT color emoji, and a 191 KB binary. But the fonts render just as nice with the assembly glyph engine doing the font job.&lt;/li&gt;
  &lt;li&gt;vim has 35 years of plugins. scribe has 72 hours of me. The comparison is “the editor I use” against “the editor I used to use”, not feature counts.&lt;/li&gt;
  &lt;li&gt;I do not recommend any of this for anybody else. The whole premise of the previous post was that &lt;strong&gt;the audience is one&lt;/strong&gt;. Building for one is not the same as not sharing. All the sources are public. Take what is useful, ignore the rest.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-small-print&quot;&gt;The small print&lt;/h2&gt;

&lt;p&gt;All binary sizes from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stat -c%s&lt;/code&gt; on 2026-05-03. Shared-object counts from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldd | grep -c &apos;=&amp;gt;&apos;&lt;/code&gt;. Startup measurements from 1000-iteration loops on the 2026 Dell XPS 14 (the model that shipped in early January this year). Measurements that risked perturbing my running session, interactive terminal startup and live RSS of foreground processes, were skipped. The CHasm sources are at &lt;a href=&quot;https://github.com/isene/chasm&quot;&gt;github.com/isene/chasm&lt;/a&gt;; the Fe₂O₃ sources at &lt;a href=&quot;https://github.com/isene/fe2o3&quot;&gt;github.com/isene/fe2o3&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/05/Audience-of-One-Numbers.html</link>
          
        
            <category>Geekery</category>
        
            <category>Technology</category>
        
          
        
          
      </item>
    
    <item>
        <title>Ja, vi elsker — a heavier take on the anthem</title>
        <description>&lt;video controls=&quot;&quot; poster=&quot;/assets/posts/javielsker.png&quot; preload=&quot;metadata&quot; style=&quot;width:100%;max-width:720px;display:block;margin:1em auto;&quot;&gt;
  &lt;source src=&quot;/assets/posts/javielsker.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;I put my own spin on &lt;em&gt;Ja, vi elsker&lt;/em&gt; — Norway’s national anthem — and pushed it a couple of notches harder than the brass-band version you usually hear on the 17th of May. Out on Spotify now.&lt;/p&gt;

&lt;iframe style=&quot;border-radius:12px;display:block;margin:1em auto;&quot; src=&quot;https://open.spotify.com/embed/track/5XywaQ8znGluytLGfu0jal?utm_source=generator&quot; width=&quot;100%&quot; height=&quot;152&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot; allow=&quot;autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture&quot; loading=&quot;lazy&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Find me on Spotify as &lt;strong&gt;Geir Isene&lt;/strong&gt;. The full back catalogue is on the &lt;a href=&quot;/music/&quot;&gt;Music page&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 03 May 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/05/Ja-Vi-Elsker.html</link>
          
        
            <category>Music</category>
        
            <category>Norway</category>
        
          
        
          
      </item>
    
    <item>
        <title>A desktop made for one</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/posts/audience-of-one.png&quot; alt=&quot;A desktop made for one&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For the first time in twenty-five years I’m sitting in front of a computer where almost every program I touch was designed by me. One tool at a time, the off-the-shelf option got swapped out for something a little closer to how my hands wanted to work. (I &lt;a href=&quot;/2026/04/MyTools.html&quot;&gt;wrote about the start of this&lt;/a&gt; a couple of weeks ago — that post laid out the early swaps; this one is the view from the other side of the journey.)&lt;/p&gt;

&lt;p&gt;It’s been a crazy few weeks guiding Claude Code inbetween all the other stuff I’m doing in life. I direct CC, it works while I do other stuff. I get a second or few in between tasks, and I respond. Then off it goes adding features or hunting bugs.&lt;/p&gt;

&lt;p&gt;Two suites in a happy marriage: &lt;strong&gt;&lt;a href=&quot;https://github.com/isene/chasm&quot;&gt;CHasm&lt;/a&gt;&lt;/strong&gt;, the bedrock — pure x86_64 assembly, no libc, the layer that paints pixels and reads keys. &lt;strong&gt;&lt;a href=&quot;https://github.com/isene/fe2o3&quot;&gt;Fe₂O₃&lt;/a&gt;&lt;/strong&gt;, the application layer in Rust, sitting on a small shared TUI library called &lt;a href=&quot;https://github.com/isene/crust&quot;&gt;crust&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-chasm-layer-assembly&quot;&gt;The CHasm layer (assembly)&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Role&lt;/th&gt;
      &lt;th&gt;Was&lt;/th&gt;
      &lt;th&gt;Now&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Window manager&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://i3wm.org/&quot;&gt;i3-wm&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/tile&quot;&gt;tile&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Status bar / tray&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://i3wm.org/docs/userguide.html#_configuring_i3bar&quot;&gt;i3bar&lt;/a&gt; + &lt;a href=&quot;https://github.com/brndnmtthws/conky&quot;&gt;conky&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/strip&quot;&gt;strip&lt;/a&gt; + &lt;a href=&quot;https://github.com/isene/chasm-bits&quot;&gt;asmites&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Screen locker&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/i3/i3lock&quot;&gt;i3lock&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/bolt&quot;&gt;bolt&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Terminal emulator&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://sw.kovidgoyal.net/kitty/&quot;&gt;kitty&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/glass&quot;&gt;glass&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Login shell&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.zsh.org/&quot;&gt;zsh&lt;/a&gt; → &lt;a href=&quot;https://github.com/isene/rsh&quot;&gt;rsh&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/bare&quot;&gt;bare&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;File viewer&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.greenwoodsoftware.com/less/&quot;&gt;less&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/show&quot;&gt;show&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;the-feo-layer-rust-on-crust&quot;&gt;The Fe₂O₃ layer (Rust on crust)&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Role&lt;/th&gt;
      &lt;th&gt;Was&lt;/th&gt;
      &lt;th&gt;Now&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Text editor&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;&lt;a href=&quot;https://www.vim.org/&quot;&gt;VIM&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/scribe&quot;&gt;scribe&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;File manager&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/ranger/ranger&quot;&gt;ranger&lt;/a&gt; → &lt;a href=&quot;https://github.com/isene/RTFM&quot;&gt;RTFM&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/pointer&quot;&gt;pointer&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Email / RSS / chat&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;http://www.mutt.org/&quot;&gt;mutt&lt;/a&gt; + &lt;a href=&quot;https://newsbeuter.org/&quot;&gt;newsbeuter&lt;/a&gt; + various web logins&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/kastrup&quot;&gt;kastrup&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Calendars&lt;/td&gt;
      &lt;td&gt;Google + MS web&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/tock&quot;&gt;tock&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Astronomy panel&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/astropanel&quot;&gt;astropanel&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/astro&quot;&gt;astro&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Movies / series&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/IMDB&quot;&gt;IMDB-terminal&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/isene/watchit&quot;&gt;watchit&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;What’s left? &lt;a href=&quot;https://weechat.org/&quot;&gt;WeeChat&lt;/a&gt; for IRC and other chats. &lt;a href=&quot;https://www.mozilla.org/firefox/&quot;&gt;Firefox&lt;/a&gt; — the only GUI program I still use regularly. That’s it. Everything else is mine.&lt;/p&gt;

&lt;h2 id=&quot;the-vim-line&quot;&gt;The vim line&lt;/h2&gt;

&lt;p&gt;Let me get a bit sentimental about &lt;a href=&quot;https://www.vim.org/&quot;&gt;vim&lt;/a&gt;, because vim was the one I thought I’d never replace.&lt;/p&gt;

&lt;p&gt;I started using it in 2001. For twenty-five years, every email I wrote went through vim. Every article. Every blog post. Every line of code, every &lt;a href=&quot;https://github.com/isene/HyperList&quot;&gt;HyperList&lt;/a&gt;, and every book. It was the one tool I would have called &lt;em&gt;part of how I think&lt;/em&gt;. The muscle memory was so deep that I’d open random text fields in browsers and ended with typing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:w&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then in three days I had &lt;a href=&quot;https://github.com/isene/scribe&quot;&gt;scribe&lt;/a&gt; and stopped using vim.&lt;/p&gt;

&lt;p&gt;The first commit landed at 00:09 on May 1st. By afternoon today (May 3rd) vim was replaced. Twenty-five years of muscle memory rerouted in seventy-two hours.&lt;/p&gt;

&lt;p&gt;Vim is wonderful, but scribe is mine. It’s modal like vim, but missing the ninety percent of features I never used, and carrying the handful of writer-shaped tweaks I always wished vim had. Soft-wrap by default. Reading mode with Limelight-style focus. AI in the prompt without leaving the buffer. HyperList editing with full syntax highlighting and the encryption format the &lt;a href=&quot;https://github.com/isene/hyperlist&quot;&gt;Ruby HyperList app&lt;/a&gt; uses. Persistent registers shared across concurrent sessions is a cool feature. None of it revolutionary, but all of it shaped to my exact workflow. And whenever I think of an enhancement I want, it’s just minutes away. It used to be waiting for months or years or forever for some developer to get the same idea as mine and introduce it into the tool I use.&lt;/p&gt;

&lt;h2 id=&quot;why-this-is-possible-now&quot;&gt;Why this is possible now&lt;/h2&gt;

&lt;p&gt;It used to be that writing your own editor, your own file manager, your own window manager, was a project of years. I know, it took me a few years to get RTFM right. A serious undertaking with a serious cost. The economics of it didn’t work for most people, even programmers. You’d touch a piece of it, get most of the way, run out of weekend, and go back to the off-the-shelf tool.&lt;/p&gt;

&lt;p&gt;That barrier is much lower now. With Rust, &lt;a href=&quot;https://claude.com/claude-code&quot;&gt;CC as the workhorse&lt;/a&gt;, and the fact that the hard problems of TUI programming have been documented to death… the cost of “build the tool you actually want” has fallen by orders of magnitude.&lt;/p&gt;

&lt;p&gt;I don’t think this is a story about AI or about Rust specifically. Both helped. But the deeper point is that the gap between “I wish my editor did X” and “okay, here’s an editor that does X” is now small enough to fit inside a few evenings of focused work.&lt;/p&gt;

&lt;h2 id=&quot;im-not-selling-anything&quot;&gt;I’m not selling anything&lt;/h2&gt;

&lt;p&gt;I should say what this post is &lt;em&gt;not&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It’s not an invitation to use my software. Honestly, please don’t. None of it is built for you. It’s built for me — for the way I hold my hands, the way I think about email, the way I want my calendar to render. I’m sure other people would find a hundred sharp edges I’ve never noticed because they happen to align perfectly with what I do.&lt;/p&gt;

&lt;p&gt;It’s also not a request for kudos. The code isn’t novel, nor are the ideas. There’s nothing here that hasn’t been done before by someone with more taste, discipline or talent.&lt;/p&gt;

&lt;p&gt;What I want to do is show one specific thing: &lt;strong&gt;it is now genuinely feasible to make a desktop computing environment that fits one person.&lt;/strong&gt; Instead of a configuration of someone else’s tools. This is no longer a heroic decade-long undertaking. This is an actual, weekend-by-weekend, “this thing in my life now does exactly what I want” replacement.&lt;/p&gt;

&lt;h2 id=&quot;the-joy-of-an-audience-of-one&quot;&gt;The joy of an audience of one&lt;/h2&gt;

&lt;p&gt;The best part of building for myself: the relief of not having to care.&lt;/p&gt;

&lt;p&gt;I don’t have to think about configurability for someone with different preferences. And I don’t have to support corner cases I’d never personally hit. Nor do I have to write documentation for users who don’t exist. No more arguing on issue trackers about whether a default is the right default — &lt;em&gt;of course&lt;/em&gt; it’s the right default, it’s the one I want.&lt;/p&gt;

&lt;p&gt;The editor’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\?&lt;/code&gt; cheatsheet shows the keys &lt;em&gt;I&lt;/em&gt; memorised, in the order &lt;em&gt;I&lt;/em&gt; prefer, with the bindings &lt;em&gt;I&lt;/em&gt; think are sensible. Arrogance? Nope, it’s design without committee. The audience is one person. Decisions take seconds.&lt;/p&gt;

&lt;p&gt;It turns out an enormous amount of software complexity comes from accommodating users who aren’t you. Strip that out and what’s left is small, fast, exactly-shaped, and a quiet pleasure to use.&lt;/p&gt;

&lt;h2 id=&quot;so&quot;&gt;So&lt;/h2&gt;

&lt;p&gt;If you’ve ever caught yourself thinking “I wish my editor / file manager / status bar / shell just did this one thing differently” and you’ve been told the answer is to write a plugin, learn an obscure config language, or accept the way it is, then consider that the third option is more available than it used to be: Build Your Own Software (BYOS).&lt;/p&gt;

&lt;p&gt;You probably won’t replace your whole desktop. I didn’t plan to either. But the satisfaction of having even one tool in your daily workflow that fits you exactly is worth a weekend.&lt;/p&gt;

&lt;p&gt;I’m a rabbit in spring :)&lt;/p&gt;
</description>
        <pubDate>Sun, 03 May 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/05/Audience-of-One.html</link>
          
        
            <category>Geekery</category>
        
            <category>Technology</category>
        
          
        
          
      </item>
    
    <item>
        <title>A desktop that bends to me</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/posts/chasm-desktop.png&quot; alt=&quot;My desktop, the assembly side&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Three weeks ago I posted about &lt;a href=&quot;https://isene.org/2026/04/Bare.html&quot;&gt;bare&lt;/a&gt;, my login shell in pure x86_64 assembly. It was the start of a sprint. Now the whole stack is mine.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/isene/bare&quot;&gt;bare&lt;/a&gt; is the shell. &lt;a href=&quot;https://github.com/isene/glass&quot;&gt;glass&lt;/a&gt; is the terminal emulator. &lt;a href=&quot;https://github.com/isene/tile&quot;&gt;tile&lt;/a&gt; is the window manager. &lt;a href=&quot;https://github.com/isene/strip&quot;&gt;strip&lt;/a&gt; is the bar. &lt;a href=&quot;https://github.com/isene/show&quot;&gt;show&lt;/a&gt; is the file viewer. &lt;a href=&quot;https://github.com/isene/bolt&quot;&gt;bolt&lt;/a&gt; is the screen locker. All in x86_64 assembly. Single static binaries with no libc or any bloat and with minimum CPU cycles. Built with &lt;a href=&quot;https://claude.com/claude-code&quot;&gt;Claude Code&lt;/a&gt; over a few evenings. The &lt;a href=&quot;https://github.com/isene/chasm&quot;&gt;CHasm&lt;/a&gt; suite.&lt;/p&gt;

&lt;p&gt;The Rust side, &lt;a href=&quot;https://github.com/isene/fe2o3&quot;&gt;Fe2O3&lt;/a&gt;, absorbed almost every other tool in my daily use. &lt;a href=&quot;https://github.com/isene/RTFM&quot;&gt;RTFM&lt;/a&gt; became &lt;a href=&quot;https://github.com/isene/pointer&quot;&gt;pointer&lt;/a&gt; and then the rest of my Ruby tools became fresh and rusty; &lt;a href=&quot;https://github.com/isene/kastrup&quot;&gt;kastrup&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/tock&quot;&gt;tock&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/astro&quot;&gt;astro&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/scroll&quot;&gt;scroll&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/watchit&quot;&gt;watchit&lt;/a&gt;. Each is a static binary, snappy like a rattlesnake and uses memory I can count on one hand.&lt;/p&gt;

&lt;p&gt;The only GUI program I regularly run now is Firefox.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/fe2o3-desktop.png&quot; alt=&quot;My desktop, the Rust side&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A laptop on full battery now lasts more than three hours longer than it used to. The fan is mostly silent. Cold-start times are gone since everything is already warm by the time my finger leaves the Enter key.&lt;/p&gt;

&lt;p&gt;I had a chat with Claude about the typical pushback when I tell people that I built my daily-driver tools with AI. The pushback comes in flavours: “I don’t trust AI code”, “yeah, it can prototype, but how do you maintain it?”, “what’s the fun in that?”, “but, but you didn’t actually &lt;em&gt;make&lt;/em&gt; it!”.&lt;/p&gt;

&lt;p&gt;These all miss the same mark.&lt;/p&gt;

&lt;p&gt;I never wrote kitty. I never wrote i3, or zsh, or vim, or Firefox. I ran them for years and never asked who wrote them or how. I cared whether they worked, whether they fit how I think, whether I could lean on them. The authorship question never came up because I had no alternative.&lt;/p&gt;

&lt;p&gt;But I got tired of subtly adapting to how applications work. Someone wrote it a specific way, and it may be highly configurable, like the i3 window manager. But it was never &lt;em&gt;exactly&lt;/em&gt; like I wanted it. Almost, but not on the mark.&lt;/p&gt;

&lt;p&gt;What changed is not who writes the code. It is who has agency.&lt;/p&gt;

&lt;p&gt;For three decades the tool was the fixed point and I adapted to it. I learned its quirks, accepted its compromises, built habits around its limitations. Now the tool bends to me. When tile annoys me I describe the annoyance and tile changes. When glass needs a sequence it does not handle, it gets one before the tea water boils.&lt;/p&gt;

&lt;p&gt;And when it comes to maintenance… we have done lots. Five bolt bugs found via diagnostic logs I cannot read on my own (machine code), patched, retested, committed, tagged, all in a short stint. The loop is tighter than most teams manage with a full-time engineer on payroll. I read the symptoms. Claude reads the code. We converge.&lt;/p&gt;

&lt;p&gt;The “but you didn’t make it” critique falls apart the moment you remember most people are running thirty years of code they didn’t write either. They just had no agency over it. What changed isn’t the authorship question, it’s the agency question.&lt;/p&gt;

&lt;p&gt;This is not me telling you to do the same (you could if you just clone the repos for inspiration and let Claude Code go at it to make it how &lt;em&gt;you&lt;/em&gt; want it). The point here is that it fits one shape, mine. If your shape is different, build differently. Or do not build at all and use what works.&lt;/p&gt;

&lt;p&gt;I am writing this down because the transition has been strange and the strangeness deserves a note. I have been a tweaker since 1999. The tweaking has finally caught up with the tools. There is nothing left to compromise on. That is a quiet kind of luxury.&lt;/p&gt;

&lt;p&gt;The next quirk will surface. It looks like it’s going to be replacing my most beloved tool of all: VIM. Time for a better text editor. For me.&lt;/p&gt;
</description>
        <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/05/Agency.html</link>
          
        
            <category>Geekery</category>
        
            <category>Technology</category>
        
          
        
          
      </item>
    
    <item>
        <title>My tools - all vibecoded</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/posts/mytools2.png&quot; alt=&quot;My tools&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From 1978 until summer last year I had been programming in 30+ different languages, including Assembly and lots of Ruby. Then I got going with &lt;a href=&quot;https://claude.com/claude-code&quot;&gt;Claude Code&lt;/a&gt; (CC). Since then I have ported most of my Ruby tools to &lt;a href=&quot;https://github.com/isene/fe2o3&quot;&gt;Rust&lt;/a&gt; and then started moving my most basic tools over to pure &lt;a href=&quot;https://github.com/isene/chasm&quot;&gt;Assembly&lt;/a&gt;. I haven’t typed code in the past 9 months.&lt;/p&gt;

&lt;p&gt;I am a long-time tweaker of my setup. Running Linux since 1999, I used to search extensively for the right tools to match my needs; &lt;a href=&quot;https://www.vim.org/&quot;&gt;VIM&lt;/a&gt;, &lt;a href=&quot;https://i3wm.org/&quot;&gt;i3 window manager&lt;/a&gt;, &lt;a href=&quot;https://sw.kovidgoyal.net/kitty/&quot;&gt;kitty terminal&lt;/a&gt;, &lt;a href=&quot;https://github.com/brndnmtthws/conky&quot;&gt;conky&lt;/a&gt;, etc. I managed to tune my setup to fit me almost perfectly. Almost. I subtly adapted to the software, changing the way I would ideally work to work the way the software would let me.&lt;/p&gt;

&lt;p&gt;I went from using &lt;a href=&quot;https://github.com/ranger/ranger&quot;&gt;Ranger&lt;/a&gt; as my file manager to writing &lt;a href=&quot;https://github.com/isene/RTFM&quot;&gt;RTFM&lt;/a&gt; to have it exactly the way I wanted it. Years of hand-coding Ruby. Then came a rush of applications, still hand-coding like mad; &lt;a href=&quot;https://github.com/isene/rcurses&quot;&gt;rcurses&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/astropanel&quot;&gt;astropanel&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/IMDB&quot;&gt;IMDB&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/rsh&quot;&gt;rsh&lt;/a&gt;, and many more. While I love Ruby’s elegance, it is slow. And being a performance junkie, I decided to let CC loose and port my main Ruby tools to Rust with amazing speed boosts.&lt;/p&gt;

&lt;p&gt;But that wasn’t enough. I still had stuff I wasn’t totally happy with and that still could use a speed increase. And so I got CC to churn out &lt;a href=&quot;https://isene.org/2026/04/Bare.html&quot;&gt;“bare” as my new login shell&lt;/a&gt; - a port of my Ruby Shell. I posted a link to &lt;a href=&quot;https://lobste.rs/s/wnizjm/my_login_shell_assembly&quot;&gt;lobste.rs about that&lt;/a&gt; that got some interesting reactions.&lt;/p&gt;

&lt;p&gt;The resulting Assembly shell is a 150Kb executable with a &lt;a href=&quot;https://github.com/isene/bare#benchmark&quot;&gt;9 microsecond startup time&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But a super-fast shell in a slow terminal? I know kitty hacks speed with running in single-instance mode, but even that can be made to go faster (and the single instance mode of kitty does have some drawbacks). And so &lt;a href=&quot;https://github.com/isene/glass&quot;&gt;glass&lt;/a&gt; the terminal emulator was born.&lt;/p&gt;

&lt;p&gt;How about a faster window manager that is tailored exactly to my needs? Yup, with CC anything is possible. Say hello to the new window manager, &lt;a href=&quot;https://github.com/isene/tile&quot;&gt;tile&lt;/a&gt;. And its companion &lt;a href=&quot;https://github.com/isene/strip&quot;&gt;strip&lt;/a&gt; (a replacement for &lt;a href=&quot;https://i3wm.org/docs/userguide.html#_configuring_i3bar&quot;&gt;i3bar&lt;/a&gt; and the like).&lt;/p&gt;

&lt;p&gt;This makes my window/terminal/shell experience lightning fast with no wasted CPU cycles and minimum memory footprint. This has boosted the battery life of my Dell XPS14 laptop by a few hours (the noisy fan is mostly quiet now). The setup is doing precisely what I need it to do. And if I need something changed or new features, then that is only a prompt away and some minutes of tweaking.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/chasm-desktop.png&quot; alt=&quot;The whole CHasm stack in one frame&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The whole stack in a single screen: &lt;strong&gt;tile&lt;/strong&gt; holding the layout, &lt;strong&gt;strip&lt;/strong&gt; + &lt;strong&gt;asmites&lt;/strong&gt; (the per-segment programs in &lt;a href=&quot;https://github.com/isene/chasm-bits&quot;&gt;chasm-bits&lt;/a&gt;) along the top status row, &lt;strong&gt;glass&lt;/strong&gt; in every pane (with pseudo-transparency picking up the wallpaper), &lt;strong&gt;bare&lt;/strong&gt; behind every prompt, and &lt;strong&gt;show&lt;/strong&gt; rendering syntax-highlighted source in the left and bottom-right panes. Every binary in that picture is pure x86_64 assembly talking straight to the kernel and the X server. No libc, no toolkit, nothing in between.&lt;/p&gt;

&lt;p&gt;My central apps like &lt;a href=&quot;https://github.com/isene/pointer&quot;&gt;pointer&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/kastrup&quot;&gt;kastrup&lt;/a&gt;, &lt;a href=&quot;https://github.com/isene/tock&quot;&gt;tock&lt;/a&gt; and &lt;a href=&quot;https://github.com/isene/nova&quot;&gt;nova&lt;/a&gt; can stay as single-binary executables written in Rust. They are fast enough (for now).&lt;/p&gt;

&lt;p&gt;From what I can research, nobody has previously built shell, terminal emulator, and window manager in pure x86_64 Linux assembly. And it was done in about two weeks.&lt;/p&gt;

&lt;p&gt;This is a whole new world where I command my own environment in ways that was completely out of reach back in 2025. I foresee the death of software as we know it where people use general purpose apps. I expect AI to craft tailor-made solutions for anyone with the imagination to ask for it.&lt;/p&gt;
</description>
        <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/04/MyTools.html</link>
          
        
            <category>Geekery</category>
        
            <category>Technology</category>
        
          
        
          
      </item>
    
    <item>
        <title>Making others feel good</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://isene.org/2022/04/Siv.html&quot;&gt;Siv&lt;/a&gt; reminded me of something important a couple of weeks ago; “It is more important to make the other person feel good than it is to be right.” This was reinforced by a couple of comments by &lt;a href=&quot;https://dualog.com/about-us/&quot;&gt;Morten Lind-Olsen&lt;/a&gt; the other day.&lt;/p&gt;

&lt;p&gt;This can be debated, and you can easily find counter-examples. But let it sink in just a bit. If the other person is not feeling good, then any right you may have or be, will not make much impact. A person needs to be receptive to receive.&lt;/p&gt;

&lt;p&gt;It’s in line with this quote from &lt;a href=&quot;https://www.goodreads.com/quotes/62616-when-the-choice-is-to-be-right-or-to-be&quot;&gt;Wayne Dyer&lt;/a&gt;, “When the choice is to be right or to be kind, always make the choice that brings peace.”&lt;/p&gt;

&lt;p&gt;And this attributed to &lt;a href=&quot;https://blog.innertune.com/lao-tzu-quotes/&quot;&gt;Lao Tzu&lt;/a&gt;, “Let go of your attachment to being right, and suddenly your mind is more open. You’re able to benefit from the unique viewpoints of others, without being crippled by your own judgment.”&lt;/p&gt;

&lt;p&gt;Or from &lt;a href=&quot;https://en.wikipedia.org/wiki/Scooter_(band)&quot;&gt;Scooter&lt;/a&gt; (originally John Templeton), “It’s nice to be important, but it’s more important to be nice.”&lt;/p&gt;

&lt;p&gt;Peace.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/kind2.png&quot; alt=&quot;In kind&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/04/Kind.html</link>
          
        
            <category>Philosophy</category>
        
            <category>Coaching</category>
        
          
        
          
      </item>
    
    <item>
        <title>Free Will; TEG released</title>
        <description>&lt;p&gt;After more than 40 years of research into Free Will and Mathematics, I have released my work on &lt;a href=&quot;https://isene.com/freewill&quot;&gt;Trans-Existential Grounding (TEG)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://philpapers.org/rec/ISEAMF&quot;&gt;academic paper&lt;/a&gt; was accepted on PhilPapers, marking a step toward a popular science book, “The Freedom Proof”.&lt;/p&gt;

&lt;p&gt;I’ve written several articles on Free Will over the years, including the &lt;a href=&quot;https://isene.org/onepagebooks/#1pb-3-free-will&quot;&gt;OnePageBook&lt;/a&gt;. But last summer I got the real breakthrough. Since then I’ve been busy formulating the mathematics and ensuring it is sound, and in parallel writing the upcoming book.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/teg1.png&quot; alt=&quot;TEG route 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The academic paper is mathematics-heavy, while the book takes a very different approach. It focuses on the reason for existence, your choices and personal responsibility.&lt;/p&gt;

&lt;p&gt;Stay tuned for progress on this project.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/teg2.png&quot; alt=&quot;TEG route 2&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/04/TEG.html</link>
          
        
            <category>Free Will</category>
        
            <category>Philosophy</category>
        
            <category>Mathematics</category>
        
            <category>Science</category>
        
          
        
          
      </item>
    
    <item>
        <title>My Login Shell in Assembly</title>
        <description>&lt;p&gt;Three shells. Three languages. One obsession with going deeper. And faster.&lt;/p&gt;

&lt;p&gt;I started with hand-crafting &lt;a href=&quot;https://github.com/isene/rsh&quot;&gt;rsh&lt;/a&gt;. Written in Ruby over a few years. Now 4,048 lines, full-featured, comfortable, slow. 300 millisecond startup. Fine for a scripting language, frustrating when I open lots of terminals in quick succession.&lt;/p&gt;

&lt;p&gt;Then I decided to &lt;a href=&quot;https://github.com/isene/rush&quot;&gt;rush&lt;/a&gt; to the next level. Rewriting rsh in Rust. Rush has 4,280 lines, same feature set, 26 millisecond startup. Part of the Fe2O3 suite of Rust terminal tools. Fast, but still loading a runtime, linking against libc, initializing a memory allocator.&lt;/p&gt;

&lt;p&gt;The question became, “what if there was nothing between my keystrokes and the kernel?”&lt;/p&gt;

&lt;h2 id=&quot;bare&quot;&gt;bare&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/isene/bare&quot;&gt;bare&lt;/a&gt; is an interactive shell written entirely in x86_64 Linux assembly.&lt;/p&gt;

&lt;p&gt;While I have written my fair share of assembly through the years (even raw hex coding), my projects have mainly been on the coconut processor, and never on x86. In just 4 evenings with maybe 6 hours total of coding with Claude Code, bare became my login shell.&lt;/p&gt;

&lt;p&gt;This shell has no libc, no runtime, no dynamic linking. Pure syscalls. The binary is 126KB and starts in &lt;strong&gt;8 microseconds&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./bare --bench
bare startup: 8 microseconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-numbers&quot;&gt;The numbers&lt;/h2&gt;

&lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 1em 0;&quot;&gt;
  &lt;tr&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: left;&quot;&gt;&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;rsh (Ruby)&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;rush (Rust)&lt;/th&gt;
    &lt;th style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;bare (Assembly)&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Language&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;Ruby&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;Rust&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;x86_64 ASM&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Source lines&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;4,048&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;4,280&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;13,366&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Binary size&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;~15MB (interpreter)&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;2.6MB&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;126KB&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Dependencies&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;Ruby runtime&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;libc, 8 crates&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;&lt;b&gt;none&lt;/b&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Startup&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;~300ms&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;~26ms&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;&lt;b&gt;8&amp;micro;s&lt;/b&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px;&quot;&gt;Dynamic linking&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;Yes&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;Yes&lt;/td&gt;
    &lt;td style=&quot;border: 1px solid #555; padding: 8px; text-align: center;&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;bare is &lt;strong&gt;3.4x faster than bash&lt;/strong&gt; on per-invocation CPU time and &lt;strong&gt;27x faster than rush&lt;/strong&gt;. The binary is 21x smaller than rush.&lt;/p&gt;

&lt;h2 id=&quot;what-you-get&quot;&gt;What you get&lt;/h2&gt;

&lt;p&gt;bare is now my daily login shell. It has:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dynamic prompt with git dirty indicator (green/red dot, no fork needed)&lt;/li&gt;
  &lt;li&gt;Multi-pipe, redirections, command chaining, background jobs&lt;/li&gt;
  &lt;li&gt;Command substitution &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$(cmd)&lt;/code&gt;, brace expansion &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{a,b,c}&lt;/code&gt;, globs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[a-z]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Nick aliases, global aliases, abbreviations (expand on space)&lt;/li&gt;
  &lt;li&gt;Interactive tab completion with LS_COLORS and cycling&lt;/li&gt;
  &lt;li&gt;Ctrl-R history search, inline suggestions, prefix filtering with Up/Down&lt;/li&gt;
  &lt;li&gt;Alt-F/Alt-B word movement&lt;/li&gt;
  &lt;li&gt;Job control (Ctrl-Z, fg, bg)&lt;/li&gt;
  &lt;li&gt;6 color themes, 18 configurable colors&lt;/li&gt;
  &lt;li&gt;Syntax highlighting while you type&lt;/li&gt;
  &lt;li&gt;Config file auto-saved on exit&lt;/li&gt;
  &lt;li&gt;Plugin system (any executable in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.bare/plugins/&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;AI integration via plugins (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:ask&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:suggest&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;time&lt;/code&gt; builtin, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--bench&lt;/code&gt; flag&lt;/li&gt;
  &lt;li&gt;Session save/load, calculator, command stats, validation rules&lt;/li&gt;
  &lt;li&gt;Companion TUI configurator: &lt;a href=&quot;https://github.com/isene/bareconf&quot;&gt;bareconf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything is coded with direct kernel interaction. Every &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read()&lt;/code&gt;, every &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;write()&lt;/code&gt;, every &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execve()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pipe()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dup2()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wait4()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt; is a raw &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;syscall&lt;/code&gt; instruction. No wrappers, no abstractions.&lt;/p&gt;

&lt;h2 id=&quot;the-details&quot;&gt;The details&lt;/h2&gt;

&lt;p&gt;The entire shell is one assembly file: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bare.asm&lt;/code&gt;. NASM syntax. Every feature that other shells delegate to libraries, bare implements from scratch:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Terminal control&lt;/strong&gt;: raw mode via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl(TCSETS)&lt;/code&gt;, character-by-character input&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Line editing&lt;/strong&gt;: cursor positioning with ANSI escape sequences&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tab completion&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opendir&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getdents64&lt;/code&gt; syscalls to scan directories&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Git branch&lt;/strong&gt;: reads &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git/HEAD&lt;/code&gt; directly, walks parent directories&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Git dirty&lt;/strong&gt;: compares &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stat()&lt;/code&gt; mtimes of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git/index&lt;/code&gt; vs ref file&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;History&lt;/strong&gt;: file I/O with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;write&lt;/code&gt; syscalls&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Job control&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wait4&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WUNTRACED&lt;/code&gt;, manual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIGSTOP&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Config&lt;/strong&gt;: hand-rolled line parser for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.barerc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The BSS section allocates all buffers statically. No heap, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brk&lt;/code&gt;. The kernel zero-fills BSS pages on demand.&lt;/p&gt;

&lt;h2 id=&quot;the-journey&quot;&gt;The journey&lt;/h2&gt;

&lt;p&gt;Going from Ruby to Rust was about speed. Going from Rust to assembly was about obsession and a dose of nostalgia and seeing what is actually possible with AI coding.&lt;/p&gt;

&lt;p&gt;When you write a shell in assembly, you learn exactly what a shell does. There’s no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::process::Command&lt;/code&gt;. There’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork()&lt;/code&gt; returning in two processes and you handling both. There’s no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crossterm::terminal::enable_raw_mode()&lt;/code&gt;. There’s a 60-byte termios struct and an ioctl number.&lt;/p&gt;

&lt;p&gt;Every bug teaches you something about Linux. A segfault from writing to the text section. A hang from SIGTTOU when the process group doesn’t own the terminal. A crash from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt; being a NASM keyword, not ASCII 36. All of these and more Claude and I had to get and debug.&lt;/p&gt;

&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/isene/bare.git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;bare
make
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or grab the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.deb&lt;/code&gt; from &lt;a href=&quot;https://github.com/isene/bare/releases&quot;&gt;the releases page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/bare-screenshot.png&quot; alt=&quot;bare shell screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Set it as your terminal shell and feel the difference. You probably don’t need 8 microsecond startup. But there is something satisfying about a shell with nothing between you and the kernel.&lt;/p&gt;

&lt;h2 id=&quot;chasm&quot;&gt;CHasm&lt;/h2&gt;

&lt;p&gt;bare is the first project in the &lt;strong&gt;CHasm&lt;/strong&gt; suite (CHange to ASM). Because sometimes the right answer to “can we make it faster?” is “remove everything.”&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Link to this post: https://isene.org/2026/04/Bare.html&lt;/p&gt;
</description>
        <pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate>
        
        <link>/2026/04/Bare.html</link>
          
        
            <category>Geekery</category>
        
            <category>Technology</category>
        
          
        
          
      </item>
    
  </channel>
</rss>
