<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Technology on sugar, spice, &amp;terminal? nice</title>
    <link>https://terminal.space/category/tech/</link>
    <description>Recent content in Technology on sugar, spice, &amp;terminal? nice</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 24 Feb 2026 15:50:31 +0000</lastBuildDate>
    <atom:link href="https://terminal.space/category/tech/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>My first Spec-Driven Development project</title>
      <link>https://terminal.space/tech/my-first-spec-driven-development-project/</link>
      <pubDate>Tue, 24 Feb 2026 15:50:31 +0000</pubDate>
      <guid>https://terminal.space/tech/my-first-spec-driven-development-project/</guid>
      <description>&lt;p&gt;Previous: &lt;a href=&#34;https://terminal.space/tech/introducing-frozendb/&#34;&gt;Introducing FrozenDB&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;Look ma, no hands&amp;rdquo; - I wrote &lt;a href=&#34;https://github.com/susu-dot-dev/frozenDB&#34;&gt;FrozenDB&lt;/a&gt; without writing lines of code. Instead, I used &lt;a href=&#34;https://github.com/github/spec-kit/blob/main/spec-driven.md&#34;&gt;spec-driven development&lt;/a&gt; to generate all of the user stories, map them carefully to technical requirements and have AI generate the code. I&amp;rsquo;ll go into SDD more deeply later, but for this post I wanted to share some of the learnings I had over the &lt;a href=&#34;https://github.com/susu-dot-dev/frozenDB/tree/main/specs&#34;&gt;40 specs&lt;/a&gt; I wrote as part of the process.&lt;/p&gt;&#xA;&lt;h1 id=&#34;start-small&#34;&gt;Start small&lt;/h1&gt;&#xA;&lt;p&gt;My first few specs took a lot of development cycles. I spent a lot of time in the &lt;code&gt;/speckit.plan&lt;/code&gt; stage refining the research and approach I wanted to take. Then, when I let the AI implement the specs, it went off and did something I didn&amp;rsquo;t want it to do. So I would have to go back to an earlier step (usually the spec.md), refine the requirements, and update every other document. This takes a lot of time and context switching. I realized my user stories were too big. For example, my &lt;a href=&#34;https://github.com/susu-dot-dev/frozenDB/blob/main/specs/001-create-db/spec.md&#34;&gt;first spec&lt;/a&gt; covered creating the database file, defining a header, and making it append-only. This took a very long time to get right, and involved a lot of tuning of every step of the spec.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introducing FrozenDB</title>
      <link>https://terminal.space/tech/introducing-frozendb/</link>
      <pubDate>Thu, 19 Feb 2026 17:56:30 +0000</pubDate>
      <guid>https://terminal.space/tech/introducing-frozendb/</guid>
      <description>&lt;p&gt;To make apple pie from scratch, you must first invent a database to store your recipes. - &lt;a href=&#34;https://en.wikipedia.org/wiki/Cosmos_(Sagan_book)&#34;&gt;Carl Sagan&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Well Carl (and avid readers), let me introduce you to &lt;a href=&#34;https://github.com/susu-dot-dev/frozenDB&#34;&gt;FrozenDB&lt;/a&gt;. This is my twist on a single-file database, with the requirement that it operates on append-only files. FrozenDB is not something for production, but a learning exercise. This companion post expands on some of the things I learned about append-only structures, and database mechanics.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Privacy and the Panopticon at the airport</title>
      <link>https://terminal.space/tech/privacy-and-the-panopticon-at-the-airport/</link>
      <pubDate>Sun, 15 Feb 2026 22:21:53 +0000</pubDate>
      <guid>https://terminal.space/tech/privacy-and-the-panopticon-at-the-airport/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/privacy-and-the-panopticon-at-the-airport/images/satwika-ananta-yUSNX3gjIQ4-unsplash.jpeg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;&amp;ldquo;Your ID is immaterial. We only use our face recognition software&amp;rdquo; is just the &lt;a href=&#34;https://arstechnica.com/tech-policy/2025/10/ices-forced-face-scans-to-verify-citizens-is-unconstitutional-lawmakers-say/&#34;&gt;latest trend&lt;/a&gt; in surveillance and control in the United States. This blog post is not about ICE&amp;rsquo;s Mobile Fortify, however, but connecting the dots between those ICE encounters and the compliant, unquestioning behavior of travelers at the airport. Staring into a camera adds specific, tagged training data to improve biometric algorithms (besides making you easy to identify later). A culture of blind compliance reinforces behaviors for both police state and its subjects for how these interactions should go.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI Killed Resumes</title>
      <link>https://terminal.space/tech/ai-killed-resumes/</link>
      <pubDate>Sat, 09 Aug 2025 05:05:48 +0000</pubDate>
      <guid>https://terminal.space/tech/ai-killed-resumes/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/ai-killed-resumes/images/interview-1.jpeg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m currently &lt;a href=&#34;https://ats.rippling.com/anaconda/jobs/46798a3e-1119-4a4e-b249-f9b7e2e549d9&#34;&gt;hiring a backend software engineer&lt;/a&gt; for my team. On the first day, we received hundreds of applications.&lt;/p&gt;&#xA;&lt;p&gt;Hundreds of &lt;strong&gt;garbage&lt;/strong&gt; applications.&lt;/p&gt;&#xA;&lt;p&gt;This isn&amp;rsquo;t entirely a new phenomenon. No matter what you put in the job requirements, I&amp;rsquo;ve always gotten a sea of &amp;ldquo;hey I&amp;rsquo;m a sales analyst, but I applied anyways&amp;rdquo; or &amp;ldquo;I&amp;rsquo;m applying for a senior role with 1 year of experience&amp;rdquo;. At least these types of applications have been extremely easy to filter away with any half-competent ATS tracking system, without introducing too many false negatives.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HowNot2 mock in Deno</title>
      <link>https://terminal.space/tech/hownot2-mock-in-deno/</link>
      <pubDate>Thu, 10 Jul 2025 15:00:30 +0000</pubDate>
      <guid>https://terminal.space/tech/hownot2-mock-in-deno/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/hownot2-mock-in-deno/images/naoki-suzuki-JL3or092e-8-unsplash1.jpg&#34;&#xA;    alt=&#34;A funky crocodile made out of cups and other materials. It is sitting on top of some other cartoon character, wearing a read hat&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;A funky crocodile made out of cups and other materials. It is sitting on top of some other cartoon character, wearing a read hat&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Mocking functions in deno is very limited, compared to NodeJS. Maybe, it&amp;rsquo;s so bad that it&amp;rsquo;s actually great. As your resident ruby-hater-in-chief, I&amp;rsquo;m here to tell you that code &amp;ldquo;magically working&amp;rdquo; comes at great cost. Today we&amp;rsquo;re going to learn about why modern javascript broke mocking, and why Deno refused to create magic to pretend otherwise.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why can&#39;t we (pip and conda) be friends?</title>
      <link>https://terminal.space/tech/why-cant-we-pip-and-conda-be-friends/</link>
      <pubDate>Wed, 09 Jul 2025 15:19:32 +0000</pubDate>
      <guid>https://terminal.space/tech/why-cant-we-pip-and-conda-be-friends/</guid>
      <description>&lt;p&gt;&amp;ldquo;Don&amp;rsquo;t mix pip and conda&amp;rdquo; - is the general advice from &lt;a href=&#34;https://www.anaconda.com/blog/using-pip-in-a-conda-environment&#34;&gt;Anaconda&lt;/a&gt;, or if you must, use pip after conda. But why? One of the reasons is that conda and pip have different ways of tracking which packages are installed in an environment, and which packages should be installed in an environment. Let&amp;rsquo;s dig in.&lt;/p&gt;&#xA;&lt;h2 id=&#34;i-just-came-here-for-the-tldr&#34;&gt;I just came here for the TL;DR:&lt;/h2&gt;&#xA;&lt;p&gt;Too bad there isn&amp;rsquo;t a TL;DR. If you&amp;rsquo;d rather run the examples yourself, however, head over to &lt;a href=&#34;https://github.com/intentionally-left-nil/py_dependency_investigation&#34;&gt;https://github.com/intentionally-left-nil/py_dependency_investigation&lt;/a&gt; and follow the instructions. You can run any of the scenarios in the &lt;a href=&#34;https://github.com/intentionally-left-nil/py_dependency_investigation/blob/main/Makefile&#34;&gt;makefile&lt;/a&gt;, and make up your own conclusions&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ignore your post-training and sound normal, damnit</title>
      <link>https://terminal.space/tech/ignore-your-post-training-and-sound-normal-damnit/</link>
      <pubDate>Sat, 21 Jun 2025 05:32:17 +0000</pubDate>
      <guid>https://terminal.space/tech/ignore-your-post-training-and-sound-normal-damnit/</guid>
      <description>&lt;h2 id=&#34;the-technical-bits-are-at-the-bottom-just-skip-ahead-if-you-want-&#34;&gt;The technical bits are at the bottom, just skip ahead if you want :)&lt;/h2&gt;&#xA;&lt;p&gt;For all my academic friends out there, yes - this is yet another blog article lamenting the rise of AI-generated text. However, my beef isn&amp;rsquo;t the atrophy of critical thinking, investment of time, or ability to write. Instead, I can&amp;rsquo;t get the thing to sound like me. I&amp;rsquo;ll go into &lt;em&gt;why&lt;/em&gt; I want a bot to generate content, but first we need to take a sidebar into what outcome I&amp;rsquo;m going for in the first place.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding Softmax</title>
      <link>https://terminal.space/tech/understanding-softmax/</link>
      <pubDate>Wed, 04 Jun 2025 15:27:15 +0000</pubDate>
      <guid>https://terminal.space/tech/understanding-softmax/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/understanding-softmax/images/boliviainteligente-iKUKpvYikig-unsplash1.jpg&#34;&#xA;    alt=&#34;A collection of pastel colored billiard balls&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;A collection of pastel colored billiard balls&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;When running an inference server, you can choose settings like &lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;top-p&lt;/code&gt;, and &lt;code&gt;top-k&lt;/code&gt;. To understand these values, we really just need an understanding of the softmax activation function. I couldn&amp;rsquo;t really find one single website that made the reasoning behind softmax click very easily, so I decided to make a blog post about it. Maybe your brain is wired like mine and this will help :)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Backing up docker volumes</title>
      <link>https://terminal.space/tech/backing-up-docker-volumes/</link>
      <pubDate>Mon, 09 Dec 2024 14:57:12 +0000</pubDate>
      <guid>https://terminal.space/tech/backing-up-docker-volumes/</guid>
      <description>&lt;p&gt;In today&amp;rsquo;s I-can&amp;rsquo;t-believe-I&amp;rsquo;m-doing-this-in-2024&lt;/p&gt;&#xA;&lt;p&gt;I needed to re-build my webserver because it kept hard-freezing every week (another post for another day). Since I use a docker setup for this, my setup is pretty turnkey - I just needed to copy over my docker volumes from the old host to the new host.&lt;/p&gt;&#xA;&lt;p&gt;That turned out to be a lot more annoying than what I wanted. See, this functionality hasn&amp;rsquo;t existed for a long time. You had to use some DIY &lt;a href=&#34;https://stackoverflow.com/questions/38298645/how-should-i-backup-restore-docker-named-volumes&#34;&gt;StackOverflow&lt;/a&gt; scripts. Apparently, this functionality is now built into Docker Desktop, but A. I&amp;rsquo;m ssh&amp;rsquo;d into a server and B. Docker Desktop is the trojan horse where they extort people for licenses. In either case, I just have access to the docker daemon.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hibernating is easy now?</title>
      <link>https://terminal.space/tech/hibernating-is-easy-now/</link>
      <pubDate>Mon, 02 Sep 2024 21:33:09 +0000</pubDate>
      <guid>https://terminal.space/tech/hibernating-is-easy-now/</guid>
      <description>&lt;p&gt;Alternatively: S0ix is still awful&lt;/p&gt;&#xA;&lt;p&gt;My Linux laptop runs out of battery all the time. It goes to sleep, and then it just drains and drains until it&amp;rsquo;s dead. It&amp;rsquo;s a problem we&amp;rsquo;ve largely solved on phones (and phone operating systems), but still struggle with on desktop operating systems.&lt;/p&gt;&#xA;&lt;p&gt;I remember doing a lot of debugging back when I worked on Windows 8 to try to diagnose bad suspend times (those prototype devices were terrible in many other ways but the standby sticks out in my memory)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hello activitypub?</title>
      <link>https://terminal.space/tech/hello-activitypub/</link>
      <pubDate>Sun, 05 May 2024 06:17:41 +0000</pubDate>
      <guid>https://terminal.space/tech/hello-activitypub/</guid>
      <description>&lt;p&gt;Will this federate? Who knows! Will comments work? probably not!&lt;/p&gt;</description>
    </item>
    <item>
      <title>Adding a sliding animation in 2024 - WHY IS THIS SO HARD</title>
      <link>https://terminal.space/tech/adding-a-sliding-animation-in-2024-why-is-this-so-hard/</link>
      <pubDate>Sun, 05 May 2024 05:44:38 +0000</pubDate>
      <guid>https://terminal.space/tech/adding-a-sliding-animation-in-2024-why-is-this-so-hard/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/adding-a-sliding-animation-in-2024-why-is-this-so-hard/images/karl-abuid-7ezVb0oTQ6M-unsplash.jpg&#34;&#xA;    alt=&#34;A tower of blocks&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;A tower of blocks&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I had a scenario for a &lt;a href=&#34;https://github.com/intentionally-left-nil/wall_of_thanks/&#34;&gt;personal project&lt;/a&gt; where I had e.g. a (+) button, and clicking that button should insert a new thingy into the DOM. No problem-o. &lt;code&gt;button.addAdjacentHTML(element, &amp;lt;div&amp;gt;thingy&amp;lt;/div&amp;gt;)&lt;/code&gt; to the rescue.&lt;/p&gt;&#xA;&lt;p&gt;Okay, now do it, but with animations. Sure easy, peasy. Let me just animate opacity 0 -&amp;gt; 1 and&amp;hellip; oh, that works for the new element, but the rest of the page just snaps to the new layout. That&amp;rsquo;s pretty jarring.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Easy, secure API keys</title>
      <link>https://terminal.space/tech/easy-secure-api-keys/</link>
      <pubDate>Sun, 27 Aug 2023 02:06:05 +0000</pubDate>
      <guid>https://terminal.space/tech/easy-secure-api-keys/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/easy-secure-api-keys/images/christian-lendl-ZyttGSu-o2E-unsplash.jpg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I needed to add API key authentication to our work environment. I needed:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;To develop the functionality quickly&lt;/li&gt;&#xA;&lt;li&gt;Be confident in the security of the system&#xA;&lt;ul&gt;&#xA;&lt;li&gt;API keys should only be visible once when created&lt;/li&gt;&#xA;&lt;li&gt;Should be hard to impersonate other users/be resilient to DB leak&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Have an upgrade path for when we want to change/improve things&lt;/li&gt;&#xA;&lt;li&gt;Performance isn&amp;rsquo;t a huge consideration&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I was able to use JWT tokens in a slightly clever way to make this happen. The best part is, there are no stored secrets on the server side. All of the server data could be revealed publicly without compromising the security. Here&amp;rsquo;s how:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automatic recovery using lvm-autosnap</title>
      <link>https://terminal.space/tech/automatic-recovery-using-lvm-autosnap/</link>
      <pubDate>Wed, 12 Oct 2022 20:00:17 +0000</pubDate>
      <guid>https://terminal.space/tech/automatic-recovery-using-lvm-autosnap/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/automatic-recovery-using-lvm-autosnap/images/dietmar-becker-8Zt0xOOK4nI-unsplash.jpg&#34;&#xA;    alt=&#34;Two vintage cars side-by-side. The one on the left is rusted out and missing headlights. The one on the right has been restored to good condition &#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;Two vintage cars side-by-side. The one on the left is rusted out and missing headlights. The one on the right has been restored to good condition&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;TL;DR: &lt;a href=&#34;https://github.com/intentionally-left-nil/lvm-autosnap&#34;&gt;https://github.com/intentionally-left-nil/lvm-autosnap&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Running linux is an adventure. About a year ago, I switched from MacOS to Ubuntu (eww snaps), then Fedora (fine), then Manjaro (yeah that was a mistake) until finally landing on the final boss, Arch linux. Honestly, Arch is great. It does what I want, which is to spend an inordinate amount of time fixing things that used to work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Go concurrency the right way (e.g. my way)</title>
      <link>https://terminal.space/tech/go-concurrency-the-right-way-e-g-my-way/</link>
      <pubDate>Fri, 23 Sep 2022 04:01:41 +0000</pubDate>
      <guid>https://terminal.space/tech/go-concurrency-the-right-way-e-g-my-way/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/go-concurrency-the-right-way-e-g-my-way/images/john-cameron-kY2H30v6Bs4-unsplash.jpg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;My take on go concurrency is that there are 3 things that matter, and we can create a robust pattern using &amp;hellip; 3 technologies to help us out. None of this is really new, but I haven&amp;rsquo;t seen the material presented from this particular viewpoint. With that, and the additional caveat that this isn&amp;rsquo;t a beginner&amp;rsquo;s guide, let&amp;rsquo;s jump straight in&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-matters&#34;&gt;What matters&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Startup&lt;/li&gt;&#xA;&lt;li&gt;Shutdown&lt;/li&gt;&#xA;&lt;li&gt;Throughput&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Once everything is _working_ it&amp;rsquo;s not all that complicated (*) to do concurrency in golang (or any other programming language. Data comes in, it gets farmed out to wherever it needs to go, and you have some synchronization method to prevent corruption.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introducing Async Service</title>
      <link>https://terminal.space/tech/introducing-async-service/</link>
      <pubDate>Sat, 20 Aug 2022 07:04:44 +0000</pubDate>
      <guid>https://terminal.space/tech/introducing-async-service/</guid>
      <description>&lt;h1 id=&#34;distributed-tasks-with-postgres--rabbitmq&#34;&gt;Distributed tasks with Postgres &amp;amp; Rabbitmq&lt;/h1&gt;&#xA;&lt;p&gt;TL;DR: &lt;a href=&#34;https://www.db-fiddle.com/f/yeKfmXg2nLbhZBLzWi11W/2&#34;&gt;Check out the code here&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;At my workplace, we needed a mechanism to:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Have service A tell service B to start executing long-running tasks, with notifications upon completion&lt;/li&gt;&#xA;&lt;li&gt;Add reliability to cross-service infrastructure to be resilient to temporary outages&lt;/li&gt;&#xA;&lt;li&gt;Support nested jobs where Job 1 needs to complete sub-steps 1a, 1b, 1c, etc. which are all jobs themselves&lt;/li&gt;&#xA;&lt;li&gt;Support scaling to accommodate large surges of jobs&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;I considered different off-the-shelf products, but ended up feeling like we would need to fork the functionality to get the behavior we wanted. I also wanted to avoid introducing yet-another-stack, query syntax, and more into our system. Since our backend already is based around postgres and rabbitmq, I singlehandedly designed and implemented async service to handle our needs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Initramfs with systemd &amp; LUKS</title>
      <link>https://terminal.space/tech/initramfs-with-systemd-luks/</link>
      <pubDate>Sun, 31 Jul 2022 02:20:45 +0000</pubDate>
      <guid>https://terminal.space/tech/initramfs-with-systemd-luks/</guid>
      <description>&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[me@mycomputer]# cat /etc/sbupdate.conf | grep &amp;#34;^CMDLINE_DEFAULT&amp;#34;&#xA;CMDLINE_DEFAULT=&amp;#34;rd.luks.uuid=c1f995f5-a8f7-47f0-b085-6d3a159e1874 rd.luks.allow-discards resume=UUID=51384ac6-f197-41d9-b8c8-c9607d7e01c8 rd.udev.log-priority=3 nvme.noacpi=1 quiet splash root=UUID=a645810c-ef87-4a9a-9239-afdeaf292e6e rw&amp;#34;&#xA;&#xA;[me@mycomputer]# cat /etc/mkinitcpio.conf | grep &amp;#34;^HOOKS&amp;#34;&#xA;HOOKS=(systemd keyboard autodetect sd-vconsole modconf block sd-encrypt lvm2 filesystems fsck)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My old boot process looks like this:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;UEFI (with secure boot on)&lt;/li&gt;&#xA;&lt;li&gt;systemd-boot&lt;/li&gt;&#xA;&lt;li&gt;unified kernel.efi (initramfs + kernel params + kernel all rolled into one efi and signed)&lt;/li&gt;&#xA;&lt;li&gt;initramfs (busybox)&lt;/li&gt;&#xA;&lt;li&gt;encrypt hook: detects that a password is needed -&amp;gt; prompt for password&lt;/li&gt;&#xA;&lt;li&gt;Unlock LUKS partition&lt;/li&gt;&#xA;&lt;li&gt;LVM hook detects the LUKS partition and loads the logical volume groups/volumes&lt;/li&gt;&#xA;&lt;li&gt;The root partition is loaded and control gets passed off to the real kernel&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Which was set up via the following configs:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Interfaces in golang</title>
      <link>https://terminal.space/tech/interfaces-in-golang/</link>
      <pubDate>Tue, 11 Jan 2022 08:48:23 +0000</pubDate>
      <guid>https://terminal.space/tech/interfaces-in-golang/</guid>
      <description>&lt;h2 id=&#34;tldr&#34;&gt;TL;DR:&lt;/h2&gt;&#xA;&lt;p&gt;An interface just defines a collection of methods. When you create an instance, it&amp;rsquo;s just a wrapper around a concrete type. In addition to the concrete type, the interface contains an extra array of function pointers. These function pointers correspond to each method in the interface that the concrete type implements&lt;/p&gt;&#xA;&lt;h2 id=&#34;first-a-detour&#34;&gt;First, a detour&lt;/h2&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s define a custom type, and some methods that go with it:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;package main&#xA;&#xA;import &amp;#34;fmt&amp;#34;&#xA;&#xA;type ComputerProgrammer string&#xA;&#xA;func (c ComputerProgrammer) Greet(name string) string {&#xA;&#x9;return string(c) + &amp;#34;: hello, &amp;#34; + name&#xA;}&#xA;&#xA;func (c ComputerProgrammer) Walk(distance int) int {&#xA;&#x9;return len(c) + distance&#xA;}&#xA;&#xA;func main() {&#xA;&#x9;a := ComputerProgrammer(&amp;#34;golang&amp;#34;)&#xA;&#x9;fmt.Println(a.Greet(&amp;#34;world&amp;#34;), a.Walk(5))&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When go compiles this code, it generates a function similar to this:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Secure DNS</title>
      <link>https://terminal.space/tech/secure-dns/</link>
      <pubDate>Thu, 30 Dec 2021 08:06:19 +0000</pubDate>
      <guid>https://terminal.space/tech/secure-dns/</guid>
      <description>&lt;p&gt;TL;DR: Use a VPN if you really care.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://imgs.xkcd.com/comics/networking%5Fproblems.png&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Hey, you over there! Want to take something that works perfectly well and make it more complicated? Sure ya do! Oh, need a little more convincing?&lt;/p&gt;&#xA;&lt;p&gt;Okay - here&amp;rsquo;s the rundown. We use &lt;code&gt;https&lt;/code&gt; to keep the baddies from seeing what we browse on the internet. So far, so good. However, there&amp;rsquo;s a problem - DNS. DNS isn&amp;rsquo;t encrypted for &amp;hellip;. reasons (see the above webcomic). And if you don&amp;rsquo;t change any of your settings, then you&amp;rsquo;re probably getting your DNS records from your ISP. Which means your ISP knows everything about what you try to visit.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Matching socks: Nginx &#43; php = Wordpress (Part 3)</title>
      <link>https://terminal.space/tech/matching-socks-nginx-php-wordpress-part-3/</link>
      <pubDate>Wed, 02 Jun 2021 11:01:09 +0000</pubDate>
      <guid>https://terminal.space/tech/matching-socks-nginx-php-wordpress-part-3/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/matching-socks-nginx-php-wordpress-part-3/images/alfred-rowe-1zTetyivDYE-unsplash.jpg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://terminal.space/tech/wordpress-hosting-docker-style-part-1/&#34;&gt;Part 1: Wordpress hosting, docker style&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://terminal.space/tech/cron-letsencrypt-docker-style-part-2/&#34;&gt;Part 2: Cron + LetsEncrypt, docker style&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://terminal.space/tech/matching-socks-nginx-php-wordpress-part-3/&#34;&gt;Part 3: Matching socks: Nginx + php = Wordpress&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Previously, we&amp;rsquo;ve covered terminating SSL connections and running cron jobs. Now it&amp;rsquo;s time to actually set up a wordpress installation. The two main ingredients are a web server, and a php server. All requests go through the web server (nginx, again in this case). If the filepath ends in a .php extension, then the request gets forwarded to the php-fpm (basically php with a &lt;a href=&#34;https://stackoverflow.com/a/2089297/3029173&#34;&gt;FastCGI&lt;/a&gt; implementation) to do the server-side processing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ad Blocking w/Raspberry Pi</title>
      <link>https://terminal.space/tech/ad-blocking-w-raspberry-pi/</link>
      <pubDate>Mon, 10 May 2021 23:53:27 +0000</pubDate>
      <guid>https://terminal.space/tech/ad-blocking-w-raspberry-pi/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/ad-blocking-w-raspberry-pi/images/harrison-broadbent-bw5a4zQMRCI-unsplash.jpg&#34;&#xA;    alt=&#34;Image of a Raspberry Pi&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;Image of a Raspberry Pi&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve used different technologies to block ads for a long time. I remember my first computer used &lt;a href=&#34;https://en.wikipedia.org/wiki/Proxomitron&#34;&gt;Proxomitron&lt;/a&gt; to great success in the early web. (HTTPS wasn&amp;rsquo;t much of a thing back then which made MITM proxies a lot easier to set up!)&lt;/p&gt;&#xA;&lt;p&gt;My Pi-Hole recently started acting more and more strangely, so I decided it was time to start fresh - and document it this time. I have three goals for this project:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cron &#43; LetsEncrypt, docker style (Part 2)</title>
      <link>https://terminal.space/tech/cron-letsencrypt-docker-style-part-2/</link>
      <pubDate>Mon, 15 Mar 2021 20:49:50 +0000</pubDate>
      <guid>https://terminal.space/tech/cron-letsencrypt-docker-style-part-2/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/cron-letsencrypt-docker-style-part-2/images/glenn-carstens-peters-piNf3C4TViA-unsplash.jpg&#34;&#xA;    alt=&#34;Cornfield&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;Cornfield&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://terminal.space/tech/wordpress-hosting-docker-style-part-1/&#34;&gt;Part 1: Wordpress hosting, docker style&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://terminal.space/tech/cron-letsencrypt-docker-style-part-2/&#34;&gt;Part 2: Cron + LetsEncrypt, docker style&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://terminal.space/tech/matching-socks-nginx-php-wordpress-part-3/&#34;&gt;Part 3: Matching socks: Nginx + php = Wordpress&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Today, I&amp;rsquo;m going to talk about running background jobs with docker. On a non-docker system, you can set up a server to do many things at once - for example run nginx AND update your SSL certs periodically. However, with Docker, you have to choose. You either need to run each process as a separate docker container, or you need to use some sort of supervisor process (supervisord, &lt;a href=&#34;https://laptrinhx.com/docker-containers-running-alpine-linux-and-s6-for-process-management-solid-reliable-containers-3512281510/&#34;&gt;s6&lt;/a&gt;, systemd, etc) which will in-turn kick off the other processes you&amp;rsquo;re interested in.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wordpress feature hacking</title>
      <link>https://terminal.space/tech/wordpress-feature-hacking/</link>
      <pubDate>Thu, 11 Mar 2021 00:18:18 +0000</pubDate>
      <guid>https://terminal.space/tech/wordpress-feature-hacking/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m using &lt;a href=&#34;https://www.kokoanalytics.com/&#34;&gt;Koko analytics&lt;/a&gt; on my site to generally see if it&amp;rsquo;s getting traffic (it&amp;rsquo;s not :D). One thing I wanted to add was a site counter as a throwback to my original website which tracked such things. The data is clearly there since Koko can display the visitors over time:&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/wordpress-feature-hacking/images/Screen-Shot-2021-03-10-at-3.51.14-PM.png&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Okay, so let&amp;rsquo;s get started. Luckily, after cloning the repo, I found an existing &lt;a href=&#34;https://github.com/AnilRedshift/koko-analytics/blob/site_counter/src/class-shortcode-most-viewed-posts.php&#34;&gt;file which generates a shortcode&lt;/a&gt;. I started there &amp;amp; copy/paste/changed the filename. I didn&amp;rsquo;t know how to get the data I wanted, but I just wanted the file to show up. I ended up searching for &lt;code&gt;Shortcode_Most_Viewed_Posts&lt;/code&gt; to see how it gets used, and I found the following snippet:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wordpress hosting, docker style (Part 1)</title>
      <link>https://terminal.space/tech/wordpress-hosting-docker-style-part-1/</link>
      <pubDate>Tue, 09 Mar 2021 07:07:32 +0000</pubDate>
      <guid>https://terminal.space/tech/wordpress-hosting-docker-style-part-1/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/wordpress-hosting-docker-style-part-1/images/beanca-du-toit-pCNiuZ8lvpc-unsplash.jpg&#34;&#xA;    alt=&#34;A whale, coming out of the water&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;A whale, coming out of the water&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://terminal.space/tech/wordpress-hosting-docker-style-part-1/&#34;&gt;Part 1: Wordpress hosting, docker style&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://terminal.space/tech/cron-letsencrypt-docker-style-part-2/&#34;&gt;Part 2: Cron + LetsEncrypt, docker style&lt;/a&gt;&lt;br&gt;&#xA;&lt;a href=&#34;https://terminal.space/tech/matching-socks-nginx-php-wordpress-part-3/&#34;&gt;Part 3: Matching socks: Nginx + php = Wordpress&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Those &lt;a href=&#34;https://terminal.space/tech/wordpress-hosting-from-scratch/&#34;&gt;segfaults&lt;/a&gt; I mentioned? Yeah, they proved unsolvable. Nginx Unit seems to be having a rough time and un-extracting Nginx Unit from the install script was more difficult than expected too.&lt;/p&gt;&#xA;&lt;p&gt;Instead, I spent more time than that setting up my &lt;a href=&#34;https://github.com/AnilRedshift/www_docker/&#34;&gt;own cluster of docker containers&lt;/a&gt;. The benefit is that I can now run a whole copy locally, test changes, and then push to production. It also allows me to track what changes to all the various .conf files I&amp;rsquo;ve been making. Today, I&amp;rsquo;ll talk about setting up a SSL-terminating reverse-proxy, and how to host it with docker-compose.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TIL: Filtering email with Protonmail</title>
      <link>https://terminal.space/tech/til-filtering-email-with-protonmail/</link>
      <pubDate>Sun, 07 Mar 2021 17:14:54 +0000</pubDate>
      <guid>https://terminal.space/tech/til-filtering-email-with-protonmail/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m subscribed to an email listserv. The problem is they&amp;rsquo;re always ending up in my ProtonMail spam folder.&lt;/p&gt;&#xA;&lt;p&gt;ProtonMail offers &lt;a href=&#34;https://protonmail.com/support/knowledge-base/spam-filtering/&#34;&gt;only a very simple option&lt;/a&gt; in the UI for dealing with spam: An explicit allowed senders list, and a blocked senders list. For me, that doesn&amp;rsquo;t work because each email comes from a different sender in the listserv, and I don&amp;rsquo;t want to keep adding every person&amp;rsquo;s name.&lt;/p&gt;&#xA;&lt;p&gt;However, ProtonMail actually does provide a very powerful scripting capability, if you&amp;rsquo;re willing to write some code. To get started, head to settings -&amp;gt; filter -&amp;gt; add filter&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fairphone 3&#43; Review</title>
      <link>https://terminal.space/tech/fairphone-3-review/</link>
      <pubDate>Sat, 27 Feb 2021 00:48:41 +0000</pubDate>
      <guid>https://terminal.space/tech/fairphone-3-review/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/fairphone-3-review/images/Fairphone.jpg&#34;&#xA;    alt=&#34;Back image of the Fairphone 3&amp;#43;&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;p&gt;Back image of the Fairphone 3+&lt;/p&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;TL;DR: The Fairphone3+ works well with T-Mobile in the United States. It connects smoothly and performs just like you&amp;rsquo;d expect any other Android phone to work.&lt;/p&gt;&#xA;&lt;p&gt;I was in the market to replace my old iPhone, and decided to give the &lt;a href=&#34;https://www.fairphone.com/en/story/&#34;&gt;Fairphone&lt;/a&gt; a go. I definitely have a sense of &amp;ldquo;well is there an ethical smartphone under capitalism?&amp;rdquo; nihilism. However, I&amp;rsquo;m trying my best to hold that in duality and try better. Or as &lt;a href=&#34;https://tatianamac.com/posts/why-judgment-isnt-helpful/&#34;&gt;Tatiana Mac writes&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wordpress hosting from scratch</title>
      <link>https://terminal.space/tech/wordpress-hosting-from-scratch/</link>
      <pubDate>Fri, 26 Feb 2021 11:58:43 +0000</pubDate>
      <guid>https://terminal.space/tech/wordpress-hosting-from-scratch/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/wordpress-hosting-from-scratch/images/vilmar-simion-ffREEWWVimk-unsplash-1.jpg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Alternative title: Why it&amp;rsquo;s worth it to pay for wordpress hosting.&lt;br&gt;&#xA;Alternative title 2: Why is Ansible so complicated?&lt;/p&gt;&#xA;&lt;p&gt;I have no idea why someone would scan the outside of a PSU, but it makes for a segue to this lede - which promises to be the best part of this post:&lt;/p&gt;&#xA;&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;&#xA;      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/bOfpQt4KFCc?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;&#xA;    &lt;/div&gt;&#xA;&#xA;&lt;p&gt;Just your typical barcode jam sesh&lt;/p&gt;</description>
    </item>
    <item>
      <title>Goodbye, AWS; hello, world!</title>
      <link>https://terminal.space/tech/goodbye-aws-hello-world/</link>
      <pubDate>Sun, 21 Feb 2021 05:51:07 +0000</pubDate>
      <guid>https://terminal.space/tech/goodbye-aws-hello-world/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://terminal.space/tech/goodbye-aws-hello-world/images/hello-i-m-nik-r22qS5ejODs-unsplash.jpg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Let me start at the end - Hello, world! Welcome to my new blog. This is the first time I&amp;rsquo;ve revamped the &lt;a href=&#34;https://terminal.space&#34;&gt;terminal.space&lt;/a&gt; domain since its inception. It was previously, well, just a terminal, and not a very good one at that. But now, I have an actual (w/root!) webserver and a motivation to write.&lt;/p&gt;&#xA;&lt;p&gt;As I&amp;rsquo;m going through the incantations to configure everything (probably incorrectly), I wanted to take a moment to pay homage to &lt;a href=&#34;https://web.archive.org/web/20090217050544/http://spyware-free.us/&#34;&gt;my very first website&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
